From f02ca8abc0bcbf59a85fb0da0d6d2fd2215d9ea1 Mon Sep 17 00:00:00 2001 From: Tig Date: Thu, 13 Jun 2024 08:52:55 -0700 Subject: [PATCH] Added horizontal scenario stuff --- Terminal.Gui/Input/CommandContext.cs | 5 +- Terminal.Gui/View/Layout/Pos.cs | 18 ++ Terminal.Gui/View/Layout/PosAlign.cs | 103 +++++------ Terminal.Gui/Views/ColorPicker.cs | 2 +- Terminal.Gui/Views/Shortcut.cs | 91 +++++---- UICatalog/Scenarios/Shortcuts.cs | 266 ++++++++++++++++++++------- 6 files changed, 334 insertions(+), 151 deletions(-) diff --git a/Terminal.Gui/Input/CommandContext.cs b/Terminal.Gui/Input/CommandContext.cs index 5d3269226..555b179c8 100644 --- a/Terminal.Gui/Input/CommandContext.cs +++ b/Terminal.Gui/Input/CommandContext.cs @@ -1,14 +1,17 @@ #nullable enable namespace Terminal.Gui; + +#pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved /// /// Provides context for a that is being invoked. /// /// /// To define a that is invoked with context, -/// use +/// use . /// /// +#pragma warning restore CS1574 // XML comment has cref attribute that could not be resolved public record struct CommandContext { /// diff --git a/Terminal.Gui/View/Layout/Pos.cs b/Terminal.Gui/View/Layout/Pos.cs index a5cf52249..f6966e64f 100644 --- a/Terminal.Gui/View/Layout/Pos.cs +++ b/Terminal.Gui/View/Layout/Pos.cs @@ -336,6 +336,24 @@ public abstract class Pos /// internal virtual bool ReferencesOtherViews () { return false; } + public bool Has (Type type, out Pos pos) + { + pos = this; + if (type == GetType()) + { + return true; + } + + // If we are a PosCombine, we have to check the left and right + // to see if they are of the type we are looking for. + if (this is PosCombine { } combine && (combine.Left.Has (type, out pos) || combine.Right.Has (type, out pos))) + { + return true; + } + + return false; + } + #endregion virtual methods #region operators diff --git a/Terminal.Gui/View/Layout/PosAlign.cs b/Terminal.Gui/View/Layout/PosAlign.cs index 306017d65..79e22d410 100644 --- a/Terminal.Gui/View/Layout/PosAlign.cs +++ b/Terminal.Gui/View/Layout/PosAlign.cs @@ -70,59 +70,67 @@ public class PosAlign : Pos List dimensionsList = new (); // PERF: If this proves a perf issue, consider caching a ref to this list in each item - List viewsInGroup = views.Where ( - v => - { - return dimension switch - { - Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, - Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, - _ => false - }; - }) - .ToList (); + List posAligns = views.Select ( + v => + { + switch (dimension) + { + case Dimension.Width when v.X.Has (typeof (PosAlign), out var pos): - if (viewsInGroup.Count == 0) - { - return; - } + if (pos is PosAlign posAlignX && posAlignX.GroupId == groupId) + { + return posAlignX; + } + + break; + case Dimension.Height when v.Y.Has (typeof (PosAlign), out var pos): + if (pos is PosAlign posAlignY && posAlignY.GroupId == groupId) + { + return posAlignY; + } + + break; + } + + return null; + }) + .ToList (); // PERF: We iterate over viewsInGroup multiple times here. Aligner? firstInGroup = null; // Update the dimensionList with the sizes of the views - for (var index = 0; index < viewsInGroup.Count; index++) + for (var index = 0; index < posAligns.Count; index++) { - View view = viewsInGroup [index]; - PosAlign? posAlign = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign; - - if (posAlign is { }) + if (posAligns [index] is { }) { - if (index == 0) + if (firstInGroup is null) { - firstInGroup = posAlign.Aligner; + firstInGroup = posAligns [index]!.Aligner; } - dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height); + dimensionsList.Add (dimension == Dimension.Width ? views [index].Frame.Width : views [index].Frame.Height); } } + if (firstInGroup is null) + { + return; + } + // Update the first item in the group with the new container size. - firstInGroup!.ContainerSize = size; + firstInGroup.ContainerSize = size; // Align int [] locations = firstInGroup.Align (dimensionsList.ToArray ()); // Update the cached location for each item - for (var index = 0; index < viewsInGroup.Count; index++) + for (int posIndex = 0, locIndex = 0; posIndex < posAligns.Count; posIndex++) { - View view = viewsInGroup [index]; - PosAlign? align = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign; - - if (align is { }) + if (posAligns [posIndex] is { }) { - align._cachedLocation = locations [index]; + posAligns [posIndex]!._cachedLocation = locations [locIndex++]; } } } @@ -168,6 +176,14 @@ public class PosAlign : Pos return 0; } + // TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this. + /// + /// Returns the minimum size a group of views with the same can be. + /// + /// + /// + /// + /// public static int CalculateMinDimension (int groupId, IList views, Dimension dimension) { List dimensionsList = new (); @@ -177,11 +193,11 @@ public class PosAlign : Pos v => { return dimension switch - { - Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, - Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, - _ => false - }; + { + Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, + Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, + _ => false + }; }) .ToList (); @@ -192,8 +208,6 @@ public class PosAlign : Pos // PERF: We iterate over viewsInGroup multiple times here. - Aligner? firstInGroup = null; - // Update the dimensionList with the sizes of the views for (var index = 0; index < viewsInGroup.Count; index++) { @@ -203,26 +217,11 @@ public class PosAlign : Pos if (posAlign is { }) { - if (index == 0) - { - firstInGroup = posAlign.Aligner; - - //if (!posAlign._cachedLocation.HasValue) - //{ - // AlignAndUpdateGroup (groupId, viewsInGroup, dimension, firstInGroup.ContainerSize ); - //} - - } - dimensionsList.Add (dimension == Dimension.Width ? view.Frame.Width : view.Frame.Height); } } // Align - var aligner = firstInGroup; - aligner.ContainerSize = dimensionsList.Sum(); - int [] locations = aligner.Align (dimensionsList.ToArray ()); - return dimensionsList.Sum (); } } diff --git a/Terminal.Gui/Views/ColorPicker.cs b/Terminal.Gui/Views/ColorPicker.cs index addf7a1a4..c033cb4f0 100644 --- a/Terminal.Gui/Views/ColorPicker.cs +++ b/Terminal.Gui/Views/ColorPicker.cs @@ -48,7 +48,7 @@ public class ColorPicker : View private void ColorPicker_MouseClick (object sender, MouseEventEventArgs me) { - if (CanFocus) + // if (CanFocus) { Cursor = new Point (me.MouseEvent.Position.X / _boxWidth, me.MouseEvent.Position.Y / _boxHeight); SetFocus (); diff --git a/Terminal.Gui/Views/Shortcut.cs b/Terminal.Gui/Views/Shortcut.cs index 296932398..1dfabeb86 100644 --- a/Terminal.Gui/Views/Shortcut.cs +++ b/Terminal.Gui/Views/Shortcut.cs @@ -27,8 +27,7 @@ namespace Terminal.Gui; /// right side. /// /// -/// The command text can be set by setting the 's Text property or by setting -/// . +/// The command text can be set by setting the 's Text property. /// /// /// The help text can be set by setting the property or by setting . @@ -59,27 +58,31 @@ public class Shortcut : View TitleChanged += Shortcut_TitleChanged; // This needs to be set before CommandView is set - CommandView = new (); + CommandView = new () + { + Width = Dim.Auto (), + Height = Dim.Auto (), + }; HelpView.Id = "_helpView"; HelpView.CanFocus = false; SetHelpViewDefaultLayout (); Add (HelpView); - HelpView.MouseClick += Shortcut_MouseClick; KeyView.Id = "_keyView"; KeyView.CanFocus = false; SetKeyViewDefaultLayout (); Add (KeyView); + // If the user clicks anywhere on the Shortcut, other than the CommandView, invoke the Command + MouseClick += Shortcut_MouseClick; + HelpView.MouseClick += Shortcut_MouseClick; KeyView.MouseClick += Shortcut_MouseClick; - MouseClick += Shortcut_MouseClick; + LayoutStarted += OnLayoutStarted; Initialized += OnInitialized; - LayoutStarted += OnLayoutStarted; - return; void OnInitialized (object sender, EventArgs e) @@ -111,10 +114,19 @@ public class Shortcut : View // Helper to set Width consistently Dim GetWidthDimAuto () { + // TODO: PosAlign.CalculateMinDimension is a hack. Need to figure out a better way of doing this. return Dim.Auto (DimAutoStyle.Content, maximumContentDim: Dim.Func (() => PosAlign.CalculateMinDimension (0, Subviews, Dimension.Width))); } } + + /// + /// Gets or sets the for this . The default is + /// , which is ideal for status bars and toolbars. If set to , + /// the Shortcut will be configured for vertical layout, which is ideal for menus. + /// + public Orientation Orientation { get; set; } = Orientation.Horizontal; + // When one of the subviews is "empty" we don't want to show it. So we // Use Add/Remove. We need to be careful to add them in the right order // so Pos.Align works correctly. @@ -122,7 +134,7 @@ public class Shortcut : View { RemoveAll (); - if (!string.IsNullOrEmpty (CommandView.Text)) + if (CommandView.Visible) { Add (CommandView); } @@ -161,7 +173,7 @@ public class Shortcut : View if (currentWidth < _minimumDimAutoWidth) { int delta = _minimumDimAutoWidth.Value - currentWidth; - int maxHelpWidth = int.Max (0, HelpView.Text.GetColumns () + 2 - delta); + int maxHelpWidth = int.Max (0, HelpView.Text.GetColumns () + Margin.Thickness.Horizontal - delta); switch (maxHelpWidth) { @@ -180,13 +192,14 @@ public class Shortcut : View case 2: // Scrunch just the right margin - HelpView.Margin.Thickness = new (1, 0, 0, 0); + var t = GetMarginThickness (); + HelpView.Margin.Thickness = new (t.Right, t.Top, t.Left - 1, t.Bottom); break; default: // Default margin - HelpView.Margin.Thickness = new (1, 0, 1, 0); + HelpView.Margin.Thickness = GetMarginThickness (); break; } @@ -208,6 +221,18 @@ public class Shortcut : View } } + private Thickness GetMarginThickness () + { + if (Orientation == Orientation.Vertical) + { + return new Thickness (1, 0, 1, 0); + } + else + { + return new Thickness (1, 0, 1, 0); + } + } + private Color? _savedForeColor; private void Shortcut_Highlight (object sender, HighlightEventArgs e) @@ -339,18 +364,26 @@ public class Shortcut : View // TODO: Determine if it makes sense to allow the CommandView to be focusable. // Right now, we don't set CanFocus to false here. - _commandView.CanFocus = false; + //_commandView.CanFocus = true; + + //// Bar will set the width of all CommandViews to the width of the widest CommandViews. + ////if (_commandView.Width == Dim.Absolute(0)) + //{ + // _commandView.Width = Dim.Auto (); + //} + + ////if (_commandView.Height == Dim.Absolute (0)) + //{ + // _commandView.Height = Dim.Auto (); + //} - // Bar will set the width of all CommandViews to the width of the widest CommandViews. - _commandView.Width = Dim.Auto (); - _commandView.Height = Dim.Auto (); _commandView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast); _commandView.Y = 0; //Pos.Center (); _commandView.MouseClick += Shortcut_MouseClick; _commandView.Accept += CommandViewAccept; - _commandView.Margin.Thickness = new (1, 0, 1, 0); + _commandView.Margin.Thickness = GetMarginThickness (); _commandView.HotKeyChanged += (s, e) => { @@ -364,7 +397,6 @@ public class Shortcut : View _commandView.HotKeySpecifier = new ('_'); Title = _commandView.Text; - _commandView.TextChanged += CommandViewTextChanged; SetHelpViewDefaultLayout (); SetKeyViewDefaultLayout (); @@ -373,8 +405,6 @@ public class Shortcut : View return; - void CommandViewMouseEvent (object sender, MouseEventEventArgs e) { e.Handled = true; } - void CommandViewTextChanged (object sender, StateEventArgs e) { Title = _commandView.Text; @@ -417,11 +447,12 @@ public class Shortcut : View private void SetHelpViewDefaultLayout () { - HelpView.Margin.Thickness = new (1, 0, 1, 0); + HelpView.Margin.Thickness = GetMarginThickness (); HelpView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast); HelpView.Y = 0; //Pos.Center (), HelpView.Width = Dim.Auto (DimAutoStyle.Text); - HelpView.Height = Dim.Height (CommandView); + HelpView.Height = CommandView?.IsAdded == true ? Dim.Height (CommandView) : 1; + HelpView.Visible = true; HelpView.VerticalTextAlignment = Alignment.Center; } @@ -537,12 +568,12 @@ public class Shortcut : View private void SetKeyViewDefaultLayout () { - KeyView.Margin.Thickness = new (1, 0, 1, 0); + KeyView.Margin.Thickness = GetMarginThickness(); KeyView.X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast); - //KeyView.Y = Pos.Center (); KeyView.Width = Dim.Auto (DimAutoStyle.Text, Dim.Func (GetMinimumKeyViewSize)); - KeyView.Height = Dim.Height (CommandView); + KeyView.Height = CommandView?.IsAdded == true ? Dim.Height (CommandView) : 1; + KeyView.Visible = true; // Right align the text in the keyview @@ -582,6 +613,7 @@ public class Shortcut : View switch (KeyBindingScope) { case KeyBindingScope.Application: + handled = false; break; case KeyBindingScope.Focused: @@ -663,18 +695,9 @@ public class Shortcut : View /// public override bool OnLeave (View view) { + // Reset the color scheme (to SuperView). ColorScheme = null; - return base.OnLeave (view); - if (SuperView is { }) - { - ColorScheme = new (SuperView?.ColorScheme) - { - Normal = SuperView.ColorScheme.Normal, - HotNormal = SuperView.ColorScheme.HotNormal - }; - } - return base.OnLeave (view); } diff --git a/UICatalog/Scenarios/Shortcuts.cs b/UICatalog/Scenarios/Shortcuts.cs index 9bcc7426f..e232f47fe 100644 --- a/UICatalog/Scenarios/Shortcuts.cs +++ b/UICatalog/Scenarios/Shortcuts.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Timers; using Terminal.Gui; namespace UICatalog.Scenarios; @@ -34,15 +35,16 @@ public class Shortcuts : Scenario { X = Pos.AnchorEnd (), Width = 40, - Height = Dim.Fill (), + Height = Dim.Fill (4), ColorScheme = Colors.ColorSchemes ["Toplevel"], Source = new ListWrapper (eventSource) }; Application.Top.Add (eventLog); - var shortcut1 = new Shortcut + var vShortcut1 = new Shortcut { - X = 20, + Orientation = Orientation.Vertical, + X = 0, Width = 35, Title = "A_pp Shortcut", Key = Key.F1, @@ -50,14 +52,15 @@ public class Shortcuts : Scenario KeyBindingScope = KeyBindingScope.Application, BorderStyle = LineStyle.Dotted }; - shortcut1.Border.Thickness = new (1, 1, 1, 1); - Application.Top.Add (shortcut1); + vShortcut1.Border.Thickness = new (1, 1, 1, 1); + Application.Top.Add (vShortcut1); - var shortcut2 = new Shortcut + var vShortcut2 = new Shortcut { - X = 20, - Y = Pos.Bottom (shortcut1) - 1, - Width = Dim.Width (shortcut1), + Orientation = Orientation.Vertical, + X = 0, + Y = Pos.Bottom (vShortcut1) - 1, + Width = Dim.Width (vShortcut1), Key = Key.F2, Text = "Width is ^", KeyBindingScope = KeyBindingScope.HotKey, @@ -69,71 +72,73 @@ public class Shortcuts : Scenario } }; - ((RadioGroup)shortcut2.CommandView).SelectedItemChanged += (o, args) => + ((RadioGroup)vShortcut2.CommandView).SelectedItemChanged += (o, args) => { eventSource.Add ($"SelectedItemChanged: {o.GetType ().Name} - {args.SelectedItem}"); eventLog.MoveDown (); }; - shortcut2.Accept += (o, args) => + vShortcut2.Accept += (o, args) => { // Cycle to next item. If at end, set 0 - if (((RadioGroup)shortcut2.CommandView).SelectedItem < ((RadioGroup)shortcut2.CommandView).RadioLabels.Length - 1) + if (((RadioGroup)vShortcut2.CommandView).SelectedItem < ((RadioGroup)vShortcut2.CommandView).RadioLabels.Length - 1) { - ((RadioGroup)shortcut2.CommandView).SelectedItem++; + ((RadioGroup)vShortcut2.CommandView).SelectedItem++; } else { - ((RadioGroup)shortcut2.CommandView).SelectedItem = 0; + ((RadioGroup)vShortcut2.CommandView).SelectedItem = 0; } }; - shortcut2.Border.Thickness = new (1, 1, 1, 1); - Application.Top.Add (shortcut2); + vShortcut2.Border.Thickness = new (1, 1, 1, 1); + Application.Top.Add (vShortcut2); - var shortcut3 = new Shortcut + var vShortcut3 = new Shortcut { - X = 20, - Y = Pos.Bottom (shortcut2), + Orientation = Orientation.Vertical, + X = 0, + Y = Pos.Bottom (vShortcut2), CommandView = new CheckBox { Text = "_Align" }, Key = Key.F3, HelpText = "Width is Fill", Width = Dim.Fill () - Dim.Width (eventLog), KeyBindingScope = KeyBindingScope.HotKey, - BorderStyle = LineStyle.Dotted + BorderStyle = LineStyle.Rounded }; - shortcut3.CommandView.CanFocus = true; - shortcut3.Border.Thickness = new (1, 1, 1, 0); + vShortcut3.Border.Thickness = new (1, 1, 1, 0); - ((CheckBox)shortcut3.CommandView).Toggled += (s, e) => + ((CheckBox)vShortcut3.CommandView).Toggled += (s, e) => { - if (shortcut3.CommandView is CheckBox cb) + if (vShortcut3.CommandView is CheckBox cb) { eventSource.Add ($"Toggled: {cb.Text}"); eventLog.MoveDown (); var max = 0; + var toAlign = Application.Top.Subviews.Where (v => v is Shortcut s && s.Orientation == Orientation.Vertical && s.BorderStyle == LineStyle.Rounded); if (e.NewValue == true) { - foreach (Shortcut peer in Application.Top.Subviews.Where (v => v is Shortcut)!) + foreach (Shortcut peer in toAlign) { max = Math.Max (max, peer.KeyView.Text.GetColumns ()); } } - foreach (Shortcut peer in Application.Top.Subviews.Where (v => v is Shortcut)!) + foreach (Shortcut peer in toAlign) { peer.MinimumKeyViewSize = max; } } }; - Application.Top.Add (shortcut3); + Application.Top.Add (vShortcut3); - var shortcut4 = new Shortcut + var vShortcut4 = new Shortcut { - X = 20, - Y = Pos.Bottom (shortcut3), - Width = Dim.Width (shortcut3), + Orientation = Orientation.Vertical, + X = 0, + Y = Pos.Bottom (vShortcut3), + Width = Dim.Width (vShortcut3), CommandView = new Button { Title = "B_utton", @@ -141,41 +146,56 @@ public class Shortcuts : Scenario HelpText = "Width is Fill", Key = Key.K, KeyBindingScope = KeyBindingScope.HotKey, - BorderStyle = LineStyle.Dotted + BorderStyle = LineStyle.Rounded }; - Button button = (Button)shortcut4.CommandView; - shortcut4.CommandView.Accept += Button_Clicked; - shortcut4.CommandView.CanFocus = true; - shortcut4.Border.Thickness = new (1, 0, 1,0); + Button button = (Button)vShortcut4.CommandView; + vShortcut4.CommandView.Accept += Button_Clicked; + vShortcut4.Border.Thickness = new (1, 0, 1, 0); - Application.Top.Add (shortcut4); + Application.Top.Add (vShortcut4); - var shortcut5 = new Shortcut + var vShortcut5 = new Shortcut { - X = 20, - Y = Pos.Bottom (shortcut4) , - Width = Dim.Width (shortcut4), + Orientation = Orientation.Vertical, + X = 0, + Y = Pos.Bottom (vShortcut4), + Width = Dim.Width (vShortcut4), - Title = "Fi_ve", Key = Key.F5.WithCtrl.WithAlt.WithShift, - HelpText = "Width is Fill", + HelpText = "CommandView.CanFocus", KeyBindingScope = KeyBindingScope.HotKey, - BorderStyle = LineStyle.Dotted + BorderStyle = LineStyle.Rounded, + CommandView = new CheckBox { Text = "_CanFocus" }, }; - shortcut5.Border.Thickness = new (1, 0, 1, 1); + vShortcut5.Border.Thickness = new (1, 0, 1, 1); - Application.Top.Add (shortcut5); + ((CheckBox)vShortcut5.CommandView).Toggled += (s, e) => + { + if (vShortcut5.CommandView is CheckBox cb) + { + eventSource.Add ($"Toggled: {cb.Text}"); + eventLog.MoveDown (); - var shortcutSlider = new Shortcut + foreach (Shortcut peer in Application.Top.Subviews.Where (v => v is Shortcut)!) + { + peer.CanFocus = e.NewValue == true; + peer.CommandView.CanFocus = e.NewValue == true; + } + } + }; + Application.Top.Add (vShortcut5); + + var vShortcutSlider = new Shortcut { - X = 20, - Y = Pos.Bottom (shortcut5) - 1, + Orientation = Orientation.Vertical, + X = 0, + Y = Pos.Bottom (vShortcut5) - 1, Key = Key.F5, HelpText = "Width is Fill", - Width = Dim.Width (shortcut5), + Width = Dim.Width (vShortcut5), KeyBindingScope = KeyBindingScope.HotKey, - BorderStyle = LineStyle.Dotted, + BorderStyle = LineStyle.Rounded, CommandView = new Slider { Orientation = Orientation.Vertical, @@ -183,31 +203,151 @@ public class Shortcuts : Scenario } }; - ((Slider)shortcutSlider.CommandView).Options = new () { new () { Legend = "A" }, new () { Legend = "B" }, new () { Legend = "C" } }; - ((Slider)shortcutSlider.CommandView).SetOption (0); - shortcutSlider.Border.Thickness = new (1, 1, 1, 1); + ((Slider)vShortcutSlider.CommandView).Options = new () { new () { Legend = "A" }, new () { Legend = "B" }, new () { Legend = "C" } }; + ((Slider)vShortcutSlider.CommandView).SetOption (0); + vShortcutSlider.Border.Thickness = new (1, 1, 1, 1); - ((Slider)shortcutSlider.CommandView).OptionsChanged += (o, args) => + ((Slider)vShortcutSlider.CommandView).OptionsChanged += (o, args) => { eventSource.Add ($"OptionsChanged: {o.GetType ().Name} - {args.Options}"); eventLog.MoveDown (); }; - Application.Top.Add (shortcutSlider); + Application.Top.Add (vShortcutSlider); - var shortcut6 = new Shortcut + var vShortcut6 = new Shortcut { - X = 20, - Y = Pos.Bottom (shortcutSlider) - 1, - Width = Dim.Width (shortcutSlider), + Orientation = Orientation.Vertical, + X = 0, + Y = Pos.Bottom (vShortcutSlider) - 1, + Width = Dim.Width (vShortcutSlider), Title = "_No Key", HelpText = "Keyless", - BorderStyle = LineStyle.Dotted + BorderStyle = LineStyle.Rounded }; - shortcut6.Border.Thickness = new (1, 1, 1, 1); + vShortcut6.Border.Thickness = new (1, 1, 1, 1); + + Application.Top.Add (vShortcut6); + + ((CheckBox)vShortcut3.CommandView).OnToggled(); + + // Horizontal + var hShortcut1 = new Shortcut + { + X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1), + Y = Pos.Bottom (eventLog) + 1, + Key = Key.F7, + HelpText = "Horizontal", + BorderStyle = LineStyle.Dashed, + CanFocus = false + }; + hShortcut1.Border.Thickness = new (0, 0, 1, 0); + + hShortcut1.CommandView = new ProgressBar + { + Text = "Progress", + Title = "P", + Fraction = 0.5f, + Width = 10, + Height = 1, + ProgressBarStyle = ProgressBarStyle.Continuous + }; + hShortcut1.CommandView.Width = 10; + hShortcut1.CommandView.Height = 1; + hShortcut1.CommandView.CanFocus = false; + Timer timer = new (10) + { + AutoReset = true, + }; + timer.Elapsed += (o, args) => + { + if (hShortcut1.CommandView is ProgressBar pb) + { + if (pb.Fraction == 1.0) + { + pb.Fraction = 0; + } + pb.Fraction += 0.01f; + + Application.Wakeup (); + + pb.SetNeedsDisplay (); + } + }; + timer.Start (); + + Application.Top.Add (hShortcut1); + + var textField = new TextField () + { + Text = "Edit me", + Width = 10, + Height = 1, + CanFocus = true + }; + + var hShortcut2 = new Shortcut + { + X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1), + Y = Pos.Top (hShortcut1), + Key = Key.F8, + HelpText = "Edit", + CanFocus = true, + BorderStyle = LineStyle.Dashed, + CommandView = textField, + }; + hShortcut2.Border.Thickness = new (0, 0, 1, 0); + + Application.Top.Add (hShortcut2); + + var hShortcutBG = new Shortcut + { + X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1)-1, + Y = Pos.Top (hShortcut2), + Key = Key.F9, + HelpText = "BG Color", + BorderStyle = LineStyle.Dashed, + CanFocus = false + }; + + var bgColor = new ColorPicker () + { + CanFocus = false, + BoxHeight = 1, + BoxWidth = 1, + }; + bgColor.ColorChanged += (o, args) => + { + Application.Top.ColorScheme = new ColorScheme (Application.Top.ColorScheme) + { + Normal = new Attribute (Application.Top.ColorScheme.Normal.Foreground, args.Color), + }; + }; + hShortcutBG.CommandView = bgColor; + hShortcutBG.Border.Thickness = new (1, 0, 1, 0); + + Application.Top.Add (hShortcutBG); + + var hShortcut3 = new Shortcut + { + X = Pos.Align (Alignment.Start, AlignmentModes.IgnoreFirstOrLast, 1), + Y = Pos.Top (hShortcut2), + Key = Key.Esc, + KeyBindingScope = KeyBindingScope.Application, + Title = "Quit", + HelpText = "App Scope", + BorderStyle = LineStyle.Dashed, + CanFocus = false + }; + hShortcut3.Border.Thickness = new (0); + hShortcut3.Accept += (o, args) => + { + Application.RequestStop (); + }; + + Application.Top.Add (hShortcut3); - Application.Top.Add (shortcut6); foreach (View sh in Application.Top.Subviews.Where (v => v is Shortcut)!) {