diff --git a/src/Modern.Forms/ControlPaint.cs b/src/Modern.Forms/ControlPaint.cs index fdc08c9..3d077be 100644 --- a/src/Modern.Forms/ControlPaint.cs +++ b/src/Modern.Forms/ControlPaint.cs @@ -106,6 +106,41 @@ public static void DrawMaximizeGlyph (PaintEventArgs e, Rectangle rectangle) e.Canvas.DrawRectangle (rectangle, Theme.ForegroundColorOnAccent); } + /// + /// Draws a restore glyph, as seen on FormTitleBar when the window is maximized. + /// + public static void DrawRestoreGlyph (PaintEventArgs e, Rectangle rectangle) + { + var color = Theme.ForegroundColorOnAccent; + var offset = e.LogicalToDeviceUnits (2); + + var back = new Rectangle ( + rectangle.X + offset, + rectangle.Y, + rectangle.Width - offset - 1, + rectangle.Height - offset - 1); + + var front = new Rectangle ( + rectangle.X, + rectangle.Y + offset, + rectangle.Width - offset, + rectangle.Height - offset); + + // Draw "front" "window" + e.Canvas.DrawRectangle (front, color); + + // Draw "back" "window" + using var path = new SKPath (); + + path.MoveTo (back.Left, front.Top); + path.LineTo (back.Left, back.Top); + path.LineTo (back.Right, back.Top); + path.LineTo (back.Right, back.Bottom); + path.LineTo (front.Right, back.Bottom); + + e.Canvas.DrawPath (path, color); + } + /// /// Draws a minimize glyph, as seen on FormTitleBar. /// @@ -114,7 +149,6 @@ public static void DrawMinimizeGlyph (PaintEventArgs e, Rectangle rectangle) e.Canvas.DrawLine (rectangle.X, rectangle.Y, rectangle.Right, rectangle.Y, Theme.ForegroundColorOnAccent); } - /// /// Draws a RadioButton glyph. /// diff --git a/src/Modern.Forms/Extensions/SkiaExtensions.cs b/src/Modern.Forms/Extensions/SkiaExtensions.cs index f01ca02..7bdb2fd 100644 --- a/src/Modern.Forms/Extensions/SkiaExtensions.cs +++ b/src/Modern.Forms/Extensions/SkiaExtensions.cs @@ -144,6 +144,16 @@ public static void DrawLine (this SKCanvas canvas, float x1, float y1, float x2, canvas.DrawLine (x1, y1, x2, y2, paint); } + /// + /// Draws a path. + /// + public static void DrawPath (this SKCanvas canvas, SKPath path, SKColor color, int thickness = 1) + { + using var paint = new SKPaint { Color = color, StrokeWidth = thickness, IsStroke = true }; + + canvas.DrawPath (path, paint); + } + /// /// Draws an unfilled rectangle. /// diff --git a/src/Modern.Forms/FormTitleBar.cs b/src/Modern.Forms/FormTitleBar.cs index 118a315..0c06c47 100644 --- a/src/Modern.Forms/FormTitleBar.cs +++ b/src/Modern.Forms/FormTitleBar.cs @@ -30,7 +30,7 @@ public FormTitleBar () minimize_button.Click += (o, e) => { var form_min = FindForm (); - if (form_min != null) + if (form_min is not null) form_min.WindowState = FormWindowState.Minimized; }; @@ -38,8 +38,13 @@ public FormTitleBar () maximize_button.Click += (o, e) => { var form = FindForm (); - if (form != null) - form.WindowState = form.WindowState == FormWindowState.Maximized ? FormWindowState.Normal : FormWindowState.Maximized; + if (form is not null) { + form.WindowState = form.WindowState == FormWindowState.Maximized + ? FormWindowState.Normal + : FormWindowState.Maximized; + + UpdateMaximizeButtonGlyph (); + } }; close_button = Controls.AddImplicitControl (new TitleBarButton (TitleBarButton.TitleBarButtonGlyph.Close)); @@ -64,6 +69,7 @@ public bool AllowMaximize { get => maximize_button.Visible; set { maximize_button.Visible = value; + UpdateMaximizeButtonGlyph (); Invalidate (); // TODO: Shouldn't be necessary, should automatically be triggered } } @@ -126,6 +132,8 @@ protected override void OnSizeChanged (EventArgs e) // Keep our form image a square form_image.Width = Height; + + UpdateMaximizeButtonGlyph (); } /// @@ -136,7 +144,7 @@ public bool ShowImage { set { if (show_image != value) { show_image = value; - form_image.Visible = value && form_image is not null; + form_image.Visible = value && form_image.Image is not null; Invalidate (); // TODO: Shouldn't be required } } @@ -145,11 +153,38 @@ public bool ShowImage { /// public override ControlStyle Style { get; } = new ControlStyle (DefaultStyle); + private void UpdateMaximizeButtonGlyph () + { + var form = FindForm (); + + if (form == null || !maximize_button.Visible) { + maximize_button.Glyph = TitleBarButton.TitleBarButtonGlyph.Maximize; + return; + } + + maximize_button.Glyph = form.WindowState == FormWindowState.Maximized + ? TitleBarButton.TitleBarButtonGlyph.Restore + : TitleBarButton.TitleBarButtonGlyph.Maximize; + } + internal sealed class TitleBarButton : Button { private const int BUTTON_PADDING = 10; - private readonly TitleBarButtonGlyph glyph; + private TitleBarButtonGlyph glyph; + + /// + /// Gets or sets the glyph displayed by the button. + /// + public TitleBarButtonGlyph Glyph { + get => glyph; + set { + if (glyph != value) { + glyph = value; + Invalidate (); + } + } + } public TitleBarButton (TitleBarButtonGlyph glyph) { @@ -183,14 +218,21 @@ protected override void OnPaint (PaintEventArgs e) case TitleBarButtonGlyph.Maximize: ControlPaint.DrawMaximizeGlyph (e, glyph_bounds); break; + case TitleBarButtonGlyph.Restore: + ControlPaint.DrawRestoreGlyph (e, glyph_bounds); + break; } } + /// + /// Specifies which glyph is displayed by the title bar button. + /// public enum TitleBarButtonGlyph { Close, Minimize, - Maximize + Maximize, + Restore } } }