From c867d32a137fd05c13f225b5686df1f74c030b35 Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 11 Jun 2022 11:24:46 +0100 Subject: [PATCH] Fixes #1739. Setting menu UseKeysUpDownAsKeysLeftRight as false by default. (#1779) * Fixes #1739. Setting menu UseKeysUpDownAsKeysLeftRight property as false by default. * Fixed some more bugs and added support for UseKeysUpDownAsKeysLeftRight on the demo file. --- Example/demo.cs | 9 ++++ Terminal.Gui/Views/Menu.cs | 33 ++++++++++---- UnitTests/MenuTests.cs | 91 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 120 insertions(+), 13 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index c78c8066c..8b3f3cd6d 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -624,6 +624,8 @@ static class Demo { MenuItem miUseSubMenusSingleFrame = null; var useSubMenusSingleFrame = false; + MenuItem miUseKeysUpDownAsKeysLeftRight = null; + var useKeysUpDownAsKeysLeftRight = false; MenuItem miHeightAsBuffer = null; @@ -635,6 +637,9 @@ static class Demo { new MenuItem ("_Hex", "", () => { running = ShowHex; Application.RequestStop (); }, null, null, Key.AltMask | Key.CtrlMask | Key.H), new MenuItem ("_Close", "", Close, null, null, Key.AltMask | Key.Q), new MenuItem ("_Disabled", "", () => { }, () => false), + new MenuBarItem ("_SubMenu Disabled", new MenuItem [] { + new MenuItem ("_Disabled", "", () => { }, () => false) + }), null, new MenuItem ("_Quit", "", () => { if (Quit ()) { running = null; top.Running = false; } }, null, null, Key.CtrlMask | Key.Q) }), @@ -645,6 +650,10 @@ static class Demo { new MenuBarItem ("_Find and Replace", new MenuItem [] { menuItems [0], menuItems [1] }), menuItems[3], + miUseKeysUpDownAsKeysLeftRight = new MenuItem ("Use_KeysUpDownAsKeysLeftRight", "", + () => menu.UseKeysUpDownAsKeysLeftRight = miUseKeysUpDownAsKeysLeftRight.Checked = useKeysUpDownAsKeysLeftRight = !useKeysUpDownAsKeysLeftRight) { + CheckType = MenuItemCheckStyle.Checked, Checked = useKeysUpDownAsKeysLeftRight + }, miUseSubMenusSingleFrame = new MenuItem ("Use_SubMenusSingleFrame", "", () => menu.UseSubMenusSingleFrame = miUseSubMenusSingleFrame.Checked = useSubMenusSingleFrame = !useSubMenusSingleFrame) { CheckType = MenuItemCheckStyle.Checked, Checked = useSubMenusSingleFrame diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 1afad1bd5..d35ccf15e 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -421,7 +421,7 @@ namespace Terminal.Gui { AddCommand (Command.LineDown, () => MoveDown ()); AddCommand (Command.Left, () => { this.host.PreviousMenu (true); return true; }); AddCommand (Command.Right, () => { - this.host.NextMenu (this.barItems.IsTopLevel || (this.barItems.Children != null + this.host.NextMenu (!this.barItems.IsTopLevel || (this.barItems.Children != null && 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; @@ -846,7 +846,7 @@ namespace Terminal.Gui { /// /// Used for change the navigation key style. /// - public bool UseKeysUpDownAsKeysLeftRight { get; set; } = true; + public bool UseKeysUpDownAsKeysLeftRight { get; set; } = false; static ustring shortcutDelimiter = "+"; /// @@ -1122,8 +1122,12 @@ namespace Terminal.Gui { public virtual void OnMenuOpened () { MenuItem mi = null; - if (openCurrentMenu.barItems.Children != null) { + if (openCurrentMenu.barItems.Children != null && openCurrentMenu?.current > -1) { mi = openCurrentMenu.barItems.Children [openCurrentMenu.current]; + } else if (openCurrentMenu.barItems.IsTopLevel) { + mi = openCurrentMenu.barItems; + } else { + mi = openMenu.barItems.Children [openMenu.current]; } MenuOpened?.Invoke (mi); } @@ -1395,7 +1399,9 @@ namespace Terminal.Gui { void RemoveSubMenu (int index, bool ignoreUseSubMenusSingleFrame = false) { - if (openSubMenu == null || (UseSubMenusSingleFrame && !ignoreUseSubMenusSingleFrame && openSubMenu.Count > 0)) + if (openSubMenu == null || (UseSubMenusSingleFrame + && !ignoreUseSubMenusSingleFrame && openSubMenu.Count == 0)) + return; for (int i = openSubMenu.Count - 1; i > index; i--) { isMenuClosing = true; @@ -1542,18 +1548,27 @@ namespace Terminal.Gui { NextMenu (false, ignoreUseSubMenusSingleFrame); } } else { - var subMenu = openCurrentMenu.barItems.SubMenu (openCurrentMenu.barItems.Children [openCurrentMenu.current]); + var subMenu = openCurrentMenu.current > -1 + ? openCurrentMenu.barItems.SubMenu (openCurrentMenu.barItems.Children [openCurrentMenu.current]) + : null; if ((selectedSub == -1 || openSubMenu == null || openSubMenu?.Count == selectedSub) && subMenu == null) { if (openSubMenu != null && !CloseMenu (false, true)) return; NextMenu (false, ignoreUseSubMenusSingleFrame); - } else if (subMenu != null || - !openCurrentMenu.barItems.Children [openCurrentMenu.current].IsFromSubMenu) + } else if (subMenu != null || (openCurrentMenu.current > -1 + && !openCurrentMenu.barItems.Children [openCurrentMenu.current].IsFromSubMenu)) { selectedSub++; - else + openCurrentMenu.CheckSubMenu (); + } else { + if (CloseMenu (false, true, ignoreUseSubMenusSingleFrame)) { + NextMenu (false, ignoreUseSubMenusSingleFrame); + } return; + } + SetNeedsDisplay (); - openCurrentMenu.CheckSubMenu (); + if (UseKeysUpDownAsKeysLeftRight) + openCurrentMenu.CheckSubMenu (); } break; } diff --git a/UnitTests/MenuTests.cs b/UnitTests/MenuTests.cs index 29830ec5c..420f61512 100644 --- a/UnitTests/MenuTests.cs +++ b/UnitTests/MenuTests.cs @@ -177,6 +177,88 @@ Edit void Copy () => miAction = "Copy"; } + [Fact, AutoInitShutdown] + public void MenuOpened_On_Disabled_MenuItem () + { + MenuItem miCurrent = null; + Menu mCurrent = null; + + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("_File", new MenuItem [] { + new MenuBarItem ("_New", new MenuItem [] { + new MenuItem ("_New doc", "Creates new doc.", null, () => false) + }), + new MenuItem ("_Save", "Saves the file.", null, null) + }) + }); + menu.MenuOpened += (e) => { + miCurrent = e; + mCurrent = menu.openMenu; + }; + menu.UseKeysUpDownAsKeysLeftRight = true; + Application.Top.Add (menu); + + // open the menu + Assert.True (menu.MouseEvent (new MouseEvent () { + X = 1, + Y = 0, + Flags = MouseFlags.Button1Pressed, + View = menu + })); + Assert.True (menu.IsMenuOpen); + Assert.Equal ("_File", miCurrent.Parent.Title); + Assert.Equal ("_New", miCurrent.Title); + + Assert.True (mCurrent.MouseEvent (new MouseEvent () { + X = 1, + Y = 1, + Flags = MouseFlags.ReportMousePosition, + View = mCurrent + })); + Assert.True (menu.IsMenuOpen); + Assert.Equal ("_File", miCurrent.Parent.Title); + Assert.Equal ("_New", miCurrent.Title); + + Assert.True (mCurrent.MouseEvent (new MouseEvent () { + X = 1, + Y = 2, + Flags = MouseFlags.ReportMousePosition, + View = mCurrent + })); + Assert.True (menu.IsMenuOpen); + Assert.Equal ("_File", miCurrent.Parent.Title); + Assert.Equal ("_Save", miCurrent.Title); + + // close the menu + Assert.True (menu.MouseEvent (new MouseEvent () { + X = 1, + Y = 0, + Flags = MouseFlags.Button1Pressed, + View = menu + })); + Assert.False (menu.IsMenuOpen); + + // open the menu + Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ()))); + Assert.True (menu.IsMenuOpen); + Assert.Equal ("_New", miCurrent.Parent.Title); + Assert.Equal ("_New doc", miCurrent.Title); + + Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()))); + Assert.True (menu.IsMenuOpen); + Assert.Equal ("_File", miCurrent.Parent.Title); + Assert.Equal ("_Save", miCurrent.Title); + + Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()))); + Assert.True (menu.IsMenuOpen); + Assert.Equal ("_File", miCurrent.Parent.Title); + Assert.Equal ("_New", miCurrent.Title); + + // close the menu + Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ()))); + Assert.False (menu.IsMenuOpen); + } + [Fact] [AutoInitShutdown] public void MouseEvent_Test () @@ -293,6 +375,7 @@ Edit miCurrent = null; mCurrent = null; }; + menu.UseKeysUpDownAsKeysLeftRight = true; Application.Top.Add (menu); Application.Begin (Application.Top); @@ -304,7 +387,7 @@ Edit Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); Assert.True (menu.IsMenuOpen); Assert.Equal ("_About", GetCurrentMenuBarItemTitle ()); - Assert.Equal ("None", GetCurrentMenuTitle ()); + Assert.Equal ("_About", GetCurrentMenuTitle ()); Assert.True (menu.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); Assert.True (menu.IsMenuOpen); @@ -363,7 +446,7 @@ Edit Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); Assert.True (menu.IsMenuOpen); Assert.Equal ("_About", GetCurrentMenuBarItemTitle ()); - Assert.Equal ("None", GetCurrentMenuTitle ()); + Assert.Equal ("_About", GetCurrentMenuTitle ()); Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); Assert.True (menu.IsMenuOpen); @@ -393,7 +476,7 @@ Edit Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); Assert.True (menu.IsMenuOpen); Assert.Equal ("_About", GetCurrentMenuBarItemTitle ()); - Assert.Equal ("None", GetCurrentMenuTitle ()); + Assert.Equal ("_About", GetCurrentMenuTitle ()); Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); Assert.False (menu.IsMenuOpen); Assert.Equal ("Closed", GetCurrentMenuBarItemTitle ()); @@ -603,7 +686,7 @@ Edit new MenuItem ("Three", "", null), }) }); - + menu.UseKeysUpDownAsKeysLeftRight = true; Application.Top.Add (menu); Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y));