diff --git a/.github/workflows/api-docs.yml b/.github/workflows/api-docs.yml index c82fc6520..879323519 100644 --- a/.github/workflows/api-docs.yml +++ b/.github/workflows/api-docs.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v2 - name: Setup .NET Core - uses: actions/setup-dotnet@v3.0.2 + uses: actions/setup-dotnet@v3.0.3 with: dotnet-version: 6.0.100 diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index 200fe5984..692419b9b 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup .NET Core - uses: actions/setup-dotnet@v3.0.2 + uses: actions/setup-dotnet@v3.0.3 with: dotnet-version: 6.0.100 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 44a76c881..8951b7109 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -30,7 +30,7 @@ jobs: echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.CommitsSinceVersionSource }}" - name: Setup dotnet - uses: actions/setup-dotnet@v3.0.2 + uses: actions/setup-dotnet@v3.0.3 with: dotnet-version: 6.0.100 diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 10754106d..3df94d23a 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -758,6 +758,7 @@ namespace Terminal.Gui { return true; var item = barItems.Children [meY]; if (item == null || !item.IsEnabled ()) disabled = true; + if (disabled) return true; current = meY; if (item != null && !disabled) RunSelected (); @@ -1074,7 +1075,7 @@ namespace Terminal.Gui { if (i == selected && IsMenuOpen) { hotColor = i == selected ? ColorScheme.HotFocus : ColorScheme.HotNormal; normalColor = i == selected ? ColorScheme.Focus : GetNormalColor (); - } else { + } else { hotColor = ColorScheme.HotNormal; normalColor = GetNormalColor (); } diff --git a/Terminal.Gui/Views/TreeView.cs b/Terminal.Gui/Views/TreeView.cs index 4f8692d74..aa070d499 100644 --- a/Terminal.Gui/Views/TreeView.cs +++ b/Terminal.Gui/Views/TreeView.cs @@ -140,12 +140,12 @@ namespace Terminal.Gui { /// public MouseFlags? ObjectActivationButton { get; set; } = MouseFlags.Button1DoubleClicked; - + /// /// Delegate for multi colored tree views. Return the to use /// for each passed object or null to use the default. /// - public Func ColorGetter {get;set;} + public Func ColorGetter { get; set; } /// /// Secondary selected regions of tree when is true @@ -227,14 +227,15 @@ namespace Terminal.Gui { /// Defaults to /// public CursorVisibility DesiredCursorVisibility { - get { + get { return MultiSelect ? desiredCursorVisibility : CursorVisibility.Invisible; } set { - desiredCursorVisibility = value; - - if (desiredCursorVisibility != value && HasFocus) { - Application.Driver.SetCursorVisibility (DesiredCursorVisibility); + if (desiredCursorVisibility != value) { + desiredCursorVisibility = value; + if (HasFocus) { + Application.Driver.SetCursorVisibility (DesiredCursorVisibility); + } } } } @@ -626,7 +627,7 @@ namespace Terminal.Gui { /// /// /// - public int? GetObjectRow(T toFind) + public int? GetObjectRow (T toFind) { var idx = BuildLineMap ().IndexOf (o => o.Model.Equals (toFind)); diff --git a/UnitTests/MenuTests.cs b/UnitTests/MenuTests.cs index a587a996b..613b3afb5 100644 --- a/UnitTests/MenuTests.cs +++ b/UnitTests/MenuTests.cs @@ -1133,8 +1133,8 @@ Edit string padding (int i) { int n = 0; - while (i > 0){ - n += Menus [i-1].TitleLength + 2; + while (i > 0) { + n += Menus [i - 1].TitleLength + 2; i--; } return new string (' ', n); @@ -1153,12 +1153,12 @@ Edit public string expectedBottomRow (int i) => $"{d.LLCorner}{new String (d.HLine.ToString () [0], Menus [i].Children [0].TitleLength + 3)}{d.LRCorner} \n"; // The fulll expected string for an open sub menu - public string expectedSubMenuOpen (int i) => ClosedMenuText + + public string expectedSubMenuOpen (int i) => ClosedMenuText + (Menus [i].Children.Length > 0 ? padding (i) + expectedTopRow (i) + padding (i) + expectedMenuItemRow (i) + - padding (i) + expectedBottomRow (i) - : + padding (i) + expectedBottomRow (i) + : ""); public ExpectedMenuBar (MenuBarItem [] menus) : base (menus) @@ -1481,14 +1481,14 @@ Edit MenuBarItem [] items = new MenuBarItem [expectedMenu.Menus.Length]; for (var i = 0; i < expectedMenu.Menus.Length; i++) { - items [i] = new MenuBarItem (expectedMenu.Menus [i].Title, expectedMenu.Menus [i].Children.Length > 0 + items [i] = new MenuBarItem (expectedMenu.Menus [i].Title, expectedMenu.Menus [i].Children.Length > 0 ? new MenuItem [] { new MenuItem (expectedMenu.Menus [i].Children [0].Title, "", null), - } + } : Array.Empty ()); } var menu = new MenuBar (items); - + var tf = new TextField () { Y = 2, Width = 10 }; Application.Top.Add (menu, tf); @@ -1559,5 +1559,82 @@ Edit Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F10 | Key.ShiftMask, new KeyModifiers ()))); Assert.False (menu.IsMenuOpen); } + + [Fact, AutoInitShutdown] + public void Disabled_MenuItem_Is_Never_Selected () + { + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("Menu", new MenuItem [] { + new MenuItem ("Enabled 1", "", null), + new MenuItem ("Disabled", "", null, () => false), + null, + new MenuItem ("Enabled 2", "", null) + }) + }); + + var top = Application.Top; + top.Add (menu); + Application.Begin (top); + + var attributes = new Attribute [] { + // 0 + menu.ColorScheme.Normal, + // 1 + menu.ColorScheme.Focus, + // 2 + menu.ColorScheme.Disabled + }; + + TestHelpers.AssertDriverColorsAre (@" +00000000000000", attributes); + + Assert.True (menu.MouseEvent (new MouseEvent { + X = 0, + Y = 0, + Flags = MouseFlags.Button1Pressed, + View = menu + })); + top.Redraw (top.Bounds); + TestHelpers.AssertDriverColorsAre (@" +11111100000000 +00000000000000 +01111111111110 +02222222222220 +00000000000000 +00000000000000 +00000000000000", attributes); + + Assert.True (top.Subviews [1].MouseEvent (new MouseEvent { + X = 0, + Y = 2, + Flags = MouseFlags.Button1Clicked, + View = top.Subviews [1] + })); + top.Subviews [1].Redraw (top.Bounds); + TestHelpers.AssertDriverColorsAre (@" +11111100000000 +00000000000000 +01111111111110 +02222222222220 +00000000000000 +00000000000000 +00000000000000", attributes); + + Assert.True (top.Subviews [1].MouseEvent (new MouseEvent { + X = 0, + Y = 2, + Flags = MouseFlags.ReportMousePosition, + View = top.Subviews [1] + })); + top.Subviews [1].Redraw (top.Bounds); + TestHelpers.AssertDriverColorsAre (@" +11111100000000 +00000000000000 +01111111111110 +02222222222220 +00000000000000 +00000000000000 +00000000000000", attributes); + } } } diff --git a/UnitTests/TreeViewTests.cs b/UnitTests/TreeViewTests.cs index 7e47e58d5..31c6bf538 100644 --- a/UnitTests/TreeViewTests.cs +++ b/UnitTests/TreeViewTests.cs @@ -839,26 +839,26 @@ namespace Terminal.Gui.Views { Assert.Equal (0, tv.GetObjectRow (n2)); } [Fact, AutoInitShutdown] - public void TestTreeViewColor() + public void TestTreeViewColor () { - var tv = new TreeView{Width = 20,Height = 10}; + var tv = new TreeView { Width = 20, Height = 10 }; - var n1 = new TreeNode("normal"); - var n1_1 = new TreeNode("pink"); - var n1_2 = new TreeNode("normal"); - n1.Children.Add(n1_1); - n1.Children.Add(n1_2); + var n1 = new TreeNode ("normal"); + var n1_1 = new TreeNode ("pink"); + var n1_2 = new TreeNode ("normal"); + n1.Children.Add (n1_1); + n1.Children.Add (n1_2); - var n2 = new TreeNode("pink"); - tv.AddObject(n1); - tv.AddObject(n2); - tv.Expand(n1); + var n2 = new TreeNode ("pink"); + tv.AddObject (n1); + tv.AddObject (n2); + tv.Expand (n1); - var pink = new Attribute(Color.Magenta,Color.Black); - var hotpink = new Attribute(Color.BrightMagenta,Color.Black); + var pink = new Attribute (Color.Magenta, Color.Black); + var hotpink = new Attribute (Color.BrightMagenta, Color.Black); - tv.ColorScheme = new ColorScheme(); - tv.Redraw(tv.Bounds); + tv.ColorScheme = new ColorScheme (); + tv.Redraw (tv.Bounds); // Normal drawing of the tree view TestHelpers.AssertDriverContentsAre( @@ -866,7 +866,7 @@ namespace Terminal.Gui.Views { │ ├─pink │ └─normal └─pink -",output); +", output); // Should all be the same color TestHelpers.AssertDriverColorsAre( @"00000000 @@ -874,30 +874,29 @@ namespace Terminal.Gui.Views { 0000000000 000000 ", - new []{tv.ColorScheme.Normal,pink}); + new [] { tv.ColorScheme.Normal, pink }); // create a new color scheme - var pinkScheme = new ColorScheme - { + var pinkScheme = new ColorScheme { Normal = pink, Focus = hotpink }; // and a delegate that uses the pink color scheme // for nodes "pink" - tv.ColorGetter = (n)=> n.Text.Equals("pink") ? pinkScheme : null; + tv.ColorGetter = (n) => n.Text.Equals ("pink") ? pinkScheme : null; // redraw now that the custom color // delegate is registered - tv.Redraw(tv.Bounds); - + tv.Redraw (tv.Bounds); + // Same text TestHelpers.AssertDriverContentsAre( @"├-normal │ ├─pink │ └─normal └─pink -",output); +", output); // but now the item (only not lines) appear // in pink when they are the word "pink" TestHelpers.AssertDriverColorsAre( @@ -906,7 +905,32 @@ namespace Terminal.Gui.Views { 0000000000 001111 ", - new []{tv.ColorScheme.Normal,pink}); + new [] { tv.ColorScheme.Normal, pink }); + } + + [Fact, AutoInitShutdown] + public void DesiredCursorVisibility_MultiSelect () + { + var tv = new TreeView { Width = 20, Height = 10 }; + + var n1 = new TreeNode ("normal"); + var n2 = new TreeNode ("pink"); + tv.AddObject (n1); + tv.AddObject (n2); + + Application.Top.Add (tv); + Application.Begin (Application.Top); + + Assert.True (tv.MultiSelect); + Assert.True (tv.HasFocus); + Assert.Equal (CursorVisibility.Invisible, tv.DesiredCursorVisibility); + + tv.SelectAll (); + tv.DesiredCursorVisibility = CursorVisibility.Default; + Application.Refresh (); + Application.Driver.GetCursorVisibility (out CursorVisibility visibility); + Assert.Equal (CursorVisibility.Default, tv.DesiredCursorVisibility); + Assert.Equal (CursorVisibility.Default, visibility); } /// diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index 5cc67ac22..32e835362 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -26,7 +26,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive