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;