From 8b900c9d58a2cd6d5824e7ea2c95dd0a8ac197e5 Mon Sep 17 00:00:00 2001 From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com> Date: Mon, 8 Jun 2026 19:51:22 +0200 Subject: [PATCH] Add printLine support for commands and implement basic UI controls rendering --- Kernel.cs | 4 +- Processes/DesktopProcess.cs | 28 ++++++++++ Processes/TerminalProcess.cs | 6 +- UI/CLI/CommandManager.cs | 4 +- UI/CLI/Commands/ClearCommand.cs | 2 +- UI/CLI/Commands/HaltCommand.cs | 4 +- UI/CLI/Commands/HelpCommand.cs | 6 +- UI/CLI/Commands/ProcessCommands.cs | 18 +++--- UI/CLI/ICommand.cs | 4 +- UI/GUI/CLI/Commands/StartGuiCommand.cs | 4 +- UI/GUI/Rendering/CanvasRenderSource.cs | 73 ++++++++++++++++++++++++- UI/GUI/UIEelements/Controls/Button.cs | 18 ++++++ UI/GUI/UIEelements/Controls/CheckBox.cs | 24 ++++++++ UI/GUI/UIEelements/Shapes/Line.cs | 12 ++++ 14 files changed, 178 insertions(+), 29 deletions(-) create mode 100644 UI/GUI/UIEelements/Controls/Button.cs create mode 100644 UI/GUI/UIEelements/Controls/CheckBox.cs create mode 100644 UI/GUI/UIEelements/Shapes/Line.cs diff --git a/Kernel.cs b/Kernel.cs index dfdb708..b8ce5c6 100644 --- a/Kernel.cs +++ b/Kernel.cs @@ -41,7 +41,7 @@ public class Kernel : Sys.Kernel for (int i = 0; i < 5; i++) { - ProcessManager.SpawnProcess(); + //ProcessManager.SpawnProcess(); } Console.WriteLine(CosmosFeatures.MouseEnabled); @@ -66,7 +66,7 @@ public class Kernel : Sys.Kernel return; } - if (CommandManager.TryExecute(input)) + if (CommandManager.TryExecute(input, line => Console.WriteLine(line))) { return; } diff --git a/Processes/DesktopProcess.cs b/Processes/DesktopProcess.cs index d664172..051734d 100644 --- a/Processes/DesktopProcess.cs +++ b/Processes/DesktopProcess.cs @@ -36,6 +36,34 @@ public class DesktopProcess : Process // Start the terminal process within the desktop environment ProcessManager.SpawnProcess(); + // Create a test window for new UI controls + Window testWindow = WindowManager.CreateWindow(this, "UI Controls Test", new System.Drawing.Point(500, 50), new System.Drawing.Size(200, 180)); + + testWindow.CreateUIElement(b => + { + b.Position = new System.Drawing.Point(20, 30); + b.Size = new System.Drawing.Size(100, 30); + b.Text = "Click Me"; + b.BackgroundColor = System.Drawing.Color.LightBlue; + }); + + testWindow.CreateUIElement(c => + { + c.Position = new System.Drawing.Point(20, 80); + c.Text = "Check Me"; + c.IsChecked = true; + }); + + testWindow.CreateUIElement(l => + { + l.Position = new System.Drawing.Point(20, 130); + l.EndPosition = new System.Drawing.Point(180, 130); + l.Color = System.Drawing.Color.Red; + }); + + testWindow.AutoFlush = true; + testWindow.Flush(); + while (!StopRequested) { WindowManager.Update(); diff --git a/Processes/TerminalProcess.cs b/Processes/TerminalProcess.cs index 1c6b996..0d2d9b8 100644 --- a/Processes/TerminalProcess.cs +++ b/Processes/TerminalProcess.cs @@ -77,15 +77,11 @@ public class TerminalProcess : Process } else { - bool found = CommandManager.TryExecute(cmd); + bool found = CommandManager.TryExecute(cmd, line => PrintLine(line)); if (!found) { PrintLine($"\"{cmd}\" is not a command"); } - else - { - PrintLine("Command executed. (Output sent to background console)"); - } } } UpdateDisplay(); diff --git a/UI/CLI/CommandManager.cs b/UI/CLI/CommandManager.cs index 36b5dcf..5c54228 100644 --- a/UI/CLI/CommandManager.cs +++ b/UI/CLI/CommandManager.cs @@ -24,7 +24,7 @@ public static class CommandManager return commands.Values.OrderBy(command => command.Name); } - public static bool TryExecute(string input) + public static bool TryExecute(string input, Action printLine) { string trimmedInput = input.Trim(); @@ -51,7 +51,7 @@ public static class CommandManager arguments = trimmedInput.Substring(commandName.Length).TrimStart(); } - entry.Value.Execute(arguments); + entry.Value.Execute(arguments, printLine); return true; } diff --git a/UI/CLI/Commands/ClearCommand.cs b/UI/CLI/Commands/ClearCommand.cs index d07ff9d..f301797 100644 --- a/UI/CLI/Commands/ClearCommand.cs +++ b/UI/CLI/Commands/ClearCommand.cs @@ -8,7 +8,7 @@ public sealed class ClearCommand : ICommand public string Description => "Clear the screen"; - public void Execute(string? arguments) + public void Execute(string? arguments, Action printLine) { Console.Clear(); } diff --git a/UI/CLI/Commands/HaltCommand.cs b/UI/CLI/Commands/HaltCommand.cs index 9c6258e..15ee976 100644 --- a/UI/CLI/Commands/HaltCommand.cs +++ b/UI/CLI/Commands/HaltCommand.cs @@ -8,9 +8,9 @@ public sealed class HaltCommand : ICommand public string Description => "Halt the system"; - public void Execute(string? arguments) + public void Execute(string? arguments, Action printLine) { - Console.WriteLine("Halting system..."); + printLine("Halting system..."); Environment.Exit(0); } } \ No newline at end of file diff --git a/UI/CLI/Commands/HelpCommand.cs b/UI/CLI/Commands/HelpCommand.cs index 01e07e9..9e23943 100644 --- a/UI/CLI/Commands/HelpCommand.cs +++ b/UI/CLI/Commands/HelpCommand.cs @@ -8,13 +8,13 @@ public sealed class HelpCommand : ICommand public string Description => "Show this help message"; - public void Execute(string? arguments) + public void Execute(string? arguments, Action printLine) { - Console.WriteLine("Available commands:"); + printLine("Available commands:"); foreach (ICommand command in CommandManager.GetCommands()) { - Console.WriteLine($" {command.Name,-12} - {command.Description}"); + printLine($" {command.Name,-12} - {command.Description}"); } } } \ No newline at end of file diff --git a/UI/CLI/Commands/ProcessCommands.cs b/UI/CLI/Commands/ProcessCommands.cs index 59944c3..9ba876b 100644 --- a/UI/CLI/Commands/ProcessCommands.cs +++ b/UI/CLI/Commands/ProcessCommands.cs @@ -9,10 +9,10 @@ public sealed class SpawnTestProcessCommand : ICommand public string Description => "Spawn the test process"; - public void Execute(string? arguments) + public void Execute(string? arguments, Action printLine) { int processId = ProcessManager.SpawnProcess(); - Console.WriteLine($"Spawned TestProcess with ID {processId}"); + printLine($"Spawned TestProcess with ID {processId}"); } } @@ -22,15 +22,15 @@ public sealed class ListProcessesCommand : ICommand public string Description => "List running processes"; - public void Execute(string? arguments) + public void Execute(string? arguments, Action printLine) { IEnumerable processes = ProcessManager.GetAllProcesses(); - Console.WriteLine("Running processes:"); + printLine("Running processes:"); foreach (Process process in processes) { - Console.WriteLine($" ID: {process.Id}, Name: {process.Name}"); + printLine($" ID: {process.Id}, Name: {process.Name}"); } } } @@ -41,23 +41,23 @@ public sealed class StopProcessCommand : ICommand public string Description => "Stop a process by ID"; - public void Execute(string? arguments) + public void Execute(string? arguments, Action printLine) { string? idText = arguments; if (string.IsNullOrWhiteSpace(idText)) { - Console.WriteLine("Usage: stop "); + printLine("Usage: stop "); return; } if (int.TryParse(idText, out int processId)) { ProcessManager.StopProcess(processId); - Console.WriteLine($"Stopped process with ID {processId}"); + printLine($"Stopped process with ID {processId}"); return; } - Console.WriteLine("Invalid process ID"); + printLine("Invalid process ID"); } } \ No newline at end of file diff --git a/UI/CLI/ICommand.cs b/UI/CLI/ICommand.cs index 217f883..1920173 100644 --- a/UI/CLI/ICommand.cs +++ b/UI/CLI/ICommand.cs @@ -1,10 +1,12 @@ namespace RemSox.UI.GUI.CLI; +using System; + public interface ICommand { string Name { get; } string Description { get; } - void Execute(string? arguments); + void Execute(string? arguments, Action printLine); } diff --git a/UI/GUI/CLI/Commands/StartGuiCommand.cs b/UI/GUI/CLI/Commands/StartGuiCommand.cs index d74725f..1659c76 100644 --- a/UI/GUI/CLI/Commands/StartGuiCommand.cs +++ b/UI/GUI/CLI/Commands/StartGuiCommand.cs @@ -10,9 +10,9 @@ public class StartGuiCommand : ICommand public string Name => "start-gui"; public string Description => "Starts the Graphical User Interface (Desktop Process)"; - public void Execute(string? args) + public void Execute(string? arguments, Action printLine) { - Console.WriteLine("Starting Desktop Process..."); + printLine("Starting Desktop Process..."); ProcessManager.SpawnProcess(); } } diff --git a/UI/GUI/Rendering/CanvasRenderSource.cs b/UI/GUI/Rendering/CanvasRenderSource.cs index 21231f3..2b17f8c 100644 --- a/UI/GUI/Rendering/CanvasRenderSource.cs +++ b/UI/GUI/Rendering/CanvasRenderSource.cs @@ -90,6 +90,21 @@ public sealed class CanvasRenderSource : IRenderSource { RenderText(windowCanvas, command); } + + if (command.ElementType == "Line") + { + RenderLine(windowCanvas, command); + } + + if (command.ElementType == "Button") + { + RenderButton(windowCanvas, command); + } + + if (command.ElementType == "CheckBox") + { + RenderCheckBox(windowCanvas, command); + } } if (changed) @@ -111,7 +126,7 @@ public sealed class CanvasRenderSource : IRenderSource isZOrderDirty = false; } - //screenCanvas.Clear(Color.Black); + screenCanvas.Clear(Color.Black); foreach (var windowId in orderedWindowsCache) { @@ -195,7 +210,61 @@ public sealed class CanvasRenderSource : IRenderSource if (!string.IsNullOrEmpty(content)) { - canvas.DrawString(content, Cosmos.Kernel.System.Graphics.Fonts.PCScreenFont.DefaultFont, color, command.Position.X, command.Position.Y); + canvas.DrawString(content, PCScreenFont.DefaultFont, color, command.Position.X, command.Position.Y); + } + } + + private static void RenderLine(Canvas canvas, RenderCommand command) + { + Color color = command.Properties.TryGetValue("Color", out object? rawColor) && rawColor is Color lineColor + ? lineColor + : Color.White; + + Point endPosition = command.Properties.TryGetValue("EndPosition", out object? rawEnd) && rawEnd is Point endPoint + ? endPoint + : command.Position; + + canvas.DrawLine(color, command.Position.X, command.Position.Y, endPosition.X, endPosition.Y); + } + + private static void RenderButton(Canvas canvas, RenderCommand command) + { + Color bgColor = command.Properties.TryGetValue("BackgroundColor", out object? rawBgColor) && rawBgColor is Color c1 ? c1 : Color.LightGray; + Color textColor = command.Properties.TryGetValue("TextColor", out object? rawTextColor) && rawTextColor is Color c2 ? c2 : Color.Black; + Size size = command.Properties.TryGetValue("Size", out object? rawSize) && rawSize is Size s ? s : new Size(60, 20); + string text = command.Properties.TryGetValue("Text", out object? rawText) && rawText is string t ? t : string.Empty; + + canvas.DrawFilledRectangle(bgColor, command.Position.X, command.Position.Y, size.Width, size.Height); + canvas.DrawRectangle(Color.DarkGray, command.Position.X, command.Position.Y, size.Width, size.Height); + + if (!string.IsNullOrEmpty(text)) + { + int textX = command.Position.X + (size.Width / 2) - (text.Length * 8 / 2); + int textY = command.Position.Y + (size.Height / 2) - 8; + canvas.DrawString(text, PCScreenFont.DefaultFont, textColor, textX, textY); + } + } + + private static void RenderCheckBox(Canvas canvas, RenderCommand command) + { + Color bgColor = command.Properties.TryGetValue("BackgroundColor", out object? rawBgColor) && rawBgColor is Color c1 ? c1 : Color.LightGray; + Color textColor = command.Properties.TryGetValue("TextColor", out object? rawTextColor) && rawTextColor is Color c2 ? c2 : Color.White; + bool isChecked = command.Properties.TryGetValue("IsChecked", out object? rawChecked) && rawChecked is bool chk ? chk : false; + string text = command.Properties.TryGetValue("Text", out object? rawText) && rawText is string t ? t : string.Empty; + + int boxSize = 12; + + canvas.DrawFilledRectangle(bgColor, command.Position.X, command.Position.Y, boxSize, boxSize); + canvas.DrawRectangle(Color.DarkGray, command.Position.X, command.Position.Y, boxSize, boxSize); + + if (isChecked) + { + canvas.DrawFilledRectangle(Color.Black, command.Position.X + 3, command.Position.Y + 3, boxSize - 6, boxSize - 6); + } + + if (!string.IsNullOrEmpty(text)) + { + canvas.DrawString(text, PCScreenFont.DefaultFont, textColor, command.Position.X + boxSize + 5, command.Position.Y - 2); } } } \ No newline at end of file diff --git a/UI/GUI/UIEelements/Controls/Button.cs b/UI/GUI/UIEelements/Controls/Button.cs new file mode 100644 index 0000000..331cf0b --- /dev/null +++ b/UI/GUI/UIEelements/Controls/Button.cs @@ -0,0 +1,18 @@ +using System.Drawing; + +namespace RemSox.UI.GUI.UIEelements.Controls; + +public class Button() : Control("Button") +{ + public string Text + { + get; + set => SetProperty(nameof(Text), ref field, value); + } = string.Empty; + + public Color TextColor + { + get; + set => SetProperty(nameof(TextColor), ref field, value); + } = Color.Black; +} \ No newline at end of file diff --git a/UI/GUI/UIEelements/Controls/CheckBox.cs b/UI/GUI/UIEelements/Controls/CheckBox.cs new file mode 100644 index 0000000..f6539fb --- /dev/null +++ b/UI/GUI/UIEelements/Controls/CheckBox.cs @@ -0,0 +1,24 @@ +using System.Drawing; + +namespace RemSox.UI.GUI.UIEelements.Controls; + +public class CheckBox() : Control("CheckBox") +{ + public bool IsChecked + { + get; + set => SetProperty(nameof(IsChecked), ref field, value); + } = false; + + public string Text + { + get; + set => SetProperty(nameof(Text), ref field, value); + } = string.Empty; + + public Color TextColor + { + get; + set => SetProperty(nameof(TextColor), ref field, value); + } = Color.White; +} \ No newline at end of file diff --git a/UI/GUI/UIEelements/Shapes/Line.cs b/UI/GUI/UIEelements/Shapes/Line.cs new file mode 100644 index 0000000..dbd38be --- /dev/null +++ b/UI/GUI/UIEelements/Shapes/Line.cs @@ -0,0 +1,12 @@ +using System.Drawing; + +namespace RemSox.UI.GUI.UIEelements.Shapes; + +public class Line() : Shape("Line") +{ + public Point EndPosition + { + get; + set => SetProperty(nameof(EndPosition), ref field, value); + } +} \ No newline at end of file