OSGD面渲染+窗口逻辑增强

This commit is contained in:
2026-04-04 13:38:51 +08:00
parent 636f3f146d
commit 2f9df41666
7 changed files with 203 additions and 10 deletions

View File

@@ -40,6 +40,14 @@ namespace CMLeonOS.Gui.Apps.Demos
Renderer3D.DrawLine3D(window, a, b, color, FovScale, CameraDistance);
}
private void Draw3DTriangle(Vec3 a, Vec3 b, Vec3 c, Color color)
{
a = TransformPoint(a);
b = TransformPoint(b);
c = TransformPoint(c);
Renderer3D.DrawTriangle3D(window, a, b, c, color, FovScale, CameraDistance);
}
private void DrawGear(Vec3 center, double outerRadius, double innerRadius, double depth, int teeth, double angle, Color color)
{
int ringCount = teeth * 2;
@@ -70,6 +78,35 @@ namespace CMLeonOS.Gui.Apps.Demos
{
int n = (i + 1) % ringCount;
Color frontFace = Color.FromArgb(
color.R,
color.G,
color.B);
Color backFace = Color.FromArgb(
Math.Max(0, color.R - 32),
Math.Max(0, color.G - 32),
Math.Max(0, color.B - 32));
Color sideFace = Color.FromArgb(
Math.Max(0, color.R - 18),
Math.Max(0, color.G - 18),
Math.Max(0, color.B - 18));
// Front ring face (quad -> 2 triangles)
Draw3DTriangle(frontOuter[i], frontOuter[n], frontInner[n], frontFace);
Draw3DTriangle(frontOuter[i], frontInner[n], frontInner[i], frontFace);
// Back ring face
Draw3DTriangle(backOuter[i], backInner[n], backOuter[n], backFace);
Draw3DTriangle(backOuter[i], backInner[i], backInner[n], backFace);
// Outer wall
Draw3DTriangle(frontOuter[i], backOuter[n], frontOuter[n], sideFace);
Draw3DTriangle(frontOuter[i], backOuter[i], backOuter[n], sideFace);
// Inner wall
Draw3DTriangle(frontInner[i], frontInner[n], backInner[n], sideFace);
Draw3DTriangle(frontInner[i], backInner[n], backInner[i], sideFace);
Draw3DLine(frontOuter[i], frontOuter[n], color);
Draw3DLine(backOuter[i], backOuter[n], color);
Draw3DLine(frontOuter[i], backOuter[i], color);

View File

@@ -32,7 +32,7 @@ namespace CMLeonOS.Gui.ShellComponents.Dock
internal override void Clicked()
{
ProcessManager.GetProcess<WindowManager>().Focus = AppWindow;
ProcessManager.GetProcess<WindowManager>().BringToFrontAndFocus(AppWindow);
}
}
}

View File

@@ -49,6 +49,9 @@ namespace CMLeonOS.Gui.ShellComponents.Dock
internal static readonly int IconSize = 64;
internal static readonly int IconImageMaxSize = 48;
private static readonly Color DockBackground = Color.FromArgb(211, 211, 211);
private static readonly Color ActiveIconBackground = Color.FromArgb(160, 190, 255);
private static readonly Color ActiveIndicator = Color.FromArgb(36, 88, 196);
private void Render()
{
@@ -63,11 +66,22 @@ namespace CMLeonOS.Gui.ShellComponents.Dock
window.MoveAndResize((int)(wm.ScreenWidth / 2 - newDockWidth / 2), window.Y, newDockWidth, window.Height);
}
window.Clear(Color.FromArgb(211, 211, 211));
window.Clear(DockBackground);
AppWindow focusedApp = wm.GetOwningAppWindow(wm.Focus);
int x = 0;
foreach (var icon in Icons)
{
int iconWidth = (int)icon.Size;
bool isSelected = icon is AppDockIcon appDockIcon && appDockIcon.AppWindow == focusedApp;
if (isSelected && iconWidth > 4 && window.Height > 4)
{
window.DrawFilledRectangle(x + 2, 2, iconWidth - 4, window.Height - 4, ActiveIconBackground);
window.DrawFilledRectangle(x + 10, window.Height - 5, Math.Max(8, iconWidth - 20), 3, ActiveIndicator);
}
if (icon.Image != null)
{
Bitmap resizedImage = icon.Image.ResizeWidthKeepRatio((uint)Math.Min(IconImageMaxSize, icon.Size));
@@ -76,7 +90,7 @@ namespace CMLeonOS.Gui.ShellComponents.Dock
window.DrawImageAlpha(resizedImage, imageX, (int)((window.Height / 2) - (resizedImage.Height / 2)));
}
x += (int)icon.Size;
x += iconWidth;
}
wm.Update(window);

View File

@@ -18,6 +18,7 @@ using Cosmos.System;
using Cosmos.System.Graphics;
using CMLeonOS;
using CMLeonOS.Gui.ShellComponents;
using CMLeonOS.Gui.UILib;
using CMLeonOS.Settings;
using CMLeonOS.Driver;
using CMLeonOS.Logger;
@@ -193,6 +194,95 @@ namespace CMLeonOS.Gui
UpdateDock();
}
private bool IsDescendantOf(Window window, Window ancestor)
{
Window current = window;
while (current != null)
{
if (current == ancestor)
{
return true;
}
current = current.RelativeTo;
}
return false;
}
internal AppWindow GetOwningAppWindow(Window window)
{
Window current = window;
while (current != null)
{
if (current is AppWindow appWindow)
{
return appWindow;
}
current = current.RelativeTo;
}
return null;
}
internal void SetFocus(Window window, bool updateDock = true)
{
if (window == null || !Windows.Contains(window))
{
return;
}
if (Focus != null && Focus != window)
{
Focus.OnUnfocused?.Invoke();
}
Focus = window;
window.OnFocused?.Invoke();
if (updateDock)
{
UpdateDock();
}
}
internal void BringToFrontAndFocus(Window window)
{
if (window == null || !Windows.Contains(window))
{
return;
}
List<Window> toMove = new List<Window>();
for (int i = 0; i < Windows.Count; i++)
{
Window current = Windows[i];
if (current == window || IsDescendantOf(current, window))
{
toMove.Add(current);
}
}
if (toMove.Count > 0)
{
for (int i = 0; i < toMove.Count; i++)
{
Windows.Remove(toMove[i]);
}
for (int i = 0; i < toMove.Count; i++)
{
Windows.Add(toMove[i]);
}
}
SetFocus(window, updateDock: false);
RerenderAll();
UpdateDock();
}
internal void RemoveWindow(Window window, bool rerender = true)
{
Windows.Remove(window);
@@ -292,13 +382,12 @@ namespace CMLeonOS.Gui
else if (MouseManager.MouseState == MouseState.None && lastMouseState == MouseState.Left)
{
lastMouseState = MouseManager.MouseState;
if (Focus != null && Focus != window)
Window focusTarget = GetOwningAppWindow(window) ?? window;
BringToFrontAndFocus(focusTarget);
if (window != focusTarget && Windows.Contains(window))
{
Focus.OnUnfocused?.Invoke();
SetFocus(window);
}
Focus = window;
window.OnFocused?.Invoke();
window.OnClick?.Invoke(relativeX, relativeY);