diff --git a/Terminal.Gui/Core/PosDim.cs b/Terminal.Gui/Core/PosDim.cs index 1169fa049..696607696 100644 --- a/Terminal.Gui/Core/PosDim.cs +++ b/Terminal.Gui/Core/PosDim.cs @@ -52,7 +52,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Pos.PosFunc({function ()})"; + return $"PosFunc({function ()})"; } public override int GetHashCode () => function.GetHashCode (); @@ -85,7 +85,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Pos.Factor({factor})"; + return $"Factor({factor})"; } public override int GetHashCode () => factor.GetHashCode (); @@ -135,7 +135,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Pos.AnchorEnd(margin={n})"; + return $"AnchorEnd({n})"; } } @@ -174,7 +174,7 @@ namespace Terminal.Gui { public override string ToString () { - return "Pos.Center"; + return "Center"; } } @@ -209,7 +209,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Pos.Absolute({n})"; + return $"Absolute({n})"; } internal override int Anchor (int width) @@ -244,7 +244,7 @@ namespace Terminal.Gui { internal class PosCombine : Pos { internal Pos left, right; - bool add; + internal bool add; public PosCombine (bool add, Pos left, Pos right) { this.left = left; @@ -264,7 +264,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Pos.Combine({left.ToString ()}{(add ? '+' : '-')}{right.ToString ()})"; + return $"Combine({left}{(add ? '+' : '-')}{right})"; } } @@ -345,7 +345,7 @@ namespace Terminal.Gui { case 3: tside = "bottom"; break; default: tside = "unknown"; break; } - return $"Pos.View(side={tside}, target={Target.ToString ()})"; + return $"View({tside},{Target.ToString()})"; } public override int GetHashCode () => Target.GetHashCode (); @@ -442,7 +442,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Dim.DimFunc({function ()})"; + return $"DimFunc({function ()})"; } public override int GetHashCode () => function.GetHashCode (); @@ -482,7 +482,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Dim.Factor(factor={factor}, remaining={remaining})"; + return $"Factor({factor},{remaining})"; } public override int GetHashCode () => factor.GetHashCode (); @@ -522,7 +522,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Dim.Absolute({n})"; + return $"Absolute({n})"; } internal override int Anchor (int width) @@ -541,7 +541,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Dim.Fill(margin={margin})"; + return $"Fill({margin})"; } internal override int Anchor (int width) @@ -613,7 +613,7 @@ namespace Terminal.Gui { public override string ToString () { - return $"Dim.Combine({left.ToString ()}{(add ? '+' : '-')}{right.ToString ()})"; + return $"Combine({left}{(add ? '+' : '-')}{right})"; } } @@ -691,7 +691,7 @@ namespace Terminal.Gui { case 1: tside = "Width"; break; default: tside = "unknown"; break; } - return $"DimView(side={tside}, target={Target.ToString ()})"; + return $"DimView({tside},{Target.ToString ()})"; } public override int GetHashCode () => Target.GetHashCode (); diff --git a/Terminal.Gui/Core/Toplevel.cs b/Terminal.Gui/Core/Toplevel.cs index 881b97426..02691b84f 100644 --- a/Terminal.Gui/Core/Toplevel.cs +++ b/Terminal.Gui/Core/Toplevel.cs @@ -908,6 +908,12 @@ namespace Terminal.Gui { { if (!IsMdiContainer) { base.PositionCursor (); + if (Focused == null) { + EnsureFocus (); + if (Focused == null) { + Driver.SetCursorVisibility (CursorVisibility.Invisible); + } + } return; } @@ -920,6 +926,9 @@ namespace Terminal.Gui { } } base.PositionCursor (); + if (Focused == null) { + Driver.SetCursorVisibility (CursorVisibility.Invisible); + } } /// diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index fb396cc32..ada0a7ca0 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; using System.Linq; using System.Reflection; using NStack; @@ -403,7 +402,7 @@ namespace Terminal.Gui { } } - internal Rect NeedDisplay { get; set; } = Rect.Empty; + internal Rect NeedDisplay { get; private set; } = Rect.Empty; // The frame for the object. Superview relative. Rect frame; @@ -455,62 +454,15 @@ namespace Terminal.Gui { } } - public Frame Margin { get; set; } - public Frame BorderFrame { get; set; } - public Frame Padding { get; set; } - - /// - /// Temporary API to support the new v2 API - /// - public void EnableFrames () - { - IgnoreBorderPropertyOnRedraw = true; - Margin?.Dispose (); - Margin = new Frame () { - X = 0, - Y = 0, - Thickness = new Thickness (0), - ColorScheme = SuperView?.ColorScheme ?? ColorScheme, - // TODO: Create View.AddAdornment - Parent = this - }; - //Margin.DiagnosticsLabel.Text = "Margin"; - - BorderFrame?.Dispose (); - BorderFrame = new Frame () { - X = 0, - Y = 0, - BorderStyle = BorderStyle.Single, - Thickness = new Thickness (0), - ColorScheme = ColorScheme, - // TODO: Create View.AddAdornment - Parent = this - }; - - Padding?.Dispose (); - Padding = new Frame () { - X = 0, - Y = 0, - Thickness = new Thickness (0), - ColorScheme = ColorScheme, - // TODO: Create View.AddAdornment - Parent = this - }; - } - - ustring title; - - /// - /// The title to be displayed for this . - /// - /// The title. - public ustring Title { - get => title; - set { - title = value; - SetNeedsDisplay (); - } - } + ///// + ///// Gets an enumerator that enumerates the subviews in this view. + ///// + ///// The enumerator. + //public IEnumerator GetEnumerator () + //{ + // foreach (var v in InternalSubviews) + // yield return v; + //} LayoutStyle layoutStyle; @@ -547,17 +499,8 @@ namespace Terminal.Gui { /// /// public Rect Bounds { - get { - if (Padding == null || BorderFrame == null || Margin == null) { - return new Rect (Point.Empty, Frame.Size); - } - var superviewRelativeBounds = Padding.Thickness.GetInnerRect (BorderFrame.Thickness.GetInnerRect (Margin.Thickness.GetInnerRect (Frame))); - return new Rect (Point.Empty, superviewRelativeBounds.Size); - } - set { - Debug.WriteLine ($"It makes no sense to set Bounds. Use Frame instead. Bounds: {value}"); - Frame = new Rect (Frame.Location, value.Size); - } + get => new Rect (Point.Empty, Frame.Size); + set => Frame = new Rect (frame.Location, value.Size); } Pos x, y; @@ -711,10 +654,7 @@ namespace Terminal.Gui { public bool SetMinWidthHeight () { if (GetMinWidthHeight (out Size size)) { - // BUGBUG: Bounds ignores `value` on `set` so what this line of code actually does is - // `Frame = new Rect (frame.Location, value.Size);` - // ...But... `Bounds.get` simply returns `Frame` with a 0,0 for Location! - Frame = new Rect (Frame.Location, size); + Bounds = new Rect (Bounds.Location, size); TextFormatter.Size = GetBoundsTextFormatterSize (); return true; } @@ -730,14 +670,7 @@ namespace Terminal.Gui { /// Returns the container for this view, or null if this view has not been added to a container. /// /// The super view. - public virtual View SuperView { - get { - return container; - } - set { - throw new NotImplementedException (); - } - } + public View SuperView => container; /// /// Initializes a new instance of a class with the absolute @@ -840,6 +773,9 @@ namespace Terminal.Gui { TextFormatter.HotKeyChanged += TextFormatter_HotKeyChanged; TextDirection = direction; Border = border; + if (Border != null) { + Border.Child = this; + } shortcutHelper = new ShortcutHelper (); CanFocus = false; TabIndex = -1; @@ -970,9 +906,7 @@ namespace Terminal.Gui { } } - // BUGBUG: v2 - this is poorly named. First, is this reallly just about Children or - // both subviews and children? And why "Display"? It should be "Redraw". - internal bool ChildNeedsDisplay { get; set; } + internal bool ChildNeedsDisplay { get; private set; } /// /// Indicates that any child views (in the list) need to be repainted. @@ -984,7 +918,6 @@ namespace Terminal.Gui { container.SetChildNeedsDisplay (); } - // BUGBUG: v2 - this feels like a hack internal bool addingView; /// @@ -1018,6 +951,10 @@ namespace Terminal.Gui { view.tabIndex = tabIndexes.IndexOf (view); addingView = false; } + if (view.Enabled && !Enabled) { + view.oldEnabled = true; + view.Enabled = false; + } SetNeedsLayout (); SetNeedsDisplay (); OnAdded (view); @@ -1162,7 +1099,6 @@ namespace Terminal.Gui { }); } - // TODO: v2 - remove duplicate code here /// /// Clears the view region with the current color. /// @@ -1173,8 +1109,15 @@ namespace Terminal.Gui { /// public void Clear () { - var h = Frame.Height; - var w = Frame.Width; + Rect containerBounds = GetContainerBounds (); + Rect viewBounds = Bounds; + if (!containerBounds.IsEmpty) { + viewBounds.Width = Math.Min (viewBounds.Width, containerBounds.Width); + viewBounds.Height = Math.Min (viewBounds.Height, containerBounds.Height); + } + + var h = viewBounds.Height; + var w = viewBounds.Width; for (var line = 0; line < h; line++) { Move (0, line); for (var col = 0; col < w; col++) @@ -1207,16 +1150,16 @@ namespace Terminal.Gui { /// Absolute column; screen-relative. /// Absolute row; screen-relative. /// Whether to clip the result of the ViewToScreen method, if set to , the rcol, rrow values are clamped to the screen (terminal) dimensions (0..TerminalDim-1). - public virtual void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clipped = true) + public void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clipped = true) { // Computes the real row, col relative to the screen. - rrow = row + Frame.Y; - rcol = col + Frame.X; + rrow = row + frame.Y; + rcol = col + frame.X; var curContainer = container; while (curContainer != null) { - rrow += curContainer.Frame.Y; - rcol += curContainer.Frame.X; + rrow += curContainer.frame.Y; + rcol += curContainer.frame.X; curContainer = curContainer.container; } @@ -1246,7 +1189,7 @@ namespace Terminal.Gui { /// /// Converts a region in view-relative coordinates to screen-relative coordinates. /// - public virtual Rect ViewToScreen (Rect region) + internal Rect ViewToScreen (Rect region) { ViewToScreen (region.X, region.Y, out var x, out var y, clipped: false); return new Rect (x, y, region.Width, region.Height); @@ -1295,7 +1238,6 @@ namespace Terminal.Gui { /// If set to it fill will the contents. public void DrawFrame (Rect region, int padding = 0, bool fill = false) { - // TODO: Refactor to use Frames var scrRect = ViewToScreen (region); var savedClip = ClipToBounds (); Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: fill); @@ -1372,14 +1314,16 @@ namespace Terminal.Gui { return; } - if (focused?.Visible == true && focused?.Enabled == true && focused?.Frame.Width > 0 && focused.Frame.Height > 0) { + if (focused == null && SuperView != null) { + SuperView.EnsureFocus (); + } else if (focused?.Visible == true && focused?.Enabled == true && focused?.Frame.Width > 0 && focused.Frame.Height > 0) { focused.PositionCursor (); + } else if (focused?.Visible == true && focused?.Enabled == false) { + focused = null; + } else if (CanFocus && HasFocus && Visible && Frame.Width > 0 && Frame.Height > 0) { + Move (TextFormatter.HotKeyPos == -1 ? 0 : TextFormatter.CursorPosition, 0); } else { - if (CanFocus && HasFocus && Visible && Frame.Width > 0 && Frame.Height > 0) { - Move (TextFormatter.HotKeyPos == -1 ? 0 : TextFormatter.CursorPosition, 0); - } else { - Move (frame.X, frame.Y); - } + Move (frame.X, frame.Y); } } @@ -1547,25 +1491,123 @@ namespace Terminal.Gui { ChildNeedsDisplay = false; } - public virtual bool OnDrawFrames () + /// + /// Redraws this view and its subviews; only redraws the views that have been flagged for a re-display. + /// + /// The bounds (view-relative region) to redraw. + /// + /// + /// Always use (view-relative) when calling , NOT (superview-relative). + /// + /// + /// Views should set the color that they want to use on entry, as otherwise this will inherit + /// the last color that was set globally on the driver. + /// + /// + /// Overrides of must ensure they do not set Driver.Clip to a clip region + /// larger than the parameter, as this will cause the driver to clip the entire region. + /// + /// + public virtual void Redraw (Rect bounds) { - // TODO: add cancellable event - //if (!DrawFrames?.Invoke (frame)) { - // return false; - //} - - if (Margin == null || BorderFrame == null || Padding == null) { - return false; + if (!CanBeVisible (this)) { + return; } - - Margin.Redraw (Margin.Frame); - BorderFrame.Title = Title; - BorderFrame.Redraw (BorderFrame.Frame); - Padding.Redraw (Padding.Frame); - return true; + var clipRect = new Rect (Point.Empty, frame.Size); + + if (ColorScheme != null) { + Driver.SetAttribute (HasFocus ? GetFocusColor () : GetNormalColor ()); + } + + var boundsAdjustedForBorder = Bounds; + if (!IgnoreBorderPropertyOnRedraw && Border != null) { + throw new InvalidOperationException("Don't use border!"); + } else if (ustring.IsNullOrEmpty (TextFormatter.Text) && + (GetType ().IsNestedPublic && !IsOverridden (this, "Redraw") || GetType ().Name == "View") && + (!NeedDisplay.IsEmpty || ChildNeedsDisplay || LayoutNeeded)) { + + Clear (); + SetChildNeedsDisplay (); + } + + if (!ustring.IsNullOrEmpty (TextFormatter.Text)) { + Rect containerBounds = GetContainerBounds (); + Clear (ViewToScreen (GetNeedDisplay (containerBounds))); + SetChildNeedsDisplay (); + // Draw any Text + if (TextFormatter != null) { + TextFormatter.NeedsFormat = true; + } + TextFormatter?.Draw (ViewToScreen (boundsAdjustedForBorder), HasFocus ? ColorScheme.Focus : GetNormalColor (), + HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled, + containerBounds); + } + + // Invoke DrawContentEvent + OnDrawContent (boundsAdjustedForBorder); + + if (subviews != null) { + foreach (var view in subviews) { + if (!view.NeedDisplay.IsEmpty || view.ChildNeedsDisplay || view.LayoutNeeded) { + if (view.Frame.IntersectsWith (clipRect) && (view.Frame.IntersectsWith (boundsAdjustedForBorder) || boundsAdjustedForBorder.X < 0 || bounds.Y < 0)) { + if (view.LayoutNeeded) { + view.LayoutSubviews (); + } + + // Draw the subview + // Use the view's bounds (view-relative; Location will always be (0,0) + if (view.Visible && view.Frame.Width > 0 && view.Frame.Height > 0) { + var rect = view.Bounds; + view.OnDrawContent (rect); + view.Redraw (rect); + view.OnDrawContentComplete (rect); + } + } + view.NeedDisplay = Rect.Empty; + view.ChildNeedsDisplay = false; + } + } + } + + // Invoke DrawContentCompleteEvent + OnDrawContentComplete (boundsAdjustedForBorder); + + ClearLayoutNeeded (); + ClearNeedsDisplay (); } + Rect GetNeedDisplay (Rect containerBounds) + { + Rect rect = NeedDisplay; + if (!containerBounds.IsEmpty) { + rect.Width = Math.Min (NeedDisplay.Width, containerBounds.Width); + rect.Height = Math.Min (NeedDisplay.Height, containerBounds.Height); + } + + return rect; + } + + Rect GetContainerBounds () + { + var containerBounds = SuperView == null ? default : SuperView.ViewToScreen (SuperView.Bounds); + var driverClip = Driver == null ? Rect.Empty : Driver.Clip; + containerBounds.X = Math.Max (containerBounds.X, driverClip.X); + containerBounds.Y = Math.Max (containerBounds.Y, driverClip.Y); + var lenOffset = (driverClip.X + driverClip.Width) - (containerBounds.X + containerBounds.Width); + if (containerBounds.X + containerBounds.Width > driverClip.X + driverClip.Width) { + containerBounds.Width = Math.Max (containerBounds.Width + lenOffset, 0); + } else { + containerBounds.Width = Math.Min (containerBounds.Width, driverClip.Width); + } + lenOffset = (driverClip.Y + driverClip.Height) - (containerBounds.Y + containerBounds.Height); + if (containerBounds.Y + containerBounds.Height > driverClip.Y + driverClip.Height) { + containerBounds.Height = Math.Max (containerBounds.Height + lenOffset, 0); + } else { + containerBounds.Height = Math.Min (containerBounds.Height, driverClip.Height); + } + return containerBounds; + } /// /// Event invoked when the content area of the View is to be drawn. @@ -1583,30 +1625,13 @@ namespace Terminal.Gui { /// /// Enables overrides to draw infinitely scrolled content and/or a background behind added controls. /// - /// The view-relative rectangle describing the currently visible viewport into the + /// The view-relative rectangle describing the currently visible viewport into the /// /// This method will be called before any subviews added with have been drawn. /// - public virtual void OnDrawContent (Rect contentArea) + public virtual void OnDrawContent (Rect viewport) { - // TODO: Make DrawContent a cancelable event - DrawContent?.Invoke (contentArea); - - // if (!DrawContent?.Invoke(viewport)) { - if (!ustring.IsNullOrEmpty (TextFormatter.Text)) { - //Rect containerBounds = GetContainerBounds (); - //Clear (ViewToScreen (GetNeedDisplay (containerBounds))); - SetChildNeedsDisplay (); - // Draw any Text - if (TextFormatter != null) { - TextFormatter.NeedsFormat = true; - } - TextFormatter?.Draw (ViewToScreen(Bounds), HasFocus ? ColorScheme.Focus : GetNormalColor (), - HasFocus ? ColorScheme.HotFocus : Enabled ? ColorScheme.HotNormal : ColorScheme.Disabled, - contentArea, false); - } - // } - + DrawContent?.Invoke (viewport); } /// @@ -1634,113 +1659,6 @@ namespace Terminal.Gui { DrawContentComplete?.Invoke (viewport); } - /// - /// Redraws this view and its subviews; only redraws the views that have been flagged for a re-display. - /// - /// The bounds (view-relative region) to redraw. - /// - /// - /// Always use (view-relative) when calling , NOT (superview-relative). - /// - /// - /// Views should set the color that they want to use on entry, as otherwise this will inherit - /// the last color that was set globally on the driver. - /// - /// - /// Overrides of must ensure they do not set Driver.Clip to a clip region - /// larger than the parameter, as this will cause the driver to clip the entire region. - /// - /// - public virtual void Redraw (Rect bounds) - { - if (!CanBeVisible (this)) { - return; - } - - OnDrawFrames (); - - // TODO: Implement complete event - // OnDrawFramesComplete (Frame) - - if (ColorScheme != null) { - Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal); - } - - var prevClip = Driver.Clip; - Driver.Clip = ViewToScreen(Bounds); - - // TODO: Remove once new v2 api is complete - if (!IgnoreBorderPropertyOnRedraw && Border != null) { - throw new InvalidOperationException ("Don't use Border!"); - } - - // Draw content - OnDrawContent (Bounds); - - // Draw subviews - // TODO: Implement OnDrawSubviews (cancelable); - if (subviews != null) { - foreach (var view in subviews) { - if (!view.NeedDisplay.IsEmpty || view.ChildNeedsDisplay || view.LayoutNeeded) { - if (view.Frame.IntersectsWith (Driver.Clip) && (view.Frame.IntersectsWith (Bounds) || Bounds.X < 0 || Bounds.Y < 0)) { - if (view.LayoutNeeded) { - view.LayoutSubviews (); - } - - // Draw the subview - if (view.Visible && view.Frame.Width > 0 && view.Frame.Height > 0) { - var rect = view.Bounds; - view.OnDrawContent (rect); - view.Redraw (rect); - view.OnDrawContentComplete (rect); - } - } - view.NeedDisplay = Rect.Empty; - view.ChildNeedsDisplay = false; - } - } - } - - // Invoke DrawContentCompleteEvent - OnDrawContentComplete (Bounds); - - Driver.Clip = prevClip; - ClearLayoutNeeded (); - ClearNeedsDisplay (); - } - - Rect GetNeedDisplay (Rect containerBounds) - { - Rect rect = NeedDisplay; - if (!containerBounds.IsEmpty) { - rect.Width = Math.Min (NeedDisplay.Width, containerBounds.Width); - rect.Height = Math.Min (NeedDisplay.Height, containerBounds.Height); - } - - return rect; - } - - internal Rect GetContainerBounds () - { - var containerBounds = SuperView == null ? default : SuperView.ViewToScreen (SuperView.Bounds); - var driverClip = Driver == null ? Rect.Empty : Driver.Clip; - containerBounds.X = Math.Max (containerBounds.X, driverClip.X); - containerBounds.Y = Math.Max (containerBounds.Y, driverClip.Y); - var lenOffset = (driverClip.X + driverClip.Width) - (containerBounds.X + containerBounds.Width); - if (containerBounds.X + containerBounds.Width > driverClip.X + driverClip.Width) { - containerBounds.Width = Math.Max (containerBounds.Width + lenOffset, 0); - } else { - containerBounds.Width = Math.Min (containerBounds.Width, driverClip.Width); - } - lenOffset = (driverClip.Y + driverClip.Height) - (containerBounds.Y + containerBounds.Height); - if (containerBounds.Y + containerBounds.Height > driverClip.Y + driverClip.Height) { - containerBounds.Height = Math.Max (containerBounds.Height + lenOffset, 0); - } else { - containerBounds.Height = Math.Min (containerBounds.Height, driverClip.Height); - } - return containerBounds; - } - /// /// Causes the specified subview to have focus. /// @@ -2265,129 +2183,113 @@ namespace Terminal.Gui { } /// - /// Sets the View's location (setting Location to the relative coordinates - /// of the SuperView. + /// Sets the View's to the frame-relative coordinates if its container. The + /// container size and location are specified by and are relative to the + /// View's superview. /// - /// The superview-relative bounds for . - /// - /// is screen-relative; is view-relative. - ///// In v1, always has a location of {0, 0}. In v2, can be non-zero, - ///// refelcting the Margin, Border, and Padding. - /// - internal void SetRelativeLayout (Rect superviewRelativeBounds) + /// The supserview-relative rectangle describing View's container (nominally the + /// same as this.SuperView.Frame). + internal void SetRelativeLayout (Rect superviewFrame) { - int actW, actH, actX, actY; + int newX, newW, newY, newH; var autosize = Size.Empty; if (AutoSize) { + // Note this is global to this function and used as such within the local functions defined + // below. In v2 AutoSize will be re-factored to not need to be dealt with in this function. autosize = GetAutoSize (); } - bool superviewHasFrame = SuperView?.Margin != null || SuperView?.BorderFrame != null || SuperView?.Padding != null; - var contentArea = superviewRelativeBounds; - if (superviewHasFrame) { - contentArea = SuperView.Padding.Thickness.GetInnerRect (SuperView.BorderFrame.Thickness.GetInnerRect (SuperView.Margin.Thickness.GetInnerRect (superviewRelativeBounds))); - } - - actX = x?.Anchor (superviewRelativeBounds.Width) ?? 0; - actW = Math.Max (CalculateActualWidth (width, superviewRelativeBounds, actX, autosize), 0); - - switch (x) { - case Pos.PosCenter: - if (width == null) { - actW = !autosize.IsEmpty ? autosize.Width : superviewRelativeBounds.Width; - } else { - actW = width.Anchor (superviewRelativeBounds.Width); - actW = !autosize.IsEmpty && autosize.Width > actW ? autosize.Width : actW; - } - actX = x.Anchor (superviewRelativeBounds.Width - actW); - if (superviewHasFrame) { - actX += contentArea.X; - } - break; - - case Pos.PosAbsolute: - - if (superviewHasFrame) { - actX += contentArea.X; - } - break; - - case Pos.PosAnchorEnd: - - if (superviewHasFrame) { - actX += contentArea.X; - } - break; - - case Pos.PosCombine: - - if (superviewHasFrame) { - var pc = x as Pos.PosCombine; - switch (pc.left) { - case Pos.PosAbsolute: - actX += contentArea.X; - break; - - case Pos.PosAnchorEnd: - actX -= contentArea.X; - break; - - case Pos.PosCenter: - actX = x.Anchor (superviewRelativeBounds.Width - actW); - actX += contentArea.X; - break; - - case Pos.PosFactor: - actX += contentArea.X; - break; + // Returns the new dimension (width or height) and location (x or y) for the View given + // the superview's Frame.X or Frame.Y + // the superview's width or height + // the current Pos (View.X or View.Y) + // the current Dim (View.Width or View.Height) + (int newLocation, int newDimension) GetNewLocationAndDimension (int superviewLocation, int superviewDimension, Pos pos, Dim dim, int autosizeDimension) + { + int newDimension, newLocation; + switch (pos) { + case Pos.PosCenter: + if (dim == null) { + newDimension = AutoSize ? autosizeDimension : superviewDimension; + } else { + newDimension = dim.Anchor (superviewDimension); + newDimension = AutoSize && autosizeDimension > newDimension ? autosizeDimension : newDimension; } + newLocation = pos.Anchor (superviewDimension - newDimension); + break; + + case Pos.PosCombine: + var combine = pos as Pos.PosCombine; + int left, right; + (left, newDimension) = GetNewLocationAndDimension (superviewLocation, superviewDimension, combine.left, dim, autosizeDimension); + (right, newDimension) = GetNewLocationAndDimension (superviewLocation, superviewDimension, combine.right, dim, autosizeDimension); + if (combine.add) { + newLocation = left + right; + } else { + newLocation = left - right; + } + newDimension = Math.Max (CalculateNewDimension (dim, newLocation, superviewDimension, autosizeDimension), 0); + break; + + case Pos.PosAbsolute: + case Pos.PosAnchorEnd: + case Pos.PosFactor: + case Pos.PosFunc: + case Pos.PosView: + default: + newLocation = pos?.Anchor (superviewDimension) ?? 0; + newDimension = Math.Max (CalculateNewDimension (dim, newLocation, superviewDimension, autosizeDimension), 0); + break; } - break; + return (newLocation, newDimension); + } - case Pos.PosFactor: - - if (superviewHasFrame) { - actX += contentArea.X;// - SuperView.Frame.X; + // Recursively calculates the new dimension (width or height) of the given Dim given: + // the current location (x or y) + // the current dimennsion (width or height) + int CalculateNewDimension (Dim d, int location, int dimension, int autosize) + { + int newDimension; + switch (d) { + case null: + newDimension = AutoSize ? autosize : dimension; + break; + case Dim.DimCombine combine: + int leftNewDim = CalculateNewDimension (combine.left, location, dimension, autosize); + int rightNewDim = CalculateNewDimension (combine.right, location, dimension, autosize); + if (combine.add) { + newDimension = leftNewDim + rightNewDim; + } else { + newDimension = leftNewDim - rightNewDim; + } + newDimension = AutoSize && autosize > newDimension ? autosize : newDimension; + break; + + case Dim.DimFactor factor when !factor.IsFromRemaining (): + newDimension = d.Anchor (dimension); + newDimension = AutoSize && autosize > newDimension ? autosize : newDimension; + break; + + case Dim.DimFill: + default: + newDimension = Math.Max (d.Anchor (dimension - location), 0); + newDimension = AutoSize && autosize > newDimension ? autosize : newDimension; + break; } - break; - default: - if (x != null) { - throw new InvalidOperationException (x.ToString ()); - } - break; - ; - } - - if (y is Pos.PosCenter) { - if (height == null) { - actH = !autosize.IsEmpty ? autosize.Height : contentArea.Height; - } else { - actH = height.Anchor (superviewRelativeBounds.Height); - actH = !autosize.IsEmpty && autosize.Height > actH ? autosize.Height : actH; - } - actY = y.Anchor (superviewRelativeBounds.Height - actH); - } else { - actY = y?.Anchor (superviewRelativeBounds.Height) ?? 0; - actH = Math.Max (CalculateActualHight (height, superviewRelativeBounds, actY, autosize), 0); + return newDimension; } + // horiztonal + (newX, newW) = GetNewLocationAndDimension (superviewFrame.X, superviewFrame.Width, x, Width, autosize.Width); - if ((y is Pos.PosAbsolute || y is Pos.PosCenter) && (superviewHasFrame)) { - actY += contentArea.Y; - } - if ((y is Pos.PosAnchorEnd) && (superviewHasFrame)) { - actY -= contentArea.Y;// - SuperView.Frame.Y; - } - if ((y is Pos.PosFactor) && (superviewHasFrame)) { - actY += contentArea.Y;// - SuperView.Frame.Y; - } - - var r = new Rect (actX, actY, actW, actH); + // vertical + (newY, newH) = GetNewLocationAndDimension (superviewFrame.Y, superviewFrame.Height, y, Height, autosize.Height); + var r = new Rect (newX, newY, newW, newH); if (Frame != r) { Frame = r; if (!SetMinWidthHeight ()) { @@ -2396,113 +2298,6 @@ namespace Terminal.Gui { } } - private int CalculateActualWidth (Dim width, Rect hostFrame, int actX, Size s) - { - int actW; - switch (width) { - case null: - actW = AutoSize ? s.Width : hostFrame.Width; - break; - case Dim.DimCombine combine: - int leftActW = CalculateActualWidth (combine.left, hostFrame, actX, s); - int rightActW = CalculateActualWidth (combine.right, hostFrame, actX, s); - if (combine.add) { - actW = leftActW + rightActW; - } else { - actW = leftActW - rightActW; - } - actW = AutoSize && s.Width > actW ? s.Width : actW; - break; - case Dim.DimFactor factor when !factor.IsFromRemaining (): - actW = width.Anchor (hostFrame.Width); - actW = AutoSize && s.Width > actW ? s.Width : actW; - break; - default: - actW = Math.Max (width.Anchor (hostFrame.Width - actX), 0); - actW = AutoSize && s.Width > actW ? s.Width : actW; - break; - } - - return actW; - } - - private int CalculateActualHight (Dim height, Rect hostFrame, int actY, Size s) - { - int actH; - switch (height) { - case null: - actH = AutoSize ? s.Height : hostFrame.Height; - break; - case Dim.DimCombine combine: - int leftActH = CalculateActualHight (combine.left, hostFrame, actY, s); - int rightActH = CalculateActualHight (combine.right, hostFrame, actY, s); - if (combine.add) { - actH = leftActH + rightActH; - } else { - actH = leftActH - rightActH; - } - actH = AutoSize && s.Height > actH ? s.Height : actH; - break; - case Dim.DimFactor factor when !factor.IsFromRemaining (): - actH = height.Anchor (hostFrame.Height); - actH = AutoSize && s.Height > actH ? s.Height : actH; - break; - default: - actH = Math.Max (height.Anchor (hostFrame.Height - actY), 0); - actH = AutoSize && s.Height > actH ? s.Height : actH; - break; - } - - return actH; - } - - // https://en.wikipedia.org/wiki/Topological_sorting - List TopologicalSort (IEnumerable nodes, ICollection<(View From, View To)> edges) - { - var result = new List (); - - // Set of all nodes with no incoming edges - var noEdgeNodes = new HashSet (nodes.Where (n => edges.All (e => !e.To.Equals (n)))); - - while (noEdgeNodes.Any ()) { - // remove a node n from S - var n = noEdgeNodes.First (); - noEdgeNodes.Remove (n); - - // add n to tail of L - if (n != this?.SuperView) - result.Add (n); - - // for each node m with an edge e from n to m do - foreach (var e in edges.Where (e => e.From.Equals (n)).ToArray ()) { - var m = e.To; - - // remove edge e from the graph - edges.Remove (e); - - // if m has no other incoming edges then - if (edges.All (me => !me.To.Equals (m)) && m != this?.SuperView) { - // insert m into S - noEdgeNodes.Add (m); - } - } - } - - if (edges.Any ()) { - (var from, var to) = edges.First (); - if (from != Application.Top) { - if (!ReferenceEquals (from, to)) { - throw new InvalidOperationException ($"TopologicalSort (for Pos/Dim) cannot find {from} linked with {to}. Did you forget to add it to {this}?"); - } else { - throw new InvalidOperationException ("TopologicalSort encountered a recursive cycle in the relative Pos/Dim in the views of " + this); - } - } - } - - // return L (a topologically sorted order) - return result; - } - /// /// Event arguments for the event. /// @@ -2552,6 +2347,108 @@ namespace Terminal.Gui { LayoutComplete?.Invoke (args); } + internal void CollectPos (Pos pos, View from, ref HashSet nNodes, ref HashSet<(View, View)> nEdges) + { + switch (pos) { + case Pos.PosView pv: + if (pv.Target != this) { + nEdges.Add ((pv.Target, from)); + } + foreach (var v in from.InternalSubviews) { + CollectAll (v, ref nNodes, ref nEdges); + } + return; + case Pos.PosCombine pc: + foreach (var v in from.InternalSubviews) { + CollectPos (pc.left, from, ref nNodes, ref nEdges); + CollectPos (pc.right, from, ref nNodes, ref nEdges); + } + break; + } + } + + internal void CollectDim (Dim dim, View from, ref HashSet nNodes, ref HashSet<(View, View)> nEdges) + { + switch (dim) { + case Dim.DimView dv: + if (dv.Target != this) { + nEdges.Add ((dv.Target, from)); + } + foreach (var v in from.InternalSubviews) { + CollectAll (v, ref nNodes, ref nEdges); + } + return; + case Dim.DimCombine dc: + foreach (var v in from.InternalSubviews) { + CollectDim (dc.left, from, ref nNodes, ref nEdges); + CollectDim (dc.right, from, ref nNodes, ref nEdges); + } + break; + } + } + + internal void CollectAll (View from, ref HashSet nNodes, ref HashSet<(View, View)> nEdges) + { + foreach (var v in from.InternalSubviews) { + nNodes.Add (v); + if (v.layoutStyle != LayoutStyle.Computed) { + continue; + } + CollectPos (v.X, v, ref nNodes, ref nEdges); + CollectPos (v.Y, v, ref nNodes, ref nEdges); + CollectDim (v.Width, v, ref nNodes, ref nEdges); + CollectDim (v.Height, v, ref nNodes, ref nEdges); + } + } + + // https://en.wikipedia.org/wiki/Topological_sorting + internal static List TopologicalSort (View superView, IEnumerable nodes, ICollection<(View From, View To)> edges) + { + var result = new List (); + + // Set of all nodes with no incoming edges + var noEdgeNodes = new HashSet (nodes.Where (n => edges.All (e => !e.To.Equals (n)))); + + + while (noEdgeNodes.Any ()) { + // remove a node n from S + var n = noEdgeNodes.First (); + noEdgeNodes.Remove (n); + + // add n to tail of L + if (n != superView) + result.Add (n); + + // for each node m with an edge e from n to m do + foreach (var e in edges.Where (e => e.From.Equals (n)).ToArray ()) { + var m = e.To; + + // remove edge e from the graph + edges.Remove (e); + + // if m has no other incoming edges then + if (edges.All (me => !me.To.Equals (m)) && m != superView) { + // insert m into S + noEdgeNodes.Add (m); + } + } + } + + if (edges.Any ()) { + (var from, var to) = edges.First (); + if (from != Application.Top) { + if (!ReferenceEquals (from, to)) { + throw new InvalidOperationException ($"TopologicalSort (for Pos/Dim) cannot find {from} linked with {to}. Did you forget to add it to {superView}?"); + } else { + throw new InvalidOperationException ("TopologicalSort encountered a recursive cycle in the relative Pos/Dim in the views of " + superView); + } + } + } + // return L (a topologically sorted order) + return result; + } // TopologicalSort + + /// /// Invoked when a view starts executing or when the dimensions of the view have changed, for example in /// response to the container view or terminal resizing. @@ -2565,128 +2462,31 @@ namespace Terminal.Gui { return; } - // TODO: Move to new method: LayoutAdornments - if (Margin != null) { - Margin.X = 0; // Adornment location is parent-relative - Margin.Y = 0; - Margin.Width = Frame.Size.Width; - Margin.Height = Frame.Size.Height; - Margin.SetNeedsLayout (); - Margin.LayoutSubviews (); - Margin.SetNeedsDisplay (); - } - - if (BorderFrame != null) { - var border = Margin?.Thickness.GetInnerRect (Margin.Frame) ?? Frame; - BorderFrame.X = border.Location.X; - BorderFrame.Y = border.Location.Y; - BorderFrame.Width = border.Size.Width; - BorderFrame.Height = border.Size.Height; - BorderFrame.SetNeedsLayout (); - BorderFrame.LayoutSubviews (); - BorderFrame.SetNeedsDisplay (); - } - - if (Padding != null) { - var padding = BorderFrame?.Thickness.GetInnerRect (BorderFrame.Frame) ?? Margin?.Thickness.GetInnerRect (Margin.Frame) ?? Frame; - Padding.X = padding.Location.X; - Padding.Y = padding.Location.Y; - Padding.Width = padding.Size.Width; - Padding.Height = padding.Size.Height; - Padding.SetNeedsLayout (); - Padding.LayoutSubviews (); - Padding.SetNeedsDisplay (); - } - - var oldBounds = Bounds; OnLayoutStarted (new LayoutEventArgs () { OldBounds = oldBounds }); TextFormatter.Size = GetBoundsTextFormatterSize (); - // Sort out the dependencies of the X, Y, Width, Height properties var nodes = new HashSet (); var edges = new HashSet<(View, View)> (); - - void CollectPos (Pos pos, View from, ref HashSet nNodes, ref HashSet<(View, View)> nEdges) - { - switch (pos) { - case Pos.PosView pv: - if (pv.Target != this) { - nEdges.Add ((pv.Target, from)); - } - foreach (var v in from.InternalSubviews) { - CollectAll (v, ref nNodes, ref nEdges); - } - return; - case Pos.PosCombine pc: - foreach (var v in from.InternalSubviews) { - CollectPos (pc.left, from, ref nNodes, ref nEdges); - CollectPos (pc.right, from, ref nNodes, ref nEdges); - } - break; - } - } - - void CollectDim (Dim dim, View from, ref HashSet nNodes, ref HashSet<(View, View)> nEdges) - { - switch (dim) { - case Dim.DimView dv: - if (dv.Target != this) { - nEdges.Add ((dv.Target, from)); - } - foreach (var v in from.InternalSubviews) { - CollectAll (v, ref nNodes, ref nEdges); - } - return; - case Dim.DimCombine dc: - foreach (var v in from.InternalSubviews) { - CollectDim (dc.left, from, ref nNodes, ref nEdges); - CollectDim (dc.right, from, ref nNodes, ref nEdges); - } - break; - } - } - - void CollectAll (View from, ref HashSet nNodes, ref HashSet<(View, View)> nEdges) - { - foreach (var v in from.InternalSubviews) { - nNodes.Add (v); - if (v.layoutStyle != LayoutStyle.Computed) { - continue; - } - CollectPos (v.X, v, ref nNodes, ref nEdges); - CollectPos (v.Y, v, ref nNodes, ref nEdges); - CollectDim (v.Width, v, ref nNodes, ref nEdges); - CollectDim (v.Height, v, ref nNodes, ref nEdges); - } - } - CollectAll (this, ref nodes, ref edges); - - var ordered = TopologicalSort (nodes, edges); - - var bounds = Frame; - bool hasFrame = Margin != null || BorderFrame != null || Padding != null; - - if (hasFrame) { - // in v2 Bounds really is Frame-relative - bounds = new Rect (Point.Empty, Frame.Size); - } - + var ordered = View.TopologicalSort (SuperView, nodes, edges); foreach (var v in ordered) { if (v.LayoutStyle == LayoutStyle.Computed) { - v.SetRelativeLayout (bounds); + v.SetRelativeLayout (Frame); } v.LayoutSubviews (); v.LayoutNeeded = false; } + // If our SuperView is Application.Top and the layoutstyle is Computed it's a special-cass. + // Use SetRelativeaLayout with the Frame of the Application.Top if (SuperView != null && SuperView == Application.Top && LayoutNeeded && ordered.Count == 0 && LayoutStyle == LayoutStyle.Computed) { - SetRelativeLayout (SuperView.Frame); + Debug.Assert (Application.Top.Frame.Location == Point.Empty); + SetRelativeLayout (Application.Top.Frame); } LayoutNeeded = false; @@ -2836,7 +2636,13 @@ namespace Terminal.Gui { get => base.Enabled; set { if (base.Enabled != value) { - base.Enabled = value; + if (value) { + if (SuperView == null || SuperView?.Enabled == true) { + base.Enabled = value; + } + } else { + base.Enabled = value; + } if (!value && HasFocus) { SetHasFocus (false, this); } @@ -2891,11 +2697,6 @@ namespace Terminal.Gui { set { if (border != value) { border = value; - EnableFrames (); - Margin.Thickness = border.BorderThickness; - BorderFrame.Thickness = new Thickness (border.BorderStyle != BorderStyle.None ? 1 : 0); - BorderFrame.BorderStyle = border.BorderStyle; - Padding.Thickness = border.Padding; SetNeedsDisplay (); } } @@ -2908,7 +2709,7 @@ namespace Terminal.Gui { /// to draw the view's border. If no border is drawn (and the view is expected to draw the border /// itself). /// - public virtual bool IgnoreBorderPropertyOnRedraw { get; set; } = false; + public virtual bool IgnoreBorderPropertyOnRedraw { get; set; } /// /// Pretty prints the View @@ -2939,8 +2740,7 @@ namespace Terminal.Gui { if (ForceValidatePosDim) { aSize = SetWidthHeight (nBoundsSize); } else { - // BUGBUG: `Bounds.set` ignores Location. This line also changes `Frame` - Frame = new Rect (Frame.X, Frame.Y, nBoundsSize.Width, nBoundsSize.Height); + Bounds = new Rect (Bounds.X, Bounds.Y, nBoundsSize.Width, nBoundsSize.Height); } } TextFormatter.Size = GetBoundsTextFormatterSize (); @@ -2961,7 +2761,6 @@ namespace Terminal.Gui { height = rH; } if (aSize) { - // BUGBUG: `Bounds.set` ignores Location. This line also changes `Frame` Bounds = new Rect (Bounds.X, Bounds.Y, canSizeW ? rW : Bounds.Width, canSizeH ? rH : Bounds.Height); TextFormatter.Size = GetBoundsTextFormatterSize (); } @@ -2970,9 +2769,11 @@ namespace Terminal.Gui { } /// - /// Gets the size to fit all text if is true. + /// Gets the dimensions required to fit using the text specified by the + /// property and accounting for any characters. + /// . /// - /// The + /// The required to fit the text. public Size GetAutoSize () { var rect = TextFormatter.CalcRect (Bounds.X, Bounds.Y, TextFormatter.Text, TextFormatter.Direction); @@ -3007,10 +2808,11 @@ namespace Terminal.Gui { } /// - /// Get the width or height of the length. + /// Gets the width or height of the characters in the property. /// - /// if is the width (default) if is the height. - /// The length of the . + /// If (the default) the width required for the hotkey specifier is returned. Otherwise the height is returned. + /// The number of characters required for the . If the text direction specified + /// by does not match the parameter, 0 is returned. public int GetHotKeySpecifierLength (bool isWidth = true) { if (isWidth) { @@ -3025,7 +2827,7 @@ namespace Terminal.Gui { } /// - /// Gets the bounds size from a . + /// Gets the minus the size required for the . /// /// The bounds size minus the length. public Size GetTextFormatterBoundsSize () @@ -3171,14 +2973,6 @@ namespace Terminal.Gui { Remove (subview); subview.Dispose (); } - - Margin?.Dispose (); - Margin = null; - BorderFrame?.Dispose (); - BorderFrame = null; - Padding?.Dispose (); - Padding = null; - base.Dispose (disposing); } @@ -3216,7 +3010,7 @@ namespace Terminal.Gui { Initialized?.Invoke (this, EventArgs.Empty); } - internal bool CanBeVisible (View view) + bool CanBeVisible (View view) { if (!view.Visible) { return false; @@ -3343,6 +3137,17 @@ namespace Terminal.Gui { return Enabled ? ColorScheme.Normal : ColorScheme.Disabled; } + /// + /// Determines the current based on the value. + /// + /// if is + /// or if is . + /// If it's overridden can return other values. + public virtual Attribute GetFocusColor () + { + return Enabled ? ColorScheme.Focus : ColorScheme.Disabled; + } + /// /// Determines the current based on the value. /// diff --git a/UICatalog/Scenario.cs b/UICatalog/Scenario.cs index e049c4505..6aca19825 100644 --- a/UICatalog/Scenario.cs +++ b/UICatalog/Scenario.cs @@ -205,8 +205,8 @@ namespace UICatalog { } /// - /// Runs the . Override to start the using a different than `Top`. - /// + /// Runs the . Override to start the + /// using a different than `Top`. /// /// /// Overrides that do not call the base., must call before returning. diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs deleted file mode 100644 index b23ce6514..000000000 --- a/UICatalog/Scenarios/ASCIICustomButton.cs +++ /dev/null @@ -1,313 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Diagnostics; -//using Terminal.Gui; - -//namespace UICatalog.Scenarios { -// [ScenarioMetadata (Name: "ASCIICustomButtonTest", Description: "ASCIICustomButton sample")] -// [ScenarioCategory ("Controls")] -// public class ASCIICustomButtonTest : Scenario { -// private static bool smallerWindow; -// private ScrollViewTestWindow scrollViewTestWindow; -// private MenuItem miSmallerWindow; - -// public override void Init (ColorScheme colorScheme) -// { -// Application.Init (); -// scrollViewTestWindow = new ScrollViewTestWindow (); -// var menu = new MenuBar (new MenuBarItem [] { -// new MenuBarItem("Window Size", new MenuItem [] { -// miSmallerWindow = new MenuItem ("Smaller Window", "", ChangeWindowSize) { -// CheckType = MenuItemCheckStyle.Checked -// }, -// null, -// new MenuItem("Quit", "",() => Application.RequestStop(),null,null, Key.Q | Key.CtrlMask) -// }) -// }); -// Application.Top.Add (menu, scrollViewTestWindow); -// Application.Run (); -// } - -// private void ChangeWindowSize () -// { -// smallerWindow = (bool)(miSmallerWindow.Checked = !miSmallerWindow.Checked); -// scrollViewTestWindow.Dispose (); -// Application.Top.Remove (scrollViewTestWindow); -// scrollViewTestWindow = new ScrollViewTestWindow (); -// Application.Top.Add (scrollViewTestWindow); -// } - -// public override void Run () -// { -// } - -// public class ASCIICustomButton : Button { -// public string Description => $"Description of: {id}"; - -// public event Action PointerEnter; - -// private Label fill; -// private FrameView border; -// private string id; - -// public ASCIICustomButton (string text, Pos x, Pos y, int width, int height) : base (text) -// { -// CustomInitialize ("", text, x, y, width, height); -// } - -// public ASCIICustomButton (string id, string text, Pos x, Pos y, int width, int height) : base (text) -// { -// CustomInitialize (id, text, x, y, width, height); -// } - -// private void CustomInitialize (string id, string text, Pos x, Pos y, int width, int height) -// { -// this.id = id; -// X = x; -// Y = y; - -// Frame = new Rect { -// Width = width, -// Height = height -// }; - -// border = new FrameView () { -// Width = width, -// Height = height -// }; - -// AutoSize = false; - -// var fillText = new System.Text.StringBuilder (); -// for (int i = 0; i < Bounds.Height; i++) { -// if (i > 0) { -// fillText.AppendLine (""); -// } -// for (int j = 0; j < Bounds.Width; j++) { -// fillText.Append ("█"); -// } -// } - -// fill = new Label (fillText.ToString ()) { -// Visible = false, -// CanFocus = false -// }; - -// var title = new Label (text) { -// X = Pos.Center (), -// Y = Pos.Center (), -// }; - -// border.MouseClick += This_MouseClick; -// //border.Subviews [0].MouseClick += This_MouseClick; -// fill.MouseClick += This_MouseClick; -// title.MouseClick += This_MouseClick; - -// Add (border, fill, title); -// } - -// private void This_MouseClick (MouseEventArgs obj) -// { -// OnMouseEvent (obj.MouseEvent); -// } - -// public override bool OnMouseEvent (MouseEvent mouseEvent) -// { -// Debug.WriteLine ($"{mouseEvent.Flags}"); -// if (mouseEvent.Flags == MouseFlags.Button1Clicked) { -// if (!HasFocus && SuperView != null) { -// if (!SuperView.HasFocus) { -// SuperView.SetFocus (); -// } -// SetFocus (); -// SetNeedsDisplay (); -// } - -// OnClicked (); -// return true; -// } -// return base.OnMouseEvent (mouseEvent); -// } - -// public override bool OnEnter (View view) -// { -// border.Visible = false; -// fill.Visible = true; -// PointerEnter.Invoke (this); -// view = this; -// return base.OnEnter (view); -// } - -// public override bool OnLeave (View view) -// { -// border.Visible = true; -// fill.Visible = false; -// if (view == null) -// view = this; -// return base.OnLeave (view); -// } -// } - -// public class ScrollViewTestWindow : Window { -// private List