embed plugin loader directly into the launcher

This commit is contained in:
zznty
2022-10-29 01:50:14 +07:00
parent 7204815c0c
commit 66d3dc2ead
53 changed files with 5689 additions and 10 deletions

View File

@@ -0,0 +1,320 @@
using System.Diagnostics.CodeAnalysis;
using Sandbox;
using Sandbox.Game.Gui;
using Sandbox.Game.Localization;
using Sandbox.Graphics.GUI;
using VRage;
using VRage.Game;
using VRage.Utils;
using VRageMath;
using Color = VRageMath.Color;
namespace PluginLoader.GUI;
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public abstract class TableDialogBase : MyGuiScreenDebugBase
{
protected readonly string Caption;
protected readonly string DefaultKey;
protected readonly Dictionary<string, string> NamesByKey = new();
protected MyGuiControlButton CancelButton;
protected int ColumnCount;
protected MyGuiControlButton DeleteButton;
protected MyGuiControlButton LoadButton;
protected MyGuiControlButton RenameButton;
protected MyGuiControlTable Table;
protected TableDialogBase(
string caption,
string defaultKey = null)
: base(new(0.5f, 0.5f), new Vector2(1f, 0.8f),
MyGuiConstants.SCREEN_BACKGROUND_COLOR * MySandboxGame.Config.UIBkOpacity, true)
{
Caption = caption;
DefaultKey = defaultKey;
// ReSharper disable once VirtualMemberCallInConstructor
RecreateControls(true);
CanBeHidden = true;
CanHideOthers = true;
CloseButtonEnabled = true;
m_onEnterCallback = LoadAndClose;
}
protected abstract string ItemName { get; }
protected abstract string[] ColumnHeaders { get; }
protected abstract float[] ColumnWidths { get; }
protected abstract object[] ExampleValues { get; }
private Vector2 DialogSize => m_size ?? Vector2.One;
private string SelectedKey => Table.SelectedRow?.UserData as string;
public override string GetFriendlyName()
{
return "ListDialog";
}
protected virtual string NormalizeName(string name)
{
return name.Trim();
}
protected virtual int CompareNames(string a, string b)
{
return string.Compare(a, b, StringComparison.CurrentCultureIgnoreCase);
}
protected abstract IEnumerable<string> IterItemKeys();
protected abstract ItemView GetItemView(string key);
protected abstract void OnLoad(string key);
protected abstract void OnRenamed(string key, string name);
protected abstract void OnDelete(string key);
public override void RecreateControls(bool constructor)
{
base.RecreateControls(constructor);
AddCaption(Caption, Color.White.ToVector4(), new Vector2(0.0f, 0.003f));
CreateTable();
CreateButtons();
}
private void CreateTable()
{
var columnHeaders = ColumnHeaders;
var columnWidths = ColumnWidths;
if (columnHeaders == null || columnWidths == null)
return;
ColumnCount = columnHeaders.Length;
Table = new()
{
Position = new(0.001f, -0.5f * DialogSize.Y + 0.1f),
Size = new(0.85f * DialogSize.X, DialogSize.Y - 0.25f),
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP,
ColumnsCount = ColumnCount,
VisibleRowsCount = 15
};
Table.SetCustomColumnWidths(columnWidths);
var exampleValues = ExampleValues;
for (var colIdx = 0; colIdx < ColumnCount; colIdx++)
{
Table.SetColumnName(colIdx, new(columnHeaders[colIdx]));
switch (exampleValues[colIdx])
{
case int _:
Table.SetColumnComparison(colIdx, CellIntComparison);
break;
default:
Table.SetColumnComparison(colIdx, CellTextComparison);
break;
}
}
AddItems();
Table.SortByColumn(0);
Table.ItemDoubleClicked += OnItemDoubleClicked;
Controls.Add(Table);
}
private int CellTextComparison(MyGuiControlTable.Cell x, MyGuiControlTable.Cell y)
{
var a = NormalizeName(x.Text.ToString());
var b = NormalizeName(y.Text.ToString());
return CompareNames(a, b);
}
private int CellIntComparison(MyGuiControlTable.Cell x, MyGuiControlTable.Cell y)
{
return (x.UserData as int? ?? 0) - (y.UserData as int? ?? 0);
}
private void CreateButtons()
{
LoadButton = new(
visualStyle: MyGuiControlButtonStyleEnum.Default,
originAlign: MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER,
text: new("Load"), onButtonClick: OnLoadButtonClick);
RenameButton = new(
visualStyle: MyGuiControlButtonStyleEnum.Small,
originAlign: MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER,
text: new("Rename"), onButtonClick: OnRenameButtonClick);
DeleteButton = new(
visualStyle: MyGuiControlButtonStyleEnum.Small,
originAlign: MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER,
text: new("Delete"), onButtonClick: OnDeleteButtonClick);
CancelButton = new(
visualStyle: MyGuiControlButtonStyleEnum.Default,
originAlign: MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER,
text: MyTexts.Get(MyCommonTexts.Cancel), onButtonClick: OnCancelButtonClick);
var xs = 0.85f * DialogSize.X;
var y = 0.5f * (DialogSize.Y - 0.15f);
LoadButton.Position = new(-0.39f * xs, y);
RenameButton.Position = new(-0.08f * xs, y);
DeleteButton.Position = new(0.08f * xs, y);
CancelButton.Position = new(0.39f * xs, y);
LoadButton.SetToolTip($"Loads the selected {ItemName}");
RenameButton.SetToolTip($"Renames the selected {ItemName}");
DeleteButton.SetToolTip($"Deletes the selected {ItemName}");
CancelButton.SetToolTip(MyTexts.GetString(MySpaceTexts.ToolTipOptionsSpace_Cancel));
Controls.Add(LoadButton);
Controls.Add(RenameButton);
Controls.Add(DeleteButton);
Controls.Add(CancelButton);
}
private void AddItems()
{
NamesByKey.Clear();
foreach (var key in IterItemKeys())
AddRow(key);
if (TryFindRow(DefaultKey, out var rowIdx))
Table.SelectedRowIndex = rowIdx;
}
private void AddRow(string key)
{
var view = GetItemView(key);
if (view == null)
return;
var row = new MyGuiControlTable.Row(key);
for (var i = 0; i < ColumnCount; i++)
row.AddCell(new(view.Labels[i], view.Values[i]));
Table.Add(row);
NamesByKey[key] = view.Labels[0];
}
private void OnItemDoubleClicked(MyGuiControlTable table, MyGuiControlTable.EventArgs args)
{
LoadAndClose();
}
private void OnLoadButtonClick(MyGuiControlButton _)
{
LoadAndClose();
}
private void LoadAndClose()
{
if (string.IsNullOrEmpty(SelectedKey))
return;
OnLoad(SelectedKey);
CloseScreen();
}
private void OnCancelButtonClick(MyGuiControlButton _)
{
CloseScreen();
}
private void OnRenameButtonClick(MyGuiControlButton _)
{
if (string.IsNullOrEmpty(SelectedKey))
return;
if (!NamesByKey.TryGetValue(SelectedKey, out var oldName))
return;
MyGuiSandbox.AddScreen(new NameDialog(newName => OnNewNameSpecified(SelectedKey, newName),
$"Rename saved {ItemName}", oldName));
}
private void OnNewNameSpecified(string key, string newName)
{
newName = NormalizeName(newName);
if (!TryFindRow(key, out var rowIdx))
return;
OnRenamed(key, newName);
var view = GetItemView(key);
NamesByKey[key] = view.Labels[0];
var row = Table.GetRow(rowIdx);
for (var colIdx = 0; colIdx < ColumnCount; colIdx++)
{
var cell = row.GetCell(colIdx);
var sb = cell.Text;
sb.Clear();
sb.Append(view.Labels[colIdx]);
}
Table.Sort();
}
private void OnDeleteButtonClick(MyGuiControlButton _)
{
var key = SelectedKey;
if (string.IsNullOrEmpty(key))
return;
var name = NamesByKey.GetValueOrDefault(key) ?? "?";
MyGuiSandbox.AddScreen(
MyGuiSandbox.CreateMessageBox(buttonType: MyMessageBoxButtonsType.YES_NO,
messageText: new(
$"Are you sure to delete this saved {ItemName}?\r\n\r\n{name}"),
messageCaption: new("Confirmation"),
callback: result => OnDeleteForSure(result, key)));
}
private void OnDeleteForSure(MyGuiScreenMessageBox.ResultEnum result, string key)
{
if (result != MyGuiScreenMessageBox.ResultEnum.YES)
return;
NamesByKey.Remove(key);
if (TryFindRow(key, out var rowIdx))
Table.Remove(Table.GetRow(rowIdx));
OnDelete(key);
}
private bool TryFindRow(string key, out int index)
{
if (key == null)
{
index = -1;
return false;
}
var count = Table.RowsCount;
for (index = 0; index < count; index++)
if (Table.GetRow(index).UserData as string == key)
return true;
index = -1;
return false;
}
}