From 20249faa101a50181349fe624c1254535488e620 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 27 Aug 2024 16:49:30 -0700 Subject: [PATCH] Fixed adornment editor scenarios --- .github/workflows/publish.yml | 1 + Terminal.Gui/Application/Application.Run.cs | 10 +- .../Application/ApplicationOverlapped.cs | 4 +- Terminal.Gui/Application/MainLoop.cs | 1 + Terminal.Gui/Input/Responder.cs | 1 + .../Text/Autocomplete/PopupAutocomplete.cs | 5 +- Terminal.Gui/Text/CollectionNavigatorBase.cs | 1 + Terminal.Gui/View/Adornment/Adornment.cs | 2 +- Terminal.Gui/View/Orientation/IOrientation.cs | 4 +- Terminal.Gui/View/View.Adornments.cs | 1 + Terminal.Gui/View/View.Content.cs | 5 +- Terminal.Gui/View/View.Drawing.cs | 2 + Terminal.Gui/View/View.Hierarchy.cs | 10 +- Terminal.Gui/View/View.Keyboard.cs | 10 +- Terminal.Gui/View/View.Layout.cs | 12 +- Terminal.Gui/View/View.Navigation.cs | 24 ++-- Terminal.Gui/View/View.Text.cs | 2 +- Terminal.Gui/View/View.cs | 30 ++--- Terminal.Gui/Views/Bar.cs | 13 +- Terminal.Gui/Views/ColorPicker.cs | 2 +- Terminal.Gui/Views/ColorPicker16.cs | 1 + Terminal.Gui/Views/TextField.cs | 3 + Terminal.Gui/Views/TextView.cs | 3 + UICatalog/Scenarios/AdornmentEditor.cs | 3 +- UICatalog/Scenarios/Adornments.cs | 29 +---- UICatalog/Scenarios/AdornmentsEditor.cs | 103 +++++++++++++--- UICatalog/Scenarios/AllViewsTester.cs | 37 +++--- UICatalog/Scenarios/ContentScrolling.cs | 29 +---- UICatalog/Scenarios/Navigation.cs | 97 ++++++++------- UICatalog/Scenarios/NumericUpDownDemo.cs | 11 +- UICatalog/Scenarios/ProgressBarStyles.cs | 2 +- UICatalog/Scenarios/ShadowStyles.cs | 28 +---- UICatalog/Scenarios/ViewExperiments.cs | 111 +----------------- 33 files changed, 261 insertions(+), 336 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index beeb09d03..d968715b5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -44,6 +44,7 @@ jobs: run: | dotnet-gitversion /updateprojectfiles dotnet build --no-incremental --nologo --force --configuration Release + dotnet test --configuration Release - name: Pack run: dotnet pack -c Release --include-symbols -p:Version='${{ steps.gitversion.outputs.SemVer }}' diff --git a/Terminal.Gui/Application/Application.Run.cs b/Terminal.Gui/Application/Application.Run.cs index 110627bd9..f85c8fdb9 100644 --- a/Terminal.Gui/Application/Application.Run.cs +++ b/Terminal.Gui/Application/Application.Run.cs @@ -189,11 +189,15 @@ public static partial class Application // Run (Begin, Run, End, Stop) // TODO: Should this use FindDeepestFocusableView instead? // Try to set initial focus to any TabStop - if (!toplevel.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop)) + if (!toplevel.HasFocus) { - // That didn't work. Try TabGroup. - toplevel.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup); + if (!toplevel.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop)) + { + // That didn't work. Try TabGroup. + toplevel.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup); + } } + ApplicationOverlapped.BringOverlappedTopToFront (); if (refreshDriver) diff --git a/Terminal.Gui/Application/ApplicationOverlapped.cs b/Terminal.Gui/Application/ApplicationOverlapped.cs index fa11ae1f8..328897580 100644 --- a/Terminal.Gui/Application/ApplicationOverlapped.cs +++ b/Terminal.Gui/Application/ApplicationOverlapped.cs @@ -96,12 +96,12 @@ public static class ApplicationOverlapped foreach (Toplevel top in OverlappedChildren) { - if (type is { } && top.GetType () == type && exclude?.Contains (top.Data.ToString ()) == false) + if (type is { } && top.GetType () == type && exclude?.Contains (top.Data?.ToString ()) == false) { return top; } - if ((type is { } && top.GetType () != type) || exclude?.Contains (top.Data.ToString ()) == true) + if ((type is { } && top.GetType () != type) || exclude?.Contains (top.Data?.ToString ()) == true) { continue; } diff --git a/Terminal.Gui/Application/MainLoop.cs b/Terminal.Gui/Application/MainLoop.cs index fdd2c5639..ee4bba220 100644 --- a/Terminal.Gui/Application/MainLoop.cs +++ b/Terminal.Gui/Application/MainLoop.cs @@ -296,6 +296,7 @@ internal class MainLoop : IDisposable /// Invoked when a new timeout is added. To be used in the case when /// is . /// + [CanBeNull] internal event EventHandler TimeoutAdded; /// Wakes up the that might be waiting on input. diff --git a/Terminal.Gui/Input/Responder.cs b/Terminal.Gui/Input/Responder.cs index 44ed5a2a8..43cc08240 100644 --- a/Terminal.Gui/Input/Responder.cs +++ b/Terminal.Gui/Input/Responder.cs @@ -26,6 +26,7 @@ public class Responder : IDisposable } /// Event raised when has been called to signal that this object is being disposed. + [CanBeNull] public event EventHandler Disposing; /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs index b829dac03..2bb70ddf6 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs @@ -535,7 +535,10 @@ public abstract partial class PopupAutocomplete : AutocompleteBase { if (_popup is null) { - _popup = new Popup (this) { Frame = Rectangle.Empty }; + _popup = new Popup (this) + { + CanFocus = false + }; _top?.Add (_popup); } } diff --git a/Terminal.Gui/Text/CollectionNavigatorBase.cs b/Terminal.Gui/Text/CollectionNavigatorBase.cs index df58dfbc4..4caa219cd 100644 --- a/Terminal.Gui/Text/CollectionNavigatorBase.cs +++ b/Terminal.Gui/Text/CollectionNavigatorBase.cs @@ -147,6 +147,7 @@ public abstract class CollectionNavigatorBase public virtual void OnSearchStringChanged (KeystrokeNavigatorEventArgs e) { SearchStringChanged?.Invoke (this, e); } /// This event is invoked when changes. Useful for debugging. + [CanBeNull] public event EventHandler SearchStringChanged; /// Returns the collection being navigated element at . diff --git a/Terminal.Gui/View/Adornment/Adornment.cs b/Terminal.Gui/View/Adornment/Adornment.cs index e7cff5e8b..6c575ad99 100644 --- a/Terminal.Gui/View/Adornment/Adornment.cs +++ b/Terminal.Gui/View/Adornment/Adornment.cs @@ -86,7 +86,7 @@ public class Adornment : View /// Adornments cannot be used as sub-views (see ); setting this property will throw /// . /// - public override View SuperView + public override View? SuperView { get => null!; set => throw new InvalidOperationException (@"Adornments can not be Subviews or have SuperViews. Use Parent instead."); diff --git a/Terminal.Gui/View/Orientation/IOrientation.cs b/Terminal.Gui/View/Orientation/IOrientation.cs index c5a7c115f..db76a6f83 100644 --- a/Terminal.Gui/View/Orientation/IOrientation.cs +++ b/Terminal.Gui/View/Orientation/IOrientation.cs @@ -19,7 +19,7 @@ public interface IOrientation /// /// Raised when is changing. Can be cancelled. /// - public event EventHandler> OrientationChanging; + public event EventHandler>? OrientationChanging; /// /// Called when is changing. @@ -32,7 +32,7 @@ public interface IOrientation /// /// Raised when has changed. /// - public event EventHandler> OrientationChanged; + public event EventHandler>? OrientationChanged; /// /// Called when has been changed. diff --git a/Terminal.Gui/View/View.Adornments.cs b/Terminal.Gui/View/View.Adornments.cs index 2d179079e..6013f5b5b 100644 --- a/Terminal.Gui/View/View.Adornments.cs +++ b/Terminal.Gui/View/View.Adornments.cs @@ -194,6 +194,7 @@ public partial class View // Adornments /// /// Fired when the is changing. Allows the event to be cancelled. /// + [CanBeNull] public event EventHandler> BorderStyleChanging; /// diff --git a/Terminal.Gui/View/View.Content.cs b/Terminal.Gui/View/View.Content.cs index 131dd90ba..12851d12c 100644 --- a/Terminal.Gui/View/View.Content.cs +++ b/Terminal.Gui/View/View.Content.cs @@ -154,7 +154,7 @@ public partial class View /// /// Event raised when the changes. /// - public event EventHandler ContentSizeChanged; + public event EventHandler? ContentSizeChanged; /// /// Converts a Content-relative location to a Screen-relative location. @@ -357,8 +357,7 @@ public partial class View /// Fired when the changes. This event is fired after the has been /// updated. /// - [CanBeNull] - public event EventHandler ViewportChanged; + public event EventHandler? ViewportChanged; /// /// Called when the changes. Invokes the event. diff --git a/Terminal.Gui/View/View.Drawing.cs b/Terminal.Gui/View/View.Drawing.cs index 3ec493b57..bf3cc75df 100644 --- a/Terminal.Gui/View/View.Drawing.cs +++ b/Terminal.Gui/View/View.Drawing.cs @@ -262,6 +262,7 @@ public partial class View // Drawing APIs /// . /// /// + [CanBeNull] public event EventHandler DrawContent; /// Event invoked when the content area of the View is completed drawing. @@ -272,6 +273,7 @@ public partial class View // Drawing APIs /// . /// /// + [CanBeNull] public event EventHandler DrawContentComplete; /// Utility function to draw strings that contain a hotkey. diff --git a/Terminal.Gui/View/View.Hierarchy.cs b/Terminal.Gui/View/View.Hierarchy.cs index baae44f7a..590c3f735 100644 --- a/Terminal.Gui/View/View.Hierarchy.cs +++ b/Terminal.Gui/View/View.Hierarchy.cs @@ -18,7 +18,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView, /// 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 + public virtual View? SuperView { get => _superView!; set => throw new NotImplementedException (); @@ -52,7 +52,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView, _subviews.Add (view); view._superView = this; - if (view.Enabled && view.Visible && view.CanFocus) + if (view is { Enabled: true, Visible: true, CanFocus: true }) { // Add will cause the newly added subview to gain focus if it's focusable if (HasFocus) @@ -94,7 +94,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView, /// the lifecycle of the subviews to be transferred to this View. /// /// - public void Add (params View [] views) + public void Add (params View []? views) { if (views is null) { @@ -108,7 +108,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView, } /// Event fired when this view is added to another. - public event EventHandler Added; + public event EventHandler? Added; /// Get the top superview of a given . /// The superview view. @@ -222,7 +222,7 @@ public partial class View // SuperView/SubView hierarchy management (SuperView, } /// Event fired when this view is removed from another. - public event EventHandler Removed; + public event EventHandler? Removed; /// diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index f5b35803d..a218702da 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -48,7 +48,7 @@ public partial class View // Keyboard APIs } /// Invoked when the is changed. - public event EventHandler HotKeyChanged; + public event EventHandler? HotKeyChanged; private Key _hotKey = new (); private void TitleTextFormatter_HotKeyChanged (object? sender, KeyChangedEventArgs e) { HotKeyChanged?.Invoke (this, e); } @@ -364,7 +364,7 @@ public partial class View // Keyboard APIs /// /// See for an overview of Terminal.Gui keyboard APIs. /// - public event EventHandler KeyDown; + public event EventHandler? KeyDown; /// /// Low-level API called when the user presses a key, allowing views do things during key down events. This is @@ -412,7 +412,7 @@ public partial class View // Keyboard APIs /// /// See for an overview of Terminal.Gui keyboard APIs. /// - public event EventHandler ProcessKeyDown; + public event EventHandler? ProcessKeyDown; #endregion KeyDown Event @@ -503,7 +503,7 @@ public partial class View // Keyboard APIs /// See for an overview of Terminal.Gui keyboard APIs. /// /// - public event EventHandler KeyUp; + public event EventHandler? KeyUp; #endregion KeyUp Event @@ -512,7 +512,7 @@ public partial class View // Keyboard APIs #region Key Bindings /// Gets the key bindings for this view. - public KeyBindings KeyBindings { get; internal set; } + public KeyBindings KeyBindings { get; internal set; } = null!; private Dictionary> CommandImplementations { get; } = new (); diff --git a/Terminal.Gui/View/View.Layout.cs b/Terminal.Gui/View/View.Layout.cs index c13367df3..b407d4fa1 100644 --- a/Terminal.Gui/View/View.Layout.cs +++ b/Terminal.Gui/View/View.Layout.cs @@ -163,7 +163,7 @@ public partial class View // Layout APIs } else { - View t = viewToMove!.SuperView; + View? t = viewToMove!.SuperView; while (t is { } and not Toplevel) { @@ -194,7 +194,7 @@ public partial class View // Layout APIs } else { - View t = viewToMove!.SuperView; + View? t = viewToMove!.SuperView; while (t is { } and not Toplevel) { @@ -311,7 +311,7 @@ public partial class View // Layout APIs public virtual Rectangle FrameToScreen () { Rectangle screen = Frame; - View current = SuperView; + View? current = SuperView; while (current is { }) { @@ -547,14 +547,14 @@ public partial class View // Layout APIs /// Subscribe to this event to perform tasks when the has been resized or the layout has /// otherwise changed. /// - public event EventHandler LayoutComplete; + public event EventHandler? LayoutComplete; /// Fired after the View's method has completed. /// /// Subscribe to this event to perform tasks when the has been resized or the layout has /// otherwise changed. /// - public event EventHandler LayoutStarted; + public event EventHandler? LayoutStarted; /// /// Adjusts given the SuperView's ContentSize (nominally the same as @@ -694,7 +694,7 @@ public partial class View // Layout APIs HashSet nodes = new (); HashSet<(View, View)> edges = new (); CollectAll (this, ref nodes, ref edges); - List ordered = TopologicalSort (SuperView, nodes, edges); + List ordered = TopologicalSort (SuperView!, nodes, edges); foreach (View v in ordered) { diff --git a/Terminal.Gui/View/View.Navigation.cs b/Terminal.Gui/View/View.Navigation.cs index 315b53488..e5fda2de5 100644 --- a/Terminal.Gui/View/View.Navigation.cs +++ b/Terminal.Gui/View/View.Navigation.cs @@ -152,7 +152,7 @@ public partial class View // Focus and cross-view navigation management (TabStop /// /// Raised by the virtual method. /// - public event EventHandler CanFocusChanged; + public event EventHandler? CanFocusChanged; /// /// Focuses the deepest focusable Subview if one exists. If there are no focusable Subviews then the focus is set to the view itself. @@ -485,15 +485,15 @@ public partial class View // Focus and cross-view navigation management (TabStop /// Use to be notified after the focus has changed. /// /// - public event EventHandler HasFocusChanging; + public event EventHandler? HasFocusChanging; /// /// Called when this view should stop being focused. /// - /// The new focused view. If it is not known which view will be focused. + /// The new focused view. If it is not known which view will be focused. /// Set to true to indicate method is being called recurively, traversing down the focus chain. /// - private void SetHasFocusFalse (View? newFocusedVew, bool traversingDown = false) + private void SetHasFocusFalse (View? newFocusedView, bool traversingDown = false) { // Pre-conditions if (!_hasFocus) @@ -502,7 +502,7 @@ public partial class View // Focus and cross-view navigation management (TabStop } // If newFocusedVew is null, we need to find the view that should get focus, and SetFocus on it. - if (!traversingDown && newFocusedVew is null) + if (!traversingDown && newFocusedView is null) { if (SuperView?._previouslyMostFocused is { } && SuperView?._previouslyMostFocused != this) { @@ -539,16 +539,16 @@ public partial class View // Focus and cross-view navigation management (TabStop // Before we can leave focus, we need to make sure that all views down the subview-hierarchy have left focus. View? mostFocused = MostFocused; - if (mostFocused is { } && (newFocusedVew is null || mostFocused != newFocusedVew)) + if (mostFocused is { } && (newFocusedView is null || mostFocused != newFocusedView)) { // Start at the bottom and work our way up to us - View bottom = mostFocused; + View? bottom = mostFocused; while (bottom is { } && bottom != this) { if (bottom.HasFocus) { - bottom.SetHasFocusFalse (newFocusedVew, true); + bottom.SetHasFocusFalse (newFocusedView, true); } bottom = bottom.SuperView; @@ -560,7 +560,7 @@ public partial class View // Focus and cross-view navigation management (TabStop bool previousValue = HasFocus; // Note, can't be cancelled. - NotifyFocusChanging (HasFocus, !HasFocus, newFocusedVew, this); + NotifyFocusChanging (HasFocus, !HasFocus, newFocusedView, this); // Get whatever peer has focus, if any View? focusedPeer = SuperView?.Focused; @@ -572,11 +572,11 @@ public partial class View // Focus and cross-view navigation management (TabStop if (appFocused is { } || appFocused == this) { - Application.Navigation.SetFocused (SuperView); + Application.Navigation.SetFocused (newFocusedView ?? SuperView); } } - NotifyFocusChanged (HasFocus, this, newFocusedVew); + NotifyFocusChanged (HasFocus, this, newFocusedView); if (_hasFocus) { @@ -633,7 +633,7 @@ public partial class View // Focus and cross-view navigation management (TabStop /// This event cannot be cancelled. /// /// - public event EventHandler HasFocusChanged; + public event EventHandler? HasFocusChanged; #endregion HasFocus diff --git a/Terminal.Gui/View/View.Text.cs b/Terminal.Gui/View/View.Text.cs index 163aa967a..508637b56 100644 --- a/Terminal.Gui/View/View.Text.cs +++ b/Terminal.Gui/View/View.Text.cs @@ -4,7 +4,7 @@ namespace Terminal.Gui; public partial class View // Text Property APIs { - private string _text; + private string _text = null!; /// /// Called when the has changed. Fires the event. diff --git a/Terminal.Gui/View/View.cs b/Terminal.Gui/View/View.cs index 4751b6d80..134928ebd 100644 --- a/Terminal.Gui/View/View.cs +++ b/Terminal.Gui/View/View.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +#nullable enable +using System.ComponentModel; using System.Diagnostics; namespace Terminal.Gui; @@ -112,11 +113,11 @@ public partial class View : Responder, ISupportInitializeNotification /// /// to cancel the event. /// - public event EventHandler Accept; + public event EventHandler? Accept; /// Gets or sets arbitrary data for the view. /// This property is not used internally. - public object Data { get; set; } + public object? Data { get; set; } /// Gets or sets an identifier for the view; /// The identifier. @@ -168,7 +169,7 @@ public partial class View : Responder, ISupportInitializeNotification /// Points to the current driver in use by the view, it is a convenience property for simplifying the development /// of new views. /// - public static ConsoleDriver Driver => Application.Driver; + public static ConsoleDriver Driver => Application.Driver!; /// Initializes a new instance of . /// @@ -191,7 +192,7 @@ public partial class View : Responder, ISupportInitializeNotification /// configurations and assignments to be performed before the being shown. /// View implements to allow for more sophisticated initialization. /// - public event EventHandler Initialized; + public event EventHandler? Initialized; /// /// Get or sets if the has been initialized (via @@ -313,7 +314,8 @@ public partial class View : Responder, ISupportInitializeNotification HasFocus = false; } - if (_enabled && CanFocus && Visible && !HasFocus && SuperView is { } && SuperView?.Focused is null) + if (_enabled && CanFocus && Visible && !HasFocus + && SuperView is null or { HasFocus: true, Visible: true, Enabled: true, Focused: null }) { SetFocus (); } @@ -345,7 +347,7 @@ public partial class View : Responder, ISupportInitializeNotification } /// Event fired when the value is being changed. - public event EventHandler EnabledChanged; + public event EventHandler? EnabledChanged; /// Method invoked when the property from a view is changed. public virtual void OnEnabledChanged () { EnabledChanged?.Invoke (this, EventArgs.Empty); } @@ -377,8 +379,8 @@ public partial class View : Responder, ISupportInitializeNotification } } - if (_visible && CanFocus && Enabled && !HasFocus - && (SuperView is null || SuperView is { HasFocus: true, Visible: true, Enabled: true, Focused: null })) + if (_visible && CanFocus && Enabled && !HasFocus + && SuperView is null or { HasFocus: true, Visible: true, Enabled: true, Focused: null }) { SetFocus (); } @@ -395,7 +397,7 @@ public partial class View : Responder, ISupportInitializeNotification public bool ClearOnVisibleFalse { get; set; } = true; /// Event fired when the value is being changed. - public event EventHandler VisibleChanged; + public event EventHandler? VisibleChanged; /// /// INTERNAL method for determining if all the specified view and all views up the Superview hierarchy are visible. @@ -409,7 +411,7 @@ public partial class View : Responder, ISupportInitializeNotification return false; } - for (View c = view.SuperView; c != null; c = c.SuperView) + for (View? c = view.SuperView; c != null; c = c.SuperView) { if (!c.Visible) { @@ -483,7 +485,7 @@ public partial class View : Responder, ISupportInitializeNotification SetHotKeyFromTitle (); SetNeedsDisplay (); #if DEBUG - if (_title is { } && string.IsNullOrEmpty (Id)) + if (string.IsNullOrEmpty (Id)) { Id = _title; } @@ -524,13 +526,13 @@ public partial class View : Responder, ISupportInitializeNotification } /// Event fired after the has been changed. - public event EventHandler> TitleChanged; + public event EventHandler>? TitleChanged; /// /// Event fired when the is changing. Set to `true` /// to cancel the Title change. /// - public event EventHandler> TitleChanging; + public event EventHandler>? TitleChanging; #endregion } diff --git a/Terminal.Gui/Views/Bar.cs b/Terminal.Gui/Views/Bar.cs index 0871a13f4..d30ced79e 100644 --- a/Terminal.Gui/Views/Bar.cs +++ b/Terminal.Gui/Views/Bar.cs @@ -1,3 +1,4 @@ +#nullable enable namespace Terminal.Gui; /// @@ -43,7 +44,7 @@ public class Bar : View, IOrientation, IDesignable } } - private void Bar_Initialized (object sender, EventArgs e) { ColorScheme = Colors.ColorSchemes ["Menu"]; } + private void Bar_Initialized (object? sender, EventArgs e) { ColorScheme = Colors.ColorSchemes ["Menu"]; } /// public override void SetBorderStyle (LineStyle value) @@ -72,10 +73,10 @@ public class Bar : View, IOrientation, IDesignable } /// - public event EventHandler> OrientationChanging; + public event EventHandler>? OrientationChanging; /// - public event EventHandler> OrientationChanged; + public event EventHandler>? OrientationChanged; /// Called when has changed. /// @@ -132,9 +133,9 @@ public class Bar : View, IOrientation, IDesignable /// Removes a at specified index of . /// The zero-based index of the item to remove. /// The removed. - public Shortcut RemoveShortcut (int index) + public Shortcut? RemoveShortcut (int index) { - View toRemove = null; + View? toRemove = null; for (var i = 0; i < Subviews.Count; i++) { @@ -158,7 +159,7 @@ public class Bar : View, IOrientation, IDesignable { base.OnLayoutStarted (args); - View prevBarItem = null; + View? prevBarItem = null; switch (Orientation) { diff --git a/Terminal.Gui/Views/ColorPicker.cs b/Terminal.Gui/Views/ColorPicker.cs index c9e5afe35..088bc1bb0 100644 --- a/Terminal.Gui/Views/ColorPicker.cs +++ b/Terminal.Gui/Views/ColorPicker.cs @@ -316,7 +316,7 @@ public class ColorPicker : View private void UpdateValueFromTextField (object? sender, HasFocusEventArgs e) { - if (e.NewValue) + if (e.NewValue) { return; } diff --git a/Terminal.Gui/Views/ColorPicker16.cs b/Terminal.Gui/Views/ColorPicker16.cs index a413c8633..7312f113b 100644 --- a/Terminal.Gui/Views/ColorPicker16.cs +++ b/Terminal.Gui/Views/ColorPicker16.cs @@ -51,6 +51,7 @@ public class ColorPicker16 : View } /// Fired when a color is picked. + [CanBeNull] public event EventHandler ColorChanged; /// Cursor for the selected color. diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 3eb67ee99..90512edfd 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -39,6 +39,9 @@ public class TextField : View Used = true; WantMousePositionReports = true; + // By default, disable hotkeys (in case someome sets Title) + HotKeySpecifier = new ('\xffff'); + _historyText.ChangeText += HistoryText_ChangeText; Initialized += TextField_Initialized; diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 8966fa51e..b1ea9de04 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -1997,6 +1997,9 @@ public class TextView : View CursorVisibility = CursorVisibility.Default; Used = true; + // By default, disable hotkeys (in case someome sets Title) + HotKeySpecifier = new ('\xffff'); + _model.LinesLoaded += Model_LinesLoaded!; _historyText.ChangeText += HistoryText_ChangeText!; diff --git a/UICatalog/Scenarios/AdornmentEditor.cs b/UICatalog/Scenarios/AdornmentEditor.cs index 8edd97f96..4a5a7a38d 100644 --- a/UICatalog/Scenarios/AdornmentEditor.cs +++ b/UICatalog/Scenarios/AdornmentEditor.cs @@ -91,7 +91,8 @@ public class AdornmentEditor : View BorderStyle = LineStyle.Dashed; Initialized += AdornmentEditor_Initialized; - TabStop = TabBehavior.TabGroup; + CanFocus = true; + TabStop = TabBehavior.TabStop; } private void AdornmentEditor_Initialized (object sender, EventArgs e) diff --git a/UICatalog/Scenarios/Adornments.cs b/UICatalog/Scenarios/Adornments.cs index 3602e22be..42bd156f0 100644 --- a/UICatalog/Scenarios/Adornments.cs +++ b/UICatalog/Scenarios/Adornments.cs @@ -130,36 +130,13 @@ public class Adornments : Scenario #endif }; - Application.MouseEvent += ApplicationOnMouseEvent; + editor.AutoSelectViewToEdit = true; + editor.AutoSelectSuperView = window; + editor.AutoSelectAdornments = true; Application.Run (app); app.Dispose (); Application.Shutdown (); - - return; - - void ApplicationOnMouseEvent (object sender, MouseEvent e) - { - if (!editor.AutoSelectViewToEdit || editor.FrameToScreen ().Contains (e.Position)) - { - return; - } - - // TODO: Add a setting (property) so only subviews of a specified view are considered. - View view = e.View; - - if (view is { } && e.Flags == MouseFlags.Button1Clicked) - { - if (view is Adornment adornment) - { - editor.ViewToEdit = adornment.Parent; - } - else - { - editor.ViewToEdit = view; - } - } - } } } diff --git a/UICatalog/Scenarios/AdornmentsEditor.cs b/UICatalog/Scenarios/AdornmentsEditor.cs index a86ab70ae..2bfecec0f 100644 --- a/UICatalog/Scenarios/AdornmentsEditor.cs +++ b/UICatalog/Scenarios/AdornmentsEditor.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Text; using Terminal.Gui; @@ -19,31 +20,43 @@ public class AdornmentsEditor : View //SuperViewRendersLineCanvas = true; + CanFocus = true; + TabStop = TabBehavior.TabGroup; Initialized += AdornmentsEditor_Initialized; } private readonly ViewDiagnosticFlags _savedDiagnosticFlags = Diagnostics; - private View _viewToEdit; + private View? _viewToEdit; - private Label _lblView; // Text describing the vi + private Label? _lblView; // Text describing the vi - private MarginEditor _marginEditor; - private BorderEditor _borderEditor; - private PaddingEditor _paddingEditor; + private MarginEditor? _marginEditor; + private BorderEditor? _borderEditor; + private PaddingEditor? _paddingEditor; // TODO: Move Diagnostics to a separate Editor class (DiagnosticsEditor?). - private CheckBox _diagPaddingCheckBox; - private CheckBox _diagRulerCheckBox; + private CheckBox? _diagPaddingCheckBox; + private CheckBox? _diagRulerCheckBox; /// - /// Gets or sets whether the AdornmentsEditor should automatically select the View to edit when the mouse is clicked - /// anywhere outside the editor. + /// Gets or sets whether the AdornmentsEditor should automatically select the View to edit + /// based on the values of and . /// public bool AutoSelectViewToEdit { get; set; } - public View ViewToEdit + /// + /// Gets or sets the View that will scope the behavior of . + /// + public View? AutoSelectSuperView { get; set; } + + /// + /// Gets or sets whether auto select with the mouse will select Adornments or just Views. + /// + public bool AutoSelectAdornments { get; set; } + + public View? ViewToEdit { get => _viewToEdit; set @@ -55,11 +68,66 @@ public class AdornmentsEditor : View _viewToEdit = value; - _marginEditor.AdornmentToEdit = _viewToEdit?.Margin ?? null; - _borderEditor.AdornmentToEdit = _viewToEdit?.Border ?? null; - _paddingEditor.AdornmentToEdit = _viewToEdit?.Padding ?? null; + if (_viewToEdit is not Adornment) + { + _marginEditor!.AdornmentToEdit = _viewToEdit?.Margin ?? null; + _borderEditor!.AdornmentToEdit = _viewToEdit?.Border ?? null; + _paddingEditor!.AdornmentToEdit = _viewToEdit?.Padding ?? null; + } - _lblView.Text = $"{_viewToEdit?.GetType ().Name}: {_viewToEdit?.Id}" ?? string.Empty; + if (_lblView is { }) + { + _lblView.Text = $"{_viewToEdit?.GetType ().Name}: {_viewToEdit?.Id}" ?? string.Empty; + } + } + } + + + private void NavigationOnFocusedChanged (object? sender, EventArgs e) + { + if (AutoSelectSuperView is null) + { + return; + } + + if (ApplicationNavigation.IsInHierarchy (this, Application.Navigation!.GetFocused ())) + { + return; + } + + if (!ApplicationNavigation.IsInHierarchy (AutoSelectSuperView, Application.Navigation!.GetFocused ())) + { + return; + } + + ViewToEdit = Application.Navigation!.GetFocused (); + } + + private void ApplicationOnMouseEvent (object? sender, MouseEvent e) + { + if (e.Flags != MouseFlags.Button1Clicked || !AutoSelectViewToEdit) + { + return; + } + + if ((AutoSelectSuperView is { } && !AutoSelectSuperView.FrameToScreen ().Contains (e.Position)) + || FrameToScreen ().Contains (e.Position)) + { + return; + } + + View view = e.View; + + if (view is { }) + { + if (view is Adornment adornment) + { + ViewToEdit = AutoSelectAdornments ? adornment : adornment.Parent; + } + else + { + ViewToEdit = view; + } } } @@ -70,7 +138,7 @@ public class AdornmentsEditor : View base.Dispose (disposing); } - private void AdornmentsEditor_Initialized (object sender, EventArgs e) + private void AdornmentsEditor_Initialized (object? sender, EventArgs e) { BorderStyle = LineStyle.Dotted; @@ -152,5 +220,8 @@ public class AdornmentsEditor : View Add (_diagRulerCheckBox); _diagRulerCheckBox.Y = Pos.Bottom (_diagPaddingCheckBox); + + Application.MouseEvent += ApplicationOnMouseEvent; + Application.Navigation!.FocusedChanged += NavigationOnFocusedChanged; } } diff --git a/UICatalog/Scenarios/AllViewsTester.cs b/UICatalog/Scenarios/AllViewsTester.cs index ed5d74bf6..368d438d8 100644 --- a/UICatalog/Scenarios/AllViewsTester.cs +++ b/UICatalog/Scenarios/AllViewsTester.cs @@ -68,7 +68,7 @@ public class AllViewsTester : Scenario Y = 0, Width = Dim.Auto (DimAutoStyle.Content), Height = Dim.Fill (), - CanFocus = false, + CanFocus = true, ColorScheme = Colors.ColorSchemes ["TopLevel"], Title = "Classes" }; @@ -84,7 +84,6 @@ public class AllViewsTester : Scenario SelectedItem = 0, Source = new ListWrapper (new (_viewClasses.Keys.ToList ())) }; - _classListView.OpenSelectedItem += (s, a) => { _settingsPane.SetFocus (); }; _classListView.SelectedItemChanged += (s, args) => { @@ -95,10 +94,19 @@ public class AllViewsTester : Scenario _hostPane.Remove (_curView); _curView.Dispose (); _curView = null; - _hostPane.Clear (); } _curView = CreateClass (_viewClasses.Values.ToArray () [_classListView.SelectedItem]); + // Add + _hostPane.Add (_curView); + + // Force ViewToEdit to be the view and not a subview + if (_adornmentsEditor is { }) + { + _adornmentsEditor.AutoSelectSuperView = _curView; + + _adornmentsEditor.ViewToEdit = _curView; + } }; _leftPane.Add (_classListView); @@ -109,7 +117,9 @@ public class AllViewsTester : Scenario Width = Dim.Auto (), Height = Dim.Fill (), ColorScheme = Colors.ColorSchemes ["TopLevel"], - BorderStyle = LineStyle.Single + BorderStyle = LineStyle.Single, + AutoSelectViewToEdit = true, + AutoSelectAdornments = false, }; var expandButton = new ExpanderButton @@ -125,7 +135,7 @@ public class AllViewsTester : Scenario Y = 0, // for menu Width = Dim.Fill (), Height = Dim.Auto (), - CanFocus = false, + CanFocus = true, ColorScheme = Colors.ColorSchemes ["TopLevel"], Title = "Settings" }; @@ -138,7 +148,8 @@ public class AllViewsTester : Scenario Y = 0, Height = Dim.Auto (), Width = Dim.Auto (), - Title = "Location (Pos)" + Title = "Location (Pos)", + TabStop = TabBehavior.TabStop, }; _settingsPane.Add (_locationFrame); @@ -188,7 +199,8 @@ public class AllViewsTester : Scenario Y = Pos.Y (_locationFrame), Height = Dim.Auto (), Width = Dim.Auto (), - Title = "Size (Dim)" + Title = "Size (Dim)", + TabStop = TabBehavior.TabStop, }; radioItems = new [] { "Auto", "_Percent(width)", "_Fill(width)", "A_bsolute(width)" }; @@ -308,12 +320,15 @@ public class AllViewsTester : Scenario Y = Pos.Bottom (_settingsPane), Width = Dim.Fill (), Height = Dim.Fill (), // + 1 for status bar + CanFocus = true, + TabStop = TabBehavior.TabGroup, ColorScheme = Colors.ColorSchemes ["Dialog"] }; app.Add (_leftPane, _adornmentsEditor, _settingsPane, _hostPane); _classListView.SelectedItem = 0; + _leftPane.SetFocus (); Application.Run (app); app.Dispose (); @@ -370,10 +385,6 @@ public class AllViewsTester : Scenario view.Initialized += View_Initialized; - // Add - _hostPane.Add (view); - _hostPane.SetNeedsDisplay (); - return view; } @@ -476,12 +487,8 @@ public class AllViewsTester : Scenario UpdateTitle (_curView); } - private void Quit () { Application.RequestStop (); } - private void UpdateSettings (View view) { - _adornmentsEditor.ViewToEdit = view; - var x = view.X.ToString (); var y = view.Y.ToString (); diff --git a/UICatalog/Scenarios/ContentScrolling.cs b/UICatalog/Scenarios/ContentScrolling.cs index da09d7476..543432a4c 100644 --- a/UICatalog/Scenarios/ContentScrolling.cs +++ b/UICatalog/Scenarios/ContentScrolling.cs @@ -407,35 +407,12 @@ public class ContentScrolling : Scenario app.Closed += (s, e) => View.Diagnostics = _diagnosticFlags; - Application.MouseEvent += ApplicationOnMouseEvent; + editor.AutoSelectViewToEdit = true; + editor.AutoSelectSuperView = view; + editor.AutoSelectAdornments = false; Application.Run (app); app.Dispose (); Application.Shutdown (); - - return; - - void ApplicationOnMouseEvent (object sender, MouseEvent e) - { - if (!editor.AutoSelectViewToEdit || editor.FrameToScreen ().Contains (e.Position)) - { - return; - } - - // TODO: Add a setting (property) so only subviews of a specified view are considered. - View view = e.View; - - if (view is { } && e.Flags == MouseFlags.Button1Clicked) - { - if (view is Adornment adornment) - { - editor.ViewToEdit = adornment.Parent; - } - else - { - editor.ViewToEdit = view; - } - } - } } } diff --git a/UICatalog/Scenarios/Navigation.cs b/UICatalog/Scenarios/Navigation.cs index 64fd5b30b..71be6e285 100644 --- a/UICatalog/Scenarios/Navigation.cs +++ b/UICatalog/Scenarios/Navigation.cs @@ -7,6 +7,8 @@ namespace UICatalog.Scenarios; [ScenarioCategory ("Layout")] public class Navigation : Scenario { + private int _hotkeyCount; + public override void Main () { Application.Init (); @@ -31,7 +33,7 @@ public class Navigation : Scenario Title = "_1 Test Frame", X = Pos.Right (editor), Width = Dim.Fill (), - Height = Dim.Fill (), + Height = Dim.Fill () }; app.Add (testFrame); @@ -40,27 +42,27 @@ public class Navigation : Scenario { X = 0, Y = 0, - Title = $"TopButton _{GetNextHotKey ()}", + Title = $"TopButton _{GetNextHotKey ()}" }; testFrame.Add (button); - var tiledView1 = CreateTiledView (0, 2, 2); - var tiledView2 = CreateTiledView (1, Pos.Right (tiledView1), Pos.Top (tiledView1)); + View tiledView1 = CreateTiledView (0, 2, 2); + View tiledView2 = CreateTiledView (1, Pos.Right (tiledView1), Pos.Top (tiledView1)); testFrame.Add (tiledView1); testFrame.Add (tiledView2); - var tiledView3 = CreateTiledView (1, Pos.Right (tiledView2), Pos.Top (tiledView2)); + View tiledView3 = CreateTiledView (1, Pos.Right (tiledView2), Pos.Top (tiledView2)); tiledView3.TabStop = TabBehavior.TabGroup; tiledView3.BorderStyle = LineStyle.Double; testFrame.Add (tiledView3); - var overlappedView1 = CreateOverlappedView (2, Pos.Center () - 5, Pos.Center ()); - var tiledSubView = CreateTiledView (4, 0, 2); + View overlappedView1 = CreateOverlappedView (2, Pos.Center () - 5, Pos.Center ()); + View tiledSubView = CreateTiledView (4, 0, 2); overlappedView1.Add (tiledSubView); - var overlappedView2 = CreateOverlappedView (3, Pos.Center () + 10, Pos.Center () + 5); + View overlappedView2 = CreateOverlappedView (3, Pos.Center () + 10, Pos.Center () + 5); // BUGBUG: F6 through nested tab groups doesn't work yet. #if NESTED_TABGROUPS @@ -79,59 +81,20 @@ public class Navigation : Scenario { X = Pos.AnchorEnd (), Y = Pos.AnchorEnd (), - Title = $"TopButton _{GetNextHotKey ()}", + Title = $"TopButton _{GetNextHotKey ()}" }; testFrame.Add (button); + editor.AutoSelectSuperView = testFrame; Application.Run (app); app.Dispose (); Application.Shutdown (); } - private int _hotkeyCount; - - private char GetNextHotKey () - { - return (char)((int)'A' + _hotkeyCount++); - } - - private View CreateTiledView (int id, Pos x, Pos y) - { - View overlapped = new View - { - X = x, - Y = y, - Height = Dim.Auto (), - Width = Dim.Auto (), - Title = $"Tiled{id} _{GetNextHotKey ()}", - Id = $"Tiled{id}", - BorderStyle = LineStyle.Single, - CanFocus = true, // Can't drag without this? BUGBUG - TabStop = TabBehavior.TabStop, - Arrangement = ViewArrangement.Fixed - }; - - Button button = new () - { - Title = $"Tiled Button{id} _{GetNextHotKey ()}" - }; - overlapped.Add (button); - - button = new () - { - Y = Pos.Bottom (button), - Title = $"Tiled Button{id} _{GetNextHotKey ()}" - }; - overlapped.Add (button); - - return overlapped; - } - - private View CreateOverlappedView (int id, Pos x, Pos y) { - View overlapped = new View + var overlapped = new View { X = x, Y = y, @@ -162,4 +125,38 @@ public class Navigation : Scenario return overlapped; } + + private View CreateTiledView (int id, Pos x, Pos y) + { + var overlapped = new View + { + X = x, + Y = y, + Height = Dim.Auto (), + Width = Dim.Auto (), + Title = $"Tiled{id} _{GetNextHotKey ()}", + Id = $"Tiled{id}", + BorderStyle = LineStyle.Single, + CanFocus = true, // Can't drag without this? BUGBUG + TabStop = TabBehavior.TabStop, + Arrangement = ViewArrangement.Fixed + }; + + Button button = new () + { + Title = $"Tiled Button{id} _{GetNextHotKey ()}" + }; + overlapped.Add (button); + + button = new () + { + Y = Pos.Bottom (button), + Title = $"Tiled Button{id} _{GetNextHotKey ()}" + }; + overlapped.Add (button); + + return overlapped; + } + + private char GetNextHotKey () { return (char)('A' + _hotkeyCount++); } } diff --git a/UICatalog/Scenarios/NumericUpDownDemo.cs b/UICatalog/Scenarios/NumericUpDownDemo.cs index b514a041a..697916f43 100644 --- a/UICatalog/Scenarios/NumericUpDownDemo.cs +++ b/UICatalog/Scenarios/NumericUpDownDemo.cs @@ -15,7 +15,6 @@ public class NumericUpDownDemo : Scenario Window app = new () { Title = GetQuitKeyAndName (), - TabStop = TabBehavior.TabGroup }; var editor = new AdornmentsEditor @@ -23,7 +22,6 @@ public class NumericUpDownDemo : Scenario X = 0, Y = 0, AutoSelectViewToEdit = true, - TabStop = TabBehavior.NoStop }; app.Add (editor); @@ -50,15 +48,15 @@ public class NumericUpDownDemo : Scenario { floatEditor!.NumericUpDown!.Increment = 0.1F; floatEditor!.NumericUpDown!.Format = "{0:0.0}"; - } + editor.AutoSelectSuperView = app; + intEditor.SetFocus (); + Application.Run (app); app.Dispose (); Application.Shutdown (); - } - } internal class NumericUpDownEditor : View where T : notnull @@ -95,6 +93,7 @@ internal class NumericUpDownEditor : View where T : notnull Width = Dim.Auto (DimAutoStyle.Content); Height = Dim.Auto (DimAutoStyle.Content); TabStop = TabBehavior.TabGroup; + CanFocus = true; Initialized += NumericUpDownEditorInitialized; @@ -184,7 +183,7 @@ internal class NumericUpDownEditor : View where T : notnull // Test format to ensure it's valid _ = string.Format (_format.Text, _value); _numericUpDown.Format = _format.Text; - + _format.ColorScheme = SuperView.ColorScheme; } diff --git a/UICatalog/Scenarios/ProgressBarStyles.cs b/UICatalog/Scenarios/ProgressBarStyles.cs index d863c33c3..54855ce52 100644 --- a/UICatalog/Scenarios/ProgressBarStyles.cs +++ b/UICatalog/Scenarios/ProgressBarStyles.cs @@ -35,7 +35,7 @@ public class ProgressBarStyles : Scenario var editor = new AdornmentsEditor () { - AutoSelectViewToEdit = false + AutoSelectViewToEdit = true }; app.Add (editor); diff --git a/UICatalog/Scenarios/ShadowStyles.cs b/UICatalog/Scenarios/ShadowStyles.cs index dac89d040..4ff949c51 100644 --- a/UICatalog/Scenarios/ShadowStyles.cs +++ b/UICatalog/Scenarios/ShadowStyles.cs @@ -55,36 +55,14 @@ public class ShadowStyles : Scenario }; app.Add (button); - Application.MouseEvent += ApplicationOnMouseEvent; + editor.AutoSelectViewToEdit = true; + editor.AutoSelectSuperView = app; + editor.AutoSelectAdornments = false; Application.Run (app); app.Dispose (); Application.Shutdown (); - return; - - void ApplicationOnMouseEvent (object sender, MouseEvent e) - { - if (!editor.AutoSelectViewToEdit || editor.FrameToScreen ().Contains (e.Position)) - { - return; - } - - // TODO: Add a setting (property) so only subviews of a specified view are considered. - View view = e.View; - - if (view is { } && e.Flags == MouseFlags.Button1Clicked) - { - if (view is Adornment adornment) - { - editor.ViewToEdit = adornment.Parent; - } - else - { - editor.ViewToEdit = view; - } - } - } } } diff --git a/UICatalog/Scenarios/ViewExperiments.cs b/UICatalog/Scenarios/ViewExperiments.cs index 7054b5aa5..00870d0dc 100644 --- a/UICatalog/Scenarios/ViewExperiments.cs +++ b/UICatalog/Scenarios/ViewExperiments.cs @@ -24,7 +24,6 @@ public class ViewExperiments : Scenario { X = 0, Y = 0, - AutoSelectViewToEdit = true, TabStop = TabBehavior.NoStop }; app.Add (editor); @@ -56,9 +55,10 @@ public class ViewExperiments : Scenario }; testFrame.Add (button); - Application.MouseEvent += ApplicationOnMouseEvent; - Application.Navigation.FocusedChanged += NavigationOnFocusedChanged; + editor.AutoSelectViewToEdit = true; + editor.AutoSelectSuperView = testFrame; + editor.AutoSelectAdornments = true; Application.Run (app); app.Dispose (); @@ -66,44 +66,6 @@ public class ViewExperiments : Scenario Application.Shutdown (); return; - - - void NavigationOnFocusedChanged (object sender, EventArgs e) - { - if (!ApplicationNavigation.IsInHierarchy (testFrame, Application.Navigation!.GetFocused ())) - { - return; - } - - editor.ViewToEdit = Application.Navigation!.GetFocused (); - } - void ApplicationOnMouseEvent (object sender, MouseEvent e) - { - if (e.Flags != MouseFlags.Button1Clicked) - { - return; - } - - if (!editor.AutoSelectViewToEdit || !testFrame.FrameToScreen ().Contains (e.Position)) - { - return; - } - - // TODO: Add a setting (property) so only subviews of a specified view are considered. - View view = e.View; - - if (view is { } && e.Flags == MouseFlags.Button1Clicked) - { - if (view is Adornment adornment) - { - editor.ViewToEdit = adornment.Parent; - } - else - { - editor.ViewToEdit = view; - } - } - } } private int _hotkeyCount; @@ -112,71 +74,4 @@ public class ViewExperiments : Scenario { return (char)((int)'A' + _hotkeyCount++); } - - private View CreateTiledView (int id, Pos x, Pos y) - { - View overlapped = new View - { - X = x, - Y = y, - Height = Dim.Auto (), - Width = Dim.Auto (), - Title = $"Tiled{id} _{GetNextHotKey ()}", - Id = $"Tiled{id}", - BorderStyle = LineStyle.Single, - CanFocus = true, // Can't drag without this? BUGBUG - TabStop = TabBehavior.TabGroup, - Arrangement = ViewArrangement.Fixed - }; - - Button button = new () - { - Title = $"Tiled Button{id} _{GetNextHotKey ()}" - }; - overlapped.Add (button); - - button = new () - { - Y = Pos.Bottom (button), - Title = $"Tiled Button{id} _{GetNextHotKey ()}" - }; - overlapped.Add (button); - - return overlapped; - } - - - private View CreateOverlappedView (int id, Pos x, Pos y) - { - View overlapped = new View - { - X = x, - Y = y, - Height = Dim.Auto (), - Width = Dim.Auto (), - Title = $"Overlapped{id} _{GetNextHotKey ()}", - ColorScheme = Colors.ColorSchemes ["Toplevel"], - Id = $"Overlapped{id}", - ShadowStyle = ShadowStyle.Transparent, - BorderStyle = LineStyle.Double, - CanFocus = true, // Can't drag without this? BUGBUG - TabStop = TabBehavior.TabGroup, - Arrangement = ViewArrangement.Movable | ViewArrangement.Overlapped - }; - - Button button = new () - { - Title = $"Button{id} _{GetNextHotKey ()}" - }; - overlapped.Add (button); - - button = new () - { - Y = Pos.Bottom (button), - Title = $"Button{id} _{GetNextHotKey ()}" - }; - overlapped.Add (button); - - return overlapped; - } }