diff --git a/Terminal.Gui/View/Adornment/Adornment.cs b/Terminal.Gui/View/Adornment/Adornment.cs index 3b407d575d..8c09e634ce 100644 --- a/Terminal.Gui/View/Adornment/Adornment.cs +++ b/Terminal.Gui/View/Adornment/Adornment.cs @@ -184,17 +184,17 @@ protected override bool OnClearingViewport () /// Does nothing for Adornment /// - protected override bool OnRenderingLineCanvas () { return true; } - - /// - /// Adornments only render to their 's or Parent's SuperView's LineCanvas, so setting this - /// property throws an . - /// - public override bool SuperViewRendersLineCanvas - { - get => false; - set => throw new InvalidOperationException (@"Adornment can only render to their Parent or Parent's Superview."); - } + protected override bool OnRenderingLineCanvas () { return false; } + + ///// + ///// Adornments only render to their 's or Parent's SuperView's LineCanvas, so setting this + ///// property throws an . + ///// + //public override bool SuperViewRendersLineCanvas + //{ + // get => false; + // set => throw new InvalidOperationException (@"Adornment can only render to their Parent or Parent's Superview."); + //} /// protected override void OnDrawComplete () { } diff --git a/Terminal.Gui/View/Adornment/Border.cs b/Terminal.Gui/View/Adornment/Border.cs index 26fed69f8c..c7bc412c7f 100644 --- a/Terminal.Gui/View/Adornment/Border.cs +++ b/Terminal.Gui/View/Adornment/Border.cs @@ -111,64 +111,126 @@ internal void AdvanceDrawIndicator () } } -#if SUBVIEW_BASED_BORDER - private Line _left; + public Line TopLeft { get; internal set; } + public Line TopRight { get; internal set; } + public Line Left { get; internal set; } + public Line Right { get; internal set; } + public Line Bottom { get; internal set; } + public View TitleLabel { get; internal set; } /// /// The close button for the border. Set to , to to enable. /// public Button CloseButton { get; internal set; } -#endif /// public override void BeginInit () { base.BeginInit (); + //SuperViewRendersLineCanvas = true; + + if (Thickness == Thickness.Empty) + { + return; + } ShowHideDrawIndicator (); -#if SUBVIEW_BASED_BORDER - if (Parent is { }) + + TopLeft = new () { - // Left - _left = new () - { - Orientation = Orientation.Vertical, - }; - Add (_left); + Id = "TopLeft", + Orientation = Orientation.Horizontal, + }; + Add (TopLeft); - CloseButton = new Button () - { - Text = "X", - CanFocus = true, - Visible = false, - }; - CloseButton.Accept += (s, e) => - { - e.Cancel = Parent.InvokeCommand (Command.QuitToplevel) == true; - }; - Add (CloseButton); + TopRight = new () + { + Id = "TopRight", + Orientation = Orientation.Horizontal, + }; + Add (TopRight); - LayoutStarted += OnLayoutStarted; - } -#endif - } + Left = new () + { + Id = "Left", + Orientation = Orientation.Vertical, + }; + Add (Left); -#if SUBVIEW_BASED_BORDER - private void OnLayoutStarted (object sender, LayoutEventArgs e) - { - _left.Border.LineStyle = LineStyle; + Right = new () + { + Id = "Right", + Orientation = Orientation.Vertical, + }; - _left.X = Thickness.Left - 1; - _left.Y = Thickness.Top - 1; - _left.Width = 1; - _left.Height = Height; + Add (Right); - CloseButton.X = Pos.AnchorEnd (Thickness.Right / 2 + 1) - - (Pos.Right (CloseButton) - - Pos.Left (CloseButton)); - CloseButton.Y = 0; -} -#endif + Bottom = new () + { + Id = "Bottom", + Orientation = Orientation.Horizontal, + }; + Add (Bottom); + + TitleLabel = new View () + { + Id = "TitleLabel", + Text = Parent.Title, + CanFocus = false, + TextAlignment = Alignment.Center, + VerticalTextAlignment = Alignment.Center, + }; + Add (TitleLabel); + + SetSubviewLayout (); + } + + private void SetSubviewLayout () + { + TopLeft.X = Pos.Func (() => Thickness.Left / 2); + TopLeft.Y = Pos.Func (() => Thickness.Top / 2); + TopLeft.Width = 2; + TopLeft.Height = 1; + TopLeft.Visible = Thickness.Top > 0; + + TopRight.X = Pos.Right (TitleLabel); + TopRight.Y = Pos.Func (() => Thickness.Top / 2); + TopRight.Width = Dim.Fill () - Dim.Func (() => Thickness.Right / 2); + TopRight.Height = 1; + TopRight.Visible = Thickness.Top > 0; + + Left.X = Pos.Func (() => Thickness.Left / 2); + Left.Y = Pos.Top (TopRight); + Left.Height = Dim.Fill () - Dim.Func (() => Thickness.Bottom / 2); + Left.Width = 1; + Left.Visible = Thickness.Left > 0; + + Right.X = Pos.Right (TopRight) - 1; + Right.Y = Pos.Top (TopRight); + Right.Height = Dim.Fill () - Dim.Func (() => Thickness.Bottom / 2); + Right.Width = 1; + Right.Visible = Thickness.Right > 0; + + Bottom.X = Pos.Func (() => Thickness.Left / 2); + Bottom.Y = Pos.Bottom (Left) - 1; + Bottom.Width = Dim.Fill () - Dim.Func (() => Thickness.Right / 2); + Bottom.Height = 1; + Bottom.Visible = Thickness.Bottom > 0; + + TitleLabel.X = Pos.Right (TopLeft); + TitleLabel.Y = Pos.Func (() => Thickness.Top / 2 - TitleLabel.Frame.Height / 2); + TitleLabel.Height = _settings.FastHasFlags (BorderSettings.Title) ? Thickness.Top : 0; + TitleLabel.Width = Dim.Func (() => _settings.FastHasFlags (BorderSettings.Title) ? TitleLabel.TextFormatter.FormatAndGetSize ().Width + TitleLabel.GetAdornmentsThickness ().Horizontal : 0); + //TitleLabel.Border.Thickness = new (1, 0, 1, 0); + //TitleLabel.Border.LineStyle = LineStyle.Dotted; + //TitleLabel.SuperViewRendersLineCanvas = true; + + //CloseButton.X = Pos.Left (Right) - 1; + //CloseButton.Y = Pos.Func (() => Thickness.Top / 2); + //CloseButton.Width = 1; + //CloseButton.Height = 1; + //CloseButton.Visible = false; + } /// /// The color scheme for the Border. If set to , gets the @@ -640,6 +702,13 @@ private void Application_UnGrabbingMouse (object? sender, GrabMouseEventArgs e) #endregion Mouse Support + /// + protected override bool OnDrawingSubviews () + { + return base.OnDrawingSubviews (); + + } + /// protected override bool OnDrawingContent () { @@ -648,6 +717,8 @@ protected override bool OnDrawingContent () return true; } + return true; + Rectangle screenBounds = ViewportToScreen (Viewport); // TODO: v2 - this will eventually be two controls: "BorderView" and "Label" (for the title) @@ -727,7 +798,7 @@ protected override bool OnDrawingContent () , Parent.HasFocus ? focus : GetNormalColor (), Parent.HasFocus ? focus : GetHotNormalColor ()); - Parent?.LineCanvas.Exclude(new(titleRect)); + Parent?.LineCanvas.Exclude (new (titleRect)); } if (canDrawBorder && LineStyle != LineStyle.None) diff --git a/Terminal.Gui/View/View.Drawing.cs b/Terminal.Gui/View/View.Drawing.cs index adea35c36a..dbf37c0a88 100644 --- a/Terminal.Gui/View/View.Drawing.cs +++ b/Terminal.Gui/View/View.Drawing.cs @@ -137,7 +137,7 @@ private void DoDrawBorderAndPaddingSubViews () if (Border?.Subviews is { } && Border.Thickness != Thickness.Empty) { // PERFORMANCE: Get the check for DrawIndicator out of this somehow. - foreach (View subview in Border.Subviews.Where (v => v.Visible || v.Id == "DrawIndicator")) + foreach (View subview in Border.Subviews.Where (v => (v.Visible || v.Id == "DrawIndicator") && v.SuperViewRendersLineCanvas == false)) { if (subview.Id != "DrawIndicator") { @@ -585,12 +585,12 @@ private void DoRenderLineCanvas () /// public void RenderLineCanvas () { - if (Driver is null) + if (Driver is null || LineCanvas.Bounds == Rectangle.Empty) { return; } - if (!SuperViewRendersLineCanvas && LineCanvas.Bounds != Rectangle.Empty) + if (!SuperViewRendersLineCanvas) { foreach (KeyValuePair p in LineCanvas.GetCellMap ()) { @@ -607,6 +607,11 @@ public void RenderLineCanvas () LineCanvas.Clear (); } + else + { + //SuperView?.LineCanvas.Merge (LineCanvas); + //LineCanvas.Clear (); + } } #endregion DrawLineCanvas diff --git a/Terminal.Gui/Views/Line.cs b/Terminal.Gui/Views/Line.cs index 9d28893733..a5a925c4e3 100644 --- a/Terminal.Gui/Views/Line.cs +++ b/Terminal.Gui/Views/Line.cs @@ -18,9 +18,27 @@ public Line () _orientationHelper = new (this); _orientationHelper.Orientation = Orientation.Horizontal; - OnOrientationChanged(Orientation); + OnOrientationChanged (Orientation); } + private LineStyle? _lineStyle; + + /// + /// Gets or sets the style of the Line. The default is the of the SuperView. + /// + public LineStyle LineStyle + { + get + { + if (_lineStyle.HasValue) + { + return _lineStyle.Value; + } + + return SuperView?.BorderStyle ?? LineStyle.Single; + } + set => _lineStyle = value; + } #region IOrientation members /// @@ -61,18 +79,24 @@ public void OnOrientationChanged (Orientation newOrientation) } #endregion + /// + protected override bool OnClearingViewport () { return true; } + /// protected override bool OnDrawingContent () { Point pos = ViewportToScreen (Viewport).Location; int length = Orientation == Orientation.Horizontal ? Frame.Width : Frame.Height; + if (length == 0) + { + return true; + } LineCanvas?.AddLine ( pos, length, Orientation, - BorderStyle - ); + LineStyle); //SuperView?.SetNeedsDraw (); return true; diff --git a/UICatalog/Scenarios/Generic.cs b/UICatalog/Scenarios/Generic.cs index dc9131623a..d1e75cdff0 100644 --- a/UICatalog/Scenarios/Generic.cs +++ b/UICatalog/Scenarios/Generic.cs @@ -16,12 +16,20 @@ public override void Main () Window appWindow = new () { Title = GetQuitKeyAndName (), + //BorderStyle = LineStyle.None }; - var button = new Button { Id = "button", X = Pos.Center (), Y = 1, Text = "_Press me!" }; + //var button = new Button { Id = "button", X = Pos.Center (), Y = 1, Text = "_Press me!" }; - button.Accepting += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed the button!", "_Ok"); - appWindow.Add (button); + //button.Accepting += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed the button!", "_Ok"); + //appWindow.Add (button); + + //Line line = new () + //{ + // LineStyle = LineStyle.Double, + // Width = 10, + //}; + //appWindow.Add (line); // Run - Start the application. Application.Run (appWindow);