diff --git a/Terminal.Gui/View/Adornment/Margin.cs b/Terminal.Gui/View/Adornment/Margin.cs index a7273a74c..f76f0e8b8 100644 --- a/Terminal.Gui/View/Adornment/Margin.cs +++ b/Terminal.Gui/View/Adornment/Margin.cs @@ -1,7 +1,5 @@ #nullable enable -using System.Drawing; - namespace Terminal.Gui; /// The Margin for a . @@ -28,93 +26,43 @@ public class Margin : Adornment CanFocus = false; } - private void Margin_LayoutStarted (object? sender, LayoutEventArgs e) - { - // Adjust the shadow such that it is drawn aligned with the Border - if (ShadowStyle != Gui.ShadowStyle.None && _rightShadow is { } && _bottomShadow is { }) - { - _rightShadow.Y = Parent.Border.Thickness.Top > 0 ? Parent.Border.Thickness.Top - (Parent.Border.Thickness.Top > 2 && Parent.Border.ShowTitle ? 1 : 0) : 1; - _bottomShadow.X = Parent.Border.Thickness.Left > 0 ? Parent.Border.Thickness.Left : 1; - } - } - private bool _pressed; - private void Margin_Highlight (object? sender, CancelEventArgs e) + + private ShadowView? _bottomShadow; + private ShadowView? _rightShadow; + + /// + public override void BeginInit () { - if (ShadowStyle != Gui.ShadowStyle.None) + base.BeginInit (); + + if (Parent is null) { - if (_pressed && e.NewValue == HighlightStyle.None) - { - Thickness = new (Thickness.Left - 1, Thickness.Top, Thickness.Right + 1, Thickness.Bottom); - - if (_rightShadow is { }) - { - _rightShadow.Visible = true; - } - - if (_bottomShadow is { }) - { - _bottomShadow.Visible = true; - } - - _pressed = false; - return; - } - - if (!_pressed && (e.NewValue.HasFlag (HighlightStyle.Pressed) /*|| e.HighlightStyle.HasFlag (HighlightStyle.PressedOutside)*/)) - { - Thickness = new (Thickness.Left + 1, Thickness.Top, Thickness.Right - 1, Thickness.Bottom); - _pressed = true; - if (_rightShadow is { }) - { - _rightShadow.Visible = false; - } - - if (_bottomShadow is { }) - { - _bottomShadow.Visible = false; - } - } + return; } - } + ShadowStyle = base.ShadowStyle; - /// - public override void OnDrawContent (Rectangle viewport) - { - Rectangle screen = ViewportToScreen (viewport); - Attribute normalAttr = GetNormalColor (); - - Driver?.SetAttribute (normalAttr); - - - // This just draws/clears the thickness, not the insides. - if (ShadowStyle != ShadowStyle.None) - { - screen = Rectangle.Inflate (screen, -1, -1); - } - Thickness.Draw (screen, ToString ()); - - if (Subviews.Count > 0) - { - // Draw subviews - // TODO: Implement OnDrawSubviews (cancelable); - if (Subviews is { } && SubViewNeedsDisplay) - { - IEnumerable subviewsNeedingDraw = Subviews.Where ( - view => view.Visible - && (view.NeedsDisplay || view.SubViewNeedsDisplay || view.LayoutNeeded) - ); - foreach (View view in subviewsNeedingDraw) - { - if (view.LayoutNeeded) - { - view.LayoutSubviews (); - } - view.Draw (); - } - } - } + Add ( + _rightShadow = new() + { + X = Pos.AnchorEnd (1), + Y = 0, + Width = 1, + Height = Dim.Fill (), + ShadowStyle = ShadowStyle, + Orientation = Orientation.Vertical + }, + _bottomShadow = new() + { + X = 0, + Y = Pos.AnchorEnd (1), + Width = Dim.Fill (), + Height = 1, + ShadowStyle = ShadowStyle, + Orientation = Orientation.Horizontal + } + ); } /// @@ -139,18 +87,48 @@ public class Margin : Adornment } } - /// - public override ShadowStyle ShadowStyle + /// + public override void OnDrawContent (Rectangle viewport) { - get => base.ShadowStyle; - set + Rectangle screen = ViewportToScreen (viewport); + Attribute normalAttr = GetNormalColor (); + + Driver?.SetAttribute (normalAttr); + + // This just draws/clears the thickness, not the insides. + if (ShadowStyle != ShadowStyle.None) { - base.ShadowStyle = SetShadow (value); + screen = Rectangle.Inflate (screen, -1, -1); + } + + Thickness.Draw (screen, ToString ()); + + if (Subviews.Count > 0) + { + // Draw subviews + // TODO: Implement OnDrawSubviews (cancelable); + if (Subviews is { } && SubViewNeedsDisplay) + { + IEnumerable subviewsNeedingDraw = Subviews.Where ( + view => view.Visible + && (view.NeedsDisplay || view.SubViewNeedsDisplay || view.LayoutNeeded) + ); + + foreach (View view in subviewsNeedingDraw) + { + if (view.LayoutNeeded) + { + view.LayoutSubviews (); + } + + view.Draw (); + } + } } } /// - /// Sets whether the Margin includes a shadow effect. The shadow is drawn on the right and bottom sides of the + /// Sets whether the Margin includes a shadow effect. The shadow is drawn on the right and bottom sides of the /// Margin. /// public ShadowStyle SetShadow (ShadowStyle style) @@ -181,42 +159,73 @@ public class Margin : Adornment { _bottomShadow.ShadowStyle = style; } + return style; } - private ShadowView? _bottomShadow; - private ShadowView? _rightShadow; - /// - public override void BeginInit () + public override ShadowStyle ShadowStyle { - base.BeginInit (); - - if (Parent is null) - { - return; - } - - ShadowStyle = base.ShadowStyle; - Add ( - _rightShadow = new ShadowView - { - X = Pos.AnchorEnd (1), - Y = 0, - Width = 1, - Height = Dim.Fill (), - ShadowStyle = ShadowStyle, - Orientation = Orientation.Vertical - }, - _bottomShadow = new ShadowView - { - X = 0, - Y = Pos.AnchorEnd (1), - Width = Dim.Fill (), - Height = 1, - ShadowStyle = ShadowStyle, - Orientation = Orientation.Horizontal - } - ); + get => base.ShadowStyle; + set => base.ShadowStyle = SetShadow (value); } -} \ No newline at end of file + + private void Margin_Highlight (object? sender, CancelEventArgs e) + { + if (ShadowStyle != ShadowStyle.None) + { + if (_pressed && e.NewValue == HighlightStyle.None) + { + // If the view is pressed and the highlight is being removed, move the shadow back. + // Note, for visual effects reasons, we only move horizontally. + // TODO: Add a setting or flag that lets the shadow move vertically as well. + Thickness = new (Thickness.Left - 1, Thickness.Top, Thickness.Right + 1, Thickness.Bottom); + + if (_rightShadow is { }) + { + _rightShadow.Visible = true; + } + + if (_bottomShadow is { }) + { + _bottomShadow.Visible = true; + } + + _pressed = false; + + return; + } + + if (!_pressed && e.NewValue.HasFlag (HighlightStyle.Pressed)) + { + // If the view is not pressed and we want highlight move the shadow + // Note, for visual effects reasons, we only move horizontally. + // TODO: Add a setting or flag that lets the shadow move vertically as well. + Thickness = new (Thickness.Left + 1, Thickness.Top, Thickness.Right - 1, Thickness.Bottom); + _pressed = true; + + if (_rightShadow is { }) + { + _rightShadow.Visible = false; + } + + if (_bottomShadow is { }) + { + _bottomShadow.Visible = false; + } + } + } + } + + private void Margin_LayoutStarted (object? sender, LayoutEventArgs e) + { + // Adjust the shadow such that it is drawn aligned with the Border + if (ShadowStyle != ShadowStyle.None && _rightShadow is { } && _bottomShadow is { }) + { + _rightShadow.Y = Parent.Border.Thickness.Top > 0 + ? Parent.Border.Thickness.Top - (Parent.Border.Thickness.Top > 2 && Parent.Border.ShowTitle ? 1 : 0) + : 1; + _bottomShadow.X = Parent.Border.Thickness.Left > 0 ? Parent.Border.Thickness.Left : 1; + } + } +}