mirror of
https://github.com/Stone-Red-Code/RemSox.git
synced 2026-09-06 23:41:33 +02:00
Reorganize project structure
This commit is contained in:
@@ -0,0 +1,898 @@
|
||||
using RemSox.Kernel.Processing;
|
||||
using RemSox.Kernel.UI.GUI.UIEelements;
|
||||
using RemSox.Kernel.UI.GUI.UIEelements.Controls;
|
||||
using RemSox.Kernel.UI.GUI.UIEelements.Shapes;
|
||||
using RemSox.Kernel.UI.GUI.Windows;
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
|
||||
using YesNt.Interpreter.Runtime;
|
||||
using YesNt.Interpreter.Utilities;
|
||||
|
||||
using ShapesRectangle = RemSox.Kernel.UI.GUI.UIEelements.Shapes.Rectangle;
|
||||
|
||||
namespace RemSox.Kernel.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Registers all YesNt statements that expose the WindowManager / UI element API.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// All ui_* and win_* statements support two argument styles:
|
||||
/// <br/> positional: ui_rect ${id} 20 20 100 60 0 128 255
|
||||
/// <br/> named: ui_rect ${id} x=20 y=20 w=100 h=60 r=0 g=128 b=255
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Commas are treated as whitespace in both modes, so you can write:
|
||||
/// <br/> ui_rect ${id} x=20,y=20,w=100,h=60,r=0,g=128,b=255
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If any argument contains '=', the statement parses in named mode
|
||||
/// (order-independent). Otherwise, positional mode is used.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Substitutions:
|
||||
/// <br/> %win_last_id expands to the id of the last created window
|
||||
/// <br/> %ui_last_id expands to the id of the last created UI element
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class YesNtWindowStatements(Process ownerProcess)
|
||||
{
|
||||
private readonly Dictionary<int, Window> windows = [];
|
||||
private readonly Dictionary<int, object> uiElements = [];
|
||||
|
||||
private int lastWindowId;
|
||||
private int lastUiId;
|
||||
|
||||
public void Register(YesNtInterpreter interpreter)
|
||||
{
|
||||
RegisterWindowStatements(interpreter);
|
||||
RegisterButtonStatement(interpreter);
|
||||
RegisterCheckBoxStatement(interpreter);
|
||||
RegisterLabelStatement(interpreter);
|
||||
RegisterTextBoxStatement(interpreter);
|
||||
RegisterRadioButtonStatement(interpreter);
|
||||
RegisterProgressBarStatement(interpreter);
|
||||
RegisterSliderStatement(interpreter);
|
||||
RegisterPanelStatement(interpreter);
|
||||
RegisterLineStatement(interpreter);
|
||||
RegisterRectStatement(interpreter);
|
||||
RegisterCircleStatement(interpreter);
|
||||
RegisterRemoveStatement(interpreter);
|
||||
RegisterLastIdSubstitutions(interpreter);
|
||||
}
|
||||
|
||||
// --- Argument parser ---
|
||||
|
||||
private static string[] ParseTokens(string input)
|
||||
{
|
||||
return input.Split([' ', ','], StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
private static bool IsNamed(string[] tokens)
|
||||
{
|
||||
foreach (string t in tokens)
|
||||
{
|
||||
if (t.Contains('='))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryGetInt(string[] tokens, bool named, string name, int pos, out int value)
|
||||
{
|
||||
value = 0;
|
||||
|
||||
if (named)
|
||||
{
|
||||
string prefix = name + '=';
|
||||
foreach (string t in tokens)
|
||||
{
|
||||
if (t.StartsWith(prefix) && int.TryParse(t.AsSpan(prefix.Length), out value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pos < tokens.Length && int.TryParse(tokens[pos], out value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryGetString(string[] tokens, bool named, string name, int pos, out string value)
|
||||
{
|
||||
value = string.Empty;
|
||||
|
||||
if (named)
|
||||
{
|
||||
string prefix = name + '=';
|
||||
foreach (string t in tokens)
|
||||
{
|
||||
if (t.StartsWith(prefix))
|
||||
{
|
||||
value = t[prefix.Length..].FromSafeString();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pos < tokens.Length)
|
||||
{
|
||||
value = tokens[pos].FromSafeString();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- Window statements ---
|
||||
|
||||
private void RegisterWindowStatements(YesNtInterpreter interpreter)
|
||||
{
|
||||
// win_create "Title" w h [chrome=true|false]
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_create", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
string trimmed = args.Trim();
|
||||
string title;
|
||||
int w, h;
|
||||
bool chrome = true;
|
||||
|
||||
if (trimmed.StartsWith('"'))
|
||||
{
|
||||
int end = trimmed.IndexOf('"', 1);
|
||||
if (end < 0)
|
||||
{
|
||||
context.Exit("[win_create] Missing closing quote", false);
|
||||
return;
|
||||
}
|
||||
title = trimmed[1..end];
|
||||
string[] tokens = ParseTokens(trimmed[(end + 1)..]);
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (!TryGetInt(tokens, named, "w", 0, out w) || !TryGetInt(tokens, named, "h", 1, out h))
|
||||
{
|
||||
context.Exit("[win_create] Expected width and height", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryGetString(tokens, named, "chrome", 2, out string chromeStr))
|
||||
{
|
||||
_ = bool.TryParse(chromeStr, out chrome);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] tokens = ParseTokens(trimmed);
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (!TryGetString(tokens, named, "title", 0, out title) ||
|
||||
!TryGetInt(tokens, named, "w", 1, out w) ||
|
||||
!TryGetInt(tokens, named, "h", 2, out h))
|
||||
{
|
||||
context.Exit("[win_create] Usage: win_create \"Title\" w h [chrome=false]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryGetString(tokens, named, "chrome", 3, out string chromeStr))
|
||||
{
|
||||
_ = bool.TryParse(chromeStr, out chrome);
|
||||
}
|
||||
}
|
||||
|
||||
Window win = WindowManager.CreateWindow(ownerProcess, title, new Size(w, h));
|
||||
win.HasChrome = chrome;
|
||||
|
||||
int id = lastWindowId = win.Id;
|
||||
windows[id] = win;
|
||||
});
|
||||
|
||||
// win_close id
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_close", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (TryGetWindow(args, out Window? win))
|
||||
{
|
||||
WindowManager.CloseWindow(win);
|
||||
_ = windows.Remove(win.Id);
|
||||
}
|
||||
});
|
||||
|
||||
// win_flush id
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_flush", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (TryGetWindow(args, out Window? win))
|
||||
{
|
||||
win.Flush();
|
||||
}
|
||||
});
|
||||
|
||||
// win_title id "New Title"
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_title", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
string trimmed = args.Trim();
|
||||
string[] tokens = ParseTokens(trimmed);
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (!TryGetInt(tokens, named, "id", 0, out int id) || !windows.TryGetValue(id, out Window? win))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string title;
|
||||
if (trimmed.Contains('"'))
|
||||
{
|
||||
int start = trimmed.IndexOf('"') + 1;
|
||||
int end = trimmed.IndexOf('"', start);
|
||||
title = end >= 0 ? trimmed[start..end] : trimmed[start..];
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = TryGetString(tokens, named, "title", 1, out title);
|
||||
}
|
||||
|
||||
win.Title = title;
|
||||
});
|
||||
|
||||
// win_autoflush id true|false
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_autoflush", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
string[] tokens = ParseTokens(args.Trim());
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (TryGetInt(tokens, named, "id", 0, out int id) &&
|
||||
TryGetString(tokens, named, "enabled", 1, out string enabledStr) &&
|
||||
bool.TryParse(enabledStr, out bool enabled) &&
|
||||
windows.TryGetValue(id, out Window? win))
|
||||
{
|
||||
win.AutoFlush = enabled;
|
||||
}
|
||||
});
|
||||
|
||||
// win_chrome id true|false
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_chrome", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
string[] tokens = ParseTokens(args.Trim());
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (TryGetInt(tokens, named, "id", 0, out int id) &&
|
||||
TryGetString(tokens, named, "chrome", 1, out string chromeStr) &&
|
||||
bool.TryParse(chromeStr, out bool chrome) &&
|
||||
windows.TryGetValue(id, out Window? win))
|
||||
{
|
||||
win.HasChrome = chrome;
|
||||
}
|
||||
});
|
||||
|
||||
// win_focus id
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_focus", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (TryGetWindow(args, out Window? win))
|
||||
{
|
||||
WindowManager.FocusWindow(win);
|
||||
}
|
||||
});
|
||||
|
||||
// win_move id x y
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_move", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
string[] tokens = ParseTokens(args.Trim());
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (TryGetInt(tokens, named, "id", 0, out int id) &&
|
||||
TryGetInt(tokens, named, "x", 1, out int x) &&
|
||||
TryGetInt(tokens, named, "y", 2, out int y) &&
|
||||
windows.TryGetValue(id, out Window? win))
|
||||
{
|
||||
win.Position = new Point(x, y);
|
||||
}
|
||||
});
|
||||
|
||||
// win_resize id w h
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_resize", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
string[] tokens = ParseTokens(args.Trim());
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (TryGetInt(tokens, named, "id", 0, out int id) &&
|
||||
TryGetInt(tokens, named, "w", 1, out int w) &&
|
||||
TryGetInt(tokens, named, "h", 2, out int h) &&
|
||||
windows.TryGetValue(id, out Window? win))
|
||||
{
|
||||
win.Size = new Size(w, h);
|
||||
}
|
||||
});
|
||||
|
||||
// win_invalidate_all
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("win_invalidate_all", YesNt.Interpreter.Enums.SearchMode.Contains, YesNt.Interpreter.Enums.SpaceAround.None)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) => WindowManager.InvalidateAll());
|
||||
}
|
||||
|
||||
// --- Control statements ---
|
||||
|
||||
private void RegisterButtonStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_button", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetInt(tokens, named, "w", 2, out int w) ||
|
||||
!TryGetInt(tokens, named, "h", 3, out int h) ||
|
||||
!TryGetString(tokens, named, "label", 4, out string label))
|
||||
{
|
||||
context.Exit("[ui_button] Usage: ui_button winId x y w h \"Label\" [r g b]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = ParseColor(tokens, named, 5);
|
||||
|
||||
Button button = win.CreateUIElement<Button>(b =>
|
||||
{
|
||||
b.Position = new Point(x, y);
|
||||
b.Size = new Size(w, h);
|
||||
b.Text = label;
|
||||
if (color != Color.Empty)
|
||||
{
|
||||
b.BackgroundColor = color;
|
||||
}
|
||||
});
|
||||
|
||||
lastUiId = button.Id;
|
||||
uiElements[lastUiId] = button;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterCheckBoxStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_checkbox", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetString(tokens, named, "label", 2, out string label))
|
||||
{
|
||||
context.Exit("[ui_checkbox] Usage: ui_checkbox winId x y \"Label\" [checked] [r g b]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
int checkPos = named ? -1 : 3;
|
||||
_ = TryGetString(tokens, named, "checked", checkPos, out string checkedStr);
|
||||
_ = bool.TryParse(checkedStr, out bool isChecked);
|
||||
|
||||
Color color = ParseColor(tokens, named, named ? -1 : 4);
|
||||
|
||||
CheckBox checkBox = win.CreateUIElement<CheckBox>(c =>
|
||||
{
|
||||
c.Position = new Point(x, y);
|
||||
c.Text = label;
|
||||
c.IsChecked = isChecked;
|
||||
if (color != Color.Empty)
|
||||
{
|
||||
c.BackgroundColor = color;
|
||||
}
|
||||
});
|
||||
|
||||
lastUiId = checkBox.Id;
|
||||
uiElements[lastUiId] = checkBox;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterLabelStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_label", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetString(tokens, named, "label", 2, out string text))
|
||||
{
|
||||
context.Exit("[ui_label] Usage: ui_label winId x y \"Text\" [fontSize] [r g b]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
_ = TryGetInt(tokens, named, "fontSize", 3, out int fontSize);
|
||||
Color color = ParseColor(tokens, named, named ? -1 : 4);
|
||||
if (color == Color.Empty)
|
||||
{
|
||||
color = Color.White;
|
||||
}
|
||||
|
||||
Text label = win.CreateUIElement<Text>(t =>
|
||||
{
|
||||
t.Position = new Point(x, y);
|
||||
t.Content = text;
|
||||
t.FontSize = fontSize;
|
||||
t.Color = color;
|
||||
});
|
||||
|
||||
lastUiId = label.Id;
|
||||
uiElements[lastUiId] = label;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterTextBoxStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_textbox", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetInt(tokens, named, "w", 2, out int w) ||
|
||||
!TryGetInt(tokens, named, "h", 3, out int h) ||
|
||||
!TryGetString(tokens, named, "label", 4, out string placeholder))
|
||||
{
|
||||
context.Exit("[ui_textbox] Usage: ui_textbox winId x y w h \"Placeholder\"", false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Render placeholder as a Text element inside a styled Rectangle
|
||||
ShapesRectangle border = win.CreateUIElement<ShapesRectangle>(r =>
|
||||
{
|
||||
r.Position = new Point(x, y);
|
||||
r.Size = new Size(w, h);
|
||||
r.Color = Color.DarkGray;
|
||||
});
|
||||
|
||||
if (!string.IsNullOrEmpty(placeholder))
|
||||
{
|
||||
Text text = win.CreateUIElement<Text>(t =>
|
||||
{
|
||||
t.Position = new Point(x + 2, y + (h / 2) - 8);
|
||||
t.Content = placeholder;
|
||||
t.FontSize = 12;
|
||||
t.Color = Color.Gray;
|
||||
t.MaxWidth = w - 4;
|
||||
});
|
||||
lastUiId = text.Id;
|
||||
uiElements[lastUiId] = text;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastUiId = border.Id;
|
||||
uiElements[lastUiId] = border;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterRadioButtonStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_radio", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetString(tokens, named, "label", 2, out string label))
|
||||
{
|
||||
context.Exit("[ui_radio] Usage: ui_radio winId x y \"Label\" [checked] [r g b]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
_ = TryGetString(tokens, named, "checked", 3, out string checkedStr);
|
||||
_ = bool.TryParse(checkedStr, out bool isChecked);
|
||||
|
||||
Color color = ParseColor(tokens, named, 4);
|
||||
|
||||
RadioButton radio = win.CreateUIElement<RadioButton>(r =>
|
||||
{
|
||||
r.Position = new Point(x, y);
|
||||
r.Text = label;
|
||||
r.IsChecked = isChecked;
|
||||
if (color != Color.Empty)
|
||||
{
|
||||
r.BackgroundColor = color;
|
||||
}
|
||||
});
|
||||
|
||||
lastUiId = radio.Id;
|
||||
uiElements[lastUiId] = radio;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterProgressBarStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_progressbar", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetInt(tokens, named, "w", 2, out int w) ||
|
||||
!TryGetInt(tokens, named, "h", 3, out int h))
|
||||
{
|
||||
context.Exit("[ui_progressbar] Usage: ui_progressbar winId x y w h [value] [r g b]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
_ = TryGetInt(tokens, named, "value", 4, out int value);
|
||||
|
||||
ProgressBar bar = win.CreateUIElement<ProgressBar>(p =>
|
||||
{
|
||||
p.Position = new Point(x, y);
|
||||
p.Size = new Size(w, h);
|
||||
p.Value = value;
|
||||
});
|
||||
|
||||
Color fillColor = ParseColor(tokens, named, 5);
|
||||
if (fillColor != Color.Empty)
|
||||
{
|
||||
bar.FillColor = fillColor;
|
||||
}
|
||||
|
||||
lastUiId = bar.Id;
|
||||
uiElements[lastUiId] = bar;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterSliderStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_slider", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetInt(tokens, named, "w", 2, out int w) ||
|
||||
!TryGetInt(tokens, named, "h", 3, out int h))
|
||||
{
|
||||
context.Exit("[ui_slider] Usage: ui_slider winId x y w h [min] [max] [value]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
Slider slider = win.CreateUIElement<Slider>(s =>
|
||||
{
|
||||
s.Position = new Point(x, y);
|
||||
s.Size = new Size(w, h);
|
||||
|
||||
if (TryGetInt(tokens, named, "min", 4, out int min))
|
||||
{
|
||||
s.MinValue = min;
|
||||
}
|
||||
if (TryGetInt(tokens, named, "max", 5, out int max))
|
||||
{
|
||||
s.MaxValue = max;
|
||||
}
|
||||
if (TryGetInt(tokens, named, "value", 6, out int value))
|
||||
{
|
||||
s.Value = value;
|
||||
}
|
||||
});
|
||||
|
||||
lastUiId = slider.Id;
|
||||
uiElements[lastUiId] = slider;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterPanelStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_panel", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetInt(tokens, named, "w", 2, out int w) ||
|
||||
!TryGetInt(tokens, named, "h", 3, out int h))
|
||||
{
|
||||
context.Exit("[ui_panel] Usage: ui_panel winId x y w h [r g b]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
Panel panel = win.CreateUIElement<Panel>(p =>
|
||||
{
|
||||
p.Position = new Point(x, y);
|
||||
p.Size = new Size(w, h);
|
||||
});
|
||||
|
||||
Color color = ParseColor(tokens, named, 4);
|
||||
if (color != Color.Empty)
|
||||
{
|
||||
panel.BackgroundColor = color;
|
||||
}
|
||||
|
||||
lastUiId = panel.Id;
|
||||
uiElements[lastUiId] = panel;
|
||||
});
|
||||
}
|
||||
|
||||
// --- Shape statements ---
|
||||
|
||||
private void RegisterLineStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_line", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x1", 0, out int x1) ||
|
||||
!TryGetInt(tokens, named, "y1", 1, out int y1) ||
|
||||
!TryGetInt(tokens, named, "x2", 2, out int x2) ||
|
||||
!TryGetInt(tokens, named, "y2", 3, out int y2))
|
||||
{
|
||||
context.Exit("[ui_line] Usage: ui_line winId x1 y1 x2 y2 r g b", false);
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = ParseColor(tokens, named, 4);
|
||||
if (color == Color.Empty)
|
||||
{
|
||||
color = Color.White;
|
||||
}
|
||||
|
||||
Line line = win.CreateUIElement<Line>(l =>
|
||||
{
|
||||
l.Position = new Point(x1, y1);
|
||||
l.EndPosition = new Point(x2, y2);
|
||||
l.Color = color;
|
||||
});
|
||||
|
||||
lastUiId = line.Id;
|
||||
uiElements[lastUiId] = line;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterRectStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_rect", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetInt(tokens, named, "w", 2, out int w) ||
|
||||
!TryGetInt(tokens, named, "h", 3, out int h))
|
||||
{
|
||||
context.Exit("[ui_rect] Usage: ui_rect winId x y w h r g b", false);
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = ParseColor(tokens, named, 4);
|
||||
if (color == Color.Empty)
|
||||
{
|
||||
color = Color.White;
|
||||
}
|
||||
|
||||
ShapesRectangle rect = win.CreateUIElement<ShapesRectangle>(r =>
|
||||
{
|
||||
r.Position = new Point(x, y);
|
||||
r.Size = new Size(w, h);
|
||||
r.Color = color;
|
||||
});
|
||||
|
||||
lastUiId = rect.Id;
|
||||
uiElements[lastUiId] = rect;
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterCircleStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_circle", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
if (!TryGetWindowAndArgs(args, out Window? win, out string[] tokens, out bool named))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetInt(tokens, named, "x", 0, out int x) ||
|
||||
!TryGetInt(tokens, named, "y", 1, out int y) ||
|
||||
!TryGetInt(tokens, named, "radius", 2, out int radius))
|
||||
{
|
||||
context.Exit("[ui_circle] Usage: ui_circle winId x y radius r g b [filled=false]", false);
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = ParseColor(tokens, named, 3);
|
||||
if (color == Color.Empty)
|
||||
{
|
||||
color = Color.White;
|
||||
}
|
||||
|
||||
_ = TryGetString(tokens, named, "filled", 6, out string filledStr);
|
||||
_ = bool.TryParse(filledStr, out bool filled);
|
||||
|
||||
Circle circle = win.CreateUIElement<Circle>(c =>
|
||||
{
|
||||
c.Position = new Point(x, y);
|
||||
c.Radius = radius;
|
||||
c.Color = color;
|
||||
c.IsFilled = filled;
|
||||
});
|
||||
|
||||
lastUiId = circle.Id;
|
||||
uiElements[lastUiId] = circle;
|
||||
});
|
||||
}
|
||||
|
||||
// --- Element management ---
|
||||
|
||||
private void RegisterRemoveStatement(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("ui_remove", YesNt.Interpreter.Enums.SearchMode.StartOfLine, YesNt.Interpreter.Enums.SpaceAround.End)
|
||||
{ Priority = YesNt.Interpreter.Enums.Priority.Normal },
|
||||
(args, context) =>
|
||||
{
|
||||
string[] tokens = ParseTokens(args.Trim());
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (!TryGetInt(tokens, named, "id", 0, out int id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (uiElements.TryGetValue(id, out object? elem))
|
||||
{
|
||||
if (elem is UIElement uiElem)
|
||||
{
|
||||
// Find the window that owns this element
|
||||
foreach (KeyValuePair<int, Window> kvp in windows)
|
||||
{
|
||||
kvp.Value.RemoveUIElement(uiElem.Id);
|
||||
}
|
||||
}
|
||||
_ = uiElements.Remove(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- Substitutions ---
|
||||
|
||||
private void RegisterLastIdSubstitutions(YesNtInterpreter interpreter)
|
||||
{
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("%win_last_id", YesNt.Interpreter.Enums.SearchMode.Contains, YesNt.Interpreter.Enums.SpaceAround.None)
|
||||
{ KeepStatementInArgs = true, Priority = YesNt.Interpreter.Enums.Priority.PreProcessing },
|
||||
(args, context) =>
|
||||
{
|
||||
context.CurrentLine = TemplateProcessor.ProcessSimplePlaceholders(args, "%win_last_id", lastWindowId.ToString());
|
||||
});
|
||||
|
||||
interpreter.AddStatement(
|
||||
new StatementInformation("%ui_last_id", YesNt.Interpreter.Enums.SearchMode.Contains, YesNt.Interpreter.Enums.SpaceAround.None)
|
||||
{ KeepStatementInArgs = true, Priority = YesNt.Interpreter.Enums.Priority.PreProcessing },
|
||||
(args, context) =>
|
||||
{
|
||||
context.CurrentLine = TemplateProcessor.ProcessSimplePlaceholders(args, "%ui_last_id", lastUiId.ToString());
|
||||
});
|
||||
}
|
||||
|
||||
// --- Helpers ---
|
||||
|
||||
private bool TryGetWindow(string input, [NotNullWhen(true)] out Window? win)
|
||||
{
|
||||
win = null;
|
||||
string[] tokens = ParseTokens(input.Trim());
|
||||
bool named = IsNamed(tokens);
|
||||
|
||||
if (TryGetInt(tokens, named, "id", 0, out int id) && windows.TryGetValue(id, out win))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetWindowAndArgs(string input, [NotNullWhen(true)] out Window? win, out string[] tokens, out bool named)
|
||||
{
|
||||
win = null;
|
||||
tokens = ParseTokens(input.Trim());
|
||||
named = IsNamed(tokens);
|
||||
|
||||
if (!TryGetInt(tokens, named, "winId", 0, out int winId) || !windows.TryGetValue(winId, out win))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Color ParseColor(string[] tokens, bool named, int pos)
|
||||
{
|
||||
if (TryGetInt(tokens, named, "r", pos, out int r) &&
|
||||
TryGetInt(tokens, named, "g", pos + 1, out int g) &&
|
||||
TryGetInt(tokens, named, "b", pos + 2, out int b))
|
||||
{
|
||||
return Color.FromArgb(r, g, b);
|
||||
}
|
||||
return Color.Empty;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user