|
@@ -37,23 +37,23 @@ namespace Terminal.Gui {
|
|
|
/// </summary>
|
|
|
internal override int [,,] Contents => contents;
|
|
|
|
|
|
- void UpdateOffscreen ()
|
|
|
- {
|
|
|
- int cols = Cols;
|
|
|
- int rows = Rows;
|
|
|
-
|
|
|
- contents = new int [rows, cols, 3];
|
|
|
- for (int r = 0; r < rows; r++) {
|
|
|
- for (int c = 0; c < cols; c++) {
|
|
|
- contents [r, c, 0] = ' ';
|
|
|
- contents [r, c, 1] = MakeColor (ConsoleColor.Gray, ConsoleColor.Black);
|
|
|
- contents [r, c, 2] = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- dirtyLine = new bool [rows];
|
|
|
- for (int row = 0; row < rows; row++)
|
|
|
- dirtyLine [row] = true;
|
|
|
- }
|
|
|
+ //void UpdateOffscreen ()
|
|
|
+ //{
|
|
|
+ // int cols = Cols;
|
|
|
+ // int rows = Rows;
|
|
|
+
|
|
|
+ // contents = new int [rows, cols, 3];
|
|
|
+ // for (int r = 0; r < rows; r++) {
|
|
|
+ // for (int c = 0; c < cols; c++) {
|
|
|
+ // contents [r, c, 0] = ' ';
|
|
|
+ // contents [r, c, 1] = MakeColor (ConsoleColor.Gray, ConsoleColor.Black);
|
|
|
+ // contents [r, c, 2] = 0;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // dirtyLine = new bool [rows];
|
|
|
+ // for (int row = 0; row < rows; row++)
|
|
|
+ // dirtyLine [row] = true;
|
|
|
+ //}
|
|
|
|
|
|
static bool sync = false;
|
|
|
|
|
@@ -89,13 +89,14 @@ namespace Terminal.Gui {
|
|
|
FakeConsole.CursorLeft = Clip.X;
|
|
|
needMove = true;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
public override void AddRune (Rune rune)
|
|
|
{
|
|
|
rune = MakePrintable (rune);
|
|
|
- if (Clip.Contains (ccol, crow)) {
|
|
|
+ var validClip = IsValidContent (ccol, crow, Clip);
|
|
|
+
|
|
|
+ if (validClip) {
|
|
|
if (needMove) {
|
|
|
//MockConsole.CursorLeft = ccol;
|
|
|
//MockConsole.CursorTop = crow;
|
|
@@ -107,7 +108,20 @@ namespace Terminal.Gui {
|
|
|
dirtyLine [crow] = true;
|
|
|
} else
|
|
|
needMove = true;
|
|
|
+
|
|
|
ccol++;
|
|
|
+ var runeWidth = Rune.ColumnWidth (rune);
|
|
|
+ if (runeWidth > 1) {
|
|
|
+ for (int i = 1; i < runeWidth; i++) {
|
|
|
+ if (validClip) {
|
|
|
+ contents [crow, ccol, 1] = currentAttribute;
|
|
|
+ contents [crow, ccol, 2] = 0;
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ccol++;
|
|
|
+ }
|
|
|
+ }
|
|
|
//if (ccol == Cols) {
|
|
|
// ccol = 0;
|
|
|
// if (crow + 1 < Rows)
|
|
@@ -218,26 +232,7 @@ namespace Terminal.Gui {
|
|
|
{
|
|
|
int top = Top;
|
|
|
int left = Left;
|
|
|
- int rows = Math.Min (Console.WindowHeight + top, Rows);
|
|
|
- int cols = Cols;
|
|
|
-
|
|
|
- FakeConsole.CursorTop = 0;
|
|
|
- FakeConsole.CursorLeft = 0;
|
|
|
- for (int row = top; row < rows; row++) {
|
|
|
- dirtyLine [row] = false;
|
|
|
- for (int col = left; col < cols; col++) {
|
|
|
- contents [row, col, 2] = 0;
|
|
|
- var color = contents [row, col, 1];
|
|
|
- if (color != redrawColor)
|
|
|
- SetColor (color);
|
|
|
- FakeConsole.Write ((char)contents [row, col, 0]);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public override void Refresh ()
|
|
|
- {
|
|
|
- int rows = Rows;
|
|
|
+ int rows = Math.Min (FakeConsole.WindowHeight + top, Rows);
|
|
|
int cols = Cols;
|
|
|
|
|
|
var savedRow = FakeConsole.CursorTop;
|
|
@@ -247,12 +242,21 @@ namespace Terminal.Gui {
|
|
|
continue;
|
|
|
dirtyLine [row] = false;
|
|
|
for (int col = 0; col < cols; col++) {
|
|
|
- if (contents [row, col, 2] != 1)
|
|
|
- continue;
|
|
|
-
|
|
|
FakeConsole.CursorTop = row;
|
|
|
FakeConsole.CursorLeft = col;
|
|
|
- for (; col < cols && contents [row, col, 2] == 1; col++) {
|
|
|
+ for (; col < cols; col++) {
|
|
|
+ if (col > 0 && contents [row, col, 2] == 0
|
|
|
+ && Rune.ColumnWidth ((char)contents [row, col - 1, 0]) > 1) {
|
|
|
+ FakeConsole.CursorLeft = col + 1;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (col < cols - 1 && Rune.ColumnWidth ((char)contents [row, col, 0]) > 1
|
|
|
+ && (contents [row, col + 1, 2] == 1 || col == cols - 1)) {
|
|
|
+
|
|
|
+ contents [row, col, 0] = ' ';
|
|
|
+ }
|
|
|
+
|
|
|
var color = contents [row, col, 1];
|
|
|
if (color != redrawColor)
|
|
|
SetColor (color);
|
|
@@ -266,6 +270,12 @@ namespace Terminal.Gui {
|
|
|
FakeConsole.CursorLeft = savedCol;
|
|
|
}
|
|
|
|
|
|
+ public override void Refresh ()
|
|
|
+ {
|
|
|
+ UpdateScreen ();
|
|
|
+ UpdateCursor ();
|
|
|
+ }
|
|
|
+
|
|
|
Attribute currentAttribute;
|
|
|
public override void SetAttribute (Attribute c)
|
|
|
{
|
|
@@ -388,6 +398,7 @@ namespace Terminal.Gui {
|
|
|
|
|
|
Action<KeyEvent> keyHandler;
|
|
|
Action<KeyEvent> keyUpHandler;
|
|
|
+ private CursorVisibility savedCursorVisibility;
|
|
|
|
|
|
public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
|
|
|
{
|
|
@@ -427,31 +438,32 @@ namespace Terminal.Gui {
|
|
|
/// <inheritdoc/>
|
|
|
public override bool GetCursorVisibility (out CursorVisibility visibility)
|
|
|
{
|
|
|
- if (FakeConsole.CursorVisible) {
|
|
|
- visibility = CursorVisibility.Default;
|
|
|
- } else {
|
|
|
- visibility = CursorVisibility.Invisible;
|
|
|
- }
|
|
|
+ visibility = FakeConsole.CursorVisible
|
|
|
+ ? CursorVisibility.Default
|
|
|
+ : CursorVisibility.Invisible;
|
|
|
|
|
|
- return false;
|
|
|
+ return FakeConsole.CursorVisible;
|
|
|
}
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
public override bool SetCursorVisibility (CursorVisibility visibility)
|
|
|
{
|
|
|
- if (visibility == CursorVisibility.Invisible) {
|
|
|
- FakeConsole.CursorVisible = false;
|
|
|
- } else {
|
|
|
- FakeConsole.CursorVisible = true;
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
+ savedCursorVisibility = visibility;
|
|
|
+ return FakeConsole.CursorVisible = visibility == CursorVisibility.Default;
|
|
|
}
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
public override bool EnsureCursorVisibility ()
|
|
|
{
|
|
|
- return false;
|
|
|
+ if (!(ccol >= 0 && crow >= 0 && ccol < Cols && crow < Rows)) {
|
|
|
+ GetCursorVisibility (out CursorVisibility cursorVisibility);
|
|
|
+ savedCursorVisibility = cursorVisibility;
|
|
|
+ SetCursorVisibility (CursorVisibility.Invisible);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ SetCursorVisibility (savedCursorVisibility);
|
|
|
+ return FakeConsole.CursorVisible;
|
|
|
}
|
|
|
|
|
|
public override void SendKeys (char keyChar, ConsoleKey key, bool shift, bool alt, bool control)
|
|
@@ -461,20 +473,24 @@ namespace Terminal.Gui {
|
|
|
|
|
|
public void SetBufferSize (int width, int height)
|
|
|
{
|
|
|
- cols = FakeConsole.WindowWidth = FakeConsole.BufferWidth = width;
|
|
|
- rows = FakeConsole.WindowHeight = FakeConsole.BufferHeight = height;
|
|
|
+ FakeConsole.SetBufferSize (width, height);
|
|
|
+ cols = width;
|
|
|
+ rows = height;
|
|
|
+ if (!HeightAsBuffer) {
|
|
|
+ SetWindowSize (width, height);
|
|
|
+ }
|
|
|
ProcessResize ();
|
|
|
}
|
|
|
|
|
|
public void SetWindowSize (int width, int height)
|
|
|
{
|
|
|
- FakeConsole.WindowWidth = width;
|
|
|
- FakeConsole.WindowHeight = height;
|
|
|
- if (width > cols || !HeightAsBuffer) {
|
|
|
- cols = FakeConsole.BufferWidth = width;
|
|
|
- }
|
|
|
- if (height > rows || !HeightAsBuffer) {
|
|
|
- rows = FakeConsole.BufferHeight = height;
|
|
|
+ FakeConsole.SetWindowSize (width, height);
|
|
|
+ if (!HeightAsBuffer) {
|
|
|
+ if (width != cols || height != rows) {
|
|
|
+ SetBufferSize (width, height);
|
|
|
+ cols = width;
|
|
|
+ rows = height;
|
|
|
+ }
|
|
|
}
|
|
|
ProcessResize ();
|
|
|
}
|
|
@@ -482,12 +498,13 @@ namespace Terminal.Gui {
|
|
|
public void SetWindowPosition (int left, int top)
|
|
|
{
|
|
|
if (HeightAsBuffer) {
|
|
|
- this.left = FakeConsole.WindowLeft = Math.Max (Math.Min (left, Cols - FakeConsole.WindowWidth), 0);
|
|
|
- this.top = FakeConsole.WindowTop = Math.Max (Math.Min (top, Rows - Console.WindowHeight), 0);
|
|
|
+ this.left = Math.Max (Math.Min (left, Cols - FakeConsole.WindowWidth), 0);
|
|
|
+ this.top = Math.Max (Math.Min (top, Rows - FakeConsole.WindowHeight), 0);
|
|
|
} else if (this.left > 0 || this.top > 0) {
|
|
|
- this.left = FakeConsole.WindowLeft = 0;
|
|
|
- this.top = FakeConsole.WindowTop = 0;
|
|
|
+ this.left = 0;
|
|
|
+ this.top = 0;
|
|
|
}
|
|
|
+ FakeConsole.SetWindowPosition (this.left, this.top);
|
|
|
}
|
|
|
|
|
|
void ProcessResize ()
|
|
@@ -500,14 +517,14 @@ namespace Terminal.Gui {
|
|
|
void ResizeScreen ()
|
|
|
{
|
|
|
if (!HeightAsBuffer) {
|
|
|
- if (Console.WindowHeight > 0) {
|
|
|
+ if (FakeConsole.WindowHeight > 0) {
|
|
|
// Can raise an exception while is still resizing.
|
|
|
try {
|
|
|
#pragma warning disable CA1416
|
|
|
- Console.CursorTop = 0;
|
|
|
- Console.CursorLeft = 0;
|
|
|
- Console.WindowTop = 0;
|
|
|
- Console.WindowLeft = 0;
|
|
|
+ FakeConsole.CursorTop = 0;
|
|
|
+ FakeConsole.CursorLeft = 0;
|
|
|
+ FakeConsole.WindowTop = 0;
|
|
|
+ FakeConsole.WindowLeft = 0;
|
|
|
#pragma warning restore CA1416
|
|
|
} catch (System.IO.IOException) {
|
|
|
return;
|
|
@@ -518,8 +535,8 @@ namespace Terminal.Gui {
|
|
|
} else {
|
|
|
try {
|
|
|
#pragma warning disable CA1416
|
|
|
- Console.WindowLeft = Math.Max (Math.Min (left, Cols - Console.WindowWidth), 0);
|
|
|
- Console.WindowTop = Math.Max (Math.Min (top, Rows - Console.WindowHeight), 0);
|
|
|
+ FakeConsole.WindowLeft = Math.Max (Math.Min (left, Cols - FakeConsole.WindowWidth), 0);
|
|
|
+ FakeConsole.WindowTop = Math.Max (Math.Min (top, Rows - FakeConsole.WindowHeight), 0);
|
|
|
#pragma warning restore CA1416
|
|
|
} catch (Exception) {
|
|
|
return;
|
|
@@ -532,7 +549,7 @@ namespace Terminal.Gui {
|
|
|
dirtyLine = new bool [Rows];
|
|
|
}
|
|
|
|
|
|
- void UpdateOffScreen ()
|
|
|
+ public override void UpdateOffScreen ()
|
|
|
{
|
|
|
// Can raise an exception while is still resizing.
|
|
|
try {
|
|
@@ -569,7 +586,17 @@ namespace Terminal.Gui {
|
|
|
#region Unused
|
|
|
public override void UpdateCursor ()
|
|
|
{
|
|
|
- //
|
|
|
+ if (!EnsureCursorVisibility ())
|
|
|
+ return;
|
|
|
+
|
|
|
+ // Prevents the exception of size changing during resizing.
|
|
|
+ try {
|
|
|
+ if (ccol >= 0 && ccol < FakeConsole.BufferWidth && crow >= 0 && crow < FakeConsole.BufferHeight) {
|
|
|
+ FakeConsole.SetCursorPosition (ccol, crow);
|
|
|
+ }
|
|
|
+ } catch (System.IO.IOException) {
|
|
|
+ } catch (ArgumentOutOfRangeException) {
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public override void StartReportingMouseMoves ()
|