mirror of
https://github.com/Stone-Red-Code/RemSox.git
synced 2026-09-09 07:46:32 +02:00
Implement z-index for windows and ensure correct stacking order on interaction
This commit is contained in:
@@ -91,7 +91,7 @@ public class Kernel : Sys.Kernel
|
|||||||
|
|
||||||
if (leftButtonDown && !wasLeftButtonDown)
|
if (leftButtonDown && !wasLeftButtonDown)
|
||||||
{
|
{
|
||||||
activeInteractWindow = TryBeginInteract(pointerPosition);
|
activeInteractWindow = WindowManager.TryBeginInteract(pointerPosition);
|
||||||
}
|
}
|
||||||
else if (leftButtonDown && activeInteractWindow is not null)
|
else if (leftButtonDown && activeInteractWindow is not null)
|
||||||
{
|
{
|
||||||
@@ -111,26 +111,6 @@ public class Kernel : Sys.Kernel
|
|||||||
|
|
||||||
lastPointerPosition = pointerPosition;
|
lastPointerPosition = pointerPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Window? TryBeginInteract(Point pointerPosition)
|
|
||||||
{
|
|
||||||
foreach (Processing.Process process in ProcessManager.GetAllProcesses())
|
|
||||||
{
|
|
||||||
List<Window> windows = WindowManager.GetWindowsForProcess(process);
|
|
||||||
|
|
||||||
for (int index = windows.Count - 1; index >= 0; index--)
|
|
||||||
{
|
|
||||||
Window window = windows[index];
|
|
||||||
|
|
||||||
if (window.TryBeginInteract(pointerPosition))
|
|
||||||
{
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TestProcess() : Processing.Process("Test Process")
|
public class TestProcess() : Processing.Process("Test Process")
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Cosmos.Kernel.System.Graphics;
|
using Cosmos.Kernel.System.Graphics;
|
||||||
|
|
||||||
namespace RemSox.UI.GUI.Rendering;
|
namespace RemSox.UI.GUI.Rendering;
|
||||||
@@ -9,11 +10,20 @@ public sealed class CanvasRenderSource : IRenderSource
|
|||||||
{
|
{
|
||||||
private static readonly Dictionary<int, Canvas> windowCanvases = new();
|
private static readonly Dictionary<int, Canvas> windowCanvases = new();
|
||||||
private static readonly Dictionary<int, Point> windowPositions = new();
|
private static readonly Dictionary<int, Point> windowPositions = new();
|
||||||
|
private static readonly Dictionary<int, int> windowZIndices = new();
|
||||||
|
|
||||||
public void Render(IEnumerable<RenderCommand> commands)
|
public void Render(IEnumerable<RenderCommand> commands)
|
||||||
{
|
{
|
||||||
foreach (RenderCommand command in commands)
|
foreach (RenderCommand command in commands)
|
||||||
{
|
{
|
||||||
|
if (command.ElementType == "Window" || command.ElementType == "WindowMove")
|
||||||
|
{
|
||||||
|
if (command.Properties.TryGetValue("ZIndex", out object? rawZIndex) && rawZIndex is int z)
|
||||||
|
{
|
||||||
|
windowZIndices[command.WindowId] = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (command.ElementType == "Window")
|
if (command.ElementType == "Window")
|
||||||
{
|
{
|
||||||
Size size = command.Properties.TryGetValue("Size", out object? rawSize) && rawSize is Size windowSize
|
Size size = command.Properties.TryGetValue("Size", out object? rawSize) && rawSize is Size windowSize
|
||||||
@@ -59,11 +69,11 @@ public sealed class CanvasRenderSource : IRenderSource
|
|||||||
{
|
{
|
||||||
screenCanvas.Clear(Color.Black);
|
screenCanvas.Clear(Color.Black);
|
||||||
|
|
||||||
foreach (var kvp in windowPositions)
|
var orderedWindows = windowPositions.Keys.OrderBy(id => windowZIndices.TryGetValue(id, out int z) ? z : 0);
|
||||||
|
|
||||||
|
foreach (var windowId in orderedWindows)
|
||||||
{
|
{
|
||||||
int windowId = kvp.Key;
|
if (windowPositions.TryGetValue(windowId, out Point position) && windowCanvases.TryGetValue(windowId, out Canvas? windowCanvas))
|
||||||
Point position = kvp.Value;
|
|
||||||
if (windowCanvases.TryGetValue(windowId, out Canvas? windowCanvas))
|
|
||||||
{
|
{
|
||||||
screenCanvas.DrawCanvas(windowCanvas, position.X, position.Y);
|
screenCanvas.DrawCanvas(windowCanvas, position.X, position.Y);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
|
|
||||||
public string Title { get; set; } = title;
|
public string Title { get; set; } = title;
|
||||||
|
|
||||||
|
public int ZIndex { get; set; }
|
||||||
|
|
||||||
public bool AutoFlush { get; set; } = false;
|
public bool AutoFlush { get; set; } = false;
|
||||||
|
|
||||||
public bool IsFocused
|
public bool IsFocused
|
||||||
@@ -51,6 +53,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
private Size lastRenderedSize = new Size(-1, -1);
|
private Size lastRenderedSize = new Size(-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 bool isFirstRender = true;
|
private bool isFirstRender = true;
|
||||||
|
|
||||||
public T CreateUIElement<T>(Action<T>? options = null) where T : UIElement, new()
|
public T CreateUIElement<T>(Action<T>? options = null) where T : UIElement, new()
|
||||||
@@ -92,6 +95,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
bool windowStateChanged = isFirstRender || Size != lastRenderedSize || IsFocused != lastRenderedIsFocused || Title != lastRenderedTitle;
|
bool windowStateChanged = isFirstRender || Size != lastRenderedSize || IsFocused != lastRenderedIsFocused || Title != lastRenderedTitle;
|
||||||
bool anyChildChanged = uiElements.Values.Any(e => e.AnyPropertyChanged);
|
bool anyChildChanged = uiElements.Values.Any(e => e.AnyPropertyChanged);
|
||||||
bool positionChanged = Position != lastRenderedPosition;
|
bool positionChanged = Position != lastRenderedPosition;
|
||||||
|
bool zIndexChanged = ZIndex != lastRenderedZIndex;
|
||||||
|
|
||||||
bool fullRedraw = windowStateChanged || anyChildChanged;
|
bool fullRedraw = windowStateChanged || anyChildChanged;
|
||||||
|
|
||||||
@@ -111,7 +115,8 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
[nameof(Size)] = Size,
|
[nameof(Size)] = Size,
|
||||||
[nameof(IsFocused)] = IsFocused,
|
[nameof(IsFocused)] = IsFocused,
|
||||||
[nameof(IsResizable)] = IsResizable,
|
[nameof(IsResizable)] = IsResizable,
|
||||||
[nameof(IsDraggable)] = IsDraggable
|
[nameof(IsDraggable)] = IsDraggable,
|
||||||
|
[nameof(ZIndex)] = ZIndex
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -128,7 +133,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
element.ClearChangedProperties();
|
element.ClearChangedProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (positionChanged)
|
else if (positionChanged || zIndexChanged)
|
||||||
{
|
{
|
||||||
commands.Add(new RenderCommand
|
commands.Add(new RenderCommand
|
||||||
{
|
{
|
||||||
@@ -136,7 +141,10 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
ElementId = Id,
|
ElementId = Id,
|
||||||
ElementType = "WindowMove",
|
ElementType = "WindowMove",
|
||||||
Position = Position,
|
Position = Position,
|
||||||
Properties = new Dictionary<string, object?>()
|
Properties = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
[nameof(ZIndex)] = ZIndex
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +155,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
lastRenderedSize = Size;
|
lastRenderedSize = Size;
|
||||||
lastRenderedIsFocused = IsFocused;
|
lastRenderedIsFocused = IsFocused;
|
||||||
lastRenderedTitle = Title;
|
lastRenderedTitle = Title;
|
||||||
|
lastRenderedZIndex = ZIndex;
|
||||||
isFirstRender = false;
|
isFirstRender = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
using RemSox.UI.GUI.Rendering;
|
using RemSox.UI.GUI.Rendering;
|
||||||
|
|
||||||
@@ -12,6 +14,7 @@ public static class WindowManager
|
|||||||
private static readonly ConcurrentDictionary<int, List<Window>> windows = new();
|
private static readonly ConcurrentDictionary<int, List<Window>> windows = new();
|
||||||
|
|
||||||
private static int nextWindowId = 1;
|
private static int nextWindowId = 1;
|
||||||
|
private static int nextZIndex = 1;
|
||||||
|
|
||||||
private static Window? focusedWindow;
|
private static Window? focusedWindow;
|
||||||
|
|
||||||
@@ -26,7 +29,8 @@ public static class WindowManager
|
|||||||
Window window = new(title, process.Id, GetNextWindowId(), renderSource)
|
Window window = new(title, process.Id, GetNextWindowId(), renderSource)
|
||||||
{
|
{
|
||||||
Position = position,
|
Position = position,
|
||||||
Size = size
|
Size = size,
|
||||||
|
ZIndex = nextZIndex++
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!windows.ContainsKey(process.Id))
|
if (!windows.ContainsKey(process.Id))
|
||||||
@@ -69,6 +73,11 @@ public static class WindowManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window != null)
|
||||||
|
{
|
||||||
|
window.ZIndex = nextZIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
Window? previousFocusedWindow = focusedWindow;
|
Window? previousFocusedWindow = focusedWindow;
|
||||||
focusedWindow = window;
|
focusedWindow = window;
|
||||||
|
|
||||||
@@ -81,6 +90,19 @@ public static class WindowManager
|
|||||||
return focusedWindow == window;
|
return focusedWindow == window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Window? TryBeginInteract(Point pointerPosition)
|
||||||
|
{
|
||||||
|
var allWindows = windows.Values.SelectMany(w => w).OrderByDescending(w => w.ZIndex);
|
||||||
|
foreach (var window in allWindows)
|
||||||
|
{
|
||||||
|
if (window.TryBeginInteract(pointerPosition))
|
||||||
|
{
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static int GetNextWindowId()
|
private static int GetNextWindowId()
|
||||||
{
|
{
|
||||||
return nextWindowId++;
|
return nextWindowId++;
|
||||||
|
|||||||
Reference in New Issue
Block a user