diff --git a/Terminal.Gui/View/ViewDrawing.cs b/Terminal.Gui/View/ViewDrawing.cs index ab8518d1d..22c25c125 100644 --- a/Terminal.Gui/View/ViewDrawing.cs +++ b/Terminal.Gui/View/ViewDrawing.cs @@ -329,13 +329,17 @@ public partial class View public virtual Attribute GetFocusColor () { ColorScheme cs = ColorScheme; - if (ColorScheme is null) { cs = new (); } - return Enabled ? cs.Focus : cs.Disabled; + if (SuperView is {} && SuperView?.Subviews!.Count(s => s.CanFocus) > 1) + { + return Enabled ? cs.Focus : cs.Disabled; + } + + return Enabled ? cs.Normal : cs.Disabled; } /// Determines the current based on the value. diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index 7c5f2b4a3..326e674da 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -380,7 +380,7 @@ public partial class Toplevel : View /// The Toplevel to adjust. public virtual void PositionToplevel (Toplevel top) { - + View superView = GetLocationEnsuringFullVisibility ( top, top.Frame.X, @@ -548,7 +548,7 @@ public partial class Toplevel : View /// to dispose objects after calling . /// public event EventHandler Unloaded; - + internal void AddMenuStatusBar (View view) { if (view is MenuBar) diff --git a/UICatalog/Scenarios/Adornments.cs b/UICatalog/Scenarios/Adornments.cs index 78fed9eab..f1701c4eb 100644 --- a/UICatalog/Scenarios/Adornments.cs +++ b/UICatalog/Scenarios/Adornments.cs @@ -19,7 +19,23 @@ public class Adornments : Scenario _diagnosticFlags = View.Diagnostics; - var view = new Window { Title = "The _Window" }; + Window app = new () + { + Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", + }; + + var editor = new AdornmentsEditor (); + app.Add (editor); + + var window = new Window + { + Title = "The _Window", + X = Pos.Right(editor), + Width = Dim.Percent (60), + Height = Dim.Percent (80), + }; + app.Add (window); + var tf1 = new TextField { Width = 10, Text = "TextField" }; var color = new ColorPicker { Title = "BG", BoxHeight = 1, BoxWidth = 1, X = Pos.AnchorEnd (11) }; color.BorderStyle = LineStyle.RoundedDotted; @@ -38,7 +54,7 @@ public class Adornments : Scenario var button = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Press me!" }; button.Accept += (s, e) => - MessageBox.Query (20, 7, "Hi", $"Am I a {view.GetType ().Name}?", "Yes", "No"); + MessageBox.Query (20, 7, "Hi", $"Am I a {window.GetType ().Name}?", "Yes", "No"); var label = new TextView { @@ -62,14 +78,14 @@ public class Adornments : Scenario Text = "Label\nY=AnchorEnd(3),Height=Dim.Fill()" }; - view.Margin.Data = "Margin"; - view.Margin.Thickness = new (3); + window.Margin.Data = "Margin"; + window.Margin.Thickness = new (3); - view.Border.Data = "Border"; - view.Border.Thickness = new (3); + window.Border.Data = "Border"; + window.Border.Thickness = new (3); - view.Padding.Data = "Padding"; - view.Padding.Thickness = new (3); + window.Padding.Data = "Padding"; + window.Padding.Thickness = new (3); var longLabel = new Label () { @@ -77,31 +93,24 @@ public class Adornments : Scenario }; longLabel.TextFormatter.WordWrap = true; - view.Add (tf1, color, button, label, btnButtonInWindow, tv, longLabel); + window.Add (tf1, color, button, label, btnButtonInWindow, tv, longLabel); - var editor = new AdornmentsEditor - { - Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", - }; - view.Width = Dim.Percent (60); - view.Height = Dim.Percent (80); + editor.Initialized += (s, e) => { editor.ViewToEdit = window; }; - editor.Initialized += (s, e) => { editor.ViewToEdit = view; }; - - view.Initialized += (s, e) => + window.Initialized += (s, e) => { var labelInPadding = new Label () { X = 1, Y = 0, Title = "_Text:" }; - view.Padding.Add (labelInPadding); + window.Padding.Add (labelInPadding); var textFieldInPadding = new TextField () { X = Pos.Right (labelInPadding) + 1, Y = Pos.Top (labelInPadding), Width = 15, Text = "some text" }; textFieldInPadding.Accept += (s, e) => MessageBox.Query (20, 7, "TextField", textFieldInPadding.Text, "Ok"); - view.Padding.Add (textFieldInPadding); + window.Padding.Add (textFieldInPadding); var btnButtonInPadding = new Button { X = Pos.Center (), Y = 0, Text = "_Button in Padding" }; btnButtonInPadding.Accept += (s, e) => MessageBox.Query (20, 7, "Hi", "Button in Padding Pressed!", "Ok"); btnButtonInPadding.BorderStyle = LineStyle.Dashed; btnButtonInPadding.Border.Thickness = new (1, 1, 1, 1); - view.Padding.Add (btnButtonInPadding); + window.Padding.Add (btnButtonInPadding); #if SUBVIEW_BASED_BORDER btnButtonInPadding.Border.CloseButton.Visible = true; @@ -117,10 +126,10 @@ public class Adornments : Scenario #endif }; - editor.Closed += (s, e) => View.Diagnostics = _diagnosticFlags; + app.Closed += (s, e) => View.Diagnostics = _diagnosticFlags; - Application.Run (editor); - editor.Dispose (); + Application.Run (app); + app.Dispose (); Application.Shutdown (); } @@ -329,7 +338,7 @@ public class Adornments : Scenario /// /// Provides an editor UI for the Margin, Border, and Padding of a View. /// - public class AdornmentsEditor : Window + public class AdornmentsEditor : View { private AdornmentEditor _borderEditor; private CheckBox _diagCheckBox; @@ -341,6 +350,10 @@ public class Adornments : Scenario public AdornmentsEditor () { ColorScheme = Colors.ColorSchemes ["Dialog"]; + + // TOOD: Use Dim.Auto + Width = 36; + Height = Dim.Fill (); } public View ViewToEdit @@ -473,9 +486,6 @@ public class Adornments : Scenario }; Add (_diagCheckBox); - _viewToEdit.X = Pos.Right (rbBorderStyle); - _viewToEdit.Y = 0; - Add (_viewToEdit); _viewToEdit.LayoutComplete += (s, e) => { diff --git a/UICatalog/Scenarios/ContentScrolling.cs b/UICatalog/Scenarios/ContentScrolling.cs index b7763b6e1..67f61d3c8 100644 --- a/UICatalog/Scenarios/ContentScrolling.cs +++ b/UICatalog/Scenarios/ContentScrolling.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Linq; using Terminal.Gui; +using static UICatalog.Scenarios.Adornments; namespace UICatalog.Scenarios; @@ -100,7 +101,22 @@ public class ContentScrolling : Scenario _diagnosticFlags = View.Diagnostics; - var view = new ScrollingDemoView { Title = "Demo View" }; + Window app = new () + { + Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", + }; + + var editor = new AdornmentsEditor (); + app.Add (editor); + + var view = new ScrollingDemoView + { + Title = "Demo View", + X = Pos.Right(editor), + Width = Dim.Fill (), + Height = Dim.Fill () + }; + app.Add (view); // Add Scroll Setting UI to Padding view.Padding.Thickness = new (0, 3, 0, 0); @@ -375,18 +391,12 @@ public class ContentScrolling : Scenario longLabel.TextFormatter.WordWrap = true; view.Add (longLabel); - var editor = new Adornments.AdornmentsEditor - { - Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", - ColorScheme = Colors.ColorSchemes ["Dialog"] - }; - editor.Initialized += (s, e) => { editor.ViewToEdit = view; }; - editor.Closed += (s, e) => View.Diagnostics = _diagnosticFlags; + app.Closed += (s, e) => View.Diagnostics = _diagnosticFlags; - Application.Run (editor); - editor.Dispose (); + Application.Run (app); + app.Dispose (); Application.Shutdown (); } } diff --git a/UICatalog/Scenarios/ProgressBarStyles.cs b/UICatalog/Scenarios/ProgressBarStyles.cs index 64ed242af..8e0a8a410 100644 --- a/UICatalog/Scenarios/ProgressBarStyles.cs +++ b/UICatalog/Scenarios/ProgressBarStyles.cs @@ -20,20 +20,30 @@ public class ProgressBarStyles : Scenario private const uint _timerTick = 20; private Timer _fractionTimer; private Timer _pulseTimer; + private ViewDiagnosticFlags _diagnosticFlags; - public override void Init () + public override void Main () { Application.Init (); - ConfigurationManager.Themes.Theme = Theme; - ConfigurationManager.Apply (); - Top = new (); + _diagnosticFlags = View.Diagnostics; - var editor = new AdornmentsEditor + Window app = new () { - Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", BorderStyle = LineStyle.Single + Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", BorderStyle = LineStyle.Single, }; - editor.ColorScheme = Colors.ColorSchemes [TopLevelColorScheme]; + + var editor = new AdornmentsEditor (); + app.Add (editor); + + View container = new () + { + X = Pos.Right (editor), + Y = 0, + Width = Dim.Fill (), + Height = Dim.Fill (), + }; + app.Add (container); const float fractionStep = 0.01F; @@ -47,16 +57,7 @@ public class ProgressBarStyles : Scenario BorderStyle = LineStyle.Single }; - pbList.SelectedItemChanged += (sender, e) => - { - editor.ViewToEdit = editor.Subviews.First ( - v => - v.GetType () == typeof (ProgressBar) - && v.Title == (string)e.Value - ); - }; - editor.Add (pbList); - pbList.SelectedItem = 0; + container.Add (pbList); #region ColorPicker @@ -80,7 +81,7 @@ public class ProgressBarStyles : Scenario Width = colorPicker.Frame.Width, Height = colorPicker.Frame.Height }; - Application.Top.LayoutSubviews(); + Application.Top.LayoutSubviews (); }; dialog.Add (colorPicker); @@ -98,7 +99,7 @@ public class ProgressBarStyles : Scenario { Text = "Foreground HotNormal Color", X = Pos.Center (), Y = Pos.Bottom (pbList) }; - editor.Add (fgColorPickerBtn); + container.Add (fgColorPickerBtn); fgColorPickerBtn.Accept += (s, e) => { @@ -123,7 +124,7 @@ public class ProgressBarStyles : Scenario { X = Pos.Center (), Y = Pos.Bottom (fgColorPickerBtn), Text = "Background HotNormal Color" }; - editor.Add (bgColorPickerBtn); + container.Add (bgColorPickerBtn); bgColorPickerBtn.Accept += (s, e) => { @@ -157,11 +158,10 @@ public class ProgressBarStyles : Scenario Y = Pos.Bottom (bgColorPickerBtn) + 1, RadioLabels = pbFormatEnum.Select (e => e.ToString ()).ToArray () }; - editor.Add (rbPBFormat); + container.Add (rbPBFormat); var button = new Button { X = Pos.Center (), Y = Pos.Bottom (rbPBFormat) + 1, Text = "Start timer" }; - - editor.Add (button); + container.Add (button); var blocksPB = new ProgressBar { @@ -172,7 +172,7 @@ public class ProgressBarStyles : Scenario BorderStyle = LineStyle.Single, CanFocus = true }; - editor.Add (blocksPB); + container.Add (blocksPB); var continuousPB = new ProgressBar { @@ -184,7 +184,7 @@ public class ProgressBarStyles : Scenario BorderStyle = LineStyle.Single, CanFocus = true }; - editor.Add (continuousPB); + container.Add (continuousPB); button.Accept += (s, e) => { @@ -222,7 +222,7 @@ public class ProgressBarStyles : Scenario { X = Pos.Center (), Y = Pos.Bottom (continuousPB) + 1, Text = "BidirectionalMarquee", Checked = true }; - editor.Add (ckbBidirectional); + container.Add (ckbBidirectional); var marqueesBlocksPB = new ProgressBar { @@ -234,7 +234,7 @@ public class ProgressBarStyles : Scenario BorderStyle = LineStyle.Single, CanFocus = true }; - editor.Add (marqueesBlocksPB); + container.Add (marqueesBlocksPB); var marqueesContinuousPB = new ProgressBar { @@ -246,13 +246,22 @@ public class ProgressBarStyles : Scenario BorderStyle = LineStyle.Single, CanFocus = true }; - editor.Add (marqueesContinuousPB); + container.Add (marqueesContinuousPB); pbList.SetSource ( - editor.Subviews.Where (v => v.GetType () == typeof (ProgressBar)) - .Select (v => v.Title) - .ToList () + container.Subviews.Where (v => v.GetType () == typeof (ProgressBar)) + .Select (v => v.Title) + .ToList () ); + + pbList.SelectedItemChanged += (sender, e) => + { + editor.ViewToEdit = container.Subviews.First ( + v => + v.GetType () == typeof (ProgressBar) + && v.Title == (string)e.Value + ); + }; pbList.SelectedItem = 0; rbPBFormat.SelectedItemChanged += (s, e) => @@ -272,8 +281,7 @@ public class ProgressBarStyles : Scenario _pulseTimer = new Timer ( _ => { - marqueesBlocksPB.Text = - marqueesContinuousPB.Text = DateTime.Now.TimeOfDay.ToString (); + marqueesBlocksPB.Text = marqueesContinuousPB.Text = DateTime.Now.TimeOfDay.ToString (); marqueesBlocksPB.Pulse (); marqueesContinuousPB.Pulse (); Application.Wakeup (); @@ -283,9 +291,15 @@ public class ProgressBarStyles : Scenario 300 ); - Top.Unloaded += Top_Unloaded; + app.Unloaded += App_Unloaded; - void Top_Unloaded (object sender, EventArgs args) + Application.Run (app); + app.Dispose (); + Application.Shutdown (); + + return; + + void App_Unloaded (object sender, EventArgs args) { if (_fractionTimer != null) { @@ -299,13 +313,7 @@ public class ProgressBarStyles : Scenario _pulseTimer = null; } - Top.Unloaded -= Top_Unloaded; + app.Unloaded -= App_Unloaded; } - - Application.Run (editor); - editor.Dispose (); - Application.Shutdown (); } - - public override void Run () { } } diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 38be22735..166e55f7c 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -345,6 +345,7 @@ internal class UICatalogApp // 'app' closed cleanly. foreach (Responder? inst in Responder.Instances) { + Debug.Assert (inst.WasDisposed); }