mirror of
https://github.com/Stone-Red-Code/RemSox.git
synced 2026-09-04 00:56:19 +02:00
Add window resizing support and improve process/thread management concurrency
This commit is contained in:
@@ -20,7 +20,7 @@ namespace RemSox;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Kernel : Sys.Kernel
|
public class Kernel : Sys.Kernel
|
||||||
{
|
{
|
||||||
private static Window? activeDragWindow = null;
|
private static Window? activeInteractWindow = null;
|
||||||
|
|
||||||
private static Point lastPointerPosition = Point.Empty;
|
private static Point lastPointerPosition = Point.Empty;
|
||||||
|
|
||||||
@@ -48,7 +48,11 @@ public class Kernel : Sys.Kernel
|
|||||||
Sys.Mouse.MouseManager.Initialize();
|
Sys.Mouse.MouseManager.Initialize();
|
||||||
Sys.Keyboard.KeyboardManager.Initialize();
|
Sys.Keyboard.KeyboardManager.Initialize();
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
ProcessManager.SpawnProcess<TestProcess>();
|
ProcessManager.SpawnProcess<TestProcess>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Console.WriteLine(CosmosFeatures.MouseEnabled);
|
Console.WriteLine(CosmosFeatures.MouseEnabled);
|
||||||
Console.WriteLine(CosmosFeatures.KeyboardEnabled);
|
Console.WriteLine(CosmosFeatures.KeyboardEnabled);
|
||||||
@@ -87,16 +91,16 @@ public class Kernel : Sys.Kernel
|
|||||||
|
|
||||||
if (leftButtonDown && !wasLeftButtonDown)
|
if (leftButtonDown && !wasLeftButtonDown)
|
||||||
{
|
{
|
||||||
activeDragWindow = TryBeginDrag(pointerPosition);
|
activeInteractWindow = TryBeginInteract(pointerPosition);
|
||||||
}
|
}
|
||||||
else if (leftButtonDown && activeDragWindow is not null)
|
else if (leftButtonDown && activeInteractWindow is not null)
|
||||||
{
|
{
|
||||||
activeDragWindow.DragTo(pointerPosition);
|
activeInteractWindow.UpdateInteraction(pointerPosition);
|
||||||
}
|
}
|
||||||
else if (!leftButtonDown && activeDragWindow is not null)
|
else if (!leftButtonDown && activeInteractWindow is not null)
|
||||||
{
|
{
|
||||||
activeDragWindow.EndDrag();
|
activeInteractWindow.EndInteraction();
|
||||||
activeDragWindow = null;
|
activeInteractWindow = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasLeftButtonDown = leftButtonDown;
|
wasLeftButtonDown = leftButtonDown;
|
||||||
@@ -108,7 +112,7 @@ public class Kernel : Sys.Kernel
|
|||||||
lastPointerPosition = pointerPosition;
|
lastPointerPosition = pointerPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Window? TryBeginDrag(Point pointerPosition)
|
private static Window? TryBeginInteract(Point pointerPosition)
|
||||||
{
|
{
|
||||||
foreach (Processing.Process process in ProcessManager.GetAllProcesses())
|
foreach (Processing.Process process in ProcessManager.GetAllProcesses())
|
||||||
{
|
{
|
||||||
@@ -118,7 +122,7 @@ public class Kernel : Sys.Kernel
|
|||||||
{
|
{
|
||||||
Window window = windows[index];
|
Window window = windows[index];
|
||||||
|
|
||||||
if (window.TryBeginDrag(pointerPosition))
|
if (window.TryBeginInteract(pointerPosition))
|
||||||
{
|
{
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace RemSox.Processing;
|
namespace RemSox.Processing;
|
||||||
|
|
||||||
public static class ProcessManager
|
public static class ProcessManager
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<int, (Process Process, Thread Thread)> processes = [];
|
private static readonly ConcurrentDictionary<int, (Process Process, Thread Thread)> processes = new();
|
||||||
|
|
||||||
private static int nextProcessId = 0;
|
private static int nextProcessId = 0;
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ public static class ProcessManager
|
|||||||
|
|
||||||
Thread thread = new(process.Run);
|
Thread thread = new(process.Run);
|
||||||
|
|
||||||
processes.Add(id, (process, thread));
|
processes.TryAdd(id, (process, thread));
|
||||||
|
|
||||||
thread.Start();
|
thread.Start();
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ public static class ProcessManager
|
|||||||
|
|
||||||
entry.Process.RequestStop();
|
entry.Process.RequestStop();
|
||||||
|
|
||||||
processes.Remove(processId);
|
processes.TryRemove(processId, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StopAllProcesses()
|
public static void StopAllProcesses()
|
||||||
|
|||||||
+88
-16
@@ -35,14 +35,16 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
|
|
||||||
public Size Size { get; set; }
|
public Size Size { get; set; }
|
||||||
|
|
||||||
public bool IsDragging => isDragging;
|
public bool IsDragging => currentInteraction == InteractionMode.Drag;
|
||||||
|
|
||||||
private readonly Dictionary<int, UIElement> uiElements = [];
|
private readonly Dictionary<int, UIElement> uiElements = [];
|
||||||
|
|
||||||
private int nextUIElementId = 1;
|
private int nextUIElementId = 1;
|
||||||
|
|
||||||
private bool isDragging;
|
private enum InteractionMode { None, Drag, ResizeTop, ResizeBottom, ResizeLeft, ResizeRight, ResizeTopLeft, ResizeTopRight, ResizeBottomLeft, ResizeBottomRight }
|
||||||
|
private InteractionMode currentInteraction = InteractionMode.None;
|
||||||
|
private Rectangle interactionStartBounds;
|
||||||
|
private Point interactionStartPointer;
|
||||||
private Point dragOffset;
|
private Point dragOffset;
|
||||||
|
|
||||||
private Point lastRenderedPosition = new Point(-1, -1);
|
private Point lastRenderedPosition = new Point(-1, -1);
|
||||||
@@ -149,28 +151,58 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryBeginDrag(Point pointerPosition)
|
public bool TryBeginInteract(Point pointerPosition)
|
||||||
{
|
{
|
||||||
if (!IsVisible || !IsDraggable || !IsPointInTitleBar(pointerPosition))
|
if (!IsVisible)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isDragging = true;
|
const int resizeMargin = 5;
|
||||||
|
|
||||||
|
bool onLeft = pointerPosition.X >= Position.X && pointerPosition.X <= Position.X + resizeMargin;
|
||||||
|
bool onRight = pointerPosition.X >= Position.X + Size.Width - resizeMargin && pointerPosition.X <= Position.X + Size.Width;
|
||||||
|
bool onTop = pointerPosition.Y >= Position.Y && pointerPosition.Y <= Position.Y + resizeMargin;
|
||||||
|
bool onBottom = pointerPosition.Y >= Position.Y + Size.Height - resizeMargin && pointerPosition.Y <= Position.Y + Size.Height;
|
||||||
|
|
||||||
|
bool inBounds = pointerPosition.X >= Position.X && pointerPosition.X <= Position.X + Size.Width &&
|
||||||
|
pointerPosition.Y >= Position.Y && pointerPosition.Y <= Position.Y + Size.Height;
|
||||||
|
|
||||||
|
currentInteraction = InteractionMode.None;
|
||||||
|
|
||||||
|
if (IsResizable)
|
||||||
|
{
|
||||||
|
if (onTop && onLeft) currentInteraction = InteractionMode.ResizeTopLeft;
|
||||||
|
else if (onTop && onRight) currentInteraction = InteractionMode.ResizeTopRight;
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
currentInteraction = InteractionMode.Drag;
|
||||||
dragOffset = new Point(pointerPosition.X - Position.X, pointerPosition.Y - Position.Y);
|
dragOffset = new Point(pointerPosition.X - Position.X, pointerPosition.Y - Position.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentInteraction != InteractionMode.None)
|
||||||
|
{
|
||||||
|
interactionStartBounds = new Rectangle(Position, Size);
|
||||||
|
interactionStartPointer = pointerPosition;
|
||||||
WindowManager.FocusWindow(this);
|
WindowManager.FocusWindow(this);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DragTo(Point pointerPosition)
|
return false;
|
||||||
{
|
|
||||||
if (!isDragging || !IsDraggable)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateInteraction(Point pointerPosition)
|
||||||
|
{
|
||||||
|
if (currentInteraction == InteractionMode.Drag)
|
||||||
|
{
|
||||||
int newX = pointerPosition.X - dragOffset.X;
|
int newX = pointerPosition.X - dragOffset.X;
|
||||||
int newY = pointerPosition.Y - dragOffset.Y;
|
int newY = pointerPosition.Y - dragOffset.Y;
|
||||||
|
|
||||||
@@ -180,13 +212,53 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
newY = Math.Max(0, newY);
|
newY = Math.Max(0, newY);
|
||||||
|
|
||||||
Position = new Point(newX, newY);
|
Position = new Point(newX, newY);
|
||||||
|
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
else if (currentInteraction != InteractionMode.None)
|
||||||
public void EndDrag()
|
|
||||||
{
|
{
|
||||||
isDragging = false;
|
int dx = pointerPosition.X - interactionStartPointer.X;
|
||||||
|
int dy = pointerPosition.Y - interactionStartPointer.Y;
|
||||||
|
|
||||||
|
int newX = interactionStartBounds.X;
|
||||||
|
int newY = interactionStartBounds.Y;
|
||||||
|
int newW = interactionStartBounds.Width;
|
||||||
|
int newH = interactionStartBounds.Height;
|
||||||
|
|
||||||
|
const int minWidth = 100;
|
||||||
|
const int minHeight = 50;
|
||||||
|
|
||||||
|
if (currentInteraction == InteractionMode.ResizeRight || currentInteraction == InteractionMode.ResizeBottomRight || currentInteraction == InteractionMode.ResizeTopRight)
|
||||||
|
{
|
||||||
|
newW = Math.Max(minWidth, interactionStartBounds.Width + dx);
|
||||||
|
}
|
||||||
|
if (currentInteraction == InteractionMode.ResizeBottom || currentInteraction == InteractionMode.ResizeBottomRight || currentInteraction == InteractionMode.ResizeBottomLeft)
|
||||||
|
{
|
||||||
|
newH = Math.Max(minHeight, interactionStartBounds.Height + dy);
|
||||||
|
}
|
||||||
|
if (currentInteraction == InteractionMode.ResizeLeft || currentInteraction == InteractionMode.ResizeBottomLeft || currentInteraction == InteractionMode.ResizeTopLeft)
|
||||||
|
{
|
||||||
|
int maxDx = interactionStartBounds.Width - minWidth;
|
||||||
|
int clampedDx = Math.Min(dx, maxDx);
|
||||||
|
newX = Math.Max(0, interactionStartBounds.X + clampedDx);
|
||||||
|
newW = interactionStartBounds.Width - clampedDx;
|
||||||
|
}
|
||||||
|
if (currentInteraction == InteractionMode.ResizeTop || currentInteraction == InteractionMode.ResizeTopLeft || currentInteraction == InteractionMode.ResizeTopRight)
|
||||||
|
{
|
||||||
|
int maxDy = interactionStartBounds.Height - minHeight;
|
||||||
|
int clampedDy = Math.Min(dy, maxDy);
|
||||||
|
newY = Math.Max(0, interactionStartBounds.Y + clampedDy);
|
||||||
|
newH = interactionStartBounds.Height - clampedDy;
|
||||||
|
}
|
||||||
|
|
||||||
|
Position = new Point(newX, newY);
|
||||||
|
Size = new Size(newW, newH);
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EndInteraction()
|
||||||
|
{
|
||||||
|
currentInteraction = InteractionMode.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsPointInTitleBar(Point pointerPosition)
|
private bool IsPointInTitleBar(Point pointerPosition)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
using RemSox.UI.GUI.Rendering;
|
using RemSox.UI.GUI.Rendering;
|
||||||
@@ -8,7 +9,7 @@ namespace RemSox.UI.GUI.Windows;
|
|||||||
public static class WindowManager
|
public static class WindowManager
|
||||||
{
|
{
|
||||||
// Process ID to list of windows
|
// Process ID to list of windows
|
||||||
private static readonly Dictionary<int, List<Window>> windows = [];
|
private static readonly ConcurrentDictionary<int, List<Window>> windows = new();
|
||||||
|
|
||||||
private static int nextWindowId = 1;
|
private static int nextWindowId = 1;
|
||||||
|
|
||||||
@@ -58,10 +59,7 @@ public static class WindowManager
|
|||||||
|
|
||||||
public static void CloseWindowsForProcess(Process process)
|
public static void CloseWindowsForProcess(Process process)
|
||||||
{
|
{
|
||||||
if (windows.ContainsKey(process.Id))
|
windows.TryRemove(process.Id, out _);
|
||||||
{
|
|
||||||
windows.Remove(process.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FocusWindow(Window? window)
|
public static void FocusWindow(Window? window)
|
||||||
|
|||||||
Reference in New Issue
Block a user