mirror of
https://github.com/Stone-Red-Code/RemSox.git
synced 2026-09-08 07:46:29 +02:00
Code cleanup
This commit is contained in:
+9
-9
@@ -1,6 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using Org.BouncyCastle.Crypto;
|
using Org.BouncyCastle.Crypto;
|
||||||
using Org.BouncyCastle.Crypto.Digests;
|
using Org.BouncyCastle.Crypto.Digests;
|
||||||
using Org.BouncyCastle.Crypto.Engines;
|
using Org.BouncyCastle.Crypto.Engines;
|
||||||
@@ -8,6 +5,9 @@ using Org.BouncyCastle.Crypto.Generators;
|
|||||||
using Org.BouncyCastle.Crypto.Modes;
|
using Org.BouncyCastle.Crypto.Modes;
|
||||||
using Org.BouncyCastle.Crypto.Parameters;
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
|
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
public static class BcAesCrypto
|
public static class BcAesCrypto
|
||||||
{
|
{
|
||||||
private const int KeySize = 32; // 256-bit AES
|
private const int KeySize = 32; // 256-bit AES
|
||||||
@@ -21,7 +21,7 @@ public static class BcAesCrypto
|
|||||||
// -----------------------------
|
// -----------------------------
|
||||||
private static byte[] DeriveKey(string password, byte[] salt)
|
private static byte[] DeriveKey(string password, byte[] salt)
|
||||||
{
|
{
|
||||||
var generator = new Pkcs5S2ParametersGenerator(new Sha256Digest());
|
Pkcs5S2ParametersGenerator generator = new(new Sha256Digest());
|
||||||
|
|
||||||
generator.Init(
|
generator.Init(
|
||||||
PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()),
|
PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()),
|
||||||
@@ -29,7 +29,7 @@ public static class BcAesCrypto
|
|||||||
Iterations
|
Iterations
|
||||||
);
|
);
|
||||||
|
|
||||||
var keyParam = (KeyParameter)generator.GenerateDerivedMacParameters(KeySize * 8);
|
KeyParameter keyParam = (KeyParameter)generator.GenerateDerivedMacParameters(KeySize * 8);
|
||||||
return keyParam.GetKey();
|
return keyParam.GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ public static class BcAesCrypto
|
|||||||
byte[] nonce = new byte[NonceSize];
|
byte[] nonce = new byte[NonceSize];
|
||||||
RandomNumberGenerator.Fill(nonce);
|
RandomNumberGenerator.Fill(nonce);
|
||||||
|
|
||||||
var cipher = new GcmBlockCipher(new AesEngine());
|
GcmBlockCipher cipher = new(new AesEngine());
|
||||||
|
|
||||||
cipher.Init(true, new AeadParameters(
|
cipher.Init(true, new AeadParameters(
|
||||||
new KeyParameter(key),
|
new KeyParameter(key),
|
||||||
@@ -58,7 +58,7 @@ public static class BcAesCrypto
|
|||||||
byte[] output = new byte[cipher.GetOutputSize(input.Length)];
|
byte[] output = new byte[cipher.GetOutputSize(input.Length)];
|
||||||
|
|
||||||
int len = cipher.ProcessBytes(input, 0, input.Length, output, 0);
|
int len = cipher.ProcessBytes(input, 0, input.Length, output, 0);
|
||||||
cipher.DoFinal(output, len);
|
_ = cipher.DoFinal(output, len);
|
||||||
|
|
||||||
// Combine: salt + nonce + ciphertext
|
// Combine: salt + nonce + ciphertext
|
||||||
byte[] result = new byte[salt.Length + nonce.Length + output.Length];
|
byte[] result = new byte[salt.Length + nonce.Length + output.Length];
|
||||||
@@ -90,7 +90,7 @@ public static class BcAesCrypto
|
|||||||
|
|
||||||
byte[] key = DeriveKey(password, salt);
|
byte[] key = DeriveKey(password, salt);
|
||||||
|
|
||||||
var cipher = new GcmBlockCipher(new AesEngine());
|
GcmBlockCipher cipher = new(new AesEngine());
|
||||||
|
|
||||||
cipher.Init(false, new AeadParameters(
|
cipher.Init(false, new AeadParameters(
|
||||||
new KeyParameter(key),
|
new KeyParameter(key),
|
||||||
@@ -101,7 +101,7 @@ public static class BcAesCrypto
|
|||||||
byte[] plain = new byte[cipher.GetOutputSize(cipherBytes.Length)];
|
byte[] plain = new byte[cipher.GetOutputSize(cipherBytes.Length)];
|
||||||
|
|
||||||
int len = cipher.ProcessBytes(cipherBytes, 0, cipherBytes.Length, plain, 0);
|
int len = cipher.ProcessBytes(cipherBytes, 0, cipherBytes.Length, plain, 0);
|
||||||
cipher.DoFinal(plain, len);
|
_ = cipher.DoFinal(plain, len);
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(plain);
|
return Encoding.UTF8.GetString(plain);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
global using Sys = Cosmos.Kernel.System;
|
global using Sys = Cosmos.Kernel.System;
|
||||||
using System.Diagnostics;
|
|
||||||
|
using Cosmos.Kernel.Core;
|
||||||
|
|
||||||
|
using RemSox.Processing.IPC;
|
||||||
|
using RemSox.UI.CLI;
|
||||||
|
using RemSox.UI.CLI.Commands;
|
||||||
|
using RemSox.UI.GUI.UIEelements.Shapes;
|
||||||
|
using RemSox.UI.GUI.Windows;
|
||||||
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime;
|
using System.Runtime;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Cosmos.Build.API.Attributes;
|
|
||||||
using Cosmos.Kernel.Core;
|
|
||||||
using Cosmos.Kernel.System.Graphics;
|
|
||||||
using RemSox.Processing;
|
|
||||||
using RemSox.Processing.IPC;
|
|
||||||
using RemSox.UI.GUI.CLI;
|
|
||||||
using RemSox.UI.GUI.CLI.Commands;
|
|
||||||
using RemSox.UI.GUI.Rendering;
|
|
||||||
using RemSox.UI.GUI.Windows;
|
|
||||||
|
|
||||||
namespace RemSox;
|
namespace RemSox;
|
||||||
|
|
||||||
@@ -25,8 +23,8 @@ public class Kernel : Sys.Kernel
|
|||||||
Console.WriteLine("Cosmos booted successfully!");
|
Console.WriteLine("Cosmos booted successfully!");
|
||||||
Console.WriteLine("Type a command to get it executed.");
|
Console.WriteLine("Type a command to get it executed.");
|
||||||
|
|
||||||
CommandManager.RegisterCommands(new ICommand[]
|
CommandManager.RegisterCommands(
|
||||||
{
|
[
|
||||||
new HelpCommand(),
|
new HelpCommand(),
|
||||||
new ClearCommand(),
|
new ClearCommand(),
|
||||||
new HaltCommand(),
|
new HaltCommand(),
|
||||||
@@ -34,7 +32,7 @@ public class Kernel : Sys.Kernel
|
|||||||
new ListProcessesCommand(),
|
new ListProcessesCommand(),
|
||||||
new StopProcessCommand(),
|
new StopProcessCommand(),
|
||||||
new StartGuiCommand()
|
new StartGuiCommand()
|
||||||
});
|
]);
|
||||||
|
|
||||||
Sys.Mouse.MouseManager.Initialize();
|
Sys.Mouse.MouseManager.Initialize();
|
||||||
Sys.Keyboard.KeyboardManager.Initialize();
|
Sys.Keyboard.KeyboardManager.Initialize();
|
||||||
@@ -82,7 +80,7 @@ public class TestProcess() : Processing.Process("Test Process")
|
|||||||
Window window = WindowManager.CreateWindow(this, "Test Window", Point.Empty, new Size(200, 150));
|
Window window = WindowManager.CreateWindow(this, "Test Window", Point.Empty, new Size(200, 150));
|
||||||
window.AutoFlush = true;
|
window.AutoFlush = true;
|
||||||
|
|
||||||
var circle = window.CreateUIElement<UI.GUI.UIEelements.Shapes.Circle>(rect =>
|
Circle circle = window.CreateUIElement<UI.GUI.UIEelements.Shapes.Circle>(rect =>
|
||||||
{
|
{
|
||||||
rect.Position = new Point(10, 10);
|
rect.Position = new Point(10, 10);
|
||||||
rect.Radius = 50;
|
rect.Radius = 50;
|
||||||
@@ -119,9 +117,11 @@ public static unsafe partial class StartupCodeHelpers
|
|||||||
public static double fmod(double x, double y)
|
public static double fmod(double x, double y)
|
||||||
{
|
{
|
||||||
if (Math.Abs(y) < double.Epsilon)
|
if (Math.Abs(y) < double.Epsilon)
|
||||||
|
{
|
||||||
return double.NaN;
|
return double.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
double q = Math.Truncate(x / y);
|
double q = Math.Truncate(x / y);
|
||||||
return x - q * y;
|
return x - (q * y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
using System;
|
|
||||||
using Cosmos.Build.API.Attributes;
|
using Cosmos.Build.API.Attributes;
|
||||||
|
|
||||||
namespace MyKernel.Plugs;
|
namespace RemSox.Plugs;
|
||||||
|
|
||||||
[Plug("System.Security.Cryptography.RandomNumberGeneratorImplementation")]
|
[Plug("System.Security.Cryptography.RandomNumberGeneratorImplementation")]
|
||||||
public static unsafe class RandomNumberGeneratorImplementationImpl
|
public static unsafe class RandomNumberGeneratorImplementationImpl
|
||||||
{
|
{
|
||||||
// Cryptographic stream generator based on ChaCha20.
|
// Cryptographic stream generator based on ChaCha20.
|
||||||
// Initial entropy is limited at boot; depends on hardware events.
|
// Initial entropy is limited at boot; depends on hardware events.
|
||||||
private static uint[] key = new uint[8];
|
private static readonly uint[] key = new uint[8];
|
||||||
private static uint[] counter = new uint[4];
|
private static readonly uint[] counter = new uint[4];
|
||||||
private static uint[] state = new uint[16];
|
private static readonly uint[] state = new uint[16];
|
||||||
|
|
||||||
private static ulong e0, e1, e2, e3;
|
private static ulong e0, e1, e2, e3;
|
||||||
private static int entropyCounter;
|
private static int entropyCounter;
|
||||||
private static bool initialized = false;
|
private static bool initialized = false;
|
||||||
|
|
||||||
private static readonly uint[] constants =
|
private static readonly uint[] constants =
|
||||||
{
|
[
|
||||||
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
|
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
|
||||||
};
|
];
|
||||||
|
|
||||||
private static uint RotL(uint x, int n)
|
private static uint RotL(uint x, int n)
|
||||||
{
|
{
|
||||||
@@ -38,10 +37,25 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
{
|
{
|
||||||
uint[] x = new uint[16];
|
uint[] x = new uint[16];
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) x[i] = constants[i];
|
for (int i = 0; i < 4; i++)
|
||||||
for (int i = 0; i < 8; i++) x[4 + i] = key[i];
|
{
|
||||||
for (int i = 0; i < 4; i++) x[12 + i] = counter[i];
|
x[i] = constants[i];
|
||||||
for (int i = 0; i < 16; i++) state[i] = x[i];
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
x[4 + i] = key[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
x[12 + i] = counter[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
state[i] = x[i];
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
@@ -57,7 +71,9 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
output[i] = x[i] + state[i];
|
output[i] = x[i] + state[i];
|
||||||
|
}
|
||||||
|
|
||||||
counter[0]++;
|
counter[0]++;
|
||||||
if (counter[0] == 0)
|
if (counter[0] == 0)
|
||||||
@@ -66,7 +82,10 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
if (counter[1] == 0)
|
if (counter[1] == 0)
|
||||||
{
|
{
|
||||||
counter[2]++;
|
counter[2]++;
|
||||||
if (counter[2] == 0) counter[3]++;
|
if (counter[2] == 0)
|
||||||
|
{
|
||||||
|
counter[3]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +121,9 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
private static void MaybeReseed()
|
private static void MaybeReseed()
|
||||||
{
|
{
|
||||||
if (++entropyCounter % 64 == 0)
|
if (++entropyCounter % 64 == 0)
|
||||||
|
{
|
||||||
Reseed();
|
Reseed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ulong ReadTSC()
|
private static ulong ReadTSC()
|
||||||
@@ -112,14 +133,20 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
|
|
||||||
private static void EnsureInitialized()
|
private static void EnsureInitialized()
|
||||||
{
|
{
|
||||||
if (initialized) return;
|
if (initialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
const ulong BUILD_NONCE = 0xDEADBEEFCAFEBABEUL;
|
const ulong BUILD_NONCE = 0xDEADBEEFCAFEBABEUL;
|
||||||
|
|
||||||
ulong heapBits;
|
ulong heapBits;
|
||||||
fixed (byte* p = new byte[1])
|
fixed (byte* p = new byte[1])
|
||||||
|
{
|
||||||
heapBits = (ulong)p;
|
heapBits = (ulong)p;
|
||||||
|
}
|
||||||
|
|
||||||
Mix(BUILD_NONCE);
|
Mix(BUILD_NONCE);
|
||||||
Mix(ReadTSC());
|
Mix(ReadTSC());
|
||||||
@@ -131,7 +158,7 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
|
|
||||||
private static readonly Lock _lock = new();
|
private static readonly Lock _lock = new();
|
||||||
|
|
||||||
private static uint[] buffer = new uint[16];
|
private static readonly uint[] buffer = new uint[16];
|
||||||
private static int bufferIndex = 16;
|
private static int bufferIndex = 16;
|
||||||
|
|
||||||
private static uint NextUInt32()
|
private static uint NextUInt32()
|
||||||
@@ -196,7 +223,7 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
{
|
{
|
||||||
Mix(scanCode);
|
Mix(scanCode);
|
||||||
Mix(flags);
|
Mix(flags);
|
||||||
Mix((ulong)keyChar);
|
Mix(keyChar);
|
||||||
Mix(tsc);
|
Mix(tsc);
|
||||||
MaybeReseed();
|
MaybeReseed();
|
||||||
}
|
}
|
||||||
@@ -208,7 +235,9 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < data.Length; i++)
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
data[i] = NextByte();
|
data[i] = NextByte();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +247,9 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
bufferPtr[i] = NextByte();
|
bufferPtr[i] = NextByte();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using Cosmos.Kernel.System.Graphics;
|
using Cosmos.Kernel.System.Graphics;
|
||||||
|
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
using RemSox.UI.GUI.Rendering;
|
using RemSox.UI.GUI.Rendering;
|
||||||
using RemSox.UI.GUI.Windows;
|
using RemSox.UI.GUI.Windows;
|
||||||
@@ -28,18 +27,18 @@ public class DesktopProcess : Process
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trigger Canvas initialization
|
// Trigger Canvas initialization
|
||||||
FullScreenCanvas.GetFullScreenCanvas();
|
_ = FullScreenCanvas.GetFullScreenCanvas();
|
||||||
|
|
||||||
// Force existing windows to redraw onto the new canvas renderer
|
// Force existing windows to redraw onto the new canvas renderer
|
||||||
WindowManager.InvalidateAll();
|
WindowManager.InvalidateAll();
|
||||||
|
|
||||||
// Start the terminal process within the desktop environment
|
// Start the terminal process within the desktop environment
|
||||||
ProcessManager.SpawnProcess<TerminalProcess>();
|
_ = ProcessManager.SpawnProcess<TerminalProcess>();
|
||||||
|
|
||||||
// Create a test window for new UI controls
|
// 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));
|
Window testWindow = WindowManager.CreateWindow(this, "UI Controls Test", new System.Drawing.Point(500, 50), new System.Drawing.Size(200, 180));
|
||||||
|
|
||||||
testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Controls.Button>(b =>
|
_ = testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Controls.Button>(b =>
|
||||||
{
|
{
|
||||||
b.Position = new System.Drawing.Point(20, 30);
|
b.Position = new System.Drawing.Point(20, 30);
|
||||||
b.Size = new System.Drawing.Size(100, 30);
|
b.Size = new System.Drawing.Size(100, 30);
|
||||||
@@ -47,14 +46,14 @@ public class DesktopProcess : Process
|
|||||||
b.BackgroundColor = System.Drawing.Color.LightBlue;
|
b.BackgroundColor = System.Drawing.Color.LightBlue;
|
||||||
});
|
});
|
||||||
|
|
||||||
testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Controls.CheckBox>(c =>
|
_ = testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Controls.CheckBox>(c =>
|
||||||
{
|
{
|
||||||
c.Position = new System.Drawing.Point(20, 80);
|
c.Position = new System.Drawing.Point(20, 80);
|
||||||
c.Text = "Check Me";
|
c.Text = "Check Me";
|
||||||
c.IsChecked = true;
|
c.IsChecked = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Shapes.Line>(l =>
|
_ = testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Shapes.Line>(l =>
|
||||||
{
|
{
|
||||||
l.Position = new System.Drawing.Point(20, 130);
|
l.Position = new System.Drawing.Point(20, 130);
|
||||||
l.EndPosition = new System.Drawing.Point(180, 130);
|
l.EndPosition = new System.Drawing.Point(180, 130);
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using Cosmos.Kernel.System;
|
|
||||||
using Cosmos.Kernel.System.Keyboard;
|
using Cosmos.Kernel.System.Keyboard;
|
||||||
|
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
|
using RemSox.UI.CLI;
|
||||||
using RemSox.UI.GUI.UIEelements;
|
using RemSox.UI.GUI.UIEelements;
|
||||||
using RemSox.UI.GUI.Windows;
|
using RemSox.UI.GUI.Windows;
|
||||||
using RemSox.UI.GUI.CLI;
|
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace RemSox.Processes;
|
namespace RemSox.Processes;
|
||||||
|
|
||||||
public class TerminalProcess : Process
|
public class TerminalProcess : Process
|
||||||
{
|
{
|
||||||
private Window? window;
|
private Window? window;
|
||||||
private readonly List<string> history = new();
|
private readonly List<string> history = [];
|
||||||
private string currentInput = "";
|
private string currentInput = "";
|
||||||
private readonly List<Text> textLines = new();
|
private readonly List<Text> textLines = [];
|
||||||
private readonly object textLinesLock = new object();
|
private readonly Lock textLinesLock = new();
|
||||||
private const int LineHeight = 30;
|
private const int LineHeight = 30;
|
||||||
private Size lastSize = new Size(-1, -1);
|
private Size lastSize = new(-1, -1);
|
||||||
|
|
||||||
public TerminalProcess() : base("Terminal")
|
public TerminalProcess() : base("Terminal")
|
||||||
{
|
{
|
||||||
@@ -64,7 +63,7 @@ public class TerminalProcess : Process
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool found = CommandManager.TryExecute(cmd, line => PrintLine(line));
|
bool found = CommandManager.TryExecute(cmd, PrintLine);
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
PrintLine($"\"{cmd}\" is not a command");
|
PrintLine($"\"{cmd}\" is not a command");
|
||||||
@@ -77,11 +76,11 @@ public class TerminalProcess : Process
|
|||||||
{
|
{
|
||||||
if (currentInput.Length > 0)
|
if (currentInput.Length > 0)
|
||||||
{
|
{
|
||||||
currentInput = currentInput.Substring(0, currentInput.Length - 1);
|
currentInput = currentInput[..^1];
|
||||||
UpdateDisplay();
|
UpdateDisplay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (keyEvent.KeyChar >= 32 && keyEvent.KeyChar <= 126) // Printable chars
|
else if (keyEvent.KeyChar is >= (char)32 and <= (char)126) // Printable chars
|
||||||
{
|
{
|
||||||
currentInput += keyEvent.KeyChar;
|
currentInput += keyEvent.KeyChar;
|
||||||
UpdateDisplay();
|
UpdateDisplay();
|
||||||
@@ -100,19 +99,25 @@ public class TerminalProcess : Process
|
|||||||
|
|
||||||
private void UpdateDisplay()
|
private void UpdateDisplay()
|
||||||
{
|
{
|
||||||
if (window == null) return;
|
if (window == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int availableHeight = window.Size.Height - 24; // 18 for title + 6 margin
|
int availableHeight = window.Size.Height - 24; // 18 for title + 6 margin
|
||||||
int maxLines = availableHeight / LineHeight - 1; // -1 for input line
|
int maxLines = (availableHeight / LineHeight) - 1; // -1 for input line
|
||||||
|
|
||||||
if (maxLines < 1) maxLines = 1;
|
if (maxLines < 1)
|
||||||
|
{
|
||||||
|
maxLines = 1;
|
||||||
|
}
|
||||||
|
|
||||||
lock (textLinesLock)
|
lock (textLinesLock)
|
||||||
{
|
{
|
||||||
// Ensure we have enough Text elements for maxLines + 1 (input line)
|
// Ensure we have enough Text elements for maxLines + 1 (input line)
|
||||||
while (textLines.Count <= maxLines)
|
while (textLines.Count <= maxLines)
|
||||||
{
|
{
|
||||||
var textElement = window.CreateUIElement<Text>(t =>
|
Text textElement = window.CreateUIElement<Text>(t =>
|
||||||
{
|
{
|
||||||
t.Color = Color.LightGreen;
|
t.Color = Color.LightGreen;
|
||||||
t.Content = "";
|
t.Content = "";
|
||||||
@@ -122,7 +127,10 @@ public class TerminalProcess : Process
|
|||||||
|
|
||||||
// Calculate starting Y to align everything flush to the bottom margin
|
// Calculate starting Y to align everything flush to the bottom margin
|
||||||
int startY = window.Size.Height - ((maxLines + 1) * LineHeight) - 5;
|
int startY = window.Size.Height - ((maxLines + 1) * LineHeight) - 5;
|
||||||
if (startY < 20) startY = 20;
|
if (startY < 20)
|
||||||
|
{
|
||||||
|
startY = 20;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < maxLines; i++)
|
for (int i = 0; i < maxLines; i++)
|
||||||
{
|
{
|
||||||
@@ -140,7 +148,7 @@ public class TerminalProcess : Process
|
|||||||
// The last line is the input line
|
// The last line is the input line
|
||||||
textLines[maxLines].Content = "> " + currentInput + "_";
|
textLines[maxLines].Content = "> " + currentInput + "_";
|
||||||
textLines[maxLines].Position = new Point(5, startY + (maxLines * LineHeight));
|
textLines[maxLines].Position = new Point(5, startY + (maxLines * LineHeight));
|
||||||
// Hide any extra text lines we don't need
|
// Hide any extra text lines we don't need
|
||||||
for (int i = maxLines + 1; i < textLines.Count; i++)
|
for (int i = maxLines + 1; i < textLines.Count; i++)
|
||||||
{
|
{
|
||||||
textLines[i].Content = "";
|
textLines[i].Content = "";
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
using System;
|
|
||||||
using RemSox.Processing;
|
|
||||||
|
|
||||||
namespace RemSox.Processing.IPC;
|
namespace RemSox.Processing.IPC;
|
||||||
|
|
||||||
internal static class InterProcessCommunicator
|
internal static class InterProcessCommunicator
|
||||||
@@ -15,7 +12,7 @@ internal static class InterProcessCommunicator
|
|||||||
{
|
{
|
||||||
message.SenderProcessId = sender.Id; // automatically set
|
message.SenderProcessId = sender.Id; // automatically set
|
||||||
|
|
||||||
foreach (var process in ProcessManager.GetAllProcesses())
|
foreach (Process process in ProcessManager.GetAllProcesses())
|
||||||
{
|
{
|
||||||
process.HandleInterProcessMessage(message);
|
process.HandleInterProcessMessage(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace RemSox.Processing.IPC;
|
namespace RemSox.Processing.IPC;
|
||||||
|
|
||||||
public abstract class Message
|
public abstract class Message
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using RemSox.Processing.IPC;
|
using RemSox.Processing.IPC;
|
||||||
|
|
||||||
namespace RemSox.Processing;
|
namespace RemSox.Processing;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using RemSox.UI.GUI.Windows;
|
using RemSox.UI.GUI.Windows;
|
||||||
|
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace RemSox.Processing;
|
namespace RemSox.Processing;
|
||||||
|
|
||||||
public static class ProcessManager
|
public static class ProcessManager
|
||||||
@@ -31,12 +31,12 @@ public static class ProcessManager
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
processes.TryRemove(id, out _);
|
_ = processes.TryRemove(id, out _);
|
||||||
WindowManager.CloseWindowsForProcess(id);
|
WindowManager.CloseWindowsForProcess(id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
processes.TryAdd(id, (process, thread));
|
_ = processes.TryAdd(id, (process, thread));
|
||||||
|
|
||||||
thread.Start();
|
thread.Start();
|
||||||
|
|
||||||
@@ -45,19 +45,21 @@ public static class ProcessManager
|
|||||||
|
|
||||||
public static void StopProcess(int processId)
|
public static void StopProcess(int processId)
|
||||||
{
|
{
|
||||||
if (!processes.TryGetValue(processId, out var entry))
|
if (!processes.TryGetValue(processId, out (Process Process, Thread Thread) entry))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
entry.Process.RequestStop();
|
entry.Process.RequestStop();
|
||||||
|
|
||||||
WindowManager.CloseWindowsForProcess(processId);
|
WindowManager.CloseWindowsForProcess(processId);
|
||||||
|
|
||||||
processes.TryRemove(processId, out _);
|
_ = processes.TryRemove(processId, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StopAllProcesses()
|
public static void StopAllProcesses()
|
||||||
{
|
{
|
||||||
foreach (var entry in processes.Values)
|
foreach ((Process Process, Thread Thread) entry in processes.Values)
|
||||||
{
|
{
|
||||||
StopProcess(entry.Process.Id);
|
StopProcess(entry.Process.Id);
|
||||||
}
|
}
|
||||||
@@ -67,7 +69,7 @@ public static class ProcessManager
|
|||||||
|
|
||||||
public static Process? GetProcess(int processId)
|
public static Process? GetProcess(int processId)
|
||||||
{
|
{
|
||||||
if (processes.TryGetValue(processId, out var entry))
|
if (processes.TryGetValue(processId, out (Process Process, Thread Thread) entry))
|
||||||
{
|
{
|
||||||
return entry.Process;
|
return entry.Process;
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,7 @@ public static class ProcessManager
|
|||||||
|
|
||||||
public static IEnumerable<Process> GetAllProcesses()
|
public static IEnumerable<Process> GetAllProcesses()
|
||||||
{
|
{
|
||||||
foreach (var entry in processes.Values)
|
foreach ((Process Process, Thread Thread) entry in processes.Values)
|
||||||
{
|
{
|
||||||
yield return entry.Process;
|
yield return entry.Process;
|
||||||
}
|
}
|
||||||
@@ -85,7 +87,7 @@ public static class ProcessManager
|
|||||||
|
|
||||||
public static bool TryGetProcess(int processId, out Process? process)
|
public static bool TryGetProcess(int processId, out Process? process)
|
||||||
{
|
{
|
||||||
if (processes.TryGetValue(processId, out var entry))
|
if (processes.TryGetValue(processId, out (Process Process, Thread Thread) entry))
|
||||||
{
|
{
|
||||||
process = entry.Process;
|
process = entry.Process;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
namespace RemSox.UI.CLI;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.CLI;
|
|
||||||
|
|
||||||
public static class CommandManager
|
public static class CommandManager
|
||||||
{
|
{
|
||||||
@@ -48,7 +46,7 @@ public static class CommandManager
|
|||||||
|
|
||||||
if (trimmedInput.Length > commandName.Length)
|
if (trimmedInput.Length > commandName.Length)
|
||||||
{
|
{
|
||||||
arguments = trimmedInput.Substring(commandName.Length).TrimStart();
|
arguments = trimmedInput[commandName.Length..].TrimStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.Value.Execute(arguments, printLine);
|
entry.Value.Execute(arguments, printLine);
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
namespace RemSox.UI.CLI.Commands;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.CLI.Commands;
|
|
||||||
|
|
||||||
public sealed class ClearCommand : ICommand
|
public sealed class ClearCommand : ICommand
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using RemSox.UI.CLI;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.CLI.Commands;
|
namespace RemSox.UI.CLI.Commands;
|
||||||
|
|
||||||
public sealed class HaltCommand : ICommand
|
public sealed class HaltCommand : ICommand
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using RemSox.UI.CLI;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.CLI.Commands;
|
namespace RemSox.UI.CLI.Commands;
|
||||||
|
|
||||||
public sealed class HelpCommand : ICommand
|
public sealed class HelpCommand : ICommand
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
|
using RemSox.UI.CLI;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.CLI.Commands;
|
namespace RemSox.UI.CLI.Commands;
|
||||||
|
|
||||||
public sealed class SpawnTestProcessCommand : ICommand
|
public sealed class SpawnTestProcessCommand : ICommand
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
|
||||||
using RemSox.Processing;
|
|
||||||
using RemSox.Processes;
|
using RemSox.Processes;
|
||||||
using RemSox.UI.GUI.CLI;
|
using RemSox.Processing;
|
||||||
|
using RemSox.UI.CLI;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.CLI.Commands;
|
namespace RemSox.UI.CLI.Commands;
|
||||||
|
|
||||||
public class StartGuiCommand : ICommand
|
public class StartGuiCommand : ICommand
|
||||||
{
|
{
|
||||||
@@ -13,6 +12,6 @@ public class StartGuiCommand : ICommand
|
|||||||
public void Execute(string? arguments, Action<string> printLine)
|
public void Execute(string? arguments, Action<string> printLine)
|
||||||
{
|
{
|
||||||
printLine("Starting Desktop Process...");
|
printLine("Starting Desktop Process...");
|
||||||
ProcessManager.SpawnProcess<DesktopProcess>();
|
_ = ProcessManager.SpawnProcess<DesktopProcess>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -1,7 +1,4 @@
|
|||||||
namespace RemSox.UI.GUI.CLI;
|
namespace RemSox.UI.CLI;
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines a command executable via the CLI or GUI terminal.
|
/// Defines a command executable via the CLI or GUI terminal.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Cosmos.Kernel.System.Graphics;
|
using Cosmos.Kernel.System.Graphics;
|
||||||
using Cosmos.Kernel.System.Graphics.Fonts;
|
using Cosmos.Kernel.System.Graphics.Fonts;
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.Rendering;
|
namespace RemSox.UI.GUI.Rendering;
|
||||||
|
|
||||||
public sealed class CanvasRenderSource : IRenderSource
|
public sealed class CanvasRenderSource : IRenderSource
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<int, Canvas> windowCanvases = new();
|
private static readonly Dictionary<int, Canvas> windowCanvases = [];
|
||||||
private static readonly Dictionary<int, Point> windowPositions = new();
|
private static readonly Dictionary<int, Point> windowPositions = [];
|
||||||
private static readonly Dictionary<int, int> windowZIndices = new();
|
private static readonly Dictionary<int, int> windowZIndices = [];
|
||||||
|
|
||||||
private static bool isDirty = true;
|
private static bool isDirty = true;
|
||||||
private static Point lastPointerPosition = new Point(-1, -1);
|
private static Point lastPointerPosition = new(-1, -1);
|
||||||
private static List<int> orderedWindowsCache = new();
|
private static List<int> orderedWindowsCache = [];
|
||||||
private static bool isZOrderDirty = true;
|
private static bool isZOrderDirty = true;
|
||||||
private static readonly object renderLock = new object();
|
private static readonly Lock renderLock = new();
|
||||||
|
|
||||||
public void Render(IEnumerable<RenderCommand> commands)
|
public void Render(IEnumerable<RenderCommand> commands)
|
||||||
{
|
{
|
||||||
@@ -29,14 +27,14 @@ public sealed class CanvasRenderSource : IRenderSource
|
|||||||
changed = true;
|
changed = true;
|
||||||
if (command.ElementType == "WindowClose")
|
if (command.ElementType == "WindowClose")
|
||||||
{
|
{
|
||||||
windowCanvases.Remove(command.WindowId);
|
_ = windowCanvases.Remove(command.WindowId);
|
||||||
windowPositions.Remove(command.WindowId);
|
_ = windowPositions.Remove(command.WindowId);
|
||||||
windowZIndices.Remove(command.WindowId);
|
_ = windowZIndices.Remove(command.WindowId);
|
||||||
isZOrderDirty = true;
|
isZOrderDirty = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.ElementType == "Window" || command.ElementType == "WindowMove")
|
if (command.ElementType is "Window" or "WindowMove")
|
||||||
{
|
{
|
||||||
if (command.Properties.TryGetValue("ZIndex", out object? rawZIndex) && rawZIndex is int z)
|
if (command.Properties.TryGetValue("ZIndex", out object? rawZIndex) && rawZIndex is int z)
|
||||||
{
|
{
|
||||||
@@ -134,7 +132,7 @@ public sealed class CanvasRenderSource : IRenderSource
|
|||||||
|
|
||||||
screenCanvas.Clear(Color.Black);
|
screenCanvas.Clear(Color.Black);
|
||||||
|
|
||||||
foreach (var windowId in orderedWindowsCache)
|
foreach (int windowId in orderedWindowsCache)
|
||||||
{
|
{
|
||||||
if (windowPositions.TryGetValue(windowId, out Point position) && windowCanvases.TryGetValue(windowId, out Canvas? windowCanvas))
|
if (windowPositions.TryGetValue(windowId, out Point position) && windowCanvases.TryGetValue(windowId, out Canvas? windowCanvas))
|
||||||
{
|
{
|
||||||
@@ -256,7 +254,7 @@ public sealed class CanvasRenderSource : IRenderSource
|
|||||||
{
|
{
|
||||||
Color bgColor = command.Properties.TryGetValue("BackgroundColor", out object? rawBgColor) && rawBgColor is Color c1 ? c1 : Color.LightGray;
|
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;
|
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;
|
bool isChecked = command.Properties.TryGetValue("IsChecked", out object? rawChecked) && rawChecked is bool chk && chk;
|
||||||
string text = command.Properties.TryGetValue("Text", out object? rawText) && rawText is string t ? t : string.Empty;
|
string text = command.Properties.TryGetValue("Text", out object? rawText) && rawText is string t ? t : string.Empty;
|
||||||
|
|
||||||
int boxSize = 12;
|
int boxSize = 12;
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ namespace RemSox.UI.GUI.Rendering;
|
|||||||
|
|
||||||
public interface IRenderSource
|
public interface IRenderSource
|
||||||
{
|
{
|
||||||
public void Render(IEnumerable<RenderCommand> commands);
|
void Render(IEnumerable<RenderCommand> commands);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.Rendering;
|
namespace RemSox.UI.GUI.Rendering;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.UIEelements;
|
namespace RemSox.UI.GUI.UIEelements;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.UIEelements.Shapes;
|
namespace RemSox.UI.GUI.UIEelements.Shapes;
|
||||||
|
|
||||||
public class Circle() : Shape("Circle")
|
public class Circle() : Shape("Circle")
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
namespace RemSox.UI.GUI.UIEelements;
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Drawing;
|
|
||||||
using RemSox.Utils;
|
using RemSox.Utils;
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace RemSox.UI.GUI.UIEelements;
|
||||||
|
|
||||||
public abstract class UIElement(string type) : ChangedPropertiesTracker
|
public abstract class UIElement(string type) : ChangedPropertiesTracker
|
||||||
{
|
{
|
||||||
public int Id { get; init; }
|
public int Id { get; init; }
|
||||||
|
|||||||
+42
-23
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Reflection;
|
|
||||||
using RemSox.UI.GUI.Rendering;
|
using RemSox.UI.GUI.Rendering;
|
||||||
using RemSox.UI.GUI.UIEelements;
|
using RemSox.UI.GUI.UIEelements;
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.Windows;
|
namespace RemSox.UI.GUI.Windows;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -38,11 +37,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
/// <summary> Gets or sets whether this window is currently focused. </summary>
|
/// <summary> Gets or sets whether this window is currently focused. </summary>
|
||||||
public bool IsFocused
|
public bool IsFocused
|
||||||
{
|
{
|
||||||
get => WindowManager.IsWindowFocused(this);
|
get => WindowManager.IsWindowFocused(this); set => WindowManager.FocusWindow(value ? this : null);
|
||||||
set
|
|
||||||
{
|
|
||||||
WindowManager.FocusWindow(value ? this : null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Gets or sets whether the window is visible. </summary>
|
/// <summary> Gets or sets whether the window is visible. </summary>
|
||||||
@@ -63,7 +58,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
/// <summary> Gets whether the window is currently being dragged. </summary>
|
/// <summary> Gets whether the window is currently being dragged. </summary>
|
||||||
public bool IsDragging => currentInteraction == InteractionMode.Drag;
|
public bool IsDragging => currentInteraction == InteractionMode.Drag;
|
||||||
|
|
||||||
private readonly object uiElementsLock = new object();
|
private readonly Lock uiElementsLock = new();
|
||||||
private readonly Dictionary<int, UIElement> uiElements = [];
|
private readonly Dictionary<int, UIElement> uiElements = [];
|
||||||
|
|
||||||
private int nextUIElementId = 1;
|
private int nextUIElementId = 1;
|
||||||
@@ -74,8 +69,8 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
private Point interactionStartPointer;
|
private Point interactionStartPointer;
|
||||||
private Point dragOffset;
|
private Point dragOffset;
|
||||||
|
|
||||||
private Point lastRenderedPosition = new Point(-1, -1);
|
private Point lastRenderedPosition = new(-1, -1);
|
||||||
private Size lastRenderedSize = new Size(-1, -1);
|
private Size lastRenderedSize = new(-1, -1);
|
||||||
private bool lastRenderedIsFocused = false;
|
private bool lastRenderedIsFocused = false;
|
||||||
private string lastRenderedTitle = string.Empty;
|
private string lastRenderedTitle = string.Empty;
|
||||||
private int lastRenderedZIndex = -1;
|
private int lastRenderedZIndex = -1;
|
||||||
@@ -235,14 +230,38 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
|
|
||||||
if (IsResizable)
|
if (IsResizable)
|
||||||
{
|
{
|
||||||
if (onTop && onLeft) currentInteraction = InteractionMode.ResizeTopLeft;
|
if (onTop && onLeft)
|
||||||
else if (onTop && onRight) currentInteraction = InteractionMode.ResizeTopRight;
|
{
|
||||||
else if (onBottom && onLeft) currentInteraction = InteractionMode.ResizeBottomLeft;
|
currentInteraction = InteractionMode.ResizeTopLeft;
|
||||||
else if (onBottom && onRight) currentInteraction = InteractionMode.ResizeBottomRight;
|
}
|
||||||
else if (onLeft && inBounds) currentInteraction = InteractionMode.ResizeLeft;
|
else if (onTop && onRight)
|
||||||
else if (onRight && inBounds) currentInteraction = InteractionMode.ResizeRight;
|
{
|
||||||
else if (onTop && inBounds) currentInteraction = InteractionMode.ResizeTop;
|
currentInteraction = InteractionMode.ResizeTopRight;
|
||||||
else if (onBottom && inBounds) currentInteraction = InteractionMode.ResizeBottom;
|
}
|
||||||
|
else if (onBottom && onLeft)
|
||||||
|
{
|
||||||
|
currentInteraction = InteractionMode.ResizeBottomLeft;
|
||||||
|
}
|
||||||
|
else if (onBottom && onRight)
|
||||||
|
{
|
||||||
|
currentInteraction = InteractionMode.ResizeBottomRight;
|
||||||
|
}
|
||||||
|
else if (onLeft && inBounds)
|
||||||
|
{
|
||||||
|
currentInteraction = InteractionMode.ResizeLeft;
|
||||||
|
}
|
||||||
|
else if (onRight && inBounds)
|
||||||
|
{
|
||||||
|
currentInteraction = InteractionMode.ResizeRight;
|
||||||
|
}
|
||||||
|
else if (onTop && inBounds)
|
||||||
|
{
|
||||||
|
currentInteraction = InteractionMode.ResizeTop;
|
||||||
|
}
|
||||||
|
else if (onBottom && inBounds)
|
||||||
|
{
|
||||||
|
currentInteraction = InteractionMode.ResizeBottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentInteraction == InteractionMode.None && IsDraggable && IsPointInTitleBar(pointerPosition))
|
if (currentInteraction == InteractionMode.None && IsDraggable && IsPointInTitleBar(pointerPosition))
|
||||||
@@ -297,22 +316,22 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
const int minWidth = 100;
|
const int minWidth = 100;
|
||||||
const int minHeight = 50;
|
const int minHeight = 50;
|
||||||
|
|
||||||
if (currentInteraction == InteractionMode.ResizeRight || currentInteraction == InteractionMode.ResizeBottomRight || currentInteraction == InteractionMode.ResizeTopRight)
|
if (currentInteraction is InteractionMode.ResizeRight or InteractionMode.ResizeBottomRight or InteractionMode.ResizeTopRight)
|
||||||
{
|
{
|
||||||
newW = Math.Max(minWidth, interactionStartBounds.Width + dx);
|
newW = Math.Max(minWidth, interactionStartBounds.Width + dx);
|
||||||
}
|
}
|
||||||
if (currentInteraction == InteractionMode.ResizeBottom || currentInteraction == InteractionMode.ResizeBottomRight || currentInteraction == InteractionMode.ResizeBottomLeft)
|
if (currentInteraction is InteractionMode.ResizeBottom or InteractionMode.ResizeBottomRight or InteractionMode.ResizeBottomLeft)
|
||||||
{
|
{
|
||||||
newH = Math.Max(minHeight, interactionStartBounds.Height + dy);
|
newH = Math.Max(minHeight, interactionStartBounds.Height + dy);
|
||||||
}
|
}
|
||||||
if (currentInteraction == InteractionMode.ResizeLeft || currentInteraction == InteractionMode.ResizeBottomLeft || currentInteraction == InteractionMode.ResizeTopLeft)
|
if (currentInteraction is InteractionMode.ResizeLeft or InteractionMode.ResizeBottomLeft or InteractionMode.ResizeTopLeft)
|
||||||
{
|
{
|
||||||
int maxDx = interactionStartBounds.Width - minWidth;
|
int maxDx = interactionStartBounds.Width - minWidth;
|
||||||
int clampedDx = Math.Min(dx, maxDx);
|
int clampedDx = Math.Min(dx, maxDx);
|
||||||
newX = Math.Max(0, interactionStartBounds.X + clampedDx);
|
newX = Math.Max(0, interactionStartBounds.X + clampedDx);
|
||||||
newW = interactionStartBounds.Width - clampedDx;
|
newW = interactionStartBounds.Width - clampedDx;
|
||||||
}
|
}
|
||||||
if (currentInteraction == InteractionMode.ResizeTop || currentInteraction == InteractionMode.ResizeTopLeft || currentInteraction == InteractionMode.ResizeTopRight)
|
if (currentInteraction is InteractionMode.ResizeTop or InteractionMode.ResizeTopLeft or InteractionMode.ResizeTopRight)
|
||||||
{
|
{
|
||||||
int maxDy = interactionStartBounds.Height - minHeight;
|
int maxDy = interactionStartBounds.Height - minHeight;
|
||||||
int clampedDy = Math.Min(dy, maxDy);
|
int clampedDy = Math.Min(dy, maxDy);
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Linq;
|
|
||||||
using Cosmos.Kernel.System.Graphics;
|
using Cosmos.Kernel.System.Graphics;
|
||||||
using Cosmos.Kernel.System.Mouse;
|
|
||||||
using Cosmos.Kernel.System.Keyboard;
|
using Cosmos.Kernel.System.Keyboard;
|
||||||
|
using Cosmos.Kernel.System.Mouse;
|
||||||
|
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
using RemSox.UI.GUI.Rendering;
|
using RemSox.UI.GUI.Rendering;
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.Windows;
|
namespace RemSox.UI.GUI.Windows;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -16,9 +14,9 @@ namespace RemSox.UI.GUI.Windows;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class WindowManager
|
public static class WindowManager
|
||||||
{
|
{
|
||||||
private static readonly object windowsLock = new object();
|
private static readonly Lock windowsLock = new();
|
||||||
// Process ID to list of windows
|
// Process ID to list of windows
|
||||||
private static readonly Dictionary<int, List<Window>> windows = new();
|
private static readonly Dictionary<int, List<Window>> windows = [];
|
||||||
|
|
||||||
private static int nextWindowId = 1;
|
private static int nextWindowId = 1;
|
||||||
private static int nextZIndex = 1;
|
private static int nextZIndex = 1;
|
||||||
@@ -28,7 +26,6 @@ public static class WindowManager
|
|||||||
private static Window? activeInteractWindow = null;
|
private static Window? activeInteractWindow = null;
|
||||||
private static Point lastPointerPosition = Point.Empty;
|
private static Point lastPointerPosition = Point.Empty;
|
||||||
private static bool wasLeftButtonDown = false;
|
private static bool wasLeftButtonDown = false;
|
||||||
private static int mousePollCounter = 0;
|
|
||||||
|
|
||||||
private static readonly MuliRenderSource renderSource = new([]);
|
private static readonly MuliRenderSource renderSource = new([]);
|
||||||
|
|
||||||
@@ -37,10 +34,9 @@ public static class WindowManager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
mousePollCounter++;
|
|
||||||
MouseManager.Poll();
|
MouseManager.Poll();
|
||||||
|
|
||||||
Point pointerPosition = new((int)MouseManager.X, (int)MouseManager.Y);
|
Point pointerPosition = new(MouseManager.X, MouseManager.Y);
|
||||||
bool leftButtonDown = MouseManager.LeftButton;
|
bool leftButtonDown = MouseManager.LeftButton;
|
||||||
|
|
||||||
if (leftButtonDown && !wasLeftButtonDown)
|
if (leftButtonDown && !wasLeftButtonDown)
|
||||||
@@ -59,7 +55,7 @@ public static class WindowManager
|
|||||||
|
|
||||||
wasLeftButtonDown = leftButtonDown;
|
wasLeftButtonDown = leftButtonDown;
|
||||||
|
|
||||||
while (KeyboardManager.TryReadKey(out KeyEvent keyEvent))
|
while (KeyboardManager.TryReadKey(out KeyEvent? keyEvent) && keyEvent is not null)
|
||||||
{
|
{
|
||||||
focusedWindow?.HandleKeyEvent(keyEvent);
|
focusedWindow?.HandleKeyEvent(keyEvent);
|
||||||
}
|
}
|
||||||
@@ -73,12 +69,18 @@ public static class WindowManager
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a new rendering source to the compositor.
|
/// Adds a new rendering source to the compositor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void AddRenderSource(IRenderSource source) => renderSource.AddSource(source);
|
public static void AddRenderSource(IRenderSource source)
|
||||||
|
{
|
||||||
|
renderSource.AddSource(source);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes an existing rendering source from the compositor.
|
/// Removes an existing rendering source from the compositor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void RemoveRenderSource(IRenderSource source) => renderSource.RemoveSource(source);
|
public static void RemoveRenderSource(IRenderSource source)
|
||||||
|
{
|
||||||
|
renderSource.RemoveSource(source);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates and registers a new window for the specified process.
|
/// Creates and registers a new window for the specified process.
|
||||||
@@ -112,13 +114,13 @@ public static class WindowManager
|
|||||||
{
|
{
|
||||||
lock (windowsLock)
|
lock (windowsLock)
|
||||||
{
|
{
|
||||||
if (windows.TryGetValue(window.ProcessId, out var processWindows))
|
if (windows.TryGetValue(window.ProcessId, out List<Window>? processWindows))
|
||||||
{
|
{
|
||||||
processWindows.Remove(window);
|
_ = processWindows.Remove(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSource.Render(new[] { new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() } });
|
renderSource.Render([new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -128,7 +130,7 @@ public static class WindowManager
|
|||||||
{
|
{
|
||||||
lock (windowsLock)
|
lock (windowsLock)
|
||||||
{
|
{
|
||||||
if (windows.TryGetValue(process.Id, out var processWindows))
|
if (windows.TryGetValue(process.Id, out List<Window>? processWindows))
|
||||||
{
|
{
|
||||||
return processWindows.ToList();
|
return processWindows.ToList();
|
||||||
}
|
}
|
||||||
@@ -150,20 +152,20 @@ public static class WindowManager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void CloseWindowsForProcess(int processId)
|
public static void CloseWindowsForProcess(int processId)
|
||||||
{
|
{
|
||||||
List<Window> windowsToClose = new();
|
List<Window> windowsToClose = [];
|
||||||
lock (windowsLock)
|
lock (windowsLock)
|
||||||
{
|
{
|
||||||
if (windows.TryGetValue(processId, out var processWindows))
|
if (windows.TryGetValue(processId, out List<Window>? processWindows))
|
||||||
{
|
{
|
||||||
windowsToClose.AddRange(processWindows);
|
windowsToClose.AddRange(processWindows);
|
||||||
windows.Remove(processId);
|
_ = windows.Remove(processId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (windowsToClose.Count > 0)
|
if (windowsToClose.Count > 0)
|
||||||
{
|
{
|
||||||
List<RenderCommand> closeCommands = new();
|
List<RenderCommand> closeCommands = [];
|
||||||
foreach (var window in windowsToClose)
|
foreach (Window window in windowsToClose)
|
||||||
{
|
{
|
||||||
closeCommands.Add(new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() });
|
closeCommands.Add(new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() });
|
||||||
}
|
}
|
||||||
@@ -181,10 +183,7 @@ public static class WindowManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window != null)
|
_ = window?.ZIndex = nextZIndex++;
|
||||||
{
|
|
||||||
window.ZIndex = nextZIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Window? previousFocusedWindow = focusedWindow;
|
Window? previousFocusedWindow = focusedWindow;
|
||||||
focusedWindow = window;
|
focusedWindow = window;
|
||||||
@@ -212,7 +211,7 @@ public static class WindowManager
|
|||||||
allWindows = windows.Values.SelectMany(w => w).OrderByDescending(w => w.ZIndex).ToList();
|
allWindows = windows.Values.SelectMany(w => w).OrderByDescending(w => w.ZIndex).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var window in allWindows)
|
foreach (Window window in allWindows)
|
||||||
{
|
{
|
||||||
if (window.TryBeginInteract(pointerPosition))
|
if (window.TryBeginInteract(pointerPosition))
|
||||||
{
|
{
|
||||||
@@ -233,7 +232,7 @@ public static class WindowManager
|
|||||||
allWindows = windows.Values.SelectMany(w => w).ToList();
|
allWindows = windows.Values.SelectMany(w => w).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var window in allWindows)
|
foreach (Window window in allWindows)
|
||||||
{
|
{
|
||||||
window.Invalidate();
|
window.Invalidate();
|
||||||
}
|
}
|
||||||
@@ -244,9 +243,9 @@ public static class WindowManager
|
|||||||
return nextWindowId++;
|
return nextWindowId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed private class MuliRenderSource(List<IRenderSource> sources) : IRenderSource
|
private sealed class MuliRenderSource(List<IRenderSource> sources) : IRenderSource
|
||||||
{
|
{
|
||||||
private readonly object sourcesLock = new object();
|
private readonly Lock sourcesLock = new();
|
||||||
|
|
||||||
public void AddSource(IRenderSource source)
|
public void AddSource(IRenderSource source)
|
||||||
{
|
{
|
||||||
@@ -260,7 +259,7 @@ public static class WindowManager
|
|||||||
{
|
{
|
||||||
lock (sourcesLock)
|
lock (sourcesLock)
|
||||||
{
|
{
|
||||||
sources.Remove(source);
|
_ = sources.Remove(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace RemSox.Utils;
|
namespace RemSox.Utils;
|
||||||
|
|
||||||
@@ -14,7 +11,7 @@ public abstract class ChangedPropertiesTracker : INotifyPropertyChanged
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var changes = new Dictionary<string, object?>();
|
Dictionary<string, object?> changes = new();
|
||||||
foreach (var name in changedPropertyNames)
|
foreach (var name in changedPropertyNames)
|
||||||
{
|
{
|
||||||
if (properties.TryGetValue(name, out var value))
|
if (properties.TryGetValue(name, out var value))
|
||||||
@@ -38,12 +35,18 @@ public abstract class ChangedPropertiesTracker : INotifyPropertyChanged
|
|||||||
{
|
{
|
||||||
field = value;
|
field = value;
|
||||||
properties[name] = value;
|
properties[name] = value;
|
||||||
changedPropertyNames.Add(name);
|
_ = changedPropertyNames.Add(name);
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearChangedProperties() => changedPropertyNames.Clear();
|
public void ClearChangedProperties()
|
||||||
|
{
|
||||||
|
changedPropertyNames.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsPropertyChanged(string name) => changedPropertyNames.Contains(name);
|
public bool IsPropertyChanged(string name)
|
||||||
|
{
|
||||||
|
return changedPropertyNames.Contains(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user