Fixes #829. Hangs with disabled menu item selected solved.

This commit is contained in:
BDisp
2020-07-27 22:10:04 +01:00
parent 4f5bf24a08
commit b7901acd2b
2 changed files with 166 additions and 55 deletions

View File

@@ -1882,6 +1882,9 @@ namespace Terminal.Gui {
Remove (subview);
subview.Dispose ();
}
if (Application.Top.focused == this) {
Application.Top.focused = null;
}
base.Dispose (disposing);
}

View File

@@ -429,66 +429,19 @@ namespace Terminal.Gui {
public override bool ProcessKey (KeyEvent kb)
{
bool disabled;
switch (kb.Key) {
case Key.Tab:
host.CleanUp ();
return true;
case Key.CursorUp:
if (barItems.IsTopLevel || current == -1)
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;
return MoveUp ();
case Key.CursorDown:
if (barItems.IsTopLevel) {
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;
return MoveDown ();
case Key.CursorLeft:
host.PreviousMenu (true);
return true;
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;
case Key.Esc:
Application.UngrabMouse ();
@@ -497,8 +450,7 @@ namespace Terminal.Gui {
case Key.Enter:
if (barItems.IsTopLevel) {
Run (barItems.Action);
} else {
CheckSubMenu ();
} else if (current > -1) {
Run (barItems.Children [current].Action);
}
return true;
@@ -520,6 +472,95 @@ namespace Terminal.Gui {
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)
{
if (!host.handled && !host.HandleGrabView (me, this)) {
@@ -558,7 +599,7 @@ namespace Terminal.Gui {
internal void CheckSubMenu ()
{
if (barItems.Children [current] == null)
if (current == -1 || barItems.Children [current] == null)
return;
var subMenu = barItems.Children [current].SubMenu;
if (subMenu != null) {
@@ -788,7 +829,7 @@ namespace Terminal.Gui {
public Action MenuClosing;
internal Menu openMenu;
Menu openCurrentMenu;
internal Menu openCurrentMenu;
internal List<Menu> openSubMenu;
View previousFocused;
internal bool isMenuOpening;
@@ -878,6 +919,10 @@ namespace Terminal.Gui {
previousFocused = SuperView.Focused;
OpenMenu (selected);
if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current)) {
CloseMenu ();
}
openCurrentMenu.CheckSubMenu ();
Application.GrabMouse (this);
}
@@ -891,9 +936,58 @@ namespace Terminal.Gui {
previousFocused = SuperView.Focused;
OpenMenu (idx, sIdx, subMenu);
if (!SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current)) {
if (subMenu == null) {
CloseMenu ();
}
}
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>
/// Closes the current Menu programatically, if open.
/// </summary>
@@ -1041,6 +1135,13 @@ namespace Terminal.Gui {
if (selected > -1)
CloseMenu (true, false);
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;
case true:
if (selectedSub > -1) {
@@ -1068,6 +1169,7 @@ namespace Terminal.Gui {
if (selected > -1)
CloseMenu (true);
OpenMenu (selected);
SelectEnabledItem (openCurrentMenu.barItems.Children, openCurrentMenu.current, out openCurrentMenu.current);
break;
case true:
if (UseKeysUpDownAsKeysLeftRight) {
@@ -1120,6 +1222,10 @@ namespace Terminal.Gui {
Application.GrabMouse (this);
selected = 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.Enter:
ProcessMenu (selected, Menus [selected]);
if (selected > -1) {
ProcessMenu (selected, Menus [selected]);
}
break;
default: