diff --git a/Terminal.Gui/Core.cs b/Terminal.Gui/Core.cs
index fa0b41354..397f9f462 100644
--- a/Terminal.Gui/Core.cs
+++ b/Terminal.Gui/Core.cs
@@ -350,6 +350,15 @@ namespace Terminal.Gui {
/// The identifier.
public ustring Id { get; set; } = "";
+ ///
+ /// Returns a value indicating if this View is currently on Top (Active)
+ ///
+ public bool IsCurrentTop {
+ get {
+ return Application.Current == this;
+ }
+ }
+
///
/// Gets or sets a value indicating whether this want mouse position reports.
///
@@ -531,7 +540,7 @@ namespace Terminal.Gui {
/// The region that must be flagged for repaint.
public void SetNeedsDisplay (Rect region)
{
- if (NeedDisplay.IsEmpty)
+ if (NeedDisplay == null || NeedDisplay.IsEmpty)
NeedDisplay = region;
else {
var x = Math.Min (NeedDisplay.X, region.X);
@@ -1015,7 +1024,7 @@ namespace Terminal.Gui {
if (subviews != null) {
foreach (var view in subviews) {
- if (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay) {
+ if (view.NeedDisplay != null && (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay)) {
if (view.Frame.IntersectsWith (clipRect) && view.Frame.IntersectsWith (region)) {
// FIXED: optimize this by computing the intersection of region and view.Bounds
@@ -1704,8 +1713,8 @@ namespace Terminal.Gui {
{
Application.CurrentView = this;
- if (this == Application.Top || this == Application.Current) {
- if (!NeedDisplay.IsEmpty) {
+ if (IsCurrentTop) {
+ if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
Driver.SetAttribute (Colors.TopLevel.Normal);
Clear (region);
Driver.SetAttribute (Colors.Base.Normal);
@@ -1887,7 +1896,7 @@ namespace Terminal.Gui {
{
Application.CurrentView = this;
- if (!NeedDisplay.IsEmpty) {
+ if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
DrawFrameWindow ();
}
contentView.Redraw (contentView.Bounds);
@@ -2487,7 +2496,7 @@ namespace Terminal.Gui {
Iteration?.Invoke (null, EventArgs.Empty);
} else if (wait == false)
return;
- if (!state.Toplevel.NeedDisplay.IsEmpty || state.Toplevel.childNeedsDisplay) {
+ if (state.Toplevel.NeedDisplay != null && (!state.Toplevel.NeedDisplay.IsEmpty || state.Toplevel.childNeedsDisplay)) {
state.Toplevel.Redraw (state.Toplevel.Bounds);
if (DebugDrawBounds)
DrawBounds (state.Toplevel);
diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs
index e3c53557b..c325485cb 100644
--- a/Terminal.Gui/Views/ListView.cs
+++ b/Terminal.Gui/Views/ListView.cs
@@ -593,12 +593,16 @@ namespace Terminal.Gui {
{
container.Move (col, line);
var t = src [item];
- if (t is ustring) {
- RenderUstr (driver, (ustring)t, col, line, width);
- } else if (t is string) {
- RenderUstr (driver, (string)t, col, line, width);
- } else
- RenderUstr (driver, t.ToString (), col, line, width);
+ if (t == null) {
+ RenderUstr (driver, ustring.Make(""), col, line, width);
+ } else {
+ if (t is ustring) {
+ RenderUstr (driver, (ustring)t, col, line, width);
+ } else if (t is string) {
+ RenderUstr (driver, (string)t, col, line, width);
+ } else
+ RenderUstr (driver, t.ToString (), col, line, width);
+ }
}
///
diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs
index 0a920a8ed..da16a08ef 100644
--- a/Terminal.Gui/Views/Menu.cs
+++ b/Terminal.Gui/Views/Menu.cs
@@ -162,6 +162,9 @@ namespace Terminal.Gui {
/// The items in the current menu.
public MenuBarItem (ustring title, MenuItem [] children)
{
+ if (children == null)
+ throw new ArgumentNullException (nameof (children), "The parameter cannot be null. Use an empty array instead.");
+
SetTitle (title ?? "");
Children = children;
}
@@ -320,7 +323,7 @@ namespace Terminal.Gui {
public override void PositionCursor ()
{
- if (host == null || !host.isMenuClosed)
+ if (host == null || host.IsMenuOpen)
if (barItems.IsTopLevel) {
host.PositionCursor ();
} else
@@ -403,11 +406,11 @@ namespace Terminal.Gui {
var item = barItems.Children [current];
if (item == null || !item.IsEnabled ()) disabled = true;
if (host.UseKeysUpDownAsKeysLeftRight && barItems.Children [current]?.SubMenu != null &&
- !disabled && !host.isMenuClosed) {
+ !disabled && host.IsMenuOpen) {
CheckSubMenu ();
break;
}
- if (host.isMenuClosed)
+ if (!host.IsMenuOpen)
host.OpenMenu (host.selected);
} while (barItems.Children [current] == null || disabled);
SetNeedsDisplay ();
@@ -563,7 +566,7 @@ namespace Terminal.Gui {
selectedSub = -1;
ColorScheme = Colors.Menu;
WantMousePositionReports = true;
- isMenuClosed = true;
+ IsMenuOpen = false;
}
bool openedByAltKey;
@@ -584,14 +587,14 @@ namespace Terminal.Gui {
{
if (keyEvent.IsAlt) {
// User pressed Alt - this may be a precursor to a menu accelerator (e.g. Alt-F)
- if (!keyEvent.IsCtrl && openedByAltKey && isMenuClosed && openMenu == null && ((uint)keyEvent.Key & (uint)Key.CharMask) == 0) {
+ if (!keyEvent.IsCtrl && openedByAltKey && !IsMenuOpen && openMenu == null && ((uint)keyEvent.Key & (uint)Key.CharMask) == 0) {
// There's no open menu, the first menu item should be highlight.
// The right way to do this is to SetFocus(MenuBar), but for some reason
// that faults.
//Activate (0);
//StartMenu ();
- isMenuClosed = false;
+ IsMenuOpen = true;
selected = 0;
CanFocus = true;
lastFocused = SuperView.MostFocused;
@@ -606,7 +609,7 @@ namespace Terminal.Gui {
if (openMenu != null)
CloseAllMenus ();
openedByAltKey = false;
- isMenuClosed = true;
+ IsMenuOpen = false;
selected = -1;
CanFocus = false;
if (lastFocused != null)
@@ -658,13 +661,13 @@ namespace Terminal.Gui {
for (int i = 0; i < Menus.Length; i++) {
if (i == selected) {
pos++;
- if (!isMenuClosed)
+ if (IsMenuOpen)
Move (pos + 1, 0);
else
Move (pos + 1, 0);
return;
} else {
- if (!isMenuClosed)
+ if (IsMenuOpen)
pos += 1 + Menus [i].TitleLength + 2;
else
pos += 2 + Menus [i].TitleLength + 1;
@@ -695,12 +698,11 @@ namespace Terminal.Gui {
View previousFocused;
internal bool isMenuOpening;
internal bool isMenuClosing;
- internal bool isMenuClosed;
///
- /// True of the menu is open; otherwise false.
+ /// True if the menu is open; otherwise false.
///
- public bool MenuOpen { get; set; }
+ public bool IsMenuOpen { get; protected set; }
View lastFocused;
@@ -748,12 +750,13 @@ namespace Terminal.Gui {
break;
}
isMenuOpening = false;
- isMenuClosed = false;
- MenuOpen = true;
+ IsMenuOpen = true;
}
- // Starts the menu from a hotkey
- void StartMenu ()
+ ///
+ /// Opens the current Menu programatically.
+ ///
+ public void OpenMenu ()
{
if (openMenu != null)
return;
@@ -778,6 +781,13 @@ namespace Terminal.Gui {
SetNeedsDisplay ();
}
+ ///
+ /// Closes the current Menu programatically, if open.
+ ///
+ public void CloseMenu()
+ {
+ CloseMenu (false, false);
+ }
internal void CloseMenu (bool reopen = false, bool isSubMenu = false)
{
isMenuClosing = true;
@@ -799,12 +809,12 @@ namespace Terminal.Gui {
if (!reopen)
selected = -1;
LastFocused.SuperView?.SetFocus (LastFocused);
+ IsMenuOpen = false;
} else {
SuperView.SetFocus (this);
- isMenuClosed = true;
+ IsMenuOpen = false;
PositionCursor ();
}
- isMenuClosed = true;
break;
case true:
@@ -816,7 +826,7 @@ namespace Terminal.Gui {
break;
}
isMenuClosing = false;
- MenuOpen = false;
+ IsMenuOpen = false;
}
void RemoveSubMenu (int index)
@@ -879,7 +889,7 @@ namespace Terminal.Gui {
if (LastFocused != null && LastFocused != this)
selected = -1;
}
- isMenuClosed = true;
+ IsMenuOpen = false;
openedByHotKey = false;
openedByAltKey = false;
}
@@ -993,8 +1003,8 @@ namespace Terminal.Gui {
public override bool ProcessHotKey (KeyEvent kb)
{
if (kb.Key == Key.F9) {
- if (isMenuClosed)
- StartMenu ();
+ if (!IsMenuOpen)
+ OpenMenu ();
else
CloseAllMenus ();
return true;
@@ -1085,7 +1095,7 @@ namespace Terminal.Gui {
for (int i = 0; i < Menus.Length; i++) {
if (cx > pos && me.X < pos + 1 + Menus [i].TitleLength) {
if (selected == i && (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked) &&
- !isMenuClosed) {
+ IsMenuOpen) {
Application.UngrabMouse ();
if (Menus [i].IsTopLevel) {
var menu = new Menu (this, i, 0, Menus [i]);
@@ -1094,7 +1104,7 @@ namespace Terminal.Gui {
CloseMenu ();
}
} else if ((me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked) &&
- isMenuClosed) {
+ !IsMenuOpen) {
if (Menus [i].IsTopLevel) {
var menu = new Menu (this, i, 0, Menus [i]);
menu.Run (Menus [i].Action);
@@ -1102,12 +1112,12 @@ namespace Terminal.Gui {
Activate (i);
}
} else if (selected != i && selected > -1 && me.Flags == MouseFlags.ReportMousePosition) {
- if (!isMenuClosed) {
+ if (IsMenuOpen) {
CloseMenu ();
Activate (i);
}
} else {
- if (!isMenuClosed)
+ if (IsMenuOpen)
Activate (i);
}
return true;
@@ -1139,7 +1149,7 @@ namespace Terminal.Gui {
handled = false;
return false;
}
- } else if (isMenuClosed && (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked ||
+ } else if (!IsMenuOpen && (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked ||
me.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition))) {
Application.GrabMouse (current);
} else {