diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 5dc55b4e9..9dd5ea556 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -436,15 +436,16 @@ namespace Terminal.Gui { internal int current; internal View previousSubFocused; - internal static Rect MakeFrame (int x, int y, MenuItem [] items, Menu parent = null) + internal static Rect MakeFrame (int x, int y, MenuItem [] items, Menu parent = null, LineStyle border = LineStyle.Single) { if (items == null || items.Length == 0) { return new Rect (); } int minX = x; int minY = y; - int maxW = (items.Max (z => z?.Width) ?? 0) + 2; // This 2 is frame border? - int maxH = items.Length + 2; // This 2 is frame border? + var borderOffset = border != LineStyle.None ? 2 : 0; // This 2 is frame border? + int maxW = (items.Max (z => z?.Width) ?? 0) + borderOffset; + int maxH = items.Length + borderOffset; if (parent != null && x + maxW > Driver.Cols) { minX = Math.Max (parent.Frame.Right - parent.Frame.Width - maxW, 0); } @@ -454,8 +455,8 @@ namespace Terminal.Gui { return new Rect (minX, minY, maxW, maxH); } - public Menu (MenuBar host, int x, int y, MenuBarItem barItems, Menu parent = null) - : base (MakeFrame (x, y, barItems.Children, parent)) + public Menu (MenuBar host, int x, int y, MenuBarItem barItems, Menu parent = null, LineStyle border = LineStyle.Single) + : base (MakeFrame (x, y, barItems.Children, parent, border)) { this.barItems = barItems; this.host = host; @@ -477,8 +478,7 @@ namespace Terminal.Gui { WantMousePositionReports = host.WantMousePositionReports; } - Border.Thickness = new Thickness (1); - Border.BorderStyle = LineStyle.Single; + BorderStyle = host.MenusBorderStyle; if (Application.Current != null) { Application.Current.DrawContentComplete += Current_DrawContentComplete; @@ -554,7 +554,7 @@ namespace Terminal.Gui { var item = barItems.Children [i]; Driver.SetAttribute (item == null ? GetNormalColor () : i == current ? ColorScheme.Focus : GetNormalColor ()); - if (item == null) { + if (item == null && BorderStyle != LineStyle.None) { Move (-1, i); Driver.AddRune (Driver.LeftTee); } else if (Frame.X < Driver.Cols) { @@ -577,7 +577,7 @@ namespace Terminal.Gui { } if (item == null) { - if (SuperView?.Frame.Right - Frame.X > Frame.Width) { + if (BorderStyle != LineStyle.None && SuperView?.Frame.Right - Frame.X > Frame.Width) { Move (Frame.Width - 2, i); Driver.AddRune (Driver.RightTee); } @@ -858,11 +858,12 @@ namespace Terminal.Gui { } host.handled = false; bool disabled; + var meYOffset = BorderStyle != LineStyle.None ? 1 : 0; if (me.Flags == MouseFlags.Button1Clicked) { disabled = false; - if (me.Y < 1) + if (me.Y < meYOffset) return true; - var meY = me.Y - 1; + var meY = me.Y - meYOffset; if (meY >= barItems.Children.Length) return true; var item = barItems.Children [meY]; @@ -877,14 +878,14 @@ namespace Terminal.Gui { me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) { disabled = false; - if (me.Y < 1 || me.Y - 1 >= barItems.Children.Length) { + if (me.Y < meYOffset || me.Y - meYOffset >= barItems.Children.Length) { return true; } - var item = barItems.Children [me.Y - 1]; + var item = barItems.Children [me.Y - meYOffset]; if (item == null) return true; if (item == null || !item.IsEnabled ()) disabled = true; if (item != null && !disabled) - current = me.Y - 1; + current = me.Y - meYOffset; if (host.UseSubMenusSingleFrame || !CheckSubMenu ()) { SetNeedsDisplay (); SetParentSetNeedsDisplay (); @@ -988,6 +989,11 @@ namespace Terminal.Gui { /// The menu array. public MenuBarItem [] Menus { get; set; } + /// + /// The default for 's border. The default is . + /// + public LineStyle MenusBorderStyle { get; set; } = LineStyle.Single; + private bool useKeysUpDownAsKeysLeftRight = false; /// @@ -1391,7 +1397,7 @@ namespace Terminal.Gui { } else { locationOffset = new Point (superView.Frame.X, superView.Frame.Y); } - openMenu = new Menu (this, Frame.X + pos + locationOffset.X, Frame.Y + 1 + locationOffset.Y, Menus [index]); + openMenu = new Menu (this, Frame.X + pos + locationOffset.X, Frame.Y + 1 + locationOffset.Y, Menus [index], null, MenusBorderStyle); openCurrentMenu = openMenu; openCurrentMenu.previousSubFocused = openMenu; @@ -1407,7 +1413,8 @@ namespace Terminal.Gui { } else { var last = openSubMenu.Count > 0 ? openSubMenu.Last () : openMenu; if (!UseSubMenusSingleFrame) { - openCurrentMenu = new Menu (this, last.Frame.Left + last.Frame.Width, last.Frame.Top + 1 + last.current, subMenu, last); + locationOffset = GetLocationOffset (); + openCurrentMenu = new Menu (this, last.Frame.Left + last.Frame.Width + locationOffset.X, last.Frame.Top + locationOffset.Y + last.current, subMenu, last, MenusBorderStyle); } else { var first = openSubMenu.Count > 0 ? openSubMenu.First () : openMenu; var mbi = new MenuItem [2 + subMenu.Children.Length]; @@ -1418,7 +1425,7 @@ namespace Terminal.Gui { } var newSubMenu = new MenuBarItem (mbi); ViewToScreen (first.Frame.Left, first.Frame.Top, out int rx, out int ry); - openCurrentMenu = new Menu (this, rx, ry, newSubMenu); + openCurrentMenu = new Menu (this, rx, ry, newSubMenu, null, MenusBorderStyle); last.Visible = false; Application.GrabMouse (openCurrentMenu); } @@ -1436,6 +1443,14 @@ namespace Terminal.Gui { IsMenuOpen = true; } + Point GetLocationOffset () + { + if (MenusBorderStyle != LineStyle.None) { + return new Point (0, 1); + } + return new Point (-2, 0); + } + /// /// Opens the Menu programatically, as though the F9 key were pressed. /// @@ -1792,7 +1807,7 @@ namespace Terminal.Gui { if (mi.IsTopLevel) { ViewToScreen (i, 0, out int rx, out int ry); - var menu = new Menu (this, rx, ry, mi); + var menu = new Menu (this, rx, ry, mi, null, MenusBorderStyle); menu.Run (mi.Action); menu.Dispose (); } else { @@ -1914,7 +1929,7 @@ namespace Terminal.Gui { if (me.Flags == MouseFlags.Button1Clicked) { if (Menus [i].IsTopLevel) { ViewToScreen (i, 0, out int rx, out int ry); - var menu = new Menu (this, rx, ry, Menus [i]); + var menu = new Menu (this, rx, ry, Menus [i], null, MenusBorderStyle); menu.Run (Menus [i].Action); menu.Dispose (); } else if (!IsMenuOpen) { diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index 3140df1af..e9ae7d988 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -777,10 +777,11 @@ namespace Terminal.Gui { } base.Redraw (Bounds); - if (this.MenuBar != null && this.MenuBar.IsMenuOpen && this.MenuBar.openMenu != null) { - // TODO: Hack until we can get compositing working right. - this.MenuBar.openMenu.Redraw (this.MenuBar.openMenu.Bounds); - } + // This is causing the menus drawn incorrectly if UseSubMenusSingleFrame is true + //if (this.MenuBar != null && this.MenuBar.IsMenuOpen && this.MenuBar.openMenu != null) { + // // TODO: Hack until we can get compositing working right. + // this.MenuBar.openMenu.Redraw (this.MenuBar.openMenu.Bounds); + //} } } diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 7d9c991ef..ece04fe68 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -249,6 +249,7 @@ namespace UICatalog { /// the command line) and each time a Scenario ends. /// public class UICatalogTopLevel : Toplevel { + public MenuItem? miIsMenuBorderDisabled; public MenuItem? miIsMouseDisabled; public MenuItem? miEnableConsoleScrolling; @@ -343,7 +344,7 @@ namespace UICatalog { //ContentPane.Tiles.ElementAt (0).ContentView.Add (CategoryListView); ScenarioListView = new ListView () { - X = Pos.Right(CategoryListView) - 1, + X = Pos.Right (CategoryListView) - 1, Y = 1, Width = Dim.Fill (0), Height = Dim.Fill (1), @@ -447,11 +448,29 @@ namespace UICatalog { new MenuItem [] { }, CreateEnableConsoleScrollingMenuItems (), CreateDisabledEnabledMouseItems (), + CreateDisabledEnabledMenuBorder (), CreateKeybindingsMenuItems () }; return menuItems; } + MenuItem [] CreateDisabledEnabledMenuBorder () + { + List menuItems = new List (); + miIsMenuBorderDisabled = new MenuItem { + Title = "Disable _Menu Border" + }; + miIsMenuBorderDisabled.Shortcut = Key.CtrlMask | Key.AltMask | (Key)miIsMenuBorderDisabled!.Title!.ToString ()!.Substring (1, 1) [0]; + miIsMenuBorderDisabled.CheckType |= MenuItemCheckStyle.Checked; + miIsMenuBorderDisabled.Action += () => { + miIsMenuBorderDisabled.Checked = (bool)!miIsMenuBorderDisabled.Checked!; + MenuBar.MenusBorderStyle = !(bool)miIsMenuBorderDisabled.Checked ? LineStyle.Single : LineStyle.None; + }; + menuItems.Add (miIsMenuBorderDisabled); + + return menuItems.ToArray (); + } + MenuItem [] CreateDisabledEnabledMouseItems () { List menuItems = new List (); @@ -676,7 +695,7 @@ namespace UICatalog { miEnableConsoleScrolling!.Checked = Application.EnableConsoleScrolling; var height = (UICatalogApp.ShowStatusBar ? 1 : 0);// + (MenuBar.Visible ? 1 : 0); - //ContentPane.Height = Dim.Fill (height); + //ContentPane.Height = Dim.Fill (height); StatusBar.Visible = UICatalogApp.ShowStatusBar; diff --git a/UnitTests/Views/MenuTests.cs b/UnitTests/Views/MenuTests.cs index f9bb15cd1..ab4e2d90d 100644 --- a/UnitTests/Views/MenuTests.cs +++ b/UnitTests/Views/MenuTests.cs @@ -18,12 +18,14 @@ namespace Terminal.Gui.ViewsTests { [Fact] public void Constuctors_Defaults () { - var menu = new Menu (new MenuBar (), 0, 0, new MenuBarItem ()); + var menuBar = new MenuBar (); + var menu = new Menu (menuBar, 0, 0, new MenuBarItem (), null, menuBar.MenusBorderStyle); Assert.Equal (Colors.Menu, menu.ColorScheme); Assert.True (menu.CanFocus); Assert.False (menu.WantContinuousButtonPressed); + Assert.Equal (LineStyle.Single, menuBar.MenusBorderStyle); - var menuBar = new MenuBar (); + menuBar = new MenuBar (); Assert.Equal (0, menuBar.X); Assert.Equal (0, menuBar.Y); Assert.IsType (menuBar.Width); @@ -861,246 +863,244 @@ Edit Assert.Equal (new Rect (1, 0, 8, 1), pos); } - // BUGBUG: Tig broke this in #2483 and is not sure why -// [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), -// }) -// }); + [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); -// Application.Begin (Application.Top); + Application.Top.Add (menu); + Application.Begin (Application.Top); -// Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); -// Assert.False (menu.UseSubMenusSingleFrame); -// menu.UseSubMenusSingleFrame = true; -// Assert.True (menu.UseSubMenusSingleFrame); + 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 -//"; + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + Numbers +"; -// var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 8, 1), pos); + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 8, 1), pos); -// Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null))); -// Application.Top.Redraw (Application.Top.Bounds); -// expected = @" -// Numbers -//┌────────┐ -//│ One │ -//│ Two ►│ -//│ Three │ -//└────────┘ -//"; + Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; -// pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 10, 6), pos); + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 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))); -// Application.Top.Redraw (Application.Top.Bounds); -// expected = @" -// Numbers -//┌─────────────┐ -//│◄ Two │ -//├─────────────┤ -//│ Sub-Menu 1 │ -//│ Sub-Menu 2 │ -//└─────────────┘ -//"; + 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 = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 15, 7), pos); + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 15, 7), pos); -// Assert.True (Application.Top.Subviews [2].ProcessKey (new KeyEvent (Key.Enter, null))); -// Application.Top.Redraw (Application.Top.Bounds); -// expected = @" -// Numbers -//┌────────┐ -//│ One │ -//│ Two ►│ -//│ Three │ -//└────────┘ -//"; + Assert.True (Application.Top.Subviews [2].ProcessKey (new KeyEvent (Key.Enter, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +┌────────┐ +│ One │ +│ Two ►│ +│ Three │ +└────────┘ +"; -// pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 10, 6), pos); + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 10, 6), pos); -// Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Esc, null))); -// Application.Top.Redraw (Application.Top.Bounds); -// expected = @" -// Numbers -//"; + Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.Esc, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers +"; -// pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 8, 1), pos); -// } + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 8, 1), pos); + } - // BUGBUG: Tig broke this in #2483 and is not sure why -// [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), -// }) -// }); + [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); -// Application.Begin (Application.Top); + Application.Top.Add (menu); + Application.Begin (Application.Top); -// Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); -// Assert.False (menu.UseSubMenusSingleFrame); -// menu.UseSubMenusSingleFrame = true; -// Assert.True (menu.UseSubMenusSingleFrame); + 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 -//"; + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + Numbers +"; -// var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 8, 1), pos); + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 8, 1), 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 │ -//└────────┘ -//"; + 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 = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 10, 6), pos); + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 10, 6), 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 │ -//└─────────────┘ -//"; + 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 = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 15, 7), pos); + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 15, 7), 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 │ -//└────────┘ -//"; + 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 = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 10, 6), pos); + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 10, 6), 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 -//"; + 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 = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 8, 1), pos); -// } + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 8, 1), pos); + } -// [Fact, AutoInitShutdown] -// public void HotKey_MenuBar_OnKeyDown_OnKeyUp_ProcessHotKey_ProcessKey () -// { -// var newAction = false; -// var copyAction = false; + [Fact, AutoInitShutdown] + public void HotKey_MenuBar_OnKeyDown_OnKeyUp_ProcessHotKey_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) -// }) -// }); + 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); -// Application.Begin (Application.Top); + Application.Top.Add (menu); + Application.Begin (Application.Top); -// Assert.False (newAction); -// Assert.False (copyAction); + 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 -//"; + 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 = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 11, 1), pos); + var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 11, 1), pos); -// Assert.True (menu.ProcessKey (new (Key.N, null))); -// Application.MainLoop.RunIteration (); -// Assert.True (newAction); + Assert.True (menu.ProcessKey (new (Key.N, null))); + Application.MainLoop.RunIteration (); + Assert.True (newAction); -// Assert.True (menu.ProcessHotKey (new (Key.AltMask, new KeyModifiers () { Alt = true }))); -// Assert.True (menu.IsMenuOpen); -// Application.Top.Redraw (Application.Top.Bounds); -// expected = @" -// File Edit -//"; + 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 = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); -// Assert.Equal (new Rect (1, 0, 11, 1), pos); + pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Assert.Equal (new Rect (1, 0, 11, 1), pos); -// Assert.True (menu.ProcessKey (new (Key.CursorRight, null))); -// Assert.True (menu.ProcessKey (new (Key.C, null))); -// Application.MainLoop.RunIteration (); -// Assert.True (copyAction); -// } + Assert.True (menu.ProcessKey (new (Key.CursorRight, null))); + Assert.True (menu.ProcessKey (new (Key.C, null))); + Application.MainLoop.RunIteration (); + Assert.True (copyAction); + } // Defines the expected strings for a Menu. Currently supports // - MenuBar with any number of MenuItems @@ -1852,5 +1852,205 @@ Edit │ Quit │ └────────────────────────────┘", output); } + + [Fact, AutoInitShutdown] + public void Menu_With_Separator_Disabled_Border () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem("File",new MenuItem [] { + new MenuItem("_Open", "Open a file", () => { }, null, null, Key.CtrlMask | Key.O), + null, + new MenuItem("_Quit","",null) + }) + }) { MenusBorderStyle = LineStyle.None }; + + Application.Top.Add (menu); + Application.Begin (Application.Top); + + menu.OpenMenu (); + Application.Refresh (); + TestHelpers.AssertDriverContentsWithFrameAre (@" + File + Open Open a file Ctrl+O +────────────────────────── + Quit ", output); + } + + [Fact, AutoInitShutdown] + public void DrawFrame_With_Positive_Positions_Disabled_Border () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem (new MenuItem [] { + new MenuItem ("One", "", null), + new MenuItem ("Two", "", null) + }) + }) { MenusBorderStyle = LineStyle.None }; + + Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); + + menu.OpenMenu (); + Application.Begin (Application.Top); + + var expected = @" + One + Two +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } + + [Fact, AutoInitShutdown] + public void DrawFrame_With_Negative_Positions_Disabled_Border () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem (new MenuItem [] { + new MenuItem ("One", "", null), + new MenuItem ("Two", "", null) + }) + }) { + X = -2, + Y = -1, + MenusBorderStyle = LineStyle.None + }; + + Assert.Equal (new Point (-2, -1), new Point (menu.Frame.X, menu.Frame.Y)); + + menu.OpenMenu (); + Application.Begin (Application.Top); + + var expected = @" +ne +wo +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + menu.CloseAllMenus (); + menu.Frame = new Rect (-2, -2, menu.Frame.Width, menu.Frame.Height); + menu.OpenMenu (); + Application.Refresh (); + + expected = @" +wo +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + menu.CloseAllMenus (); + menu.Frame = new Rect (0, 0, menu.Frame.Width, menu.Frame.Height); + ((FakeDriver)Application.Driver).SetBufferSize (3, 2); + menu.OpenMenu (); + Application.Refresh (); + + expected = @" + On + Tw +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + menu.CloseAllMenus (); + menu.Frame = new Rect (0, 0, menu.Frame.Width, menu.Frame.Height); + ((FakeDriver)Application.Driver).SetBufferSize (3, 1); + menu.OpenMenu (); + Application.Refresh (); + + expected = @" + Tw +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } + + [Fact, AutoInitShutdown] + public void UseSubMenusSingleFrame_False_Disabled_Border () + { + 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), + }) + }) { MenusBorderStyle = LineStyle.None }; + menu.UseKeysUpDownAsKeysLeftRight = true; + Application.Top.Add (menu); + Application.Begin (Application.Top); + + Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); + Assert.False (menu.UseSubMenusSingleFrame); + + Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null))); + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + Numbers + One + Two ► + Three +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + Assert.True (Application.Top.Subviews [1].ProcessKey (new KeyEvent (Key.CursorDown, null))); + Application.Top.Redraw (Application.Top.Bounds); + expected = @" + Numbers + One + Two ► Sub-Menu 1 + Three Sub-Menu 2 +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } + + [Fact, AutoInitShutdown] + public void UseSubMenusSingleFrame_True_Disabled_Border () + { + 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), + }) + }) { MenusBorderStyle = LineStyle.None }; + + Application.Top.Add (menu); + Application.Begin (Application.Top); + + Assert.Equal (Point.Empty, new Point (menu.Frame.X, menu.Frame.Y)); + Assert.False (menu.UseSubMenusSingleFrame); + menu.UseSubMenusSingleFrame = true; + Assert.True (menu.UseSubMenusSingleFrame); + + + Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, null))); + Application.Top.Redraw (Application.Top.Bounds); + var expected = @" + Numbers + One + Two ► + Three +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + + 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 +"; + + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + } } }