mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-01 16:59:35 +01:00
Fixes #829. Hangs with disabled menu item selected solved.
This commit is contained in:
@@ -1882,6 +1882,9 @@ namespace Terminal.Gui {
|
|||||||
Remove (subview);
|
Remove (subview);
|
||||||
subview.Dispose ();
|
subview.Dispose ();
|
||||||
}
|
}
|
||||||
|
if (Application.Top.focused == this) {
|
||||||
|
Application.Top.focused = null;
|
||||||
|
}
|
||||||
base.Dispose (disposing);
|
base.Dispose (disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -429,66 +429,19 @@ namespace Terminal.Gui {
|
|||||||
|
|
||||||
public override bool ProcessKey (KeyEvent kb)
|
public override bool ProcessKey (KeyEvent kb)
|
||||||
{
|
{
|
||||||
bool disabled;
|
|
||||||
switch (kb.Key) {
|
switch (kb.Key) {
|
||||||
case Key.Tab:
|
case Key.Tab:
|
||||||
host.CleanUp ();
|
host.CleanUp ();
|
||||||
return true;
|
return true;
|
||||||
case Key.CursorUp:
|
case Key.CursorUp:
|
||||||
if (barItems.IsTopLevel || current == -1)
|
return MoveUp ();
|
||||||
return true;
|
|
||||||
do {
|
|
||||||
disabled = false;
|
|
||||||
current--;
|
|
||||||
if (host.UseKeysUpDownAsKeysLeftRight) {
|
|
||||||
if (current == -1 && barItems.Children [current + 1].IsFromSubMenu && host.selectedSub > -1) {
|
|
||||||
current++;
|
|
||||||
host.PreviousMenu (true);
|
|
||||||
if (host.openMenu.current > 0) {
|
|
||||||
host.openMenu.current--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (current < 0)
|
|
||||||
current = barItems.Children.Length - 1;
|
|
||||||
var item = barItems.Children [current];
|
|
||||||
if (item == null || !item.IsEnabled ()) disabled = true;
|
|
||||||
if (host.UseKeysUpDownAsKeysLeftRight && barItems.Children [current]?.SubMenu != null &&
|
|
||||||
!disabled && host.IsMenuOpen) {
|
|
||||||
CheckSubMenu ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (barItems.Children [current] == null || disabled);
|
|
||||||
SetNeedsDisplay ();
|
|
||||||
return true;
|
|
||||||
case Key.CursorDown:
|
case Key.CursorDown:
|
||||||
if (barItems.IsTopLevel) {
|
return MoveDown ();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
current++;
|
|
||||||
disabled = false;
|
|
||||||
if (current == barItems.Children.Length)
|
|
||||||
current = 0;
|
|
||||||
var item = barItems.Children [current];
|
|
||||||
if (item == null || !item.IsEnabled ()) disabled = true;
|
|
||||||
if (host.UseKeysUpDownAsKeysLeftRight && barItems.Children [current]?.SubMenu != null &&
|
|
||||||
!disabled && host.IsMenuOpen) {
|
|
||||||
CheckSubMenu ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!host.IsMenuOpen)
|
|
||||||
host.OpenMenu (host.selected);
|
|
||||||
} while (barItems.Children [current] == null || disabled);
|
|
||||||
SetNeedsDisplay ();
|
|
||||||
return true;
|
|
||||||
case Key.CursorLeft:
|
case Key.CursorLeft:
|
||||||
host.PreviousMenu (true);
|
host.PreviousMenu (true);
|
||||||
return true;
|
return true;
|
||||||
case Key.CursorRight:
|
case Key.CursorRight:
|
||||||
host.NextMenu (barItems.IsTopLevel || barItems.Children [current].IsFromSubMenu ? true : false);
|
host.NextMenu (barItems.IsTopLevel || (barItems.Children != null && current > -1 && current < barItems.Children.Length && barItems.Children [current].IsFromSubMenu) ? true : false);
|
||||||
return true;
|
return true;
|
||||||
case Key.Esc:
|
case Key.Esc:
|
||||||
Application.UngrabMouse ();
|
Application.UngrabMouse ();
|
||||||
@@ -497,8 +450,7 @@ namespace Terminal.Gui {
|
|||||||
case Key.Enter:
|
case Key.Enter:
|
||||||
if (barItems.IsTopLevel) {
|
if (barItems.IsTopLevel) {
|
||||||
Run (barItems.Action);
|
Run (barItems.Action);
|
||||||
} else {
|
} else if (current > -1) {
|
||||||
CheckSubMenu ();
|
|
||||||
Run (barItems.Children [current].Action);
|
Run (barItems.Children [current].Action);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -520,6 +472,95 @@ namespace Terminal.Gui {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MoveDown ()
|
||||||
|
{
|
||||||
|
if (barItems.IsTopLevel) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool disabled;
|
||||||
|
do {
|
||||||
|
current++;
|
||||||
|
if (current >= barItems.Children.Length) {
|
||||||
|
current = 0;
|
||||||
|
}
|
||||||
|
if (!host.SelectEnabledItem (barItems.Children, current, out current)) {
|
||||||
|
if (current == -1 && barItems.Children [current + 1].IsFromSubMenu && host.selectedSub > -1) {
|
||||||
|
current++;
|
||||||
|
host.PreviousMenu (true);
|
||||||
|
if (host.openMenu.current > 0) {
|
||||||
|
host.openMenu.current++;
|
||||||
|
if (host.openMenu.current >= barItems.Children.Length) {
|
||||||
|
host.openMenu.current = 0;
|
||||||
|
host.SelectEnabledItem (host.openMenu.barItems.Children, host.openMenu.current, out host.openMenu.current);
|
||||||
|
}
|
||||||
|
host.openCurrentMenu = host.openMenu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var item = barItems.Children [current];
|
||||||
|
if (item?.IsEnabled () != true) {
|
||||||
|
disabled = true;
|
||||||
|
} else {
|
||||||
|
disabled = false;
|
||||||
|
}
|
||||||
|
if (host.UseKeysUpDownAsKeysLeftRight && barItems.Children [current]?.SubMenu != null &&
|
||||||
|
!disabled && host.IsMenuOpen) {
|
||||||
|
CheckSubMenu ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!host.IsMenuOpen) {
|
||||||
|
host.OpenMenu (host.selected);
|
||||||
|
}
|
||||||
|
} while (barItems.Children [current] == null || disabled);
|
||||||
|
SetNeedsDisplay ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MoveUp ()
|
||||||
|
{
|
||||||
|
if (barItems.IsTopLevel || current == -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool disabled;
|
||||||
|
do {
|
||||||
|
current--;
|
||||||
|
if (host.UseKeysUpDownAsKeysLeftRight) {
|
||||||
|
if (current == -1 && barItems.Children [current + 1].IsFromSubMenu && host.selectedSub > -1) {
|
||||||
|
current++;
|
||||||
|
host.PreviousMenu (true);
|
||||||
|
if (host.openMenu.current > 0) {
|
||||||
|
host.openMenu.current--;
|
||||||
|
host.openCurrentMenu = host.openMenu;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current < 0)
|
||||||
|
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 ();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var item = barItems.Children [current];
|
||||||
|
if (item?.IsEnabled () != true) {
|
||||||
|
disabled = true;
|
||||||
|
} else {
|
||||||
|
disabled = false;
|
||||||
|
}
|
||||||
|
if (host.UseKeysUpDownAsKeysLeftRight && barItems.Children [current]?.SubMenu != null &&
|
||||||
|
!disabled && host.IsMenuOpen) {
|
||||||
|
CheckSubMenu ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (barItems.Children [current] == null || disabled);
|
||||||
|
SetNeedsDisplay ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public override bool MouseEvent (MouseEvent me)
|
public override bool MouseEvent (MouseEvent me)
|
||||||
{
|
{
|
||||||
if (!host.handled && !host.HandleGrabView (me, this)) {
|
if (!host.handled && !host.HandleGrabView (me, this)) {
|
||||||
@@ -558,7 +599,7 @@ namespace Terminal.Gui {
|
|||||||
|
|
||||||
internal void CheckSubMenu ()
|
internal void CheckSubMenu ()
|
||||||
{
|
{
|
||||||
if (barItems.Children [current] == null)
|
if (current == -1 || barItems.Children [current] == null)
|
||||||
return;
|
return;
|
||||||
var subMenu = barItems.Children [current].SubMenu;
|
var subMenu = barItems.Children [current].SubMenu;
|
||||||
if (subMenu != null) {
|
if (subMenu != null) {
|
||||||
@@ -788,7 +829,7 @@ namespace Terminal.Gui {
|
|||||||
public Action MenuClosing;
|
public Action MenuClosing;
|
||||||
|
|
||||||
internal Menu openMenu;
|
internal Menu openMenu;
|
||||||
Menu openCurrentMenu;
|
internal Menu openCurrentMenu;
|
||||||
internal List<Menu> openSubMenu;
|
internal List<Menu> openSubMenu;
|
||||||
View previousFocused;
|
View previousFocused;
|
||||||
internal bool isMenuOpening;
|
internal bool isMenuOpening;
|
||||||
@@ -878,6 +919,10 @@ namespace Terminal.Gui {
|
|||||||
|
|
||||||
previousFocused = SuperView.Focused;
|
previousFocused = SuperView.Focused;
|
||||||
OpenMenu (selected);
|
OpenMenu (selected);
|
||||||
|
if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current)) {
|
||||||
|
CloseMenu ();
|
||||||
|
}
|
||||||
|
openCurrentMenu.CheckSubMenu ();
|
||||||
Application.GrabMouse (this);
|
Application.GrabMouse (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -891,9 +936,58 @@ namespace Terminal.Gui {
|
|||||||
previousFocused = SuperView.Focused;
|
previousFocused = SuperView.Focused;
|
||||||
|
|
||||||
OpenMenu (idx, sIdx, subMenu);
|
OpenMenu (idx, sIdx, subMenu);
|
||||||
|
if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current)) {
|
||||||
|
if (subMenu == null) {
|
||||||
|
CloseMenu ();
|
||||||
|
}
|
||||||
|
}
|
||||||
SetNeedsDisplay ();
|
SetNeedsDisplay ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool SelectEnabledItem (IEnumerable<MenuItem> chldren, int current, out int newCurrent, bool forward = true)
|
||||||
|
{
|
||||||
|
if (chldren == null) {
|
||||||
|
newCurrent = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<MenuItem> childrens;
|
||||||
|
if (forward) {
|
||||||
|
childrens = chldren;
|
||||||
|
} else {
|
||||||
|
childrens = chldren.Reverse ();
|
||||||
|
}
|
||||||
|
int count;
|
||||||
|
if (forward) {
|
||||||
|
count = -1;
|
||||||
|
} else {
|
||||||
|
count = childrens.Count ();
|
||||||
|
}
|
||||||
|
foreach (var child in childrens) {
|
||||||
|
if (forward) {
|
||||||
|
if (++count < current) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (--count > current) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (child == null || !child.IsEnabled ()) {
|
||||||
|
if (forward) {
|
||||||
|
current++;
|
||||||
|
} else {
|
||||||
|
current--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newCurrent = current;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newCurrent = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes the current Menu programatically, if open.
|
/// Closes the current Menu programatically, if open.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1041,6 +1135,13 @@ namespace Terminal.Gui {
|
|||||||
if (selected > -1)
|
if (selected > -1)
|
||||||
CloseMenu (true, false);
|
CloseMenu (true, false);
|
||||||
OpenMenu (selected);
|
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 ();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case true:
|
case true:
|
||||||
if (selectedSub > -1) {
|
if (selectedSub > -1) {
|
||||||
@@ -1068,6 +1169,7 @@ namespace Terminal.Gui {
|
|||||||
if (selected > -1)
|
if (selected > -1)
|
||||||
CloseMenu (true);
|
CloseMenu (true);
|
||||||
OpenMenu (selected);
|
OpenMenu (selected);
|
||||||
|
SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current);
|
||||||
break;
|
break;
|
||||||
case true:
|
case true:
|
||||||
if (UseKeysUpDownAsKeysLeftRight) {
|
if (UseKeysUpDownAsKeysLeftRight) {
|
||||||
@@ -1120,6 +1222,10 @@ namespace Terminal.Gui {
|
|||||||
Application.GrabMouse (this);
|
Application.GrabMouse (this);
|
||||||
selected = i;
|
selected = i;
|
||||||
OpenMenu (i);
|
OpenMenu (i);
|
||||||
|
if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current)) {
|
||||||
|
CloseMenu ();
|
||||||
|
}
|
||||||
|
openCurrentMenu.CheckSubMenu ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1173,7 +1279,9 @@ namespace Terminal.Gui {
|
|||||||
|
|
||||||
case Key.CursorDown:
|
case Key.CursorDown:
|
||||||
case Key.Enter:
|
case Key.Enter:
|
||||||
ProcessMenu (selected, Menus [selected]);
|
if (selected > -1) {
|
||||||
|
ProcessMenu (selected, Menus [selected]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user