mirror of
https://github.com/Leonmmcoset/CMLeonOS.git
synced 2026-04-21 10:53:59 +00:00
OSGD面渲染+窗口逻辑增强
This commit is contained in:
@@ -1 +1 @@
|
|||||||
2026-04-04 12:15:03
|
2026-04-04 13:32:14
|
||||||
@@ -1 +1 @@
|
|||||||
836f199
|
636f3f1
|
||||||
@@ -40,6 +40,14 @@ namespace CMLeonOS.Gui.Apps.Demos
|
|||||||
Renderer3D.DrawLine3D(window, a, b, color, FovScale, CameraDistance);
|
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)
|
private void DrawGear(Vec3 center, double outerRadius, double innerRadius, double depth, int teeth, double angle, Color color)
|
||||||
{
|
{
|
||||||
int ringCount = teeth * 2;
|
int ringCount = teeth * 2;
|
||||||
@@ -70,6 +78,35 @@ namespace CMLeonOS.Gui.Apps.Demos
|
|||||||
{
|
{
|
||||||
int n = (i + 1) % ringCount;
|
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(frontOuter[i], frontOuter[n], color);
|
||||||
Draw3DLine(backOuter[i], backOuter[n], color);
|
Draw3DLine(backOuter[i], backOuter[n], color);
|
||||||
Draw3DLine(frontOuter[i], backOuter[i], color);
|
Draw3DLine(frontOuter[i], backOuter[i], color);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace CMLeonOS.Gui.ShellComponents.Dock
|
|||||||
|
|
||||||
internal override void Clicked()
|
internal override void Clicked()
|
||||||
{
|
{
|
||||||
ProcessManager.GetProcess<WindowManager>().Focus = AppWindow;
|
ProcessManager.GetProcess<WindowManager>().BringToFrontAndFocus(AppWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ namespace CMLeonOS.Gui.ShellComponents.Dock
|
|||||||
|
|
||||||
internal static readonly int IconSize = 64;
|
internal static readonly int IconSize = 64;
|
||||||
internal static readonly int IconImageMaxSize = 48;
|
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()
|
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.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;
|
int x = 0;
|
||||||
foreach (var icon in Icons)
|
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)
|
if (icon.Image != null)
|
||||||
{
|
{
|
||||||
Bitmap resizedImage = icon.Image.ResizeWidthKeepRatio((uint)Math.Min(IconImageMaxSize, icon.Size));
|
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)));
|
window.DrawImageAlpha(resizedImage, imageX, (int)((window.Height / 2) - (resizedImage.Height / 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
x += (int)icon.Size;
|
x += iconWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
wm.Update(window);
|
wm.Update(window);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using Cosmos.System;
|
|||||||
using Cosmos.System.Graphics;
|
using Cosmos.System.Graphics;
|
||||||
using CMLeonOS;
|
using CMLeonOS;
|
||||||
using CMLeonOS.Gui.ShellComponents;
|
using CMLeonOS.Gui.ShellComponents;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
using CMLeonOS.Settings;
|
using CMLeonOS.Settings;
|
||||||
using CMLeonOS.Driver;
|
using CMLeonOS.Driver;
|
||||||
using CMLeonOS.Logger;
|
using CMLeonOS.Logger;
|
||||||
@@ -193,6 +194,95 @@ namespace CMLeonOS.Gui
|
|||||||
UpdateDock();
|
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)
|
internal void RemoveWindow(Window window, bool rerender = true)
|
||||||
{
|
{
|
||||||
Windows.Remove(window);
|
Windows.Remove(window);
|
||||||
@@ -292,13 +382,12 @@ namespace CMLeonOS.Gui
|
|||||||
else if (MouseManager.MouseState == MouseState.None && lastMouseState == MouseState.Left)
|
else if (MouseManager.MouseState == MouseState.None && lastMouseState == MouseState.Left)
|
||||||
{
|
{
|
||||||
lastMouseState = MouseManager.MouseState;
|
lastMouseState = MouseManager.MouseState;
|
||||||
|
Window focusTarget = GetOwningAppWindow(window) ?? window;
|
||||||
if (Focus != null && Focus != window)
|
BringToFrontAndFocus(focusTarget);
|
||||||
|
if (window != focusTarget && Windows.Contains(window))
|
||||||
{
|
{
|
||||||
Focus.OnUnfocused?.Invoke();
|
SetFocus(window);
|
||||||
}
|
}
|
||||||
Focus = window;
|
|
||||||
window.OnFocused?.Invoke();
|
|
||||||
|
|
||||||
window.OnClick?.Invoke(relativeX, relativeY);
|
window.OnClick?.Invoke(relativeX, relativeY);
|
||||||
|
|
||||||
|
|||||||
@@ -34,5 +34,58 @@ namespace CMLeonOS.OSGraphicDraw
|
|||||||
|
|
||||||
target.DrawLine(ax, ay, bx, by, color);
|
target.DrawLine(ax, ay, bx, by, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void DrawScanline(Window target, int x1, int x2, int y, Color color)
|
||||||
|
{
|
||||||
|
if (y < 0 || y >= target.Height) return;
|
||||||
|
if (x1 > x2)
|
||||||
|
{
|
||||||
|
int t = x1;
|
||||||
|
x1 = x2;
|
||||||
|
x2 = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x2 < 0 || x1 >= target.Width) return;
|
||||||
|
if (x1 < 0) x1 = 0;
|
||||||
|
if (x2 >= target.Width) x2 = target.Width - 1;
|
||||||
|
target.DrawHorizontalLine((x2 - x1) + 1, x1, y, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawTriangle2D(Window target, int x1, int y1, int x2, int y2, int x3, int y3, Color color)
|
||||||
|
{
|
||||||
|
if (y1 > y2) { int tx = x1; int ty = y1; x1 = x2; y1 = y2; x2 = tx; y2 = ty; }
|
||||||
|
if (y1 > y3) { int tx = x1; int ty = y1; x1 = x3; y1 = y3; x3 = tx; y3 = ty; }
|
||||||
|
if (y2 > y3) { int tx = x2; int ty = y2; x2 = x3; y2 = y3; x3 = tx; y3 = ty; }
|
||||||
|
|
||||||
|
if (y1 == y3) return;
|
||||||
|
|
||||||
|
for (int y = y1; y <= y3; y++)
|
||||||
|
{
|
||||||
|
bool lowerHalf = y > y2 || y2 == y1;
|
||||||
|
int segmentHeight = lowerHalf ? (y3 - y2) : (y2 - y1);
|
||||||
|
if (segmentHeight == 0) continue;
|
||||||
|
|
||||||
|
double alpha = (double)(y - y1) / (y3 - y1);
|
||||||
|
double beta = lowerHalf
|
||||||
|
? (double)(y - y2) / segmentHeight
|
||||||
|
: (double)(y - y1) / segmentHeight;
|
||||||
|
|
||||||
|
int ax = x1 + (int)((x3 - x1) * alpha);
|
||||||
|
int bx = lowerHalf
|
||||||
|
? x2 + (int)((x3 - x2) * beta)
|
||||||
|
: x1 + (int)((x2 - x1) * beta);
|
||||||
|
|
||||||
|
DrawScanline(target, ax, bx, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void DrawTriangle3D(Window target, Vec3 a, Vec3 b, Vec3 c, Color color, double fovScale, double cameraDistance)
|
||||||
|
{
|
||||||
|
if (!Project(a, target.Width, target.Height, fovScale, cameraDistance, out int ax, out int ay)) return;
|
||||||
|
if (!Project(b, target.Width, target.Height, fovScale, cameraDistance, out int bx, out int by)) return;
|
||||||
|
if (!Project(c, target.Width, target.Height, fovScale, cameraDistance, out int cx, out int cy)) return;
|
||||||
|
|
||||||
|
DrawTriangle2D(target, ax, ay, bx, by, cx, cy, color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user