From 484e98998a2ea9327c7cd1141da7ae4acc64a0ae Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 10 Mar 2022 00:38:38 +0000 Subject: [PATCH 1/9] Feature to display the sub-menus on a single frame instead multiple frames. --- Example/demo.cs | 30 ++- Terminal.Gui/Core/Toplevel.cs | 6 +- Terminal.Gui/Views/Menu.cs | 182 ++++++++----- UnitTests/MenuTests.cs | 465 ++++++++++++++++++++++++++++++++++ 4 files changed, 609 insertions(+), 74 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index 3f69b42e8..c963aff9e 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -119,10 +119,10 @@ static class Demo { int i = 0; string txt = "Hello world, how are you doing today?"; container.Add ( - new Label ($"{i+1}-{txt}") { TextAlignment = TextAlignment.Left, Y = 3, Width = Dim.Fill () }, - new Label ($"{i+2}-{txt}") { TextAlignment = TextAlignment.Right, Y = 5, Width = Dim.Fill () }, - new Label ($"{i+3}-{txt}") { TextAlignment = TextAlignment.Centered, Y = 7, Width = Dim.Fill () }, - new Label ($"{i+4}-{txt}") { TextAlignment = TextAlignment.Justified, Y = 9, Width = Dim.Fill () } + new Label ($"{i + 1}-{txt}") { TextAlignment = TextAlignment.Left, Y = 3, Width = Dim.Fill () }, + new Label ($"{i + 2}-{txt}") { TextAlignment = TextAlignment.Right, Y = 5, Width = Dim.Fill () }, + new Label ($"{i + 3}-{txt}") { TextAlignment = TextAlignment.Centered, Y = 7, Width = Dim.Fill () }, + new Label ($"{i + 4}-{txt}") { TextAlignment = TextAlignment.Justified, Y = 9, Width = Dim.Fill () } ); Application.Run (container); @@ -487,15 +487,15 @@ static class Demo { .OrderBy (x => x).Select (x => ustring.Make (x)).ToList (); } } - var list = new ComboBox () { Width = Dim.Fill(), Height = Dim.Fill() }; - list.SetSource(items); + var list = new ComboBox () { Width = Dim.Fill (), Height = Dim.Fill () }; + list.SetSource (items); list.OpenSelectedItem += (ListViewItemEventArgs text) => { Application.RequestStop (); }; var d = new Dialog () { Title = "Select source file", Width = Dim.Percent (50), Height = Dim.Percent (50) }; d.Add (list); Application.Run (d); - MessageBox.Query (60, 10, "Selected file", list.Text.ToString() == "" ? "Nothing selected" : list.Text.ToString(), "Ok"); + MessageBox.Query (60, 10, "Selected file", list.Text.ToString () == "" ? "Nothing selected" : list.Text.ToString (), "Ok"); } #endregion @@ -564,10 +564,9 @@ static class Demo { #endregion public static Action running = MainApp; - static void Main(string[] args) + static void Main (string [] args) { - if (args.Length > 0 && args.Contains("-usc")) - { + if (args.Length > 0 && args.Contains ("-usc")) { Application.UseSystemConsole = true; } @@ -588,7 +587,7 @@ static class Demo { if (Debugger.IsAttached) CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US"); - Application.Init(); + Application.Init (); Application.HeightAsBuffer = true; //ConsoleDriver.Diagnostics = ConsoleDriver.DiagnosticFlags.FramePadding | ConsoleDriver.DiagnosticFlags.FrameRuler; @@ -621,6 +620,9 @@ static class Demo { menuItems [2].Action = () => ShowMenuItem (menuItems [2]); menuItems [3].Action = () => ShowMenuItem (menuItems [3]); + MenuItem miUseSubMenusSingleFrame = null; + var useSubMenusSingleFrame = false; + menu = new MenuBar (new MenuBarItem [] { new MenuBarItem ("_File", new MenuItem [] { new MenuItem ("Text _Editor Demo", "", () => { running = Editor; Application.RequestStop (); }, null, null, Key.AltMask | Key.CtrlMask | Key.D), @@ -638,7 +640,11 @@ static class Demo { new MenuItem ("_Paste", "", Paste, null, null, Key.AltMask | Key.CtrlMask| Key.V), new MenuBarItem ("_Find and Replace", new MenuItem [] { menuItems [0], menuItems [1] }), - menuItems[3] + menuItems[3], + miUseSubMenusSingleFrame = new MenuItem ("Use_SubMenusSingleFrame", "", + () => menu.UseSubMenusSingleFrame = miUseSubMenusSingleFrame.Checked = useSubMenusSingleFrame = !useSubMenusSingleFrame) { + CheckType = MenuItemCheckStyle.Checked, Checked = useSubMenusSingleFrame + } }), new MenuBarItem ("_List Demos", new MenuItem [] { new MenuItem ("Select _Multiple Items", "", () => ListSelectionDemo (true), null, null, Key.AltMask + 0.ToString () [0]), diff --git a/Terminal.Gui/Core/Toplevel.cs b/Terminal.Gui/Core/Toplevel.cs index 6c602903d..3e071f0d5 100644 --- a/Terminal.Gui/Core/Toplevel.cs +++ b/Terminal.Gui/Core/Toplevel.cs @@ -347,10 +347,8 @@ namespace Terminal.Gui { case Key.AltMask: case Key.AltMask | Key.Space: case Key.CtrlMask | Key.Space: - if (MenuBar != null && MenuBar.OnKeyDown (keyEvent)) { - return true; - } - break; + case Key _ when (keyEvent.Key & Key.AltMask) == Key.AltMask: + return MenuBar != null && MenuBar.OnKeyDown (keyEvent); } return false; diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index b8105dd4e..6faeded35 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -180,7 +180,7 @@ namespace Terminal.Gui { { bool nextIsHot = false; foreach (var x in title) { - if (x == '_') { + if (x == MenuBar.HotKeySpecifier) { nextIsHot = true; } else { if (nextIsHot) { @@ -349,7 +349,7 @@ namespace Terminal.Gui { { int len = 0; foreach (var ch in title) { - if (ch == '_') + if (ch == MenuBar.HotKeySpecifier) continue; len++; } @@ -419,8 +419,9 @@ namespace Terminal.Gui { AddCommand (Command.Left, () => { this.host.PreviousMenu (true); return true; }); AddCommand (Command.Right, () => { this.host.NextMenu (this.barItems.IsTopLevel || (this.barItems.Children != null - && current > -1 && current < this.barItems.Children.Length && this.barItems.Children [current].IsFromSubMenu) - ? true : false); return true; + && current > -1 && current < this.barItems.Children.Length && this.barItems.Children [current].IsFromSubMenu), + current > -1 && host.UseSubMenusSingleFrame && this.barItems.SubMenu (this.barItems.Children [current]) != null); + return true; }); AddCommand (Command.Cancel, () => { CloseAllMenus (); return true; }); AddCommand (Command.Accept, () => { RunSelected (); return true; }); @@ -466,6 +467,8 @@ namespace Terminal.Gui { continue; if (item == null) Driver.AddRune (Driver.HLine); + else if (i == 0 && p == 0 && host.UseSubMenusSingleFrame && item.Parent.Parent != null) + Driver.AddRune (Driver.LeftArrow); else if (p == Frame.Width - 3 && barItems.SubMenu (barItems.Children [i]) != null) Driver.AddRune (Driver.RightArrow); else @@ -501,12 +504,22 @@ namespace Terminal.Gui { ViewToScreen (2, i + 1, out int vtsCol, out _, false); if (vtsCol < Driver.Cols) { Move (2, i + 1); - if (!item.IsEnabled ()) + if (!item.IsEnabled ()) { DrawHotString (textToDraw, ColorScheme.Disabled, ColorScheme.Disabled); - else + } else if (i == 0 && host.UseSubMenusSingleFrame && item.Parent.Parent != null) { + var tf = new TextFormatter () { + Alignment = TextAlignment.Centered, + HotKeySpecifier = MenuBar.HotKeySpecifier, + Text = textToDraw + }; + tf.Draw (ViewToScreen (new Rect (2, i + 1, Frame.Width - 3, 1)), + i == current ? ColorScheme.Focus : GetNormalColor (), + i == current ? ColorScheme.HotFocus : ColorScheme.HotNormal); + } else { DrawHotString (textToDraw, - i == current ? ColorScheme.HotFocus : ColorScheme.HotNormal, - i == current ? ColorScheme.Focus : GetNormalColor ()); + i == current ? ColorScheme.HotFocus : ColorScheme.HotNormal, + i == current ? ColorScheme.Focus : GetNormalColor ()); + } // The help string var l = item.ShortcutTag.RuneCount == 0 ? item.Help.RuneCount : item.Help.RuneCount + item.ShortcutTag.RuneCount + 2; @@ -590,12 +603,13 @@ namespace Terminal.Gui { // TODO: rune-ify if (barItems.Children != null && Char.IsLetterOrDigit ((char)kb.KeyValue)) { var x = Char.ToUpper ((char)kb.KeyValue); + var idx = -1; foreach (var item in barItems.Children) { + idx++; if (item == null) continue; if (item.IsEnabled () && item.HotKey == x) { - if (host.CloseMenu ()) { - Run (item.Action); - } + current = idx; + RunSelected (); return true; } } @@ -607,8 +621,15 @@ namespace Terminal.Gui { { if (barItems.IsTopLevel) { Run (barItems.Action); - } else if (current > -1) { + } else if (current > -1 && barItems.Children [current].Action != null) { Run (barItems.Children [current].Action); + } else if (current == 0 && host.UseSubMenusSingleFrame + && barItems.Children [current].Parent.Parent != null) { + + host.PreviousMenu (barItems.Children [current].Parent.IsFromSubMenu, true); + } else if (current > -1 && barItems.SubMenu (barItems.Children [current]) != null) { + + CheckSubMenu (); } } @@ -640,7 +661,7 @@ namespace Terminal.Gui { } else { disabled = false; } - if (host.UseKeysUpDownAsKeysLeftRight && barItems.SubMenu (barItems.Children [current]) != null && + if (!host.UseSubMenusSingleFrame && host.UseKeysUpDownAsKeysLeftRight && barItems.SubMenu (barItems.Children [current]) != null && !disabled && host.IsMenuOpen) { if (!CheckSubMenu ()) return false; @@ -651,7 +672,8 @@ namespace Terminal.Gui { } } while (barItems.Children [current] == null || disabled); SetNeedsDisplay (); - host.OnMenuOpened (); + if (!host.UseSubMenusSingleFrame) + host.OnMenuOpened (); return true; } @@ -663,7 +685,7 @@ namespace Terminal.Gui { bool disabled; do { current--; - if (host.UseKeysUpDownAsKeysLeftRight) { + if (host.UseKeysUpDownAsKeysLeftRight && !host.UseSubMenusSingleFrame) { if ((current == -1 || this != host.openCurrentMenu) && barItems.Children [current + 1].IsFromSubMenu && host.selectedSub > -1) { current++; host.PreviousMenu (true); @@ -678,7 +700,7 @@ namespace Terminal.Gui { current = barItems.Children.Length - 1; if (!host.SelectEnabledItem (barItems.Children, current, out current, false)) { current = 0; - if (!host.SelectEnabledItem (barItems.Children, current, out current) && !host.CloseMenu ()) { + if (!host.SelectEnabledItem (barItems.Children, current, out current) && !host.CloseMenu (false)) { return false; } break; @@ -689,7 +711,7 @@ namespace Terminal.Gui { } else { disabled = false; } - if (host.UseKeysUpDownAsKeysLeftRight && barItems.SubMenu (barItems.Children [current]) != null && + if (!host.UseSubMenusSingleFrame && host.UseKeysUpDownAsKeysLeftRight && barItems.SubMenu (barItems.Children [current]) != null && !disabled && host.IsMenuOpen) { if (!CheckSubMenu ()) return false; @@ -697,7 +719,8 @@ namespace Terminal.Gui { } } while (barItems.Children [current] == null || disabled); SetNeedsDisplay (); - host.OnMenuOpened (); + if (!host.UseSubMenusSingleFrame) + host.OnMenuOpened (); return true; } @@ -717,12 +740,14 @@ namespace Terminal.Gui { return true; var item = barItems.Children [meY]; if (item == null || !item.IsEnabled ()) disabled = true; + current = meY; if (item != null && !disabled) - Run (barItems.Children [meY].Action); + RunSelected (); return true; } else if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked || me.Flags == MouseFlags.Button1TripleClicked || me.Flags == MouseFlags.ReportMousePosition || me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) { + disabled = false; if (me.Y < 1 || me.Y - 1 >= barItems.Children.Length) { return true; @@ -732,7 +757,7 @@ namespace Terminal.Gui { if (item == null || !item.IsEnabled ()) disabled = true; if (item != null && !disabled) current = me.Y - 1; - if (!CheckSubMenu ()) + if (host.UseSubMenusSingleFrame || !CheckSubMenu ()) return true; host.OnMenuOpened (); return true; @@ -803,15 +828,14 @@ namespace Terminal.Gui { /// /// public class MenuBar : View { - /// - /// Gets or sets the array of s for the menu. Only set this when the is vislble. - /// - /// The menu array. - public MenuBarItem [] Menus { get; set; } internal int selected; internal int selectedSub; - Action action; + /// + /// Gets or sets the array of s for the menu. Only set this when the is visible. + /// + /// The menu array. + public MenuBarItem [] Menus { get; set; } /// /// Used for change the navigation key style. @@ -831,6 +855,16 @@ namespace Terminal.Gui { } } + /// + /// The specifier character for the hotkey to all menus. + /// + new public static Rune HotKeySpecifier => '_'; + + /// + /// Gets or sets if the sub-menus must be displayed in a single or multiple frames. + /// + public bool UseSubMenusSingleFrame { get; set; } + /// /// Initializes a new instance of the . /// @@ -897,7 +931,7 @@ namespace Terminal.Gui { /// public override bool OnKeyUp (KeyEvent keyEvent) { - if (keyEvent.IsAlt || (keyEvent.IsCtrl && keyEvent.Key == (Key.CtrlMask | Key.Space))) { + if (keyEvent.IsAlt || keyEvent.Key == Key.AltMask || (keyEvent.IsCtrl && keyEvent.Key == (Key.CtrlMask | Key.Space))) { // User pressed Alt - this may be a precursor to a menu accelerator (e.g. Alt-F) if (openedByAltKey && !IsMenuOpen && openMenu == null && (((uint)keyEvent.Key & (uint)Key.CharMask) == 0 || ((uint)keyEvent.Key & (uint)Key.CharMask) == (uint)Key.Space)) { @@ -1004,13 +1038,23 @@ namespace Terminal.Gui { pos += 2 + Menus [i].TitleLength + (Menus [i].Help.Length > 0 ? Menus [i].Help.Length + 2 : 0) + 1; } } - //Move (0, 0); } void Selected (MenuItem item) { - // TODO: Running = false; - action = item.Action; + var action = item.Action; + + if (action == null) + return; + + Application.UngrabMouse (); + CloseAllMenus (); + Application.Refresh (); + + Application.MainLoop.AddIdle (() => { + action (); + return false; + }); } /// @@ -1154,7 +1198,21 @@ namespace Terminal.Gui { RemoveSubMenu (sIndex); } else { var last = openSubMenu.Count > 0 ? openSubMenu.Last () : openMenu; - openCurrentMenu = new Menu (this, last.Frame.Left + last.Frame.Width, last.Frame.Top + 1 + last.current, subMenu); + if (!UseSubMenusSingleFrame) { + openCurrentMenu = new Menu (this, last.Frame.Left + last.Frame.Width, last.Frame.Top + 1 + last.current, subMenu); + } else { + var first = openSubMenu.Count > 0 ? openSubMenu.First () : openMenu; + var mbi = new MenuItem [2 + subMenu.Children.Length]; + mbi [0] = new MenuItem () { Title = subMenu.Title, Parent = subMenu }; + mbi [1] = null; + for (int j = 0; j < subMenu.Children.Length; j++) { + mbi [j + 2] = subMenu.Children [j]; + } + var newSubMenu = new MenuBarItem (mbi); + openCurrentMenu = new Menu (this, first.Frame.Left, first.Frame.Top, newSubMenu); + last.Visible = false; + Application.GrabMouse (openCurrentMenu); + } openCurrentMenu.previousSubFocused = last.previousSubFocused; openSubMenu.Add (openCurrentMenu); if (SuperView == null) { @@ -1190,7 +1248,7 @@ namespace Terminal.Gui { previousFocused = SuperView == null ? Application.Current.Focused : SuperView.Focused; OpenMenu (selected); - if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current) && !CloseMenu ()) { + if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current) && !CloseMenu (false)) { return; } if (!openCurrentMenu.CheckSubMenu ()) @@ -1209,7 +1267,7 @@ namespace Terminal.Gui { OpenMenu (idx, sIdx, subMenu); if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current) - && subMenu == null && !CloseMenu ()) { + && subMenu == null && !CloseMenu (false)) { return; } @@ -1263,19 +1321,23 @@ namespace Terminal.Gui { /// /// Closes the current Menu programatically, if open and not canceled. /// - public bool CloseMenu () + public bool CloseMenu (bool ignoreUseSubMenusSingleFrame = false) { - return CloseMenu (false, false); + return CloseMenu (false, false, ignoreUseSubMenusSingleFrame); } bool reopen; - internal bool CloseMenu (bool reopen = false, bool isSubMenu = false) + internal bool CloseMenu (bool reopen = false, bool isSubMenu = false, bool ignoreUseSubMenusSingleFrame = false) { + var mbi = isSubMenu ? openCurrentMenu.barItems : openMenu?.barItems; + if (UseSubMenusSingleFrame && mbi != null && + !ignoreUseSubMenusSingleFrame && mbi.Parent != null) { + return false; + } isMenuClosing = true; this.reopen = reopen; - var args = OnMenuClosing ( - isSubMenu ? openCurrentMenu.barItems : openMenu?.barItems, reopen, isSubMenu); + var args = OnMenuClosing (mbi, reopen, isSubMenu); if (args.Cancel) { isMenuClosing = false; if (args.CurrentMenu.Parent != null) @@ -1327,9 +1389,9 @@ namespace Terminal.Gui { return true; } - void RemoveSubMenu (int index) + void RemoveSubMenu (int index, bool ignoreUseSubMenusSingleFrame = false) { - if (openSubMenu == null) + if (openSubMenu == null || (UseSubMenusSingleFrame && !ignoreUseSubMenusSingleFrame && openSubMenu.Count > 0)) return; for (int i = openSubMenu.Count - 1; i > index; i--) { isMenuClosing = true; @@ -1338,6 +1400,8 @@ namespace Terminal.Gui { menu = openSubMenu [i - 1]; else menu = openMenu; + if (!menu.Visible) + menu.Visible = true; openCurrentMenu = menu; openCurrentMenu.SetFocus (); if (openSubMenu != null) { @@ -1350,7 +1414,7 @@ namespace Terminal.Gui { openSubMenu.Remove (menu); menu.Dispose (); } - RemoveSubMenu (i); + RemoveSubMenu (i, ignoreUseSubMenusSingleFrame); } if (openSubMenu.Count > 0) openCurrentMenu = openSubMenu.Last (); @@ -1397,7 +1461,7 @@ namespace Terminal.Gui { if (!isMenuOpening && !isMenuClosing) { if (openSubMenu != null && !CloseMenu (false, true)) return; - if (!CloseMenu ()) + if (!CloseMenu (false)) return; if (LastFocused != null && LastFocused != this) selected = -1; @@ -1420,7 +1484,7 @@ namespace Terminal.Gui { return view; } - internal void PreviousMenu (bool isSubMenu = false) + internal void PreviousMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFrame = false) { switch (isSubMenu) { case false: @@ -1429,20 +1493,20 @@ namespace Terminal.Gui { else selected--; - if (selected > -1 && !CloseMenu (true, false)) + if (selected > -1 && !CloseMenu (true, false, ignoreUseSubMenusSingleFrame)) return; OpenMenu (selected); if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current, false)) { openCurrentMenu.current = 0; if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current)) { - CloseMenu (); + CloseMenu (ignoreUseSubMenusSingleFrame); } } break; case true: if (selectedSub > -1) { selectedSub--; - RemoveSubMenu (selectedSub); + RemoveSubMenu (selectedSub, ignoreUseSubMenusSingleFrame); SetNeedsDisplay (); } else PreviousMenu (); @@ -1451,7 +1515,7 @@ namespace Terminal.Gui { } } - internal void NextMenu (bool isSubMenu = false) + internal void NextMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFrame = false) { switch (isSubMenu) { case false: @@ -1462,22 +1526,22 @@ namespace Terminal.Gui { else selected++; - if (selected > -1 && !CloseMenu (true)) + if (selected > -1 && !CloseMenu (true, ignoreUseSubMenusSingleFrame)) return; OpenMenu (selected); SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current); break; case true: if (UseKeysUpDownAsKeysLeftRight) { - if (CloseMenu (false, true)) { - NextMenu (); + if (CloseMenu (false, true, ignoreUseSubMenusSingleFrame)) { + NextMenu (false, ignoreUseSubMenusSingleFrame); } } else { var subMenu = openCurrentMenu.barItems.SubMenu (openCurrentMenu.barItems.Children [openCurrentMenu.current]); if ((selectedSub == -1 || openSubMenu == null || openSubMenu?.Count == selectedSub) && subMenu == null) { if (openSubMenu != null && !CloseMenu (false, true)) return; - NextMenu (); + NextMenu (false, ignoreUseSubMenusSingleFrame); } else if (subMenu != null || !openCurrentMenu.barItems.Children [openCurrentMenu.current].IsFromSubMenu) selectedSub++; @@ -1498,7 +1562,7 @@ namespace Terminal.Gui { for (int i = 0; i < Menus.Length; i++) { // TODO: this code is duplicated, hotkey should be part of the MenuBarItem var mi = Menus [i]; - int p = mi.Title.IndexOf ('_'); + int p = mi.Title.IndexOf (MenuBar.HotKeySpecifier); if (p != -1 && p + 1 < mi.Title.RuneCount) { if (Char.ToUpperInvariant ((char)mi.Title [p + 1]) == c) { ProcessMenu (i, mi); @@ -1543,7 +1607,7 @@ namespace Terminal.Gui { private void ProcessMenu (int i, MenuBarItem mi) { - if (selected < 0) { + if (selected < 0 && IsMenuOpen) { return; } @@ -1556,7 +1620,7 @@ namespace Terminal.Gui { Application.GrabMouse (this); selected = i; OpenMenu (i); - if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current) && !CloseMenu ()) { + if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current) && !CloseMenu (false)) { return; } if (!openCurrentMenu.CheckSubMenu ()) @@ -1577,7 +1641,7 @@ namespace Terminal.Gui { } // To ncurses simulate a AltMask key pressing Alt+Space because - // it can�t detect an alone special key down was pressed. + // it can't detect an alone special key down was pressed. if (kb.IsAlt && kb.Key == Key.AltMask && openMenu == null) { OnKeyDown (kb); OnKeyUp (kb); @@ -1606,7 +1670,7 @@ namespace Terminal.Gui { foreach (var mi in Menus [selected].Children) { if (mi == null) continue; - int p = mi.Title.IndexOf ('_'); + int p = mi.Title.IndexOf (MenuBar.HotKeySpecifier); if (p != -1 && p + 1 < mi.Title.RuneCount) { if (mi.Title [p + 1] == c) { Selected (mi); @@ -1621,7 +1685,7 @@ namespace Terminal.Gui { void CloseMenuBar () { - if (!CloseMenu ()) + if (!CloseMenu (false)) return; if (openedByAltKey) { openedByAltKey = false; @@ -1758,7 +1822,9 @@ namespace Terminal.Gui { isContextMenuLoading = false; return false; } - } else if (!IsMenuOpen && (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked || me.Flags == MouseFlags.Button1TripleClicked || me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))) { + } else if (!IsMenuOpen && (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked + || me.Flags == MouseFlags.Button1TripleClicked || me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))) { + Application.GrabMouse (current); } else if (IsMenuOpen && (me.View is MenuBar || me.View is Menu)) { Application.GrabMouse (me.View); diff --git a/UnitTests/MenuTests.cs b/UnitTests/MenuTests.cs index 13c1f9f2e..7e687210d 100644 --- a/UnitTests/MenuTests.cs +++ b/UnitTests/MenuTests.cs @@ -589,5 +589,470 @@ Edit pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); Assert.Equal (new Point (0, 1), pos); } + + [Fact, AutoInitShutdown] + public void UseSubMenusSingleFrame_False_By_Keyboard () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("Numbers", new MenuItem [] { + new MenuItem ("One", "", null), + new MenuBarItem ("Two", new MenuItem [] { + new MenuItem ("Sub-Menu 1", "", null), + new MenuItem ("Sub-Menu 2", "", null) + }), + new MenuItem ("Three", "", null), + }) + }); + + Application.Top.Add (menu); + + Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); + Assert.False (menu.UseSubMenusSingleFrame); + + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + Numbers +"; + + var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.CursorDown, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│┌─────────────┐ +│ Three ││ Sub-Menu 1 │ +└────────┘│ Sub-Menu 2 │ + └─────────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (Application.Top.Subviews [2].ProcessKey (new KeyEvent (Key.CursorLeft, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Esc, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + } + + [Fact, AutoInitShutdown] + public void UseSubMenusSingleFrame_False_By_Mouse () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("Numbers", new MenuItem [] { + new MenuItem ("One", "", null), + new MenuBarItem ("Two", new MenuItem [] { + new MenuItem ("Sub-Menu 1", "", null), + new MenuItem ("Sub-Menu 2", "", null) + }), + new MenuItem ("Three", "", null), + }) + }); + + Application.Top.Add (menu); + + Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); + Assert.False (menu.UseSubMenusSingleFrame); + + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + Numbers +"; + + var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (menu.MouseEvent (new MouseEvent () { + X = 1, + Y = 0, + Flags = MouseFlags.Button1Pressed, + View = menu + })); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.False (menu.MouseEvent (new MouseEvent () { + X = 1, + Y = 3, + Flags = MouseFlags.ReportMousePosition, + View = Application.Top.Subviews [1] + })); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│┌─────────────┐ +│ Three ││ Sub-Menu 1 │ +└────────┘│ Sub-Menu 2 │ + └─────────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.False (menu.MouseEvent (new MouseEvent () { + X = 1, + Y = 2, + Flags = MouseFlags.ReportMousePosition, + View = Application.Top.Subviews [1] + })); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.False (menu.MouseEvent (new MouseEvent () { + X = 70, + Y = 2, + Flags = MouseFlags.Button1Clicked, + View = Application.Top + })); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + } + + [Fact, AutoInitShutdown] + public void UseSubMenusSingleFrame_True_By_Keyboard () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("Numbers", new MenuItem [] { + new MenuItem ("One", "", null), + new MenuBarItem ("Two", new MenuItem [] { + new MenuItem ("Sub-Menu 1", "", null), + new MenuItem ("Sub-Menu 2", "", null) + }), + new MenuItem ("Three", "", null), + }) + }); + + Application.Top.Add (menu); + + Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); + Assert.False (menu.UseSubMenusSingleFrame); + menu.UseSubMenusSingleFrame = true; + Assert.True (menu.UseSubMenusSingleFrame); + + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + Numbers +"; + + var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.CursorDown, null))); + Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Enter, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌─────────────┐ +│◄ Two │ +├─────────────┤ +│ Sub-Menu 1 │ +│ Sub-Menu 2 │ +└─────────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (Application.Top.Subviews [2].ProcessKey (new KeyEvent (Key.Enter, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Esc, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + } + + [Fact, AutoInitShutdown] + public void UseSubMenusSingleFrame_True_By_Mouse () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("Numbers", new MenuItem [] { + new MenuItem ("One", "", null), + new MenuBarItem ("Two", new MenuItem [] { + new MenuItem ("Sub-Menu 1", "", null), + new MenuItem ("Sub-Menu 2", "", null) + }), + new MenuItem ("Three", "", null), + }) + }); + + Application.Top.Add (menu); + + Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); + Assert.False (menu.UseSubMenusSingleFrame); + menu.UseSubMenusSingleFrame = true; + Assert.True (menu.UseSubMenusSingleFrame); + + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + Numbers +"; + + var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (menu.MouseEvent (new MouseEvent () { + X = 1, + Y = 0, + Flags = MouseFlags.Button1Pressed, + View = menu + })); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.False (menu.MouseEvent (new MouseEvent () { + X = 1, + Y = 3, + Flags = MouseFlags.Button1Clicked, + View = Application.Top.Subviews [1] + })); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌─────────────┐ +│◄ Two │ +├─────────────┤ +│ Sub-Menu 1 │ +│ Sub-Menu 2 │ +└─────────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.False (menu.MouseEvent (new MouseEvent () { + X = 1, + Y = 2, + Flags = MouseFlags.Button1Clicked, + View = Application.Top.Subviews [2] + })); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.False (menu.MouseEvent (new MouseEvent () { + X = 70, + Y = 2, + Flags = MouseFlags.Button1Clicked, + View = Application.Top + })); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + } + + [Fact, AutoInitShutdown] + public void HotKey_MenuBar_OnKeyDown_OnKeyUp_ProcessKey () + { + var newAction = false; + var copyAction = false; + + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("_File", new MenuItem [] { + new MenuItem ("_New", "", () => newAction = true) + }), + new MenuBarItem ("_Edit", new MenuItem [] { + new MenuItem ("_Copy", "", () => copyAction = true) + }) + }); + + Application.Top.Add (menu); + + Assert.False (newAction); + Assert.False (copyAction); + + Assert.False (menu.OnKeyDown (new (Key.AltMask, new KeyModifiers () { Alt = true }))); + Assert.True (menu.OnKeyUp (new (Key.AltMask, new KeyModifiers () { Alt = true }))); + Assert.True (menu.IsMenuOpen); + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + File Edit +"; + + var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (menu.ProcessKey (new (Key.N, null))); + Application.MainLoop.MainIteration (); + Assert.True (newAction); + + Assert.False (menu.OnKeyDown (new (Key.AltMask, new KeyModifiers () { Alt = true }))); + Assert.True (menu.OnKeyUp (new (Key.AltMask, new KeyModifiers () { Alt = true }))); + Assert.True (menu.IsMenuOpen); + + Assert.True (menu.ProcessKey (new (Key.CursorRight, null))); + Assert.True (menu.ProcessKey (new (Key.C, null))); + Application.MainLoop.MainIteration (); + Assert.True (copyAction); + } + + [Fact, AutoInitShutdown] + public void HotKey_MenuBar_ProcessHotKey_Menu_ProcessKey () + { + var newAction = false; + var copyAction = false; + + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("_File", new MenuItem [] { + new MenuItem ("_New", "", () => newAction = true) + }), + new MenuBarItem ("_Edit", new MenuItem [] { + new MenuItem ("_Copy", "", () => copyAction = true) + }) + }); + + Application.Top.Add (menu); + + Assert.False (newAction); + Assert.False (copyAction); + + Assert.True (menu.ProcessHotKey (new (Key.AltMask | Key.F, new KeyModifiers () { Alt = true }))); + Assert.True (menu.IsMenuOpen); + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + File Edit +┌───────┐ +│ New │ +└───────┘ +"; + + var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (Application.Top.Subviews [1].ProcessKey (new (Key.N, null))); + Application.MainLoop.MainIteration (); + Assert.True (newAction); + + Assert.True (menu.ProcessHotKey (new (Key.AltMask | Key.E, new KeyModifiers () { Alt = true }))); + Assert.True (menu.IsMenuOpen); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + File Edit + ┌────────┐ + │ Copy │ + └────────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); + Assert.Equal (new Point (2, 0), pos); + + Assert.True (Application.Top.Subviews [1].ProcessKey (new (Key.C, null))); + Application.MainLoop.MainIteration (); + Assert.True (copyAction); + } } } From d9f52fc2f23daea4e15e048161703882a3859efb Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 11 Mar 2022 00:33:22 +0000 Subject: [PATCH 2/9] Changing from AssertDriverContentsWithPosAre to AssertDriverContentsWithFrameAre to return a Rect. --- UnitTests/ContextMenuTests.cs | 28 +- UnitTests/GraphViewTests.cs | 481 +++++++++++++++++++--------------- UnitTests/MenuTests.cs | 132 +++++----- UnitTests/ViewTests.cs | 28 +- 4 files changed, 364 insertions(+), 305 deletions(-) diff --git a/UnitTests/ContextMenuTests.cs b/UnitTests/ContextMenuTests.cs index 0610e1f22..496245e75 100644 --- a/UnitTests/ContextMenuTests.cs +++ b/UnitTests/ContextMenuTests.cs @@ -269,8 +269,8 @@ namespace Terminal.Gui.Core { └──────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (72, 21), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (72, 21, 80, 4), pos); cm.Hide (); Assert.Equal (new Point (80, 25), cm.Position); @@ -299,8 +299,8 @@ namespace Terminal.Gui.Core { └──────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (70, 21), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (70, 21, 78, 4), pos); cm.Hide (); Assert.Equal (new Point (70, 25), cm.Position); @@ -332,8 +332,8 @@ namespace Terminal.Gui.Core { └──────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (6, 12), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (6, 12, 14, 4), pos); cm.Hide (); Assert.Equal (new Point (6, 11), cm.Position); @@ -363,8 +363,8 @@ namespace Terminal.Gui.Core { └──── "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 1), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 1, 5, 4), pos); cm.Hide (); Assert.Equal (new Point (0, 0), cm.Position); @@ -393,8 +393,8 @@ namespace Terminal.Gui.Core { │ Two │ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 1), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 1, 8, 3), pos); cm.Hide (); Assert.Equal (new Point (0, 0), cm.Position); @@ -446,8 +446,8 @@ namespace Terminal.Gui.Core { └──────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 1), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 1, 8, 4), pos); cm.ForceMinimumPosToZero = false; cm.Show (); @@ -460,8 +460,8 @@ namespace Terminal.Gui.Core { ──────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (1, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 7, 3), pos); } [Fact, AutoInitShutdown] diff --git a/UnitTests/GraphViewTests.cs b/UnitTests/GraphViewTests.cs index 9afdfba47..c69a09787 100644 --- a/UnitTests/GraphViewTests.cs +++ b/UnitTests/GraphViewTests.cs @@ -11,40 +11,40 @@ using System.Text.RegularExpressions; using Xunit.Abstractions; namespace Terminal.Gui.Views { - + #region Helper Classes class FakeHAxis : HorizontalAxis { public List DrawAxisLinePoints = new List (); - public List LabelPoints = new List(); + public List LabelPoints = new List (); protected override void DrawAxisLine (GraphView graph, int x, int y) { base.DrawAxisLine (graph, x, y); - DrawAxisLinePoints.Add (new Point(x, y)); + DrawAxisLinePoints.Add (new Point (x, y)); } public override void DrawAxisLabel (GraphView graph, int screenPosition, string text) { base.DrawAxisLabel (graph, screenPosition, text); - LabelPoints.Add(screenPosition); + LabelPoints.Add (screenPosition); } } class FakeVAxis : VerticalAxis { public List DrawAxisLinePoints = new List (); - public List LabelPoints = new List(); + public List LabelPoints = new List (); protected override void DrawAxisLine (GraphView graph, int x, int y) { base.DrawAxisLine (graph, x, y); - DrawAxisLinePoints.Add (new Point(x, y)); + DrawAxisLinePoints.Add (new Point (x, y)); } public override void DrawAxisLabel (GraphView graph, int screenPosition, string text) { base.DrawAxisLabel (graph, screenPosition, text); - LabelPoints.Add(screenPosition); + LabelPoints.Add (screenPosition); } } #endregion @@ -96,49 +96,6 @@ namespace Terminal.Gui.Views { var actualLook = sb.ToString (); - if (!string.Equals (expectedLook, actualLook)) { - - // ignore trailing whitespace on each line - var trailingWhitespace = new Regex (@"\s+$",RegexOptions.Multiline); - - // get rid of trailing whitespace on each line (and leading/trailing whitespace of start/end of full string) - expectedLook = trailingWhitespace.Replace(expectedLook,"").Trim(); - actualLook = trailingWhitespace.Replace (actualLook, "").Trim (); - - // standardise line endings for the comparison - expectedLook = expectedLook.Replace ("\r\n", "\n"); - actualLook = actualLook.Replace ("\r\n", "\n"); - - output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); - output?.WriteLine ("But Was:" + Environment.NewLine + actualLook); - - Assert.Equal (expectedLook, actualLook); - } - } - - public static Point AssertDriverContentsWithPosAre (string expectedLook, ITestOutputHelper output) - { - var sb = new StringBuilder (); - var driver = ((FakeDriver)Application.Driver); - var x = -1; - var y = -1; - - var contents = driver.Contents; - - for (int r = 0; r < driver.Rows; r++) { - for (int c = 0; c < driver.Cols; c++) { - var rune = (char)contents [r, c, 0]; - if (x == -1 && rune != ' ') { - x = c; - y = r; - } - sb.Append (rune); - } - sb.AppendLine (); - } - - var actualLook = sb.ToString (); - if (!string.Equals (expectedLook, actualLook)) { // ignore trailing whitespace on each line @@ -157,7 +114,95 @@ namespace Terminal.Gui.Views { Assert.Equal (expectedLook, actualLook); } - return new Point (x, y); + } + + public static Rect AssertDriverContentsWithFrameAre (string expectedLook, ITestOutputHelper output) + { + var lines = new List> (); + var sb = new StringBuilder (); + var driver = ((FakeDriver)Application.Driver); + var x = -1; + var y = -1; + int w = -1; + int h = -1; + + var contents = driver.Contents; + + for (int r = 0; r < driver.Rows; r++) { + var runes = new List (); + for (int c = 0; c < driver.Cols; c++) { + var rune = (char)contents [r, c, 0]; + if (rune != ' ') { + if (x == -1) { + x = c; + y = r; + for (int i = 0; i < c; i++) { + runes.InsertRange (i, new List () { ' ' }); + } + } + if (c > w) { + w = c; + } + h = r - y; + } + if (x > -1) { + runes.Add (rune); + } + } + if (runes.Count > 0) { + lines.Add (runes); + } + } + + // Remove unnecessary empty lines + for (int r = lines.Count - 1; r > h; r--) { + lines.RemoveAt (r); + } + + // Remove trailing whitespace on each line + for (int r = 0; r < lines.Count; r++) { + List row = lines [r]; + for (int c = row.Count - 1; c >= 0; c--) { + if (row [c] != ' ') { + break; + } + row.RemoveAt (c); + } + if (row.Count == 0) { + lines.Remove (row); + } + } + + // Convert char list to string + for (int r = 0; r < lines.Count; r++) { + var line = new string (lines [r].ToArray ()); + if (r == lines.Count - 1) { + sb.Append (line); + } else { + sb.AppendLine (line); + } + } + + var actualLook = sb.ToString (); + + if (!string.Equals (expectedLook, actualLook)) { + + // Remove the first empty line from the expectedLook + expectedLook = string.Join (Environment.NewLine, expectedLook + .Split (Environment.NewLine.ToCharArray ()) + .Skip (1) + .ToArray ()).TrimEnd (); + + // standardise line endings for the comparison + expectedLook = expectedLook.Replace ("\r\n", "\n"); + actualLook = actualLook.Replace ("\r\n", "\n"); + + output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); + output?.WriteLine ("But Was:" + Environment.NewLine + actualLook); + + Assert.Equal (expectedLook, actualLook); + } + return new Rect (x, y, w > -1 ? w + 1 : 0, h > -1 ? h + 1 : 0); } #pragma warning disable xUnit1013 // Public method should be marked as test @@ -168,11 +213,11 @@ namespace Terminal.Gui.Views { /// /// Numbers between 0 and 9 for each row/col of the console. Must be valid indexes of /// - public static void AssertDriverColorsAre (string expectedLook, Attribute[] expectedColors) + public static void AssertDriverColorsAre (string expectedLook, Attribute [] expectedColors) { #pragma warning restore xUnit1013 // Public method should be marked as test - if(expectedColors.Length > 10) { + if (expectedColors.Length > 10) { throw new ArgumentException ("This method only works for UIs that use at most 10 colors"); } @@ -182,7 +227,7 @@ namespace Terminal.Gui.Views { var contents = driver.Contents; int r = 0; - foreach(var line in expectedLook.Split ('\n').Select(l=>l.Trim())) { + foreach (var line in expectedLook.Split ('\n').Select (l => l.Trim ())) { for (int c = 0; c < line.Length; c++) { @@ -195,10 +240,10 @@ namespace Terminal.Gui.Views { throw new ArgumentException ($"Bad value for expectedColors, {match.Count} Attributes had the same Value"); } - var colorUsed = Array.IndexOf(expectedColors,match[0]).ToString()[0]; + var colorUsed = Array.IndexOf (expectedColors, match [0]).ToString () [0]; var userExpected = line [c]; - if( colorUsed != userExpected) { + if (colorUsed != userExpected) { throw new Exception ($"Colors used did not match expected at row {r} and col {c}. Color index used was {colorUsed} but test expected {userExpected} (these are indexes into the expectedColors array)"); } } @@ -434,7 +479,7 @@ namespace Terminal.Gui.Views { /// is mutable a sensible place to check this is in redraw. /// [Fact] - public void CellSizeZero() + public void CellSizeZero () { InitFakeDriver (); @@ -442,8 +487,8 @@ namespace Terminal.Gui.Views { gv.ColorScheme = new ColorScheme (); gv.Bounds = new Rect (0, 0, 50, 30); gv.Series.Add (new ScatterSeries () { Points = new List { new PointF (1, 1) } }); - gv.CellSize= new PointF(0,5); - var ex = Assert.Throws(()=>gv.Redraw (gv.Bounds)); + gv.CellSize = new PointF (0, 5); + var ex = Assert.Throws (() => gv.Redraw (gv.Bounds)); Assert.Equal ("CellSize cannot be 0", ex.Message); @@ -451,7 +496,7 @@ namespace Terminal.Gui.Views { Application.Shutdown (); } - + /// /// Tests that each point in the screen space maps to a rectangle of @@ -488,7 +533,7 @@ namespace Terminal.Gui.Views { Assert.Equal (x, p.X); Assert.Equal (y, p.Y); - p = gv.GraphSpaceToScreen (new PointF (graphSpace.Right - epsilon , graphSpace.Top + epsilon)); + p = gv.GraphSpaceToScreen (new PointF (graphSpace.Right - epsilon, graphSpace.Top + epsilon)); Assert.Equal (x, p.X); Assert.Equal (y, p.Y); @@ -613,33 +658,35 @@ namespace Terminal.Gui.Views { } } - public class MultiBarSeriesTests{ + public class MultiBarSeriesTests { readonly ITestOutputHelper output; - public MultiBarSeriesTests(ITestOutputHelper output) + public MultiBarSeriesTests (ITestOutputHelper output) { this.output = output; } [Fact] - public void MultiBarSeries_BarSpacing(){ - + public void MultiBarSeries_BarSpacing () + { + // Creates clusters of 5 adjacent bars with 2 spaces between clusters - var series = new MultiBarSeries(5,7,1); + var series = new MultiBarSeries (5, 7, 1); - Assert.Equal(5,series.SubSeries.Count); + Assert.Equal (5, series.SubSeries.Count); - Assert.Equal(0,series.SubSeries.ElementAt(0).Offset); - Assert.Equal(1,series.SubSeries.ElementAt(1).Offset); - Assert.Equal(2,series.SubSeries.ElementAt(2).Offset); - Assert.Equal(3,series.SubSeries.ElementAt(3).Offset); - Assert.Equal(4,series.SubSeries.ElementAt(4).Offset); + Assert.Equal (0, series.SubSeries.ElementAt (0).Offset); + Assert.Equal (1, series.SubSeries.ElementAt (1).Offset); + Assert.Equal (2, series.SubSeries.ElementAt (2).Offset); + Assert.Equal (3, series.SubSeries.ElementAt (3).Offset); + Assert.Equal (4, series.SubSeries.ElementAt (4).Offset); } [Fact] - public void MultiBarSeriesColors_WrongNumber(){ + public void MultiBarSeriesColors_WrongNumber () + { var fake = new FakeDriver (); @@ -648,8 +695,8 @@ namespace Terminal.Gui.Views { }; // user passes 1 color only but asks for 5 bars - var ex = Assert.Throws(()=>new MultiBarSeries(5,7,1,colors)); - Assert.Equal("Number of colors must match the number of bars (Parameter 'numberOfBarsPerCategory')",ex.Message); + var ex = Assert.Throws (() => new MultiBarSeries (5, 7, 1, colors)); + Assert.Equal ("Number of colors must match the number of bars (Parameter 'numberOfBarsPerCategory')", ex.Message); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -657,7 +704,8 @@ namespace Terminal.Gui.Views { [Fact] - public void MultiBarSeriesColors_RightNumber(){ + public void MultiBarSeriesColors_RightNumber () + { var fake = new FakeDriver (); @@ -668,11 +716,11 @@ namespace Terminal.Gui.Views { }; // user passes 3 colors and asks for 3 bars - var series = new MultiBarSeries(3,7,1,colors); + var series = new MultiBarSeries (3, 7, 1, colors); - Assert.Equal(series.SubSeries.ElementAt(0).OverrideBarColor,colors[0]); - Assert.Equal(series.SubSeries.ElementAt(1).OverrideBarColor,colors[1]); - Assert.Equal(series.SubSeries.ElementAt(2).OverrideBarColor,colors[2]); + Assert.Equal (series.SubSeries.ElementAt (0).OverrideBarColor, colors [0]); + Assert.Equal (series.SubSeries.ElementAt (1).OverrideBarColor, colors [1]); + Assert.Equal (series.SubSeries.ElementAt (2).OverrideBarColor, colors [2]); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -680,20 +728,22 @@ namespace Terminal.Gui.Views { [Fact] - public void MultiBarSeriesAddValues_WrongNumber(){ - + public void MultiBarSeriesAddValues_WrongNumber () + { + // user asks for 3 bars per category - var series = new MultiBarSeries(3,7,1); + var series = new MultiBarSeries (3, 7, 1); - var ex = Assert.Throws(()=>series.AddBars("Cars",'#',1)); + var ex = Assert.Throws (() => series.AddBars ("Cars", '#', 1)); - Assert.Equal("Number of values must match the number of bars per category (Parameter 'values')",ex.Message); + Assert.Equal ("Number of values must match the number of bars per category (Parameter 'values')", ex.Message); } [Fact] - public void TestRendering_MultibarSeries(){ + public void TestRendering_MultibarSeries () + { GraphViewTests.InitFakeDriver (); @@ -703,14 +753,14 @@ namespace Terminal.Gui.Views { // y axis goes from 0.1 to 1 across 10 console rows // x axis goes from 0 to 20 across 20 console columns gv.Bounds = new Rect (0, 0, 20, 10); - gv.CellSize = new PointF(1f,0.1f); + gv.CellSize = new PointF (1f, 0.1f); gv.MarginBottom = 1; gv.MarginLeft = 1; - var multibarSeries = new MultiBarSeries (2,4,1); - + var multibarSeries = new MultiBarSeries (2, 4, 1); + //nudge them left to avoid float rounding errors at the boundaries of cells - foreach(var sub in multibarSeries.SubSeries) { + foreach (var sub in multibarSeries.SubSeries) { sub.Offset -= 0.001f; } @@ -720,28 +770,28 @@ namespace Terminal.Gui.Views { // don't show axis labels that means any labels // that appaer are explicitly from the bars - gv.AxisX = fakeXAxis = new FakeHAxis(){Increment=0}; - gv.AxisY = new FakeVAxis(){Increment=0}; + gv.AxisX = fakeXAxis = new FakeHAxis () { Increment = 0 }; + gv.AxisY = new FakeVAxis () { Increment = 0 }; - gv.Redraw(gv.Bounds); + gv.Redraw (gv.Bounds); // Since bar series has no bars yet no labels should be displayed - Assert.Empty(fakeXAxis.LabelPoints); + Assert.Empty (fakeXAxis.LabelPoints); - multibarSeries.AddBars("hey",'M',0.5001f, 0.5001f); - fakeXAxis.LabelPoints.Clear(); - gv.Redraw(gv.Bounds); - - Assert.Equal(4,fakeXAxis.LabelPoints.Single()); + multibarSeries.AddBars ("hey", 'M', 0.5001f, 0.5001f); + fakeXAxis.LabelPoints.Clear (); + gv.Redraw (gv.Bounds); - multibarSeries.AddBars("there",'M',0.24999f,0.74999f); - multibarSeries.AddBars("bob",'M',1,2); - fakeXAxis.LabelPoints.Clear(); - gv.Redraw(gv.Bounds); + Assert.Equal (4, fakeXAxis.LabelPoints.Single ()); - Assert.Equal(3,fakeXAxis.LabelPoints.Count); - Assert.Equal(4,fakeXAxis.LabelPoints[0]); - Assert.Equal(8,fakeXAxis.LabelPoints[1]); + multibarSeries.AddBars ("there", 'M', 0.24999f, 0.74999f); + multibarSeries.AddBars ("bob", 'M', 1, 2); + fakeXAxis.LabelPoints.Clear (); + gv.Redraw (gv.Bounds); + + Assert.Equal (3, fakeXAxis.LabelPoints.Count); + Assert.Equal (4, fakeXAxis.LabelPoints [0]); + Assert.Equal (8, fakeXAxis.LabelPoints [1]); Assert.Equal (12, fakeXAxis.LabelPoints [2]); string looksLike = @@ -763,7 +813,7 @@ namespace Terminal.Gui.Views { } } - public class BarSeriesTests{ + public class BarSeriesTests { private GraphView GetGraph (out FakeBarSeries series, out FakeHAxis axisX, out FakeVAxis axisY) @@ -776,46 +826,47 @@ namespace Terminal.Gui.Views { // y axis goes from 0.1 to 1 across 10 console rows // x axis goes from 0 to 10 across 20 console columns gv.Bounds = new Rect (0, 0, 20, 10); - gv.CellSize = new PointF(0.5f,0.1f); + gv.CellSize = new PointF (0.5f, 0.1f); gv.Series.Add (series = new FakeBarSeries ()); // don't show axis labels that means any labels // that appaer are explicitly from the bars - gv.AxisX = axisX = new FakeHAxis(){Increment=0}; - gv.AxisY = axisY = new FakeVAxis(){Increment=0}; + gv.AxisX = axisX = new FakeHAxis () { Increment = 0 }; + gv.AxisY = axisY = new FakeVAxis () { Increment = 0 }; return gv; } [Fact] - public void TestZeroHeightBar_WithName(){ + public void TestZeroHeightBar_WithName () + { - var graph = GetGraph(out FakeBarSeries barSeries, out FakeHAxis axisX, out FakeVAxis axisY); - graph.Redraw(graph.Bounds); + var graph = GetGraph (out FakeBarSeries barSeries, out FakeHAxis axisX, out FakeVAxis axisY); + graph.Redraw (graph.Bounds); // no bars - Assert.Empty(barSeries.BarScreenStarts); - Assert.Empty(axisX.LabelPoints); - Assert.Empty(axisY.LabelPoints); + Assert.Empty (barSeries.BarScreenStarts); + Assert.Empty (axisX.LabelPoints); + Assert.Empty (axisY.LabelPoints); // bar of height 0 - barSeries.Bars.Add(new BarSeries.Bar("hi",new GraphCellToRender('.'),0)); + barSeries.Bars.Add (new BarSeries.Bar ("hi", new GraphCellToRender ('.'), 0)); barSeries.Orientation = Orientation.Vertical; // redraw graph - graph.Redraw(graph.Bounds); + graph.Redraw (graph.Bounds); // bar should not be drawn - Assert.Empty(barSeries.BarScreenStarts); + Assert.Empty (barSeries.BarScreenStarts); - Assert.NotEmpty(axisX.LabelPoints); - Assert.Empty(axisY.LabelPoints); + Assert.NotEmpty (axisX.LabelPoints); + Assert.Empty (axisY.LabelPoints); // but bar name should be // Screen position x=2 because bars are drawn every 1f of // graph space and CellSize.X is 0.5f - Assert.Contains(2, axisX.LabelPoints); + Assert.Contains (2, axisX.LabelPoints); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -823,71 +874,73 @@ namespace Terminal.Gui.Views { [Fact] - public void TestTwoTallBars_WithOffset(){ + public void TestTwoTallBars_WithOffset () + { - var graph = GetGraph(out FakeBarSeries barSeries, out FakeHAxis axisX, out FakeVAxis axisY); - graph.Redraw(graph.Bounds); + var graph = GetGraph (out FakeBarSeries barSeries, out FakeHAxis axisX, out FakeVAxis axisY); + graph.Redraw (graph.Bounds); // no bars - Assert.Empty(barSeries.BarScreenStarts); - Assert.Empty(axisX.LabelPoints); - Assert.Empty(axisY.LabelPoints); + Assert.Empty (barSeries.BarScreenStarts); + Assert.Empty (axisX.LabelPoints); + Assert.Empty (axisY.LabelPoints); // 0.5 units of graph fit every screen cell // so 1 unit of graph space is 2 screen columns - graph.CellSize = new PointF(0.5f,0.1f); + graph.CellSize = new PointF (0.5f, 0.1f); // Start bar 1 screen unit along barSeries.Offset = 0.5f; barSeries.BarEvery = 1f; - barSeries.Bars.Add( - new BarSeries.Bar("hi1",new GraphCellToRender('.'),100)); - barSeries.Bars.Add( - new BarSeries.Bar("hi2",new GraphCellToRender('.'),100)); + barSeries.Bars.Add ( + new BarSeries.Bar ("hi1", new GraphCellToRender ('.'), 100)); + barSeries.Bars.Add ( + new BarSeries.Bar ("hi2", new GraphCellToRender ('.'), 100)); barSeries.Orientation = Orientation.Vertical; // redraw graph - graph.Redraw(graph.Bounds); + graph.Redraw (graph.Bounds); // bar should be drawn at BarEvery 1f + offset 0.5f = 3 screen units - Assert.Equal(3,barSeries.BarScreenStarts[0].X); - Assert.Equal(3,barSeries.BarScreenEnds[0].X); + Assert.Equal (3, barSeries.BarScreenStarts [0].X); + Assert.Equal (3, barSeries.BarScreenEnds [0].X); // second bar should be BarEveryx2 = 2f + offset 0.5f = 5 screen units - Assert.Equal(5,barSeries.BarScreenStarts[1].X); - Assert.Equal(5,barSeries.BarScreenEnds[1].X); + Assert.Equal (5, barSeries.BarScreenStarts [1].X); + Assert.Equal (5, barSeries.BarScreenEnds [1].X); // both bars should have labels - Assert.Equal(2,axisX.LabelPoints.Count); - Assert.Contains(3, axisX.LabelPoints); - Assert.Contains(5, axisX.LabelPoints); + Assert.Equal (2, axisX.LabelPoints.Count); + Assert.Contains (3, axisX.LabelPoints); + Assert.Contains (5, axisX.LabelPoints); // bars are very tall but should not draw up off top of screen - Assert.Equal(9,barSeries.BarScreenStarts[0].Y); - Assert.Equal(0,barSeries.BarScreenEnds[0].Y); - Assert.Equal(9,barSeries.BarScreenStarts[1].Y); - Assert.Equal(0,barSeries.BarScreenEnds[1].Y); + Assert.Equal (9, barSeries.BarScreenStarts [0].Y); + Assert.Equal (0, barSeries.BarScreenEnds [0].Y); + Assert.Equal (9, barSeries.BarScreenStarts [1].Y); + Assert.Equal (0, barSeries.BarScreenEnds [1].Y); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); } [Fact] - public void TestOneLongOneShortHorizontalBars_WithOffset(){ + public void TestOneLongOneShortHorizontalBars_WithOffset () + { - var graph = GetGraph(out FakeBarSeries barSeries, out FakeHAxis axisX, out FakeVAxis axisY); - graph.Redraw(graph.Bounds); + var graph = GetGraph (out FakeBarSeries barSeries, out FakeHAxis axisX, out FakeVAxis axisY); + graph.Redraw (graph.Bounds); // no bars - Assert.Empty(barSeries.BarScreenStarts); - Assert.Empty(axisX.LabelPoints); - Assert.Empty(axisY.LabelPoints); + Assert.Empty (barSeries.BarScreenStarts); + Assert.Empty (axisX.LabelPoints); + Assert.Empty (axisY.LabelPoints); // 0.1 units of graph y fit every screen row // so 1 unit of graph y space is 10 screen rows - graph.CellSize = new PointF(0.5f,0.1f); + graph.CellSize = new PointF (0.5f, 0.1f); // Start bar 3 screen units up (y = height-3) barSeries.Offset = 0.25f; @@ -896,64 +949,64 @@ namespace Terminal.Gui.Views { barSeries.Orientation = Orientation.Horizontal; // 1 bar that is very wide (100 graph units horizontally = screen pos 50 but bounded by screen) - barSeries.Bars.Add( - new BarSeries.Bar("hi1",new GraphCellToRender('.'),100)); + barSeries.Bars.Add ( + new BarSeries.Bar ("hi1", new GraphCellToRender ('.'), 100)); // 1 bar that is shorter - barSeries.Bars.Add( - new BarSeries.Bar("hi2",new GraphCellToRender('.'),5)); + barSeries.Bars.Add ( + new BarSeries.Bar ("hi2", new GraphCellToRender ('.'), 5)); // redraw graph - graph.Redraw(graph.Bounds); + graph.Redraw (graph.Bounds); // since bars are horizontal all have the same X start cordinates - Assert.Equal(0,barSeries.BarScreenStarts[0].X); - Assert.Equal(0,barSeries.BarScreenStarts[1].X); + Assert.Equal (0, barSeries.BarScreenStarts [0].X); + Assert.Equal (0, barSeries.BarScreenStarts [1].X); // bar goes all the way to the end so bumps up against right screen boundary // width of graph is 20 - Assert.Equal(19,barSeries.BarScreenEnds[0].X); + Assert.Equal (19, barSeries.BarScreenEnds [0].X); // shorter bar is 5 graph units wide which is 10 screen units - Assert.Equal(10,barSeries.BarScreenEnds[1].X); + Assert.Equal (10, barSeries.BarScreenEnds [1].X); // first bar should be offset 6 screen units (0.25f + 0.3f graph units) // since height of control is 10 then first bar should be at screen row 4 (10-6) - Assert.Equal(4,barSeries.BarScreenStarts[0].Y); + Assert.Equal (4, barSeries.BarScreenStarts [0].Y); // second bar should be offset 9 screen units (0.25f + 0.6f graph units) // since height of control is 10 then second bar should be at screen row 1 (10-9) - Assert.Equal(1,barSeries.BarScreenStarts[1].Y); + Assert.Equal (1, barSeries.BarScreenStarts [1].Y); // both bars should have labels but on the y axis - Assert.Equal(2,axisY.LabelPoints.Count); - Assert.Empty(axisX.LabelPoints); + Assert.Equal (2, axisY.LabelPoints.Count); + Assert.Empty (axisX.LabelPoints); // labels should align with the bars (same screen y axis point) - Assert.Contains(4, axisY.LabelPoints); - Assert.Contains(1, axisY.LabelPoints); + Assert.Contains (4, axisY.LabelPoints); + Assert.Contains (1, axisY.LabelPoints); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); } - private class FakeBarSeries : BarSeries{ + private class FakeBarSeries : BarSeries { public GraphCellToRender FinalColor { get; private set; } - public List BarScreenStarts { get; private set; } = new List(); - public List BarScreenEnds { get; private set; } = new List(); - + public List BarScreenStarts { get; private set; } = new List (); + public List BarScreenEnds { get; private set; } = new List (); + protected override GraphCellToRender AdjustColor (GraphCellToRender graphCellToRender) { - return FinalColor = base.AdjustColor (graphCellToRender); + return FinalColor = base.AdjustColor (graphCellToRender); } protected override void DrawBarLine (GraphView graph, Point start, Point end, Bar beingDrawn) { base.DrawBarLine (graph, start, end, beingDrawn); - - BarScreenStarts.Add(start); - BarScreenEnds.Add(end); + + BarScreenStarts.Add (start); + BarScreenEnds.Add (end); } } @@ -965,11 +1018,11 @@ namespace Terminal.Gui.Views { private GraphView GetGraph (out FakeHAxis axis) { - return GetGraph(out axis, out _); + return GetGraph (out axis, out _); } private GraphView GetGraph (out FakeVAxis axis) { - return GetGraph(out _, out axis); + return GetGraph (out _, out axis); } private GraphView GetGraph (out FakeHAxis axisX, out FakeVAxis axisY) { @@ -1003,15 +1056,15 @@ namespace Terminal.Gui.Views { gv.Redraw (gv.Bounds); Assert.DoesNotContain (new Point (-1, 29), axis.DrawAxisLinePoints); - Assert.Contains (new Point (0, 29),axis.DrawAxisLinePoints); + Assert.Contains (new Point (0, 29), axis.DrawAxisLinePoints); Assert.Contains (new Point (1, 29), axis.DrawAxisLinePoints); - + Assert.Contains (new Point (48, 29), axis.DrawAxisLinePoints); Assert.Contains (new Point (49, 29), axis.DrawAxisLinePoints); Assert.DoesNotContain (new Point (50, 29), axis.DrawAxisLinePoints); - Assert.InRange(axis.LabelPoints.Max(),0,49); - Assert.InRange(axis.LabelPoints.Min(),0,49); + Assert.InRange (axis.LabelPoints.Max (), 0, 49); + Assert.InRange (axis.LabelPoints.Min (), 0, 49); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1033,8 +1086,8 @@ namespace Terminal.Gui.Views { Assert.Contains (new Point (49, 19), axis.DrawAxisLinePoints); Assert.DoesNotContain (new Point (50, 19), axis.DrawAxisLinePoints); - Assert.InRange(axis.LabelPoints.Max(),0,49); - Assert.InRange(axis.LabelPoints.Min(),0,49); + Assert.InRange (axis.LabelPoints.Max (), 0, 49); + Assert.InRange (axis.LabelPoints.Min (), 0, 49); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1057,8 +1110,8 @@ namespace Terminal.Gui.Views { Assert.DoesNotContain (new Point (50, 29), axis.DrawAxisLinePoints); // Axis lables should not be drawn in the margin - Assert.InRange(axis.LabelPoints.Max(),5,49); - Assert.InRange(axis.LabelPoints.Min(),5,49); + Assert.InRange (axis.LabelPoints.Max (), 5, 49); + Assert.InRange (axis.LabelPoints.Min (), 5, 49); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1081,15 +1134,15 @@ namespace Terminal.Gui.Views { gv.Redraw (gv.Bounds); Assert.DoesNotContain (new Point (0, -1), axis.DrawAxisLinePoints); - Assert.Contains (new Point (0, 1),axis.DrawAxisLinePoints); + Assert.Contains (new Point (0, 1), axis.DrawAxisLinePoints); Assert.Contains (new Point (0, 2), axis.DrawAxisLinePoints); - + Assert.Contains (new Point (0, 28), axis.DrawAxisLinePoints); Assert.Contains (new Point (0, 29), axis.DrawAxisLinePoints); Assert.DoesNotContain (new Point (0, 30), axis.DrawAxisLinePoints); - Assert.InRange(axis.LabelPoints.Max(),0,29); - Assert.InRange(axis.LabelPoints.Min(),0,29); + Assert.InRange (axis.LabelPoints.Max (), 0, 29); + Assert.InRange (axis.LabelPoints.Min (), 0, 29); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1104,16 +1157,16 @@ namespace Terminal.Gui.Views { gv.Redraw (gv.Bounds); Assert.DoesNotContain (new Point (0, -1), axis.DrawAxisLinePoints); - Assert.Contains (new Point (0, 1),axis.DrawAxisLinePoints); + Assert.Contains (new Point (0, 1), axis.DrawAxisLinePoints); Assert.Contains (new Point (0, 2), axis.DrawAxisLinePoints); - + Assert.Contains (new Point (0, 18), axis.DrawAxisLinePoints); Assert.Contains (new Point (0, 19), axis.DrawAxisLinePoints); Assert.DoesNotContain (new Point (0, 20), axis.DrawAxisLinePoints); // Labels should not be drawn into the axis - Assert.InRange(axis.LabelPoints.Max(),0,19); - Assert.InRange(axis.LabelPoints.Min(),0,19); + Assert.InRange (axis.LabelPoints.Max (), 0, 19); + Assert.InRange (axis.LabelPoints.Min (), 0, 19); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1128,15 +1181,15 @@ namespace Terminal.Gui.Views { gv.Redraw (gv.Bounds); Assert.DoesNotContain (new Point (5, -1), axis.DrawAxisLinePoints); - Assert.Contains (new Point (5, 1),axis.DrawAxisLinePoints); + Assert.Contains (new Point (5, 1), axis.DrawAxisLinePoints); Assert.Contains (new Point (5, 2), axis.DrawAxisLinePoints); - + Assert.Contains (new Point (5, 28), axis.DrawAxisLinePoints); Assert.Contains (new Point (5, 29), axis.DrawAxisLinePoints); Assert.DoesNotContain (new Point (5, 30), axis.DrawAxisLinePoints); - Assert.InRange(axis.LabelPoints.Max(),0,29); - Assert.InRange(axis.LabelPoints.Min(),0,29); + Assert.InRange (axis.LabelPoints.Max (), 0, 29); + Assert.InRange (axis.LabelPoints.Min (), 0, 29); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1148,13 +1201,13 @@ namespace Terminal.Gui.Views { public class TextAnnotationTests { readonly ITestOutputHelper output; - public TextAnnotationTests(ITestOutputHelper output) + public TextAnnotationTests (ITestOutputHelper output) { this.output = output; } [Fact] - public void TestTextAnnotation_ScreenUnits() + public void TestTextAnnotation_ScreenUnits () { var gv = GraphViewTests.GetGraph (); @@ -1177,8 +1230,8 @@ namespace Terminal.Gui.Views { // user scrolls up one unit of graph space gv.ScrollOffset = new PointF (0, 1f); - gv.Redraw (gv.Bounds); - + gv.Redraw (gv.Bounds); + // we expect no change in the location of the annotation (only the axis label changes) // this is because screen units are constant and do not change as the viewport into // graph space scrolls to different areas of the graph @@ -1301,7 +1354,7 @@ namespace Terminal.Gui.Views { } [Theory] - [InlineData(null)] + [InlineData (null)] [InlineData (" ")] [InlineData ("\t\t")] public void TestTextAnnotation_EmptyText (string whitespace) @@ -1316,7 +1369,7 @@ namespace Terminal.Gui.Views { // add a point a bit further along the graph so if the whitespace were rendered // the test would pick it up (AssertDriverContentsAre ignores trailing whitespace on lines) var points = new ScatterSeries (); - points.Points.Add(new PointF(7, 2)); + points.Points.Add (new PointF (7, 2)); gv.Series.Add (points); gv.Redraw (gv.Bounds); @@ -1340,7 +1393,7 @@ namespace Terminal.Gui.Views { public class LegendTests { readonly ITestOutputHelper output; - public LegendTests(ITestOutputHelper output) + public LegendTests (ITestOutputHelper output) { this.output = output; } @@ -1349,7 +1402,7 @@ namespace Terminal.Gui.Views { public void LegendNormalUsage_WithBorder () { var gv = GraphViewTests.GetGraph (); - var legend = new LegendAnnotation(new Rect(2,0,5,3)); + var legend = new LegendAnnotation (new Rect (2, 0, 5, 3)); legend.AddEntry (new GraphCellToRender ('A'), "Ant"); legend.AddEntry (new GraphCellToRender ('B'), "Bat"); @@ -1404,13 +1457,13 @@ namespace Terminal.Gui.Views { public class PathAnnotationTests { readonly ITestOutputHelper output; - public PathAnnotationTests( ITestOutputHelper output) + public PathAnnotationTests (ITestOutputHelper output) { this.output = output; } [Fact] - public void PathAnnotation_Box() + public void PathAnnotation_Box () { var gv = GraphViewTests.GetGraph (); @@ -1480,9 +1533,9 @@ namespace Terminal.Gui.Views { // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); } - + [Fact] - public void XAxisLabels_With_MarginLeft() + public void XAxisLabels_With_MarginLeft () { GraphViewTests.InitFakeDriver (); var gv = new GraphView { @@ -1499,7 +1552,7 @@ namespace Terminal.Gui.Views { }); // reserve 3 cells of the left for the margin - gv.MarginLeft = 3; + gv.MarginLeft = 3; gv.MarginBottom = 1; gv.Redraw (gv.Bounds); @@ -1515,7 +1568,7 @@ namespace Terminal.Gui.Views { 0 5 "; - GraphViewTests.AssertDriverContentsAre (expected, output); + GraphViewTests.AssertDriverContentsAre (expected, output); // Shutdown must be called to safely clean up Application if Init has been called @@ -1599,7 +1652,7 @@ namespace Terminal.Gui.Views { 0┼┬┬┬┬┬┬┬┬ 0 5"; - GraphViewTests.AssertDriverContentsAre (expected,output); + GraphViewTests.AssertDriverContentsAre (expected, output); // Shutdown must be called to safely clean up Application if Init has been called @@ -1657,11 +1710,11 @@ namespace Terminal.Gui.Views { } } - public class AxisIncrementToRenderTests { + public class AxisIncrementToRenderTests { [Fact] public void AxisIncrementToRenderTests_Constructor () { - var render = new AxisIncrementToRender (Orientation.Horizontal,1,6.6f); + var render = new AxisIncrementToRender (Orientation.Horizontal, 1, 6.6f); Assert.Equal (Orientation.Horizontal, render.Orientation); Assert.Equal (1, render.ScreenLocation); diff --git a/UnitTests/MenuTests.cs b/UnitTests/MenuTests.cs index 7e687210d..acdc58b37 100644 --- a/UnitTests/MenuTests.cs +++ b/UnitTests/MenuTests.cs @@ -512,8 +512,8 @@ Edit └──────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 1), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 1, 8, 4), pos); } [Fact, AutoInitShutdown] @@ -541,8 +541,8 @@ Edit ──────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 7, 4), pos); menu.CloseAllMenus (); menu.Frame = new Rect (-1, -2, menu.Frame.Width, menu.Frame.Height); @@ -555,8 +555,8 @@ Edit ──────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (1, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 7, 3), pos); menu.CloseAllMenus (); menu.Frame = new Rect (0, 0, menu.Frame.Width, menu.Frame.Height); @@ -566,13 +566,13 @@ Edit expected = @" ┌────── -│ One -│ Two +│ One +│ Two └────── "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 1), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 1, 7, 4), pos); menu.CloseAllMenus (); menu.Frame = new Rect (0, 0, menu.Frame.Width, menu.Frame.Height); @@ -582,12 +582,12 @@ Edit expected = @" ┌────── -│ One -│ Two +│ One +│ Two "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 1), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 1, 7, 3), pos); } [Fact, AutoInitShutdown] @@ -614,8 +614,8 @@ Edit Numbers "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 9, 1), pos); Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null))); Application.Top.Redraw (Application.Top.Bounds); @@ -628,8 +628,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 10, 6), pos); Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.CursorDown, null))); Application.Top.Redraw (Application.Top.Bounds); @@ -643,8 +643,8 @@ Edit └─────────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 25, 7), pos); Assert.True (Application.Top.Subviews [2].ProcessKey (new KeyEvent (Key.CursorLeft, null))); Application.Top.Redraw (Application.Top.Bounds); @@ -657,8 +657,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 10, 6), pos); Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Esc, null))); Application.Top.Redraw (Application.Top.Bounds); @@ -666,8 +666,8 @@ Edit Numbers "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 9, 1), pos); } [Fact, AutoInitShutdown] @@ -694,8 +694,8 @@ Edit Numbers "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 9, 1), pos); Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, @@ -713,8 +713,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 10, 6), pos); Assert.False (menu.MouseEvent (new MouseEvent () { X = 1, @@ -733,8 +733,8 @@ Edit └─────────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 25, 7), pos); Assert.False (menu.MouseEvent (new MouseEvent () { X = 1, @@ -752,8 +752,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 10, 6), pos); Assert.False (menu.MouseEvent (new MouseEvent () { X = 70, @@ -766,8 +766,8 @@ Edit Numbers "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 9, 1), pos); } [Fact, AutoInitShutdown] @@ -796,8 +796,8 @@ Edit Numbers "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 9, 1), pos); Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null))); Application.Top.Redraw (Application.Top.Bounds); @@ -810,8 +810,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 10, 6), pos); Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.CursorDown, null))); Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Enter, null))); @@ -826,8 +826,8 @@ Edit └─────────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 15, 7), pos); Assert.True (Application.Top.Subviews [2].ProcessKey (new KeyEvent (Key.Enter, null))); Application.Top.Redraw (Application.Top.Bounds); @@ -840,8 +840,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 10, 6), pos); Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Esc, null))); Application.Top.Redraw (Application.Top.Bounds); @@ -849,8 +849,8 @@ Edit Numbers "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 9, 1), pos); } [Fact, AutoInitShutdown] @@ -879,8 +879,8 @@ Edit Numbers "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 9, 1), pos); Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, @@ -898,8 +898,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 10, 6), pos); Assert.False (menu.MouseEvent (new MouseEvent () { X = 1, @@ -918,8 +918,8 @@ Edit └─────────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 15, 7), pos); Assert.False (menu.MouseEvent (new MouseEvent () { X = 1, @@ -937,8 +937,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 10, 6), pos); Assert.False (menu.MouseEvent (new MouseEvent () { X = 70, @@ -951,12 +951,12 @@ Edit Numbers "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 9, 1), pos); } [Fact, AutoInitShutdown] - public void HotKey_MenuBar_OnKeyDown_OnKeyUp_ProcessKey () + public void HotKey_MenuBar_OnKeyDown_OnKeyUp_ProcessHotKey_ProcessKey () { var newAction = false; var copyAction = false; @@ -983,16 +983,22 @@ Edit File Edit "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 13, 1), pos); Assert.True (menu.ProcessKey (new (Key.N, null))); Application.MainLoop.MainIteration (); Assert.True (newAction); - Assert.False (menu.OnKeyDown (new (Key.AltMask, new KeyModifiers () { Alt = true }))); - Assert.True (menu.OnKeyUp (new (Key.AltMask, new KeyModifiers () { Alt = true }))); + Assert.True (menu.ProcessHotKey (new (Key.AltMask, new KeyModifiers () { Alt = true }))); Assert.True (menu.IsMenuOpen); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + File Edit +"; + + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 13, 1), pos); Assert.True (menu.ProcessKey (new (Key.CursorRight, null))); Assert.True (menu.ProcessKey (new (Key.C, null))); @@ -1030,8 +1036,8 @@ Edit └───────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 13, 4), pos); Assert.True (Application.Top.Subviews [1].ProcessKey (new (Key.N, null))); Application.MainLoop.MainIteration (); @@ -1047,8 +1053,8 @@ Edit └────────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (2, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 17, 4), pos); Assert.True (Application.Top.Subviews [1].ProcessKey (new (Key.C, null))); Application.MainLoop.MainIteration (); diff --git a/UnitTests/ViewTests.cs b/UnitTests/ViewTests.cs index 15a20b6a6..fb33d39c2 100644 --- a/UnitTests/ViewTests.cs +++ b/UnitTests/ViewTests.cs @@ -1876,8 +1876,8 @@ namespace Terminal.Gui.Core { └──────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 8, 4), pos); } [Fact, AutoInitShutdown] @@ -1900,8 +1900,8 @@ namespace Terminal.Gui.Core { ──────┘ "; - var pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 0), pos); + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 7, 4), pos); view.Frame = new Rect (-1, -1, 8, 4); Application.Refresh (); @@ -1912,33 +1912,33 @@ namespace Terminal.Gui.Core { ──────┘ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (6, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (6, 0, 7, 3), pos); view.Frame = new Rect (0, 0, 8, 4); ((FakeDriver)Application.Driver).SetBufferSize (7, 4); expected = @" ┌────── -│ -│ +│ +│ └────── "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 7, 4), pos); view.Frame = new Rect (0, 0, 8, 4); ((FakeDriver)Application.Driver).SetBufferSize (7, 3); expected = @" ┌────── -│ -│ +│ +│ "; - pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output); - Assert.Equal (new Point (0, 0), pos); + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (0, 0, 7, 3), pos); } } } From c1649981b5430ebd9841c36d1eaae989cfcfb5b2 Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 11 Mar 2022 13:07:43 +0000 Subject: [PATCH 3/9] Implementing UseSubMenusSingleFrame in context menu. --- Terminal.Gui/Core/ContextMenu.cs | 8 +++++++- Terminal.Gui/Views/Menu.cs | 4 +++- UICatalog/Scenarios/ContextMenus.cs | 13 ++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Terminal.Gui/Core/ContextMenu.cs b/Terminal.Gui/Core/ContextMenu.cs index 75869b2b4..3c949cf19 100644 --- a/Terminal.Gui/Core/ContextMenu.cs +++ b/Terminal.Gui/Core/ContextMenu.cs @@ -106,7 +106,8 @@ namespace Terminal.Gui { X = position.X, Y = position.Y, Width = 0, - Height = 0 + Height = 0, + UseSubMenusSingleFrame = UseSubMenusSingleFrame }; menuBar.isContextMenuLoading = true; @@ -201,5 +202,10 @@ namespace Terminal.Gui { /// Gets the that is hosting this context menu. /// public MenuBar MenuBar { get => menuBar; } + + /// + /// Gets or sets if the sub-menus must be displayed in a single or multiple frames. + /// + public bool UseSubMenusSingleFrame { get; set; } } } diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 6faeded35..cb53a7162 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -757,8 +757,10 @@ namespace Terminal.Gui { if (item == null || !item.IsEnabled ()) disabled = true; if (item != null && !disabled) current = me.Y - 1; - if (host.UseSubMenusSingleFrame || !CheckSubMenu ()) + if (host.UseSubMenusSingleFrame || !CheckSubMenu ()) { + SetNeedsDisplay (); return true; + } host.OnMenuOpened (); return true; } diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index 15f9d9c2b..d86d049bc 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -12,12 +12,19 @@ namespace UICatalog.Scenarios { private MenuItem miForceMinimumPosToZero; private bool forceMinimumPosToZero = true; private TextField tfTopLeft, tfTopRight, tfMiddle, tfBottomLeft, tfBottomRight; + private MenuItem miUseSubMenusSingleFrame; + private bool useSubMenusSingleFrame; public override void Setup () { var text = "Context Menu"; var width = 20; + Win.Add (new Label ("Press 'Ctrl + Space' to open the Window context menu.") { + X = Pos.Center (), + Y = 1 + }); + tfTopLeft = new TextField (text) { Width = width }; @@ -89,10 +96,14 @@ namespace UICatalog.Scenarios { tfBottomLeft.ContextMenu.ForceMinimumPosToZero = forceMinimumPosToZero; tfBottomRight.ContextMenu.ForceMinimumPosToZero = forceMinimumPosToZero; }) { CheckType = MenuItemCheckStyle.Checked, Checked = forceMinimumPosToZero }, + miUseSubMenusSingleFrame = new MenuItem ("Use_SubMenusSingleFrame", "", + () => contextMenu.UseSubMenusSingleFrame = miUseSubMenusSingleFrame.Checked = useSubMenusSingleFrame = !useSubMenusSingleFrame) { + CheckType = MenuItemCheckStyle.Checked, Checked = useSubMenusSingleFrame + }, null, new MenuItem ("_Quit", "", () => Application.RequestStop ()) }) - ) { ForceMinimumPosToZero = forceMinimumPosToZero }; + ) { ForceMinimumPosToZero = forceMinimumPosToZero, UseSubMenusSingleFrame = useSubMenusSingleFrame }; tfTopLeft.ContextMenu.ForceMinimumPosToZero = forceMinimumPosToZero; tfTopRight.ContextMenu.ForceMinimumPosToZero = forceMinimumPosToZero; From 3e3b67889d92e2ce095807fb6b169ffecaaee2c5 Mon Sep 17 00:00:00 2001 From: BDisp Date: Fri, 11 Mar 2022 20:37:31 +0000 Subject: [PATCH 4/9] It is needed to get rid of the first and the last line ending of expectedLook. --- UnitTests/GraphViewTests.cs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/UnitTests/GraphViewTests.cs b/UnitTests/GraphViewTests.cs index c69a09787..85ae0863a 100644 --- a/UnitTests/GraphViewTests.cs +++ b/UnitTests/GraphViewTests.cs @@ -105,7 +105,7 @@ namespace Terminal.Gui.Views { expectedLook = trailingWhitespace.Replace (expectedLook, "").Trim (); actualLook = trailingWhitespace.Replace (actualLook, "").Trim (); - // standardise line endings for the comparison + // standardize line endings for the comparison expectedLook = expectedLook.Replace ("\r\n", "\n"); actualLook = actualLook.Replace ("\r\n", "\n"); @@ -168,9 +168,6 @@ namespace Terminal.Gui.Views { } row.RemoveAt (c); } - if (row.Count == 0) { - lines.Remove (row); - } } // Convert char list to string @@ -187,16 +184,18 @@ namespace Terminal.Gui.Views { if (!string.Equals (expectedLook, actualLook)) { - // Remove the first empty line from the expectedLook - expectedLook = string.Join (Environment.NewLine, expectedLook - .Split (Environment.NewLine.ToCharArray ()) - .Skip (1) - .ToArray ()).TrimEnd (); - - // standardise line endings for the comparison + // standardize line endings for the comparison expectedLook = expectedLook.Replace ("\r\n", "\n"); actualLook = actualLook.Replace ("\r\n", "\n"); + // Remove the first and the last line ending from the expectedLook + if (expectedLook.StartsWith ("\n")) { + expectedLook = expectedLook [1..]; + } + if (expectedLook.EndsWith ("\n")) { + expectedLook = expectedLook [..^1]; + } + output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); output?.WriteLine ("But Was:" + Environment.NewLine + actualLook); From 08f2e673941f963e009f68043402a599cb81fa2f Mon Sep 17 00:00:00 2001 From: BDisp Date: Mon, 7 Mar 2022 22:59:08 +0000 Subject: [PATCH 5/9] Implementing context menu and localization on TextView. --- UICatalog/Scenarios/Editor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index 92b06fbae..f28d31622 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -27,7 +27,7 @@ namespace UICatalog.Scenarios { private Window winDialog; private TabView _tabView; private MenuItem miForceMinimumPosToZero; - private bool forceMinimumPosToZero = true; + private bool forceMinimumPosToZero; private readonly List cultureInfos = Application.SupportedCultures; public override void Init (Toplevel top, ColorScheme colorScheme) @@ -103,7 +103,7 @@ namespace UICatalog.Scenarios { miForceMinimumPosToZero = new MenuItem ("ForceMinimumPosTo_Zero", "", () => { miForceMinimumPosToZero.Checked = forceMinimumPosToZero = !forceMinimumPosToZero; _textView.ContextMenu.ForceMinimumPosToZero = forceMinimumPosToZero; - }) { CheckType = MenuItemCheckStyle.Checked, Checked = forceMinimumPosToZero }, + }), new MenuBarItem ("_Languages", GetSupportedCultures ()) }) }); From ef4ae179592bab9a1eeaf328f6d334760135db68 Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 8 Mar 2022 16:28:05 +0000 Subject: [PATCH 6/9] Change CheckType to MenuItemCheckStyle.Checked --- UICatalog/Scenarios/Editor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index f28d31622..92b06fbae 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -27,7 +27,7 @@ namespace UICatalog.Scenarios { private Window winDialog; private TabView _tabView; private MenuItem miForceMinimumPosToZero; - private bool forceMinimumPosToZero; + private bool forceMinimumPosToZero = true; private readonly List cultureInfos = Application.SupportedCultures; public override void Init (Toplevel top, ColorScheme colorScheme) @@ -103,7 +103,7 @@ namespace UICatalog.Scenarios { miForceMinimumPosToZero = new MenuItem ("ForceMinimumPosTo_Zero", "", () => { miForceMinimumPosToZero.Checked = forceMinimumPosToZero = !forceMinimumPosToZero; _textView.ContextMenu.ForceMinimumPosToZero = forceMinimumPosToZero; - }), + }) { CheckType = MenuItemCheckStyle.Checked, Checked = forceMinimumPosToZero }, new MenuBarItem ("_Languages", GetSupportedCultures ()) }) }); From 3e6a96fa7ed44715d5e04a49c90a3a4a7fdf496d Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 12 Mar 2022 17:57:55 +0000 Subject: [PATCH 7/9] Added HeightAsBuffer to the menu allowing to being configurable. --- Example/demo.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index c963aff9e..c78c8066c 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -239,6 +239,7 @@ static class Demo { static void Editor () { Application.Init (); + Application.HeightAsBuffer = heightAsBuffer; var ntop = Application.Top; @@ -582,13 +583,14 @@ static class Demo { public static MenuBar menu; public static CheckBox menuKeysStyle; public static CheckBox menuAutoMouseNav; + private static bool heightAsBuffer = false; static void MainApp () { if (Debugger.IsAttached) CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US"); Application.Init (); - Application.HeightAsBuffer = true; + Application.HeightAsBuffer = heightAsBuffer; //ConsoleDriver.Diagnostics = ConsoleDriver.DiagnosticFlags.FramePadding | ConsoleDriver.DiagnosticFlags.FrameRuler; var top = Application.Top; @@ -623,6 +625,8 @@ static class Demo { MenuItem miUseSubMenusSingleFrame = null; var useSubMenusSingleFrame = false; + MenuItem miHeightAsBuffer = null; + menu = new MenuBar (new MenuBarItem [] { new MenuBarItem ("_File", new MenuItem [] { new MenuItem ("Text _Editor Demo", "", () => { running = Editor; Application.RequestStop (); }, null, null, Key.AltMask | Key.CtrlMask | Key.D), @@ -644,7 +648,11 @@ static class Demo { miUseSubMenusSingleFrame = new MenuItem ("Use_SubMenusSingleFrame", "", () => menu.UseSubMenusSingleFrame = miUseSubMenusSingleFrame.Checked = useSubMenusSingleFrame = !useSubMenusSingleFrame) { CheckType = MenuItemCheckStyle.Checked, Checked = useSubMenusSingleFrame - } + }, + miHeightAsBuffer = new MenuItem ("_Height As Buffer", "", () => { + miHeightAsBuffer.Checked = heightAsBuffer = !heightAsBuffer; + Application.HeightAsBuffer = heightAsBuffer; + }) { CheckType = MenuItemCheckStyle.Checked, Checked = heightAsBuffer } }), new MenuBarItem ("_List Demos", new MenuItem [] { new MenuItem ("Select _Multiple Items", "", () => ListSelectionDemo (true), null, null, Key.AltMask + 0.ToString () [0]), From 04f98170236e633e992c114d70ea37c3d926349b Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 12 Mar 2022 18:20:00 +0000 Subject: [PATCH 8/9] Fixes view to screen relative on the context menu. --- Terminal.Gui/Core/ContextMenu.cs | 15 ++- UICatalog/Scenarios/ContextMenus.cs | 15 ++- UnitTests/ContextMenuTests.cs | 200 +++++++++++++++++++++++++--- 3 files changed, 202 insertions(+), 28 deletions(-) diff --git a/Terminal.Gui/Core/ContextMenu.cs b/Terminal.Gui/Core/ContextMenu.cs index 3c949cf19..47e622d4e 100644 --- a/Terminal.Gui/Core/ContextMenu.cs +++ b/Terminal.Gui/Core/ContextMenu.cs @@ -22,7 +22,7 @@ namespace Terminal.Gui { /// The host view. /// The menu items. public ContextMenu (View host, MenuBarItem menuItems) : - this (host.Frame.X + 1, host.Frame.Bottom, menuItems) + this (host.Frame.X, host.Frame.Y, menuItems) { Host = host; } @@ -75,8 +75,13 @@ namespace Terminal.Gui { container.Resized += Container_Resized; var frame = container.Frame; var position = Position; - if (Host != null && position != new Point (Host.Frame.X + 1, Host.Frame.Bottom)) { - Position = position = new Point (Host.Frame.X + 1, Host.Frame.Bottom); + if (Host != null) { + Host.ViewToScreen (container.Frame.X, container.Frame.Y, out int x, out int y); + var pos = new Point (x, y); + pos.Y += Host.Frame.Height - 1; + if (position != pos) { + Position = position = pos; + } } var rect = Menu.MakeFrame (position.X, position.Y, MenuItens.Children); if (rect.Right >= frame.Right) { @@ -93,7 +98,9 @@ namespace Terminal.Gui { if (Host == null) { position.Y = frame.Bottom - rect.Height - 1; } else { - position.Y = Host.Frame.Y - rect.Height; + Host.ViewToScreen (container.Frame.X, container.Frame.Y, out int x, out int y); + var pos = new Point (x, y); + position.Y = pos.Y - rect.Height - 1; } } else if (ForceMinimumPosToZero) { position.Y = 0; diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index d86d049bc..e9cd220d2 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -59,7 +59,7 @@ namespace UICatalog.Scenarios { Point mousePos = default; Win.KeyPress += (e) => { - if (e.KeyEvent.Key == (Key.Space | Key.CtrlMask) && !ContextMenu.IsShow) { + if (e.KeyEvent.Key == (Key.Space | Key.CtrlMask)) { ShowContextMenu (mousePos.X, mousePos.Y); e.Handled = true; } @@ -70,12 +70,21 @@ namespace UICatalog.Scenarios { ShowContextMenu (e.MouseEvent.X, e.MouseEvent.Y); e.Handled = true; } - mousePos = new Point (e.MouseEvent.X, e.MouseEvent.Y); }; + Application.RootMouseEvent += Application_RootMouseEvent; + + void Application_RootMouseEvent (MouseEvent me) + { + mousePos = new Point (me.X, me.Y); + } + Win.WantMousePositionReports = true; - Top.Closed += (_) => Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US"); + Top.Closed += (_) => { + Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US"); + Application.RootMouseEvent -= Application_RootMouseEvent; + }; } private void ShowContextMenu (int x, int y) diff --git a/UnitTests/ContextMenuTests.cs b/UnitTests/ContextMenuTests.cs index 496245e75..a975f96c7 100644 --- a/UnitTests/ContextMenuTests.cs +++ b/UnitTests/ContextMenuTests.cs @@ -42,7 +42,7 @@ namespace Terminal.Gui.Core { new MenuItem ("Two", "", null) }) ); - Assert.Equal (new Point (6, 10), cm.Position); + Assert.Equal (new Point (5, 10), cm.Position); Assert.Equal (2, cm.MenuItens.Children.Length); Assert.NotNull (cm.Host); } @@ -279,64 +279,100 @@ namespace Terminal.Gui.Core { [Fact, AutoInitShutdown] public void Show_Ensures_Display_Inside_The_Container_Without_Overlap_The_Host () { - var cm = new ContextMenu (new View () { X = 69, Y = 24, Width = 10, Height = 1 }, + var view = new View ("View") { + X = Pos.AnchorEnd (10), + Y = Pos.AnchorEnd (1), + Width = 10, + Height = 1 + }; + var cm = new ContextMenu (view, new MenuBarItem (new MenuItem [] { new MenuItem ("One", "", null), new MenuItem ("Two", "", null) }) ); - Assert.Equal (new Point (70, 25), cm.Position); + Application.Top.Add (view); + Application.Begin (Application.Top); + + Assert.Equal (new Rect (70, 24, 10, 1), view.Frame); + Assert.Equal (new Point (0, 0), cm.Position); cm.Show (); - Assert.Equal (new Point (70, 25), cm.Position); - Application.Begin (Application.Top); + Assert.Equal (new Point (70, 24), cm.Position); + Application.Top.Redraw (Application.Top.Bounds); var expected = @" ┌──────┐ │ One │ │ Two │ └──────┘ + View "; var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (70, 21, 78, 4), pos); + Assert.Equal (new Rect (70, 20, 78, 5), pos); cm.Hide (); - Assert.Equal (new Point (70, 25), cm.Position); + Assert.Equal (new Point (70, 24), cm.Position); } [Fact, AutoInitShutdown] public void Show_Display_Below_The_Bottom_Host_If_Has_Enough_Space () { - var cm = new ContextMenu (new View () { X = 10, Y = 5, Width = 10, Height = 1 }, + var view = new View ("View") { X = 10, Y = 5, Width = 10, Height = 1 }; + var cm = new ContextMenu (view, new MenuBarItem (new MenuItem [] { new MenuItem ("One", "", null), new MenuItem ("Two", "", null) }) ); - Assert.Equal (new Point (11, 6), cm.Position); - - cm.Host.X = 5; - cm.Host.Y = 10; - - cm.Show (); - Assert.Equal (new Point (6, 11), cm.Position); + Application.Top.Add (view); Application.Begin (Application.Top); + Assert.Equal (new Point (10, 5), cm.Position); + + cm.Show (); + Application.Top.Redraw (Application.Top.Bounds); + Assert.Equal (new Point (10, 5), cm.Position); + var expected = @" - ┌──────┐ - │ One │ - │ Two │ - └──────┘ + View + ┌──────┐ + │ One │ + │ Two │ + └──────┘ "; var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new Rect (6, 12, 14, 4), pos); + Assert.Equal (new Rect (10, 5, 18, 5), pos); cm.Hide (); - Assert.Equal (new Point (6, 11), cm.Position); + Assert.Equal (new Point (10, 5), cm.Position); + cm.Host.X = 5; + cm.Host.Y = 10; + cm.Host.Height = 3; + + cm.Show (); + Application.Top.Redraw (Application.Top.Bounds); + Assert.Equal (new Point (5, 12), cm.Position); + + expected = @" + View + + + ┌──────┐ + │ One │ + │ Two │ + └──────┘ +"; + + pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (5, 10, 13, 7), pos); + + cm.Hide (); + Assert.Equal (new Point (5, 12), cm.Position); } [Fact, AutoInitShutdown] @@ -515,5 +551,127 @@ namespace Terminal.Gui.Core { Assert.Equal (menu, Application.mouseGrabView); Assert.True (menu.IsMenuOpen); } + + [Fact, AutoInitShutdown] + public void ContextMenu_On_Toplevel_With_A_MenuBar_TextField_StatusBar () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("File", "", null), + new MenuBarItem ("Edit", "", null) + }); + + var label = new Label ("Label:") { + X = 2, + Y = 3 + }; + + var tf = new TextField ("TextField") { + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Width = 20 + }; + + var statusBar = new StatusBar (new StatusItem [] { + new StatusItem(Key.F1, "~F1~ Help", null), + new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", null) + }); + + Application.Top.Add (menu, label, tf, statusBar); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (45, 17); + + Assert.Equal (new Rect (9, 3, 20, 1), tf.Frame); + Assert.True (tf.HasFocus); + + tf.ContextMenu.Show (); + Assert.True (ContextMenu.IsShow); + Assert.Equal (new Point (9, 3), tf.ContextMenu.Position); + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + File Edit + + + Label: TextField + ┌────────────────────────────┐ + │ Select All Ctrl+T │ + │ Delete All Ctrl+Shift+D │ + │ Copy Ctrl+C │ + │ Cut Ctrl+X │ + │ Paste Ctrl+V │ + │ Undo Ctrl+Z │ + │ Redo Ctrl+Y │ + └────────────────────────────┘ + + + + F1 Help │ ^Q Quit +"; + + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 39, 17), pos); + } + + [Fact, AutoInitShutdown] + public void ContextMenu_On_Toplevel_With_A_MenuBar_Window_TextField_StatusBar () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("File", "", null), + new MenuBarItem ("Edit", "", null) + }); + + var label = new Label ("Label:") { + X = 2, + Y = 3 + }; + + var tf = new TextField ("TextField") { + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Width = 20 + }; + + var win = new Window ("Window"); + win.Add (label, tf); + + var statusBar = new StatusBar (new StatusItem [] { + new StatusItem(Key.F1, "~F1~ Help", null), + new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", null) + }); + + Application.Top.Add (menu, win, statusBar); + Application.Begin (Application.Top); + ((FakeDriver)Application.Driver).SetBufferSize (45, 17); + + + Assert.Equal (new Rect (9, 3, 20, 1), tf.Frame); + Assert.True (tf.HasFocus); + + tf.ContextMenu.Show (); + Assert.True (ContextMenu.IsShow); + Assert.Equal (new Point (10, 5), tf.ContextMenu.Position); + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + File Edit +┌ Window ───────────────────────────────────┐ +│ │ +│ │ +│ │ +│ Label: TextField │ +│ ┌────────────────────────────┐ │ +│ │ Select All Ctrl+T │ │ +│ │ Delete All Ctrl+Shift+D │ │ +│ │ Copy Ctrl+C │ │ +│ │ Cut Ctrl+X │ │ +│ │ Paste Ctrl+V │ │ +│ │ Undo Ctrl+Z │ │ +│ │ Redo Ctrl+Y │ │ +│ └────────────────────────────┘ │ +└───────────────────────────────────────────┘ + F1 Help │ ^Q Quit +"; + + var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (2, 0, 45, 17), pos); + } } } From 3362ca849d82ce8fe6c11404c36793bfa8ff96b0 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 17 Mar 2022 16:39:15 +0000 Subject: [PATCH 9/9] Reorganizing scenarios categories as per #1648 --- UICatalog/Scenario.cs | 4 ++-- UICatalog/Scenarios/AllViewsTester.cs | 2 +- UICatalog/Scenarios/AutoSizeAndDirectionText.cs | 2 +- UICatalog/Scenarios/CharacterMap.cs | 2 +- UICatalog/Scenarios/ClassExplorer.cs | 2 +- UICatalog/Scenarios/ComboBoxIteration.cs | 2 +- UICatalog/Scenarios/ContextMenus.cs | 2 +- UICatalog/Scenarios/DynamicMenuBar.cs | 2 +- UICatalog/Scenarios/DynamicStatusBar.cs | 2 +- UICatalog/Scenarios/GraphViewExample.cs | 2 +- UICatalog/Scenarios/HexEditor.cs | 2 +- UICatalog/Scenarios/InteractiveTree.cs | 2 +- UICatalog/Scenarios/LineViewExample.cs | 2 +- UICatalog/Scenarios/ListViewWithSelection.cs | 2 +- UICatalog/Scenarios/ListsAndCombos.cs | 2 +- UICatalog/Scenarios/Mouse.cs | 2 +- UICatalog/Scenarios/MultiColouredTable.cs | 2 +- UICatalog/Scenarios/Notepad.cs | 2 +- UICatalog/Scenarios/Progress.cs | 2 +- UICatalog/Scenarios/ProgressBarStyles.cs | 2 +- UICatalog/Scenarios/Scrolling.cs | 2 +- UICatalog/Scenarios/SyntaxHighlighting.cs | 2 +- UICatalog/Scenarios/TabViewExample.cs | 2 +- UICatalog/Scenarios/TableEditor.cs | 2 +- UICatalog/Scenarios/TextAlignments.cs | 2 +- UICatalog/Scenarios/TextAlignmentsAndDirection.cs | 2 +- UICatalog/Scenarios/TextFormatterDemo.cs | 2 +- UICatalog/Scenarios/TextViewAutocompletePopup.cs | 2 +- UICatalog/Scenarios/TimeAndDate.cs | 2 +- UICatalog/Scenarios/TopLevelNoWindowBug.cs | 2 +- UICatalog/Scenarios/TreeUseCases.cs | 2 +- UICatalog/Scenarios/TreeViewFileSystem.cs | 2 +- UICatalog/Scenarios/Unicode.cs | 2 +- UICatalog/UICatalog.cs | 2 +- 34 files changed, 35 insertions(+), 35 deletions(-) diff --git a/UICatalog/Scenario.cs b/UICatalog/Scenario.cs index 2338334bd..30310288f 100644 --- a/UICatalog/Scenario.cs +++ b/UICatalog/Scenario.cs @@ -12,7 +12,7 @@ namespace UICatalog { /// /// Create a new .cs file in the Scenarios directory that derives from . /// Annotate the derived class with a attribute specifying the scenario's name and description. - /// Add one or more attributes to the class specifying which categories the scenario belongs to. If you don't specify a category the scenario will show up in "All". + /// Add one or more attributes to the class specifying which categories the scenario belongs to. If you don't specify a category the scenario will show up in "_All". /// Implement the override which will be called when a user selects the scenario to run. /// Optionally, implement the and/or overrides to provide a custom implementation. /// @@ -213,7 +213,7 @@ namespace UICatalog { /// internal static List GetAllCategories () { - List categories = new List () { "All" }; + List categories = new List () { "_All" }; foreach (Type type in typeof (Scenario).Assembly.GetTypes () .Where (myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf (typeof (Scenario)))) { List attrs = System.Attribute.GetCustomAttributes (type).ToList (); diff --git a/UICatalog/Scenarios/AllViewsTester.cs b/UICatalog/Scenarios/AllViewsTester.cs index 91060aeb3..84e2dcdfd 100644 --- a/UICatalog/Scenarios/AllViewsTester.cs +++ b/UICatalog/Scenarios/AllViewsTester.cs @@ -10,7 +10,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "All Views Tester", Description: "Provides a test UI for all classes derived from View")] - [ScenarioCategory ("Layout")] + [ScenarioCategory ("Layout"), ScenarioCategory ("StatusBar")] public class AllViewsTester : Scenario { Window _leftPane; ListView _classListView; diff --git a/UICatalog/Scenarios/AutoSizeAndDirectionText.cs b/UICatalog/Scenarios/AutoSizeAndDirectionText.cs index e036cb45e..3315ae292 100644 --- a/UICatalog/Scenarios/AutoSizeAndDirectionText.cs +++ b/UICatalog/Scenarios/AutoSizeAndDirectionText.cs @@ -2,7 +2,7 @@ namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "AutoSize and Direction Text", Description: "Demonstrates the text auto-size and direction manipulation.")] - [ScenarioCategory ("Text")] + [ScenarioCategory ("Text"), ScenarioCategory ("AutoSize"), ScenarioCategory ("Direction")] public class AutoSizeAndDirectionText : Scenario { public override void Setup () { diff --git a/UICatalog/Scenarios/CharacterMap.cs b/UICatalog/Scenarios/CharacterMap.cs index d9586305f..eb0f8e210 100644 --- a/UICatalog/Scenarios/CharacterMap.cs +++ b/UICatalog/Scenarios/CharacterMap.cs @@ -17,7 +17,7 @@ namespace UICatalog.Scenarios { /// [ScenarioMetadata (Name: "Character Map", Description: "Illustrates a custom control and Unicode")] [ScenarioCategory ("Text")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("ScrollView")] public class CharacterMap : Scenario { CharMap _charMap; public override void Setup () diff --git a/UICatalog/Scenarios/ClassExplorer.cs b/UICatalog/Scenarios/ClassExplorer.cs index be2b2ae36..14e43b0be 100644 --- a/UICatalog/Scenarios/ClassExplorer.cs +++ b/UICatalog/Scenarios/ClassExplorer.cs @@ -10,7 +10,7 @@ using Terminal.Gui.Trees; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Class Explorer", Description: "Tree view explorer for classes by namespace based on TreeView")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("TreeView")] public class ClassExplorer : Scenario { private TreeView treeView; private TextView textView; diff --git a/UICatalog/Scenarios/ComboBoxIteration.cs b/UICatalog/Scenarios/ComboBoxIteration.cs index 0cda1edf2..f3b90d552 100644 --- a/UICatalog/Scenarios/ComboBoxIteration.cs +++ b/UICatalog/Scenarios/ComboBoxIteration.cs @@ -3,7 +3,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "ComboBoxIteration", Description: "ComboBox iteration.")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("ComboBox")] public class ComboBoxIteration : Scenario { public override void Setup () { diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index e9cd220d2..9cb6b1ac3 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -5,7 +5,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "ContextMenus", Description: "Context Menu Sample")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Menu"), ScenarioCategory ("ContextMenu")] public class ContextMenus : Scenario { private ContextMenu contextMenu = new ContextMenu (); private readonly List cultureInfos = Application.SupportedCultures; diff --git a/UICatalog/Scenarios/DynamicMenuBar.cs b/UICatalog/Scenarios/DynamicMenuBar.cs index 9a981855f..cf239fd24 100644 --- a/UICatalog/Scenarios/DynamicMenuBar.cs +++ b/UICatalog/Scenarios/DynamicMenuBar.cs @@ -10,7 +10,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Dynamic MenuBar", Description: "Demonstrates how to add and remove a MenuBar, Menus and change titles dynamically.")] - [ScenarioCategory ("Dynamic")] + [ScenarioCategory ("Menu")] public class DynamicMenuBar : Scenario { public override void Init (Toplevel top, ColorScheme colorScheme) { diff --git a/UICatalog/Scenarios/DynamicStatusBar.cs b/UICatalog/Scenarios/DynamicStatusBar.cs index 43e64188f..e30bf58a5 100644 --- a/UICatalog/Scenarios/DynamicStatusBar.cs +++ b/UICatalog/Scenarios/DynamicStatusBar.cs @@ -10,7 +10,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Dynamic StatusBar", Description: "Demonstrates how to add and remove a StatusBar and change items dynamically.")] - [ScenarioCategory ("Dynamic")] + [ScenarioCategory ("StatusBar")] public class DynamicStatusBar : Scenario { public override void Init (Toplevel top, ColorScheme colorScheme) { diff --git a/UICatalog/Scenarios/GraphViewExample.cs b/UICatalog/Scenarios/GraphViewExample.cs index f503e5b42..12521074a 100644 --- a/UICatalog/Scenarios/GraphViewExample.cs +++ b/UICatalog/Scenarios/GraphViewExample.cs @@ -9,7 +9,7 @@ using Color = Terminal.Gui.Color; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Graph View", Description: "Demos GraphView control")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("Graph")] public class GraphViewExample : Scenario { GraphView graphView; diff --git a/UICatalog/Scenarios/HexEditor.cs b/UICatalog/Scenarios/HexEditor.cs index b3dc3d488..cd10c5aad 100644 --- a/UICatalog/Scenarios/HexEditor.cs +++ b/UICatalog/Scenarios/HexEditor.cs @@ -9,7 +9,7 @@ namespace UICatalog.Scenarios { [ScenarioCategory ("Dialogs")] [ScenarioCategory ("Text")] [ScenarioCategory ("Dialogs")] - [ScenarioCategory ("TopLevel")] + [ScenarioCategory ("TopLevel"), ScenarioCategory ("IO.Stream")] public class HexEditor : Scenario { private string _fileName = "demo.bin"; private HexView _hexView; diff --git a/UICatalog/Scenarios/InteractiveTree.cs b/UICatalog/Scenarios/InteractiveTree.cs index 04f04cd82..fb646749e 100644 --- a/UICatalog/Scenarios/InteractiveTree.cs +++ b/UICatalog/Scenarios/InteractiveTree.cs @@ -10,7 +10,7 @@ using static UICatalog.Scenario; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Interactive Tree", Description: "Create nodes and child nodes in TreeView")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("TreeView")] public class InteractiveTree : Scenario { TreeView treeView; diff --git a/UICatalog/Scenarios/LineViewExample.cs b/UICatalog/Scenarios/LineViewExample.cs index fb06ffb4f..7e62a5fd7 100644 --- a/UICatalog/Scenarios/LineViewExample.cs +++ b/UICatalog/Scenarios/LineViewExample.cs @@ -10,7 +10,7 @@ using static UICatalog.Scenario; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Line View", Description: "Demonstrates the LineView control")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("Lines")] public class LineViewExample : Scenario { public override void Setup () diff --git a/UICatalog/Scenarios/ListViewWithSelection.cs b/UICatalog/Scenarios/ListViewWithSelection.cs index 6f7e1f1be..51602a4c0 100644 --- a/UICatalog/Scenarios/ListViewWithSelection.cs +++ b/UICatalog/Scenarios/ListViewWithSelection.cs @@ -8,7 +8,7 @@ using Attribute = Terminal.Gui.Attribute; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "List View With Selection", Description: "ListView with columns and selection")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("ListView")] public class ListViewWithSelection : Scenario { public CheckBox _customRenderCB; diff --git a/UICatalog/Scenarios/ListsAndCombos.cs b/UICatalog/Scenarios/ListsAndCombos.cs index 42f121457..cd4ae69c8 100644 --- a/UICatalog/Scenarios/ListsAndCombos.cs +++ b/UICatalog/Scenarios/ListsAndCombos.cs @@ -7,7 +7,7 @@ using NStack; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "ListView & ComboBox", Description: "Demonstrates a ListView populating a ComboBox that acts as a filter.")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("ListView"), ScenarioCategory ("ComboBox")] public class ListsAndCombos : Scenario { public override void Setup () diff --git a/UICatalog/Scenarios/Mouse.cs b/UICatalog/Scenarios/Mouse.cs index 9c64def99..581349d92 100644 --- a/UICatalog/Scenarios/Mouse.cs +++ b/UICatalog/Scenarios/Mouse.cs @@ -5,7 +5,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Mouse", Description: "Demonstrates how to capture mouse events")] - [ScenarioCategory ("Input")] + [ScenarioCategory ("Input"), ScenarioCategory ("Mouse")] public class Mouse : Scenario { public override void Setup () { diff --git a/UICatalog/Scenarios/MultiColouredTable.cs b/UICatalog/Scenarios/MultiColouredTable.cs index 98de29597..99533cb31 100644 --- a/UICatalog/Scenarios/MultiColouredTable.cs +++ b/UICatalog/Scenarios/MultiColouredTable.cs @@ -5,7 +5,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "MultiColouredTable", Description: "Demonstrates how to multi color cell contents")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("Colors"), ScenarioCategory ("TableView")] public class MultiColouredTable : Scenario { TableViewColors tableView; diff --git a/UICatalog/Scenarios/Notepad.cs b/UICatalog/Scenarios/Notepad.cs index 963865fac..53a301f32 100644 --- a/UICatalog/Scenarios/Notepad.cs +++ b/UICatalog/Scenarios/Notepad.cs @@ -10,7 +10,7 @@ using static UICatalog.Scenario; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Notepad", Description: "Multi tab text editor")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("TabView")] public class Notepad : Scenario { TabView tabView; diff --git a/UICatalog/Scenarios/Progress.cs b/UICatalog/Scenarios/Progress.cs index 0727f07a5..7f9d3f03d 100644 --- a/UICatalog/Scenarios/Progress.cs +++ b/UICatalog/Scenarios/Progress.cs @@ -11,7 +11,7 @@ namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Progress", Description: "Shows off ProgressBar and Threading")] [ScenarioCategory ("Controls")] [ScenarioCategory ("MainLoop")] - [ScenarioCategory ("Threading")] + [ScenarioCategory ("Threading"), ScenarioCategory ("ProgressBar")] public class Progress : Scenario { class ProgressDemo : FrameView { diff --git a/UICatalog/Scenarios/ProgressBarStyles.cs b/UICatalog/Scenarios/ProgressBarStyles.cs index a272ba708..2b89b4162 100644 --- a/UICatalog/Scenarios/ProgressBarStyles.cs +++ b/UICatalog/Scenarios/ProgressBarStyles.cs @@ -6,7 +6,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "ProgressBar Styles", Description: "Shows the ProgressBar Styles")] [ScenarioCategory ("Controls")] - [ScenarioCategory ("MainLoop")] + [ScenarioCategory ("MainLoop"), ScenarioCategory ("ProgressBar")] public class ProgressBarStyles : Scenario { private Timer _fractionTimer; private Timer _pulseTimer; diff --git a/UICatalog/Scenarios/Scrolling.cs b/UICatalog/Scenarios/Scrolling.cs index b98ffe970..d51db3cf7 100644 --- a/UICatalog/Scenarios/Scrolling.cs +++ b/UICatalog/Scenarios/Scrolling.cs @@ -5,7 +5,7 @@ namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Scrolling", Description: "Demonstrates ScrollView etc...")] [ScenarioCategory ("Controls")] [ScenarioCategory ("Bug Repro")] - + [ScenarioCategory ("ScrollView")] public class Scrolling : Scenario { class Box10x : View { diff --git a/UICatalog/Scenarios/SyntaxHighlighting.cs b/UICatalog/Scenarios/SyntaxHighlighting.cs index 7ced33d3b..d963a012a 100644 --- a/UICatalog/Scenarios/SyntaxHighlighting.cs +++ b/UICatalog/Scenarios/SyntaxHighlighting.cs @@ -8,7 +8,7 @@ using Attribute = Terminal.Gui.Attribute; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Syntax Highlighting", Description: "Text editor with keyword highlighting")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("AutoComplete")] public class SyntaxHighlighting : Scenario { SqlTextView textView; diff --git a/UICatalog/Scenarios/TabViewExample.cs b/UICatalog/Scenarios/TabViewExample.cs index efe087cab..11ce7d65e 100644 --- a/UICatalog/Scenarios/TabViewExample.cs +++ b/UICatalog/Scenarios/TabViewExample.cs @@ -10,7 +10,7 @@ using static UICatalog.Scenario; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Tab View", Description: "Demos TabView control with limited screen space in Absolute layout")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("TabView")] public class TabViewExample : Scenario { TabView tabView; diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index 0dead3a70..8710dd82f 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -12,7 +12,7 @@ namespace UICatalog.Scenarios { [ScenarioCategory ("Dialogs")] [ScenarioCategory ("Text")] [ScenarioCategory ("Dialogs")] - [ScenarioCategory ("TopLevel")] + [ScenarioCategory ("TopLevel"), ScenarioCategory ("TableView")] public class TableEditor : Scenario { TableView tableView; diff --git a/UICatalog/Scenarios/TextAlignments.cs b/UICatalog/Scenarios/TextAlignments.cs index dc875ab05..8354747e4 100644 --- a/UICatalog/Scenarios/TextAlignments.cs +++ b/UICatalog/Scenarios/TextAlignments.cs @@ -5,7 +5,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Text Alignment", Description: "Demonstrates text alignment")] - [ScenarioCategory ("Text")] + [ScenarioCategory ("Text"), ScenarioCategory ("Alignment")] public class TextAlignments : Scenario { public override void Setup () { diff --git a/UICatalog/Scenarios/TextAlignmentsAndDirection.cs b/UICatalog/Scenarios/TextAlignmentsAndDirection.cs index a0e7a8f9d..9f9a3ee57 100644 --- a/UICatalog/Scenarios/TextAlignmentsAndDirection.cs +++ b/UICatalog/Scenarios/TextAlignmentsAndDirection.cs @@ -5,7 +5,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Text Alignment and Direction", Description: "Demonstrates text alignment")] - [ScenarioCategory ("Text")] + [ScenarioCategory ("Text"), ScenarioCategory ("Alignment"), ScenarioCategory ("Direction")] public class TextAlignmentsAndDirections : Scenario { public override void Setup () diff --git a/UICatalog/Scenarios/TextFormatterDemo.cs b/UICatalog/Scenarios/TextFormatterDemo.cs index 5622a1278..08d845fb8 100644 --- a/UICatalog/Scenarios/TextFormatterDemo.cs +++ b/UICatalog/Scenarios/TextFormatterDemo.cs @@ -9,7 +9,7 @@ using Rune = System.Rune; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "TextFormatter Demo", Description: "Demos and tests the TextFormatter class.")] [ScenarioCategory ("Text")] - [ScenarioCategory ("POC")] + [ScenarioCategory ("POC"), ScenarioCategory ("TextFormat")] public class TextFormatterDemo : Scenario { public override void Setup () { diff --git a/UICatalog/Scenarios/TextViewAutocompletePopup.cs b/UICatalog/Scenarios/TextViewAutocompletePopup.cs index 8bde07405..355ce5413 100644 --- a/UICatalog/Scenarios/TextViewAutocompletePopup.cs +++ b/UICatalog/Scenarios/TextViewAutocompletePopup.cs @@ -4,7 +4,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "TextView Autocomplete Popup", Description: "Show five TextView Autocomplete Popup effects")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("AutoComplete")] public class TextViewAutocompletePopup : Scenario { TextView textViewTopLeft; diff --git a/UICatalog/Scenarios/TimeAndDate.cs b/UICatalog/Scenarios/TimeAndDate.cs index 89ba77975..bf03b5a2b 100644 --- a/UICatalog/Scenarios/TimeAndDate.cs +++ b/UICatalog/Scenarios/TimeAndDate.cs @@ -3,7 +3,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Time And Date", Description: "Illustrates TimeField and time & date handling")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("DateTime")] [ScenarioCategory ("Bug Repro")] // Issue #246 public class TimeAndDate : Scenario { Label lblOldTime; diff --git a/UICatalog/Scenarios/TopLevelNoWindowBug.cs b/UICatalog/Scenarios/TopLevelNoWindowBug.cs index 6582b2815..9c6530664 100644 --- a/UICatalog/Scenarios/TopLevelNoWindowBug.cs +++ b/UICatalog/Scenarios/TopLevelNoWindowBug.cs @@ -2,7 +2,7 @@ namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "TopLevelNoWindowBug", Description: "Illustrates that not having a Window causes MenuBar to misbehave. #437")] - [ScenarioCategory ("Bug Repro")] + [ScenarioCategory ("Bug Repro"), ScenarioCategory ("TopLevel")] public class TopLevelNoWindowBug : Scenario { diff --git a/UICatalog/Scenarios/TreeUseCases.cs b/UICatalog/Scenarios/TreeUseCases.cs index 11a269507..9679d8c4c 100644 --- a/UICatalog/Scenarios/TreeUseCases.cs +++ b/UICatalog/Scenarios/TreeUseCases.cs @@ -7,7 +7,7 @@ using Terminal.Gui.Trees; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Tree View", Description: "Simple tree view examples")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("TreeView")] public class TreeUseCases : Scenario { View currentTree; diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index 1ac497dea..bb3313b63 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -7,7 +7,7 @@ using Terminal.Gui.Trees; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "TreeViewFileSystem", Description: "Hierarchical file system explorer based on TreeView")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("TreeView"), ScenarioCategory ("Files")] public class TreeViewFileSystem : Scenario { /// diff --git a/UICatalog/Scenarios/Unicode.cs b/UICatalog/Scenarios/Unicode.cs index 0fed64890..d0177a7d0 100644 --- a/UICatalog/Scenarios/Unicode.cs +++ b/UICatalog/Scenarios/Unicode.cs @@ -6,7 +6,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { [ScenarioMetadata (Name: "Unicode", Description: "Tries to test Unicode in all controls (#204)")] [ScenarioCategory ("Text")] - [ScenarioCategory ("Controls")] + [ScenarioCategory ("Controls"), ScenarioCategory ("Unicode")] public class UnicodeInMenu : Scenario { public override void Setup () { diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 05c5c7db3..c29c1b545 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -681,7 +681,7 @@ namespace UICatalog { _categoryListViewItem = _categoryListView.SelectedItem; var item = _categories [_categoryListView.SelectedItem]; List newlist; - if (item.Equals ("All")) { + if (item.Equals ("_All")) { newlist = _scenarios; } else {