embed plugin loader directly into the launcher
This commit is contained in:
320
PluginLoader/GUI/TableDialogBase.cs
Normal file
320
PluginLoader/GUI/TableDialogBase.cs
Normal 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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user