Implement z-index for windows and ensure correct stacking order on interaction

This commit is contained in:
Stone_Red
2026-06-08 13:31:27 +02:00
parent 3be75c60f2
commit 4561e1f997
4 changed files with 50 additions and 29 deletions
+1 -21
View File
@@ -91,7 +91,7 @@ public class Kernel : Sys.Kernel
if (leftButtonDown && !wasLeftButtonDown)
{
activeInteractWindow = TryBeginInteract(pointerPosition);
activeInteractWindow = WindowManager.TryBeginInteract(pointerPosition);
}
else if (leftButtonDown && activeInteractWindow is not null)
{
@@ -111,26 +111,6 @@ public class Kernel : Sys.Kernel
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")
+14 -4
View File
@@ -1,6 +1,7 @@
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using Cosmos.Kernel.System.Graphics;
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, Point> windowPositions = new();
private static readonly Dictionary<int, int> windowZIndices = new();
public void Render(IEnumerable<RenderCommand> 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")
{
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);
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;
Point position = kvp.Value;
if (windowCanvases.TryGetValue(windowId, out Canvas? windowCanvas))
if (windowPositions.TryGetValue(windowId, out Point position) && windowCanvases.TryGetValue(windowId, out Canvas? windowCanvas))
{
screenCanvas.DrawCanvas(windowCanvas, position.X, position.Y);
}
+12 -3
View File
@@ -14,6 +14,8 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
public string Title { get; set; } = title;
public int ZIndex { get; set; }
public bool AutoFlush { get; set; } = false;
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 bool lastRenderedIsFocused = false;
private string lastRenderedTitle = string.Empty;
private int lastRenderedZIndex = -1;
private bool isFirstRender = true;
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 anyChildChanged = uiElements.Values.Any(e => e.AnyPropertyChanged);
bool positionChanged = Position != lastRenderedPosition;
bool zIndexChanged = ZIndex != lastRenderedZIndex;
bool fullRedraw = windowStateChanged || anyChildChanged;
@@ -111,7 +115,8 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
[nameof(Size)] = Size,
[nameof(IsFocused)] = IsFocused,
[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();
}
}
else if (positionChanged)
else if (positionChanged || zIndexChanged)
{
commands.Add(new RenderCommand
{
@@ -136,7 +141,10 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
ElementId = Id,
ElementType = "WindowMove",
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;
lastRenderedIsFocused = IsFocused;
lastRenderedTitle = Title;
lastRenderedZIndex = ZIndex;
isFirstRender = false;
}
}
+23 -1
View File
@@ -1,6 +1,8 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using RemSox.Processing;
using RemSox.UI.GUI.Rendering;
@@ -12,6 +14,7 @@ public static class WindowManager
private static readonly ConcurrentDictionary<int, List<Window>> windows = new();
private static int nextWindowId = 1;
private static int nextZIndex = 1;
private static Window? focusedWindow;
@@ -26,7 +29,8 @@ public static class WindowManager
Window window = new(title, process.Id, GetNextWindowId(), renderSource)
{
Position = position,
Size = size
Size = size,
ZIndex = nextZIndex++
};
if (!windows.ContainsKey(process.Id))
@@ -69,6 +73,11 @@ public static class WindowManager
return;
}
if (window != null)
{
window.ZIndex = nextZIndex++;
}
Window? previousFocusedWindow = focusedWindow;
focusedWindow = window;
@@ -81,6 +90,19 @@ public static class WindowManager
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()
{
return nextWindowId++;