From 121d30f40354f39a58c1f44561d74495fc1a52cc Mon Sep 17 00:00:00 2001 From: Leonmmcoset Date: Sat, 4 Apr 2026 14:00:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=80=E5=A4=A7=E5=8C=96=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BuildTime.txt | 2 +- GitCommit.txt | 2 +- Gui/UILib/Animations/Animation.cs | 1 + Gui/UILib/Animations/MovementAnimation.cs | 2 + Gui/UILib/AppWindow.cs | 111 ++++++++++++++++------ 5 files changed, 87 insertions(+), 31 deletions(-) diff --git a/BuildTime.txt b/BuildTime.txt index e00990f..4ee61fb 100644 --- a/BuildTime.txt +++ b/BuildTime.txt @@ -1 +1 @@ -2026-04-04 13:32:14 \ No newline at end of file +2026-04-04 13:54:37 \ No newline at end of file diff --git a/GitCommit.txt b/GitCommit.txt index dba258f..6b2193e 100644 --- a/GitCommit.txt +++ b/GitCommit.txt @@ -1 +1 @@ -636f3f1 \ No newline at end of file +2f9df41 \ No newline at end of file diff --git a/Gui/UILib/Animations/Animation.cs b/Gui/UILib/Animations/Animation.cs index afea590..346a61b 100644 --- a/Gui/UILib/Animations/Animation.cs +++ b/Gui/UILib/Animations/Animation.cs @@ -25,6 +25,7 @@ namespace CMLeonOS.UILib.Animations internal abstract class Animation { internal Action Completed { get; set; } + internal Action Advanced { get; set; } /// /// The easing type of the animation. /// diff --git a/Gui/UILib/Animations/MovementAnimation.cs b/Gui/UILib/Animations/MovementAnimation.cs index e8eac0e..7454f88 100644 --- a/Gui/UILib/Animations/MovementAnimation.cs +++ b/Gui/UILib/Animations/MovementAnimation.cs @@ -58,6 +58,7 @@ namespace CMLeonOS.UILib.Animations { control.Render(); } + Advanced?.Invoke(); } else { @@ -73,6 +74,7 @@ namespace CMLeonOS.UILib.Animations { control.Render(); } + Advanced?.Invoke(); } return Finished; } diff --git a/Gui/UILib/AppWindow.cs b/Gui/UILib/AppWindow.cs index b04b235..346ee70 100644 --- a/Gui/UILib/AppWindow.cs +++ b/Gui/UILib/AppWindow.cs @@ -150,6 +150,7 @@ namespace CMLeonOS.Gui.UILib private bool maximised = false; private bool closeAnimationRunning = false; + private bool resizeAnimationRunning = false; private int originalX; private int originalY; private int originalWidth; @@ -197,7 +198,7 @@ namespace CMLeonOS.Gui.UILib private void StartCloseAnimation() { - if (closeAnimationRunning) + if (closeAnimationRunning || resizeAnimationRunning) { return; } @@ -227,9 +228,85 @@ namespace CMLeonOS.Gui.UILib animation.Start(); } + private Rectangle GetMaximizedBounds() + { + var taskbar = ProcessManager.GetProcess(); + int taskbarHeight = taskbar.GetTaskbarHeight(); + + var dock = ProcessManager.GetProcess(); + int dockHeight = dock.GetDockHeight(); + + return new Rectangle( + 0, + taskbarHeight + titlebarHeight, + (int)wm.ScreenWidth, + (int)wm.ScreenHeight - titlebarHeight - taskbarHeight - dockHeight + ); + } + + private void StartResizeAnimation(Rectangle targetBounds) + { + if (resizeAnimationRunning) + { + return; + } + + resizeAnimationRunning = true; + + Rectangle startWindow = new Rectangle(X, Y, Width, Height); + Rectangle startDecoration = new Rectangle(decorationWindow.X, decorationWindow.Y, decorationWindow.Width, decorationWindow.Height); + Rectangle targetDecoration = new Rectangle(0, -titlebarHeight, targetBounds.Width, titlebarHeight); + + int completedCount = 0; + Action finish = () => + { + completedCount++; + if (completedCount < 2) + { + return; + } + + MoveAndResize(targetBounds.X, targetBounds.Y, targetBounds.Width, targetBounds.Height, sendWMEvent: false); + decorationWindow.MoveAndResize(targetDecoration.X, targetDecoration.Y, targetDecoration.Width, targetDecoration.Height, sendWMEvent: false); + + resizeAnimationRunning = false; + UserResized?.Invoke(); + RefreshWindowTree(); + ProcessManager.GetProcess().RerenderAll(); + }; + + MovementAnimation windowAnimation = new MovementAnimation(this) + { + From = startWindow, + To = targetBounds, + Duration = 14, + EasingType = EasingType.Sine, + EasingDirection = EasingDirection.Out, + Completed = finish + }; + windowAnimation.Advanced = () => + { + UserResized?.Invoke(); + RefreshWindowTree(); + }; + + MovementAnimation decorationAnimation = new MovementAnimation(decorationWindow) + { + From = startDecoration, + To = targetDecoration, + Duration = 14, + EasingType = EasingType.Sine, + EasingDirection = EasingDirection.Out, + Completed = finish + }; + + windowAnimation.Start(); + decorationAnimation.Start(); + } + private void DecorationClicked(int x, int y) { - if (closeAnimationRunning) + if (closeAnimationRunning || resizeAnimationRunning) { return; } @@ -245,41 +322,17 @@ namespace CMLeonOS.Gui.UILib if (maximised) { maximised = false; - - MoveAndResize(originalX, originalY, originalWidth, originalHeight, sendWMEvent: false); - - decorationWindow.Resize(originalWidth, titlebarHeight, sendWMEvent: false); - - UserResized?.Invoke(); - ProcessManager.GetProcess().RerenderAll(); + StartResizeAnimation(new Rectangle(originalX, originalY, originalWidth, originalHeight)); } else { maximised = true; - var taskbar = ProcessManager.GetProcess(); - int taskbarHeight = taskbar.GetTaskbarHeight(); - - var dock = ProcessManager.GetProcess(); - int dockHeight = dock.GetDockHeight(); - originalX = X; originalY = Y; originalWidth = Width; originalHeight = Height; - - MoveAndResize( - 0, - taskbarHeight + titlebarHeight, - (int)wm.ScreenWidth, - (int)wm.ScreenHeight - titlebarHeight - taskbarHeight - dockHeight, - sendWMEvent: false - ); - - decorationWindow.Resize((int)wm.ScreenWidth, titlebarHeight, sendWMEvent: false); - - UserResized?.Invoke(); - ProcessManager.GetProcess().RerenderAll(); + StartResizeAnimation(GetMaximizedBounds()); } RenderDecoration(); } @@ -297,7 +350,7 @@ namespace CMLeonOS.Gui.UILib buttonSpace += titlebarHeight; } if (x >= Width - buttonSpace || maximised || !_canMove) return; - if (closeAnimationRunning) return; + if (closeAnimationRunning || resizeAnimationRunning) return; uint startMouseX = MouseManager.X; uint startMouseY = MouseManager.Y;