diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
index 7d2b0b422..c915db6e4 100644
--- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
@@ -62,40 +62,61 @@ namespace Terminal.Gui {
Curses.move (crow, ccol);
needMove = false;
}
- if (runeWidth < 2 && ccol > 0
- && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
+ if (runeWidth == 0 && ccol > 0) {
+ var r = contents [crow, ccol - 1, 0];
+ var s = new string (new char [] { (char)r, (char)rune });
+ string sn;
+ if (!s.IsNormalized ()) {
+ sn = s.Normalize ();
+ } else {
+ sn = s;
+ }
+ var c = sn [0];
+ Curses.mvaddch (crow, ccol - 1, (int)(uint)c);
+ contents [crow, ccol - 1, 0] = c;
+ contents [crow, ccol - 1, 1] = CurrentAttribute;
+ contents [crow, ccol - 1, 2] = 1;
- var curAtttib = CurrentAttribute;
- Curses.attrset (contents [crow, ccol - 1, 1]);
- Curses.mvaddch (crow, ccol - 1, (int)(uint)' ');
- contents [crow, ccol - 1, 0] = (int)(uint)' ';
- Curses.move (crow, ccol);
- Curses.attrset (curAtttib);
-
- } else if (runeWidth < 2 && ccol <= Clip.Right - 1
- && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
-
- var curAtttib = CurrentAttribute;
- Curses.attrset (contents [crow, ccol + 1, 1]);
- Curses.mvaddch (crow, ccol + 1, (int)(uint)' ');
- contents [crow, ccol + 1, 0] = (int)(uint)' ';
- Curses.move (crow, ccol);
- Curses.attrset (curAtttib);
-
- }
- if (runeWidth > 1 && ccol == Clip.Right - 1) {
- Curses.addch ((int)(uint)' ');
- contents [crow, ccol, 0] = (int)(uint)' ';
} else {
- Curses.addch ((int)(uint)rune);
- contents [crow, ccol, 0] = (int)(uint)rune;
- }
- contents [crow, ccol, 1] = CurrentAttribute;
- contents [crow, ccol, 2] = 1;
- } else
- needMove = true;
+ if (runeWidth < 2 && ccol > 0
+ && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
- ccol++;
+ var curAtttib = CurrentAttribute;
+ Curses.attrset (contents [crow, ccol - 1, 1]);
+ Curses.mvaddch (crow, ccol - 1, (int)(uint)' ');
+ contents [crow, ccol - 1, 0] = (int)(uint)' ';
+ Curses.move (crow, ccol);
+ Curses.attrset (curAtttib);
+
+ } else if (runeWidth < 2 && ccol <= Clip.Right - 1
+ && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
+
+ var curAtttib = CurrentAttribute;
+ Curses.attrset (contents [crow, ccol + 1, 1]);
+ Curses.mvaddch (crow, ccol + 1, (int)(uint)' ');
+ contents [crow, ccol + 1, 0] = (int)(uint)' ';
+ Curses.move (crow, ccol);
+ Curses.attrset (curAtttib);
+
+ }
+ if (runeWidth > 1 && ccol == Clip.Right - 1) {
+ Curses.addch ((int)(uint)' ');
+ contents [crow, ccol, 0] = (int)(uint)' ';
+ } else {
+ Curses.addch ((int)(uint)rune);
+ contents [crow, ccol, 0] = (int)(uint)rune;
+ }
+ contents [crow, ccol, 1] = CurrentAttribute;
+ contents [crow, ccol, 2] = 1;
+ }
+ } else {
+ needMove = true;
+ }
+
+ if (runeWidth < 0 || runeWidth > 0) {
+ ccol++;
+ }
+
if (runeWidth > 1) {
if (validClip && ccol < Clip.Right) {
contents [crow, ccol, 1] = CurrentAttribute;
@@ -104,8 +125,9 @@ namespace Terminal.Gui {
ccol++;
}
- if (sync)
+ if (sync) {
UpdateScreen ();
+ }
}
public override void AddStr (ustring str)
@@ -143,6 +165,19 @@ namespace Terminal.Gui {
SetCursorVisibility (CursorVisibility.Default);
Curses.endwin ();
+
+ // I'm commenting this because was used in a trying to fix the Linux hanging and forgot to exclude it.
+ // Clear and reset entire screen.
+ //Console.Out.Write ("\x1b[2J");
+ //Console.Out.Flush ();
+
+ // Set top and bottom lines of a window.
+ //Console.Out.Write ("\x1b[1;25r");
+ //Console.Out.Flush ();
+
+ //Set cursor key to cursor.
+ //Console.Out.Write ("\x1b[?1l");
+ //Console.Out.Flush ();
}
public override void UpdateScreen () => window.redrawwin ();
@@ -155,6 +190,8 @@ namespace Terminal.Gui {
public Curses.Window window;
+ //static short last_color_pair = 16;
+
///
/// Creates a curses color from the provided foreground and background colors
///
@@ -180,6 +217,37 @@ namespace Terminal.Gui {
return MakeColor ((short)MapColor (fore), (short)MapColor (back));
}
+ int [,] colorPairs = new int [16, 16];
+
+ public override void SetColors (ConsoleColor foreground, ConsoleColor background)
+ {
+ // BUGBUG: This code is never called ?? See Issue #2300
+ int f = (short)foreground;
+ int b = (short)background;
+ var v = colorPairs [f, b];
+ if ((v & 0x10000) == 0) {
+ b &= 0x7;
+ bool bold = (f & 0x8) != 0;
+ f &= 0x7;
+
+ v = MakeColor ((short)f, (short)b) | (bold ? Curses.A_BOLD : 0);
+ colorPairs [(int)foreground, (int)background] = v | 0x1000;
+ }
+ SetAttribute (v & 0xffff);
+ }
+
+ Dictionary rawPairs = new Dictionary ();
+ public override void SetColors (short foreColorId, short backgroundColorId)
+ {
+ // BUGBUG: This code is never called ?? See Issue #2300
+ int key = ((ushort)foreColorId << 16) | (ushort)backgroundColorId;
+ if (!rawPairs.TryGetValue (key, out var v)) {
+ v = MakeColor (foreColorId, backgroundColorId);
+ rawPairs [key] = v;
+ }
+ SetAttribute (v);
+ }
+
static Key MapCursesKey (int cursesKey)
{
switch (cursesKey) {
@@ -767,7 +835,7 @@ namespace Terminal.Gui {
};
}
- Curses.Event reportableMouseEvents;
+ Curses.Event oldMouseEvents, reportableMouseEvents;
public override void Init (Action terminalResized)
{
if (window != null)
@@ -824,7 +892,7 @@ namespace Terminal.Gui {
Curses.noecho ();
Curses.Window.Standard.keypad (true);
- reportableMouseEvents = Curses.mousemask (Curses.Event.AllEvents | Curses.Event.ReportMousePosition, out _);
+ reportableMouseEvents = Curses.mousemask (Curses.Event.AllEvents | Curses.Event.ReportMousePosition, out oldMouseEvents);
TerminalResized = terminalResized;
if (reportableMouseEvents.HasFlag (Curses.Event.ReportMousePosition))
StartReportingMouseMoves ();
@@ -946,7 +1014,7 @@ namespace Terminal.Gui {
case Color.White:
return Curses.COLOR_WHITE | Curses.A_BOLD | Curses.COLOR_GRAY;
case Color.Invalid:
- return Curses.COLOR_BLACK;
+ return Curses.COLOR_BLACK;
}
throw new ArgumentException ("Invalid color code");
}
@@ -1020,6 +1088,23 @@ namespace Terminal.Gui {
Console.Out.Flush ();
}
+ //int lastMouseInterval;
+ //bool mouseGrabbed;
+
+ public override void UncookMouse ()
+ {
+ //if (mouseGrabbed)
+ // return;
+ //lastMouseInterval = Curses.mouseinterval (0);
+ //mouseGrabbed = true;
+ }
+
+ public override void CookMouse ()
+ {
+ //mouseGrabbed = false;
+ //Curses.mouseinterval (lastMouseInterval);
+ }
+
///
public override bool GetCursorVisibility (out CursorVisibility visibility)
{
diff --git a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs
index 3adbb7a23..661daaca4 100644
--- a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs
@@ -33,7 +33,7 @@ namespace Terminal.Gui {
UseFakeClipboard = useFakeClipboard;
FakeClipboardAlwaysThrowsNotSupportedException = fakeClipboardAlwaysThrowsNotSupportedException;
FakeClipboardIsSupportedAlwaysFalse = fakeClipboardIsSupportedAlwaysTrue;
-
+
// double check usage is correct
Debug.Assert (useFakeClipboard == false && fakeClipboardAlwaysThrowsNotSupportedException == false);
Debug.Assert (useFakeClipboard == false && fakeClipboardIsSupportedAlwaysTrue == false);
@@ -131,31 +131,51 @@ namespace Terminal.Gui {
//MockConsole.CursorTop = crow;
needMove = false;
}
- if (runeWidth < 2 && ccol > 0
+ if (runeWidth == 0 && ccol > 0) {
+ var r = contents [crow, ccol - 1, 0];
+ var s = new string (new char [] { (char)r, (char)rune });
+ string sn;
+ if (!s.IsNormalized ()) {
+ sn = s.Normalize ();
+ } else {
+ sn = s;
+ }
+ var c = sn [0];
+ contents [crow, ccol - 1, 0] = c;
+ contents [crow, ccol - 1, 1] = CurrentAttribute;
+ contents [crow, ccol - 1, 2] = 1;
+
+ } else {
+ if (runeWidth < 2 && ccol > 0
&& Rune.ColumnWidth ((Rune)contents [crow, ccol - 1, 0]) > 1) {
- contents [crow, ccol - 1, 0] = (int)(uint)' ';
+ contents [crow, ccol - 1, 0] = (int)(uint)' ';
- } else if (runeWidth < 2 && ccol <= Clip.Right - 1
- && Rune.ColumnWidth ((Rune)contents [crow, ccol, 0]) > 1) {
+ } else if (runeWidth < 2 && ccol <= Clip.Right - 1
+ && Rune.ColumnWidth ((Rune)contents [crow, ccol, 0]) > 1) {
- contents [crow, ccol + 1, 0] = (int)(uint)' ';
- contents [crow, ccol + 1, 2] = 1;
+ contents [crow, ccol + 1, 0] = (int)(uint)' ';
+ contents [crow, ccol + 1, 2] = 1;
+ }
+ if (runeWidth > 1 && ccol == Clip.Right - 1) {
+ contents [crow, ccol, 0] = (int)(uint)' ';
+ } else {
+ contents [crow, ccol, 0] = (int)(uint)rune;
+ }
+ contents [crow, ccol, 1] = CurrentAttribute;
+ contents [crow, ccol, 2] = 1;
+
+ dirtyLine [crow] = true;
}
- if (runeWidth > 1 && ccol == Clip.Right - 1) {
- contents [crow, ccol, 0] = (int)(uint)' ';
- } else {
- contents [crow, ccol, 0] = (int)(uint)rune;
- }
- contents [crow, ccol, 1] = CurrentAttribute;
- contents [crow, ccol, 2] = 1;
-
- dirtyLine [crow] = true;
- } else
+ } else {
needMove = true;
+ }
+
+ if (runeWidth < 0 || runeWidth > 0) {
+ ccol++;
+ }
- ccol++;
if (runeWidth > 1) {
if (validClip && ccol < Clip.Right) {
contents [crow, ccol, 1] = CurrentAttribute;
@@ -169,8 +189,9 @@ namespace Terminal.Gui {
// if (crow + 1 < Rows)
// crow++;
//}
- if (sync)
+ if (sync) {
UpdateScreen ();
+ }
}
public override void AddStr (ustring str)
@@ -621,6 +642,7 @@ namespace Terminal.Gui {
return hasColor;
}
+ #region Unused
public override void UpdateCursor ()
{
if (!EnsureCursorVisibility ())
@@ -636,10 +658,35 @@ namespace Terminal.Gui {
}
}
- #region Unused
- public override void StartReportingMouseMoves () {}
- public override void StopReportingMouseMoves () {}
- public override void Suspend () {}
+ public override void StartReportingMouseMoves ()
+ {
+ }
+
+ public override void StopReportingMouseMoves ()
+ {
+ }
+
+ public override void Suspend ()
+ {
+ }
+
+ public override void SetColors (ConsoleColor foreground, ConsoleColor background)
+ {
+ }
+
+ public override void SetColors (short foregroundColorId, short backgroundColorId)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void CookMouse ()
+ {
+ }
+
+ public override void UncookMouse ()
+ {
+ }
+
#endregion
public class FakeClipboard : ClipboardBase {
diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs
index 485a06f6e..9ae4eb20e 100644
--- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs
@@ -1241,30 +1241,49 @@ namespace Terminal.Gui {
var validClip = IsValidContent (ccol, crow, Clip);
if (validClip) {
- if (runeWidth < 2 && ccol > 0
- && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
+ if (runeWidth == 0 && ccol > 0) {
+ var r = contents [crow, ccol - 1, 0];
+ var s = new string (new char [] { (char)r, (char)rune });
+ string sn;
+ if (!s.IsNormalized ()) {
+ sn = s.Normalize ();
+ } else {
+ sn = s;
+ }
+ var c = sn [0];
+ contents [crow, ccol - 1, 0] = c;
+ contents [crow, ccol - 1, 1] = CurrentAttribute;
+ contents [crow, ccol - 1, 2] = 1;
- contents [crow, ccol - 1, 0] = (int)(uint)' ';
-
- } else if (runeWidth < 2 && ccol <= Clip.Right - 1
- && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
-
- contents [crow, ccol + 1, 0] = (int)(uint)' ';
- contents [crow, ccol + 1, 2] = 1;
-
- }
- if (runeWidth > 1 && ccol == Clip.Right - 1) {
- contents [crow, ccol, 0] = (int)(uint)' ';
} else {
- contents [crow, ccol, 0] = (int)(uint)rune;
- }
- contents [crow, ccol, 1] = CurrentAttribute;
- contents [crow, ccol, 2] = 1;
+ if (runeWidth < 2 && ccol > 0
+ && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
+ contents [crow, ccol - 1, 0] = (int)(uint)' ';
+
+ } else if (runeWidth < 2 && ccol <= Clip.Right - 1
+ && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
+
+ contents [crow, ccol + 1, 0] = (int)(uint)' ';
+ contents [crow, ccol + 1, 2] = 1;
+
+ }
+ if (runeWidth > 1 && ccol == Clip.Right - 1) {
+ contents [crow, ccol, 0] = (int)(uint)' ';
+ } else {
+ contents [crow, ccol, 0] = (int)(uint)rune;
+ }
+ contents [crow, ccol, 1] = CurrentAttribute;
+ contents [crow, ccol, 2] = 1;
+
+ }
dirtyLine [crow] = true;
}
- ccol++;
+ if (runeWidth < 0 || runeWidth > 0) {
+ ccol++;
+ }
+
if (runeWidth > 1) {
if (validClip && ccol < Clip.Right) {
contents [crow, ccol, 1] = CurrentAttribute;
@@ -1487,7 +1506,7 @@ namespace Terminal.Gui {
outputWidth++;
var rune = contents [row, col, 0];
char [] spair;
- if (Rune.DecodeSurrogatePair((uint) rune, out spair)) {
+ if (Rune.DecodeSurrogatePair ((uint)rune, out spair)) {
output.Append (spair);
} else {
output.Append ((char)rune);
@@ -1995,6 +2014,24 @@ namespace Terminal.Gui {
return hasColor;
}
+ #region Unused
+ public override void SetColors (ConsoleColor foreground, ConsoleColor background)
+ {
+ }
+
+ public override void SetColors (short foregroundColorId, short backgroundColorId)
+ {
+ }
+
+ public override void CookMouse ()
+ {
+ }
+
+ public override void UncookMouse ()
+ {
+ }
+ #endregion
+
//
// These are for the .NET driver, but running natively on Windows, wont run
// on the Mono emulation
diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
index 9b0568a62..8a7502c26 100644
--- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
@@ -1517,35 +1517,57 @@ namespace Terminal.Gui {
var validClip = IsValidContent (ccol, crow, Clip);
if (validClip) {
- if (runeWidth < 2 && ccol > 0
- && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
-
+ if (runeWidth == 0 && ccol > 0) {
+ var r = contents [crow, ccol - 1, 0];
+ var s = new string (new char [] { (char)r, (char)rune });
+ string sn;
+ if (!s.IsNormalized ()) {
+ sn = s.Normalize ();
+ } else {
+ sn = s;
+ }
+ var c = sn [0];
var prevPosition = crow * Cols + (ccol - 1);
- OutputBuffer [prevPosition].Char.UnicodeChar = ' ';
- contents [crow, ccol - 1, 0] = (int)(uint)' ';
-
- } else if (runeWidth < 2 && ccol <= Clip.Right - 1
- && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
-
- var prevPosition = GetOutputBufferPosition () + 1;
- OutputBuffer [prevPosition].Char.UnicodeChar = (char)' ';
- contents [crow, ccol + 1, 0] = (int)(uint)' ';
-
- }
- if (runeWidth > 1 && ccol == Clip.Right - 1) {
- OutputBuffer [position].Char.UnicodeChar = (char)' ';
- contents [crow, ccol, 0] = (int)(uint)' ';
+ OutputBuffer [prevPosition].Char.UnicodeChar = c;
+ contents [crow, ccol - 1, 0] = c;
+ OutputBuffer [prevPosition].Attributes = (ushort)CurrentAttribute;
+ contents [crow, ccol - 1, 1] = CurrentAttribute;
+ contents [crow, ccol - 1, 2] = 1;
+ WindowsConsole.SmallRect.Update (ref damageRegion, (short)(ccol - 1), (short)crow);
} else {
- OutputBuffer [position].Char.UnicodeChar = (char)rune;
- contents [crow, ccol, 0] = (int)(uint)rune;
+ if (runeWidth < 2 && ccol > 0
+ && Rune.ColumnWidth ((char)contents [crow, ccol - 1, 0]) > 1) {
+
+ var prevPosition = crow * Cols + (ccol - 1);
+ OutputBuffer [prevPosition].Char.UnicodeChar = ' ';
+ contents [crow, ccol - 1, 0] = (int)(uint)' ';
+
+ } else if (runeWidth < 2 && ccol <= Clip.Right - 1
+ && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
+
+ var prevPosition = GetOutputBufferPosition () + 1;
+ OutputBuffer [prevPosition].Char.UnicodeChar = (char)' ';
+ contents [crow, ccol + 1, 0] = (int)(uint)' ';
+
+ }
+ if (runeWidth > 1 && ccol == Clip.Right - 1) {
+ OutputBuffer [position].Char.UnicodeChar = (char)' ';
+ contents [crow, ccol, 0] = (int)(uint)' ';
+ } else {
+ OutputBuffer [position].Char.UnicodeChar = (char)rune;
+ contents [crow, ccol, 0] = (int)(uint)rune;
+ }
+ OutputBuffer [position].Attributes = (ushort)CurrentAttribute;
+ contents [crow, ccol, 1] = CurrentAttribute;
+ contents [crow, ccol, 2] = 1;
+ WindowsConsole.SmallRect.Update (ref damageRegion, (short)ccol, (short)crow);
}
- OutputBuffer [position].Attributes = (ushort)CurrentAttribute;
- contents [crow, ccol, 1] = CurrentAttribute;
- contents [crow, ccol, 2] = 1;
- WindowsConsole.SmallRect.Update (ref damageRegion, (short)ccol, (short)crow);
}
- ccol++;
+ if (runeWidth < 0 || runeWidth > 0) {
+ ccol++;
+ }
+
if (runeWidth > 1) {
if (validClip && ccol < Clip.Right) {
position = GetOutputBufferPosition ();
@@ -1558,8 +1580,9 @@ namespace Terminal.Gui {
ccol++;
}
- if (sync)
+ if (sync) {
UpdateScreen ();
+ }
}
public override void AddStr (ustring str)
@@ -1764,9 +1787,33 @@ namespace Terminal.Gui {
}
#region Unused
- public override void StartReportingMouseMoves () { }
- public override void StopReportingMouseMoves () { }
- public override void Suspend () { }
+ public override void SetColors (ConsoleColor foreground, ConsoleColor background)
+ {
+ }
+
+ public override void SetColors (short foregroundColorId, short backgroundColorId)
+ {
+ }
+
+ public override void Suspend ()
+ {
+ }
+
+ public override void StartReportingMouseMoves ()
+ {
+ }
+
+ public override void StopReportingMouseMoves ()
+ {
+ }
+
+ public override void UncookMouse ()
+ {
+ }
+
+ public override void CookMouse ()
+ {
+ }
#endregion
}
diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs
index 327c9e2c4..681a4733a 100644
--- a/Terminal.Gui/Core/Application.cs
+++ b/Terminal.Gui/Core/Application.cs
@@ -57,7 +57,7 @@ namespace Terminal.Gui {
///
///
public static class Application {
- static Stack toplevels = new Stack ();
+ static readonly Stack toplevels = new Stack ();
///
/// The current in use.
@@ -111,28 +111,33 @@ namespace Terminal.Gui {
///
public static View WantContinuousButtonPressedView { get; private set; }
+ private static bool? _heightAsBuffer;
+
///
/// The current used in the terminal.
///
+ ///
public static bool HeightAsBuffer {
get {
if (Driver == null) {
- throw new ArgumentNullException ("The driver must be initialized first.");
+ return _heightAsBuffer.HasValue && _heightAsBuffer.Value;
}
return Driver.HeightAsBuffer;
}
set {
+ _heightAsBuffer = value;
if (Driver == null) {
- throw new ArgumentNullException ("The driver must be initialized first.");
+ return;
}
- Driver.HeightAsBuffer = value;
+
+ Driver.HeightAsBuffer = _heightAsBuffer.Value;
}
}
static Key alternateForwardKey = Key.PageDown | Key.CtrlMask;
///
- /// Alternative key to navigate forwards through all views. Ctrl+Tab is always used.
+ /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.
///
public static Key AlternateForwardKey {
get => alternateForwardKey;
@@ -147,7 +152,7 @@ namespace Terminal.Gui {
static void OnAlternateForwardKeyChanged (Key oldKey)
{
- foreach (var top in toplevels) {
+ foreach (var top in toplevels.ToArray()) {
top.OnAlternateForwardKeyChanged (oldKey);
}
}
@@ -155,7 +160,7 @@ namespace Terminal.Gui {
static Key alternateBackwardKey = Key.PageUp | Key.CtrlMask;
///
- /// Alternative key to navigate backwards through all views. Shift+Ctrl+Tab is always used.
+ /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.
///
public static Key AlternateBackwardKey {
get => alternateBackwardKey;
@@ -170,7 +175,7 @@ namespace Terminal.Gui {
static void OnAlternateBackwardKeyChanged (Key oldKey)
{
- foreach (var top in toplevels) {
+ foreach (var top in toplevels.ToArray()) {
top.OnAlternateBackwardKeyChanged (oldKey);
}
}
@@ -200,7 +205,8 @@ namespace Terminal.Gui {
static void OnQuitKeyChanged (Key oldKey)
{
- foreach (var top in toplevels) {
+ // Duplicate the list so if it changes during enumeration we're safe
+ foreach (var top in toplevels.ToArray()) {
top.OnQuitKeyChanged (oldKey);
}
}
@@ -212,7 +218,7 @@ namespace Terminal.Gui {
public static MainLoop MainLoop { get; private set; }
///
- /// Disable or enable the mouse in this
+ /// Disable or enable the mouse. The mouse is enabled by default.
///
public static bool IsMouseDisabled { get; set; }
@@ -266,7 +272,7 @@ namespace Terminal.Gui {
// users use async/await on their code
//
class MainLoopSyncContext : SynchronizationContext {
- MainLoop mainLoop;
+ readonly MainLoop mainLoop;
public MainLoopSyncContext (MainLoop mainLoop)
{
@@ -305,9 +311,9 @@ namespace Terminal.Gui {
}
///
- /// If set, it forces the use of the System.Console-based driver.
+ /// If , forces the use of the System.Console-based (see ) driver. The default is .
///
- public static bool UseSystemConsole;
+ public static bool UseSystemConsole { get; set; } = false;
// For Unit testing - ignores UseSystemConsole
internal static bool ForceFakeConsole;
@@ -422,6 +428,7 @@ namespace Terminal.Gui {
MainLoop = new MainLoop (mainLoopDriver);
try {
+ Driver.HeightAsBuffer = HeightAsBuffer;
Driver.Init (TerminalResized);
} catch (InvalidOperationException ex) {
// This is a case where the driver is unable to initialize the console.
@@ -705,6 +712,7 @@ namespace Terminal.Gui {
return;
OnGrabbedMouse (view);
mouseGrabView = view;
+ Driver.UncookMouse ();
}
///
@@ -716,6 +724,7 @@ namespace Terminal.Gui {
return;
OnUnGrabbedMouse (mouseGrabView);
mouseGrabView = null;
+ Driver.CookMouse ();
}
static void OnGrabbedMouse (View view)
@@ -984,9 +993,7 @@ namespace Terminal.Gui {
toplevel.PositionToplevels ();
toplevel.WillPresent ();
if (refreshDriver) {
- if (MdiTop != null) {
- MdiTop.OnChildLoaded (toplevel);
- }
+ MdiTop?.OnChildLoaded (toplevel);
toplevel.OnLoaded ();
Redraw (toplevel);
toplevel.PositionCursor ();
@@ -1109,12 +1116,6 @@ namespace Terminal.Gui {
Driver.Refresh ();
}
- static void Refresh (View view)
- {
- view.Redraw (view.Bounds);
- Driver.Refresh ();
- }
-
///
/// Triggers a refresh of the entire display.
///
diff --git a/Terminal.Gui/Core/ConsoleDriver.cs b/Terminal.Gui/Core/ConsoleDriver.cs
index e0f52ccc6..49a50695f 100644
--- a/Terminal.Gui/Core/ConsoleDriver.cs
+++ b/Terminal.Gui/Core/ConsoleDriver.cs
@@ -170,18 +170,9 @@ namespace Terminal.Gui {
/// Attributes are used as elements that contain both a foreground and a background or platform specific features
///
///
- ///
/// s are needed to map colors to terminal capabilities that might lack colors.
/// They encode both the foreground and the background color and are used in the
/// class to define color schemes that can be used in an application.
- ///
- ///
- /// s are driver-specific and, as a result, are only valid if initialized by a .
- /// If an is created before a driver is initialized will be
- /// and attempts to use the will result in an exception. To use an that is not
- /// initilzied, after a driver is initialized, recreate the by calling the constructor
- /// or .
- ///
///
public struct Attribute {
///
@@ -433,11 +424,11 @@ namespace Terminal.Gui {
public bool Equals (ColorScheme other)
{
return other != null &&
- EqualityComparer.Default.Equals (_normal, other._normal) &&
- EqualityComparer.Default.Equals (_focus, other._focus) &&
- EqualityComparer.Default.Equals (_hotNormal, other._hotNormal) &&
- EqualityComparer.Default.Equals (_hotFocus, other._hotFocus) &&
- EqualityComparer.Default.Equals (_disabled, other._disabled);
+ EqualityComparer.Default.Equals (_normal, other._normal) &&
+ EqualityComparer.Default.Equals (_focus, other._focus) &&
+ EqualityComparer.Default.Equals (_hotNormal, other._hotNormal) &&
+ EqualityComparer.Default.Equals (_hotFocus, other._hotFocus) &&
+ EqualityComparer.Default.Equals (_disabled, other._disabled);
}
///
@@ -664,6 +655,71 @@ namespace Terminal.Gui {
BoxFix = 0x02020164,
}
+ /////
+ ///// Special characters that can be drawn with
+ /////
+ //public enum SpecialChar {
+ // ///
+ // /// Horizontal line character.
+ // ///
+ // HLine,
+
+ // ///
+ // /// Vertical line character.
+ // ///
+ // VLine,
+
+ // ///
+ // /// Stipple pattern
+ // ///
+ // Stipple,
+
+ // ///
+ // /// Diamond character
+ // ///
+ // Diamond,
+
+ // ///
+ // /// Upper left corner
+ // ///
+ // ULCorner,
+
+ // ///
+ // /// Lower left corner
+ // ///
+ // LLCorner,
+
+ // ///
+ // /// Upper right corner
+ // ///
+ // URCorner,
+
+ // ///
+ // /// Lower right corner
+ // ///
+ // LRCorner,
+
+ // ///
+ // /// Left tee
+ // ///
+ // LeftTee,
+
+ // ///
+ // /// Right tee
+ // ///
+ // RightTee,
+
+ // ///
+ // /// Top tee
+ // ///
+ // TopTee,
+
+ // ///
+ // /// The bottom tee.
+ // ///
+ // BottomTee,
+ //}
+
///
/// ConsoleDriver is an abstract class that defines the requirements for a console driver.
/// There are currently three implementations: (for Unix and Mac), , and that uses the .NET Console API.
@@ -824,8 +880,8 @@ namespace Terminal.Gui {
///
/// The current attribute the driver is using.
///
- internal virtual Attribute CurrentAttribute {
- get => _currentAttribute;
+ public virtual Attribute CurrentAttribute {
+ get => currentAttribute;
set {
if (!value.Initialized && value.HasValidColors && Application.Driver != null) {
CurrentAttribute = Application.Driver.MakeAttribute (value.Foreground, value.Background);
@@ -833,7 +889,7 @@ namespace Terminal.Gui {
}
if (!value.Initialized) Debug.WriteLine ("ConsoleDriver.CurrentAttribute: Attributes must be initialized before use.");
- _currentAttribute = value;
+ currentAttribute = value;
}
}
@@ -849,6 +905,23 @@ namespace Terminal.Gui {
CurrentAttribute = c;
}
+ ///
+ /// Set Colors from limit sets of colors. Not implemented by any driver: See Issue #2300.
+ ///
+ /// Foreground.
+ /// Background.
+ public abstract void SetColors (ConsoleColor foreground, ConsoleColor background);
+
+ // Advanced uses - set colors to any pre-set pairs, you would need to init_color
+ // that independently with the R, G, B values.
+ ///
+ /// Advanced uses - set colors to any pre-set pairs, you would need to init_color
+ /// that independently with the R, G, B values. Not implemented by any driver: See Issue #2300.
+ ///
+ /// Foreground color identifier.
+ /// Background color identifier.
+ public abstract void SetColors (short foregroundColorId, short backgroundColorId);
+
///
/// Gets the foreground and background colors based on the value.
///
@@ -1165,6 +1238,17 @@ namespace Terminal.Gui {
///
public abstract void StopReportingMouseMoves ();
+ ///
+ /// Disables the cooked event processing from the mouse driver.
+ /// At startup, it is assumed mouse events are cooked. Not implemented by any driver: See Issue #2300.
+ ///
+ public abstract void UncookMouse ();
+
+ ///
+ /// Enables the cooked event processing from the mouse driver. Not implemented by any driver: See Issue #2300.
+ ///
+ public abstract void CookMouse ();
+
///
/// Horizontal line character.
///
@@ -1354,8 +1438,7 @@ namespace Terminal.Gui {
/// Lower right rounded corner
///
public Rune LRRCorner = '\u256f';
-
- private Attribute _currentAttribute;
+ private Attribute currentAttribute;
///
/// Make the attribute for the foreground and background colors.
@@ -1383,8 +1466,6 @@ namespace Terminal.Gui {
/// Ensures all s in are correclty
/// initalized by the driver.
///
- ///
- ///
/// Flag indicating if colors are supported (not used).
public void InitalizeColorSchemes (bool supportsColors = true)
{
@@ -1397,6 +1478,35 @@ namespace Terminal.Gui {
return;
}
+ Colors.TopLevel.Normal = MakeColor (Color.BrightGreen, Color.Black);
+ Colors.TopLevel.Focus = MakeColor (Color.White, Color.Cyan);
+ Colors.TopLevel.HotNormal = MakeColor (Color.Brown, Color.Black);
+ Colors.TopLevel.HotFocus = MakeColor (Color.Blue, Color.Cyan);
+ Colors.TopLevel.Disabled = MakeColor (Color.DarkGray, Color.Black);
+
+ Colors.Base.Normal = MakeColor (Color.White, Color.Blue);
+ Colors.Base.Focus = MakeColor (Color.Black, Color.Gray);
+ Colors.Base.HotNormal = MakeColor (Color.BrightCyan, Color.Blue);
+ Colors.Base.HotFocus = MakeColor (Color.BrightBlue, Color.Gray);
+ Colors.Base.Disabled = MakeColor (Color.DarkGray, Color.Blue);
+
+ Colors.Dialog.Normal = MakeColor (Color.Black, Color.Gray);
+ Colors.Dialog.Focus = MakeColor (Color.White, Color.DarkGray);
+ Colors.Dialog.HotNormal = MakeColor (Color.Blue, Color.Gray);
+ Colors.Dialog.HotFocus = MakeColor (Color.BrightYellow, Color.DarkGray);
+ Colors.Dialog.Disabled = MakeColor (Color.Gray, Color.DarkGray);
+
+ Colors.Menu.Normal = MakeColor (Color.White, Color.DarkGray);
+ Colors.Menu.Focus = MakeColor (Color.White, Color.Black);
+ Colors.Menu.HotNormal = MakeColor (Color.BrightYellow, Color.DarkGray);
+ Colors.Menu.HotFocus = MakeColor (Color.BrightYellow, Color.Black);
+ Colors.Menu.Disabled = MakeColor (Color.Gray, Color.DarkGray);
+
+ Colors.Error.Normal = MakeColor (Color.Red, Color.White);
+ Colors.Error.Focus = MakeColor (Color.Black, Color.BrightRed);
+ Colors.Error.HotNormal = MakeColor (Color.Black, Color.White);
+ Colors.Error.HotFocus = MakeColor (Color.White, Color.BrightRed);
+ Colors.Error.Disabled = MakeColor (Color.DarkGray, Color.White);
}
}
diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs
index 8734261c0..454a64dd1 100644
--- a/Terminal.Gui/Core/View.cs
+++ b/Terminal.Gui/Core/View.cs
@@ -769,7 +769,7 @@ namespace Terminal.Gui {
void Initialize (ustring text, Rect rect, LayoutStyle layoutStyle = LayoutStyle.Computed,
TextDirection direction = TextDirection.LeftRight_TopBottom, Border border = null)
{
- TextFormatter = new TextFormatter ();
+ TextFormatter = new TextFormatter ();
TextFormatter.HotKeyChanged += TextFormatter_HotKeyChanged;
TextDirection = direction;
Border = border;
@@ -1447,8 +1447,9 @@ namespace Terminal.Gui {
///
public virtual ColorScheme ColorScheme {
get {
- if (colorScheme == null)
+ if (colorScheme == null) {
return SuperView?.ColorScheme;
+ }
return colorScheme;
}
set {
diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs
index 14cd47ece..4c8f19eee 100644
--- a/UICatalog/UICatalog.cs
+++ b/UICatalog/UICatalog.cs
@@ -164,7 +164,7 @@ namespace UICatalog {
public UICatalogTopLevel ()
{
- ColorScheme = _colorScheme;
+ ColorScheme = _colorScheme = Colors.Base;
MenuBar = new MenuBar (new MenuBarItem [] {
new MenuBarItem ("_File", new MenuItem [] {
new MenuItem ("_Quit", "Quit UI Catalog", () => RequestStop(), null, null, Key.Q | Key.CtrlMask)
diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs
index b7ef1d8db..7228d8ad6 100644
--- a/UnitTests/Application/ApplicationTests.cs
+++ b/UnitTests/Application/ApplicationTests.cs
@@ -24,7 +24,6 @@ namespace Terminal.Gui.ApplicationTests {
Assert.Null (Application.Driver);
Assert.Null (Application.Top);
Assert.Null (Application.Current);
- Assert.Throws (() => Application.HeightAsBuffer == true);
Assert.Null (Application.MainLoop);
Assert.Null (Application.Iteration);
Assert.Null (Application.RootMouseEvent);