Merge branch 'master' into docs

This commit is contained in:
Charlie Kindel
2020-05-23 19:46:12 -06:00
5 changed files with 106 additions and 55 deletions

View File

@@ -350,6 +350,15 @@ namespace Terminal.Gui {
/// <value>The identifier.</value>
public ustring Id { get; set; } = "";
/// <summary>
/// Returns a value indicating if this View is currently on Top (Active)
/// </summary>
public bool IsCurrentTop {
get {
return Application.Current == this;
}
}
/// <summary>
/// Gets or sets a value indicating whether this <see cref="View"/> want mouse position reports.
/// </summary>
@@ -531,7 +540,7 @@ namespace Terminal.Gui {
/// <param name="region">The region that must be flagged for repaint.</param>
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);

View File

@@ -65,10 +65,15 @@ namespace Terminal.Gui {
void DateField_Changed (object sender, ustring e)
{
if (!DateTime.TryParseExact (Text.ToString (), Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result))
if (!DateTime.TryParseExact (GetDate (Text).ToString(), GetInvarianteFormat (), CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result))
Text = e;
}
string GetInvarianteFormat ()
{
return $"MM{sepChar}dd{sepChar}yyyy";
}
string GetLongFormat (string lf)
{
ustring [] frm = ustring.Make (lf).Split (ustring.Make (sepChar));
@@ -195,6 +200,31 @@ namespace Terminal.Gui {
return date;
}
ustring GetDate (ustring text)
{
ustring [] vals = text.Split (ustring.Make (sepChar));
ustring [] frm = ustring.Make (Format).Split (ustring.Make (sepChar));
ustring [] date = { null, null, null };
for (int i = 0; i < frm.Length; i++) {
if (frm [i].Contains ("M")) {
date [0] = vals [i].TrimSpace ();
} else if (frm [i].Contains ("d")) {
date [1] = vals [i].TrimSpace ();
} else {
var year = vals [i].TrimSpace ();
if (year.Length == 2) {
var y = DateTime.Now.Year.ToString ();
date [2] = y.Substring (0, 2) + year.ToString ();
} else {
date [2] = vals [i].TrimSpace ();
}
}
}
return date [0] + ustring.Make (sepChar) + date [1] + ustring.Make (sepChar) + date [2];
}
int GetFormatIndex (ustring [] fm, string t)
{
int idx = -1;

View File

@@ -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);
}
}
/// <summary>

View File

@@ -162,6 +162,9 @@ namespace Terminal.Gui {
/// <param name="children">The items in the current menu.</param>
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;
/// <summary>
/// True of the menu is open; otherwise false.
/// True if the menu is open; otherwise false.
/// </summary>
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 ()
/// <summary>
/// Opens the current Menu programatically.
/// </summary>
public void OpenMenu ()
{
if (openMenu != null)
return;
@@ -778,6 +781,13 @@ namespace Terminal.Gui {
SetNeedsDisplay ();
}
/// <summary>
/// Closes the current Menu programatically, if open.
/// </summary>
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 {

View File

@@ -8,36 +8,34 @@ namespace UICatalog {
class TimeAndDate : Scenario {
public override void Setup ()
{
// NOTE: The TimeField control is not ready for prime-time. See #246
var longTime = new TimeField (0, 0, DateTime.Now, isShort: false) {
// BUGBUG: TimeField does not support Computed Layout
var longTime = new TimeField (DateTime.Now) {
X = Pos.Center (),
Y = 2,
IsShortFormat = false,
ReadOnly = false,
};
Win.Add (longTime);
var shortTime = new TimeField (0, 2, DateTime.Now, isShort: true) {
// BUGBUG: TimeField does not support Computed Layout
var shortTime = new TimeField (DateTime.Now) {
X = Pos.Center (),
Y = Pos.Bottom(longTime) + 1,
ReadOnly = true,
IsShortFormat = true,
ReadOnly = false,
};
Win.Add (shortTime);
var shortDate = new DateField (0, 2, DateTime.Now, isShort: true) {
// BUGBUG: TimeField does not support Computed Layout
var shortDate = new DateField (DateTime.Now) {
X = Pos.Center (),
Y = Pos.Bottom (shortTime) + 1,
IsShortFormat = true,
ReadOnly = true,
};
Win.Add (shortDate);
var longDate = new TimeField (0, 2, DateTime.Now, isShort: true) {
// BUGBUG: TimeField does not support Computed Layout
var longDate = new DateField (DateTime.Now) {
X = Pos.Center (),
Y = Pos.Bottom (shortDate) + 1,
IsShortFormat = false,
ReadOnly = true,
};
Win.Add (longDate);
@@ -49,14 +47,14 @@ namespace UICatalog {
longTime.ReadOnly = !longTime.ReadOnly;
shortTime.ReadOnly = !shortTime.ReadOnly;
//longTime.IsShortFormat = !longTime.IsShortFormat;
//shortTime.IsShortFormat = !shortTime.IsShortFormat;
longTime.IsShortFormat = !longTime.IsShortFormat;
shortTime.IsShortFormat = !shortTime.IsShortFormat;
longDate.ReadOnly = !longDate.ReadOnly;
shortDate.ReadOnly = !shortDate.ReadOnly;
//longDate.IsShortFormat = !longDate.IsShortFormat;
//shortDate.IsShortFormat = !shortDate.IsShortFormat;
longDate.IsShortFormat = !longDate.IsShortFormat;
shortDate.IsShortFormat = !shortDate.IsShortFormat;
}
});
}