mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Fixes remaining wide runes render issues.
This commit is contained in:
@@ -70,7 +70,9 @@ namespace Terminal.Gui {
|
||||
contents [crow, ccol - 1, 0] = (int)(uint)' ';
|
||||
Curses.move (crow, ccol);
|
||||
Curses.attrset (curAtttib);
|
||||
} else if (runeWidth < 2 && ccol < Cols - 1 && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
|
||||
|
||||
} 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]);
|
||||
@@ -78,9 +80,15 @@ namespace Terminal.Gui {
|
||||
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;
|
||||
}
|
||||
Curses.addch ((int)(uint)rune);
|
||||
contents [crow, ccol, 0] = (int)(uint)rune;
|
||||
contents [crow, ccol, 1] = currentAttribute;
|
||||
contents [crow, ccol, 2] = 1;
|
||||
} else
|
||||
@@ -88,7 +96,7 @@ namespace Terminal.Gui {
|
||||
|
||||
ccol++;
|
||||
if (runeWidth > 1) {
|
||||
if (validClip) {
|
||||
if (validClip && ccol < Clip.Right) {
|
||||
contents [crow, ccol, 1] = currentAttribute;
|
||||
contents [crow, ccol, 2] = 0;
|
||||
}
|
||||
|
||||
@@ -108,31 +108,34 @@ namespace Terminal.Gui {
|
||||
|
||||
contents [crow, ccol - 1, 0] = (int)(uint)' ';
|
||||
|
||||
} else if (runeWidth < 2 && ccol < Cols - 1
|
||||
} 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;
|
||||
|
||||
contents [crow, ccol, 0] = (int)(uint)rune;
|
||||
}
|
||||
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
|
||||
needMove = true;
|
||||
|
||||
ccol++;
|
||||
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 (validClip && ccol < Clip.Right) {
|
||||
contents [crow, ccol, 1] = currentAttribute;
|
||||
contents [crow, ccol, 2] = 0;
|
||||
}
|
||||
ccol++;
|
||||
}
|
||||
|
||||
//if (ccol == Cols) {
|
||||
// ccol = 0;
|
||||
// if (crow + 1 < Rows)
|
||||
@@ -248,17 +251,17 @@ namespace Terminal.Gui {
|
||||
|
||||
var savedRow = FakeConsole.CursorTop;
|
||||
var savedCol = FakeConsole.CursorLeft;
|
||||
for (int row = 0; row < rows; row++) {
|
||||
var savedCursorVisible = FakeConsole.CursorVisible;
|
||||
for (int row = top; row < rows; row++) {
|
||||
if (!dirtyLine [row])
|
||||
continue;
|
||||
dirtyLine [row] = false;
|
||||
for (int col = 0; col < cols; col++) {
|
||||
for (int col = left; col < cols; col++) {
|
||||
FakeConsole.CursorTop = row;
|
||||
FakeConsole.CursorLeft = 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;
|
||||
if (contents [row, col, 2] == 0) {
|
||||
FakeConsole.CursorLeft++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -273,6 +276,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
FakeConsole.CursorTop = savedRow;
|
||||
FakeConsole.CursorLeft = savedCol;
|
||||
FakeConsole.CursorVisible = savedCursorVisible;
|
||||
}
|
||||
|
||||
public override void Refresh ()
|
||||
@@ -549,13 +553,13 @@ namespace Terminal.Gui {
|
||||
}
|
||||
|
||||
Clip = new Rect (0, 0, Cols, Rows);
|
||||
|
||||
contents = new int [Rows, Cols, 3];
|
||||
dirtyLine = new bool [Rows];
|
||||
}
|
||||
|
||||
public override void UpdateOffScreen ()
|
||||
{
|
||||
contents = new int [Rows, Cols, 3];
|
||||
dirtyLine = new bool [Rows];
|
||||
|
||||
// Can raise an exception while is still resizing.
|
||||
try {
|
||||
for (int row = 0; row < rows; row++) {
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Terminal.Gui {
|
||||
int lastWindowHeight;
|
||||
int largestWindowHeight;
|
||||
#if PROCESS_REQUEST
|
||||
bool neededProcessRequest;
|
||||
bool neededProcessRequest;
|
||||
#endif
|
||||
public int NumberOfCSI { get; }
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Terminal.Gui {
|
||||
inputReady.Reset ();
|
||||
}
|
||||
#if PROCESS_REQUEST
|
||||
neededProcessRequest = false;
|
||||
neededProcessRequest = false;
|
||||
#endif
|
||||
if (inputResultQueue.Count > 0) {
|
||||
return inputResultQueue.Dequeue ();
|
||||
@@ -205,10 +205,10 @@ namespace Terminal.Gui {
|
||||
return;
|
||||
}
|
||||
#if PROCESS_REQUEST
|
||||
if (!neededProcessRequest) {
|
||||
Console.Out.Write ("\x1b[6n");
|
||||
neededProcessRequest = true;
|
||||
}
|
||||
if (!neededProcessRequest) {
|
||||
Console.Out.Write ("\x1b[6n");
|
||||
neededProcessRequest = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -469,7 +469,7 @@ namespace Terminal.Gui {
|
||||
string value = "";
|
||||
for (int i = 0; i < kChar.Length; i++) {
|
||||
var c = kChar [i];
|
||||
if (c == '[') {
|
||||
if (c == '\u001b' || c == '[') {
|
||||
foundPoint++;
|
||||
} else if (foundPoint == 1 && c != ';' && c != '?') {
|
||||
value += c.ToString ();
|
||||
@@ -1242,12 +1242,18 @@ namespace Terminal.Gui {
|
||||
|
||||
contents [crow, ccol - 1, 0] = (int)(uint)' ';
|
||||
|
||||
} else if (runeWidth < 2 && ccol < Cols - 1
|
||||
} 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, 0] = (int)(uint)rune;
|
||||
contents [crow, ccol, 1] = currentAttribute;
|
||||
contents [crow, ccol, 2] = 1;
|
||||
|
||||
@@ -1256,7 +1262,7 @@ namespace Terminal.Gui {
|
||||
|
||||
ccol++;
|
||||
if (runeWidth > 1) {
|
||||
if (validClip) {
|
||||
if (validClip && ccol < Clip.Right) {
|
||||
contents [crow, ccol, 1] = currentAttribute;
|
||||
contents [crow, ccol, 2] = 0;
|
||||
}
|
||||
@@ -1288,6 +1294,9 @@ namespace Terminal.Gui {
|
||||
StopReportingMouseMoves ();
|
||||
Console.ResetColor ();
|
||||
Clear ();
|
||||
//Set cursor key to cursor.
|
||||
Console.Out.Write ("\x1b[?25h");
|
||||
Console.Out.Flush ();
|
||||
}
|
||||
|
||||
void Clear ()
|
||||
@@ -1313,6 +1322,10 @@ namespace Terminal.Gui {
|
||||
{
|
||||
TerminalResized = terminalResized;
|
||||
|
||||
//Set cursor key to application.
|
||||
Console.Out.Write ("\x1b[?25l");
|
||||
Console.Out.Flush ();
|
||||
|
||||
Console.TreatControlCAsInput = true;
|
||||
|
||||
cols = Console.WindowWidth;
|
||||
@@ -1455,28 +1468,41 @@ namespace Terminal.Gui {
|
||||
}
|
||||
|
||||
int top = Top;
|
||||
int left = Left;
|
||||
int rows = Math.Min (Console.WindowHeight + top, Rows);
|
||||
int cols = Cols;
|
||||
System.Text.StringBuilder output = new System.Text.StringBuilder ();
|
||||
var lastCol = left;
|
||||
|
||||
var savedCursorVisible = Console.CursorVisible = false;
|
||||
Console.CursorVisible = false;
|
||||
for (int row = top; row < rows; row++) {
|
||||
if (!dirtyLine [row]) {
|
||||
continue;
|
||||
}
|
||||
dirtyLine [row] = false;
|
||||
System.Text.StringBuilder output = new System.Text.StringBuilder ();
|
||||
for (int col = 0; col < cols; col++) {
|
||||
output.Clear ();
|
||||
for (int col = left; col < cols; col++) {
|
||||
if (Console.WindowHeight > 0 && !SetCursorPosition (col, row)) {
|
||||
return;
|
||||
}
|
||||
var lastCol = -1;
|
||||
lastCol = left;
|
||||
var outputWidth = 0;
|
||||
for (; col < cols; col++) {
|
||||
if (col > 0 && contents [row, col, 2] == 0
|
||||
&& Rune.ColumnWidth ((char)contents [row, col - 1, 0]) > 1) {
|
||||
|
||||
if (col == cols - 1 && output.Length > 0) {
|
||||
Console.CursorLeft = lastCol;
|
||||
Console.Write (output);
|
||||
if (contents [row, col, 2] == 0) {
|
||||
if (output.Length > 0) {
|
||||
if (col > 0 && Rune.ColumnWidth ((char)contents [row, col - 1, 0]) < 2) {
|
||||
Console.CursorLeft = lastCol;
|
||||
Console.CursorTop = row;
|
||||
Console.Write (output);
|
||||
output.Clear ();
|
||||
lastCol += outputWidth;
|
||||
outputWidth = 0;
|
||||
if (lastCol + 1 < cols)
|
||||
lastCol++;
|
||||
}
|
||||
} else {
|
||||
if (lastCol + 1 < cols)
|
||||
lastCol++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1484,27 +1510,27 @@ namespace Terminal.Gui {
|
||||
var attr = contents [row, col, 1];
|
||||
if (attr != redrawAttr) {
|
||||
output.Append (WriteAttributes (attr));
|
||||
if (lastCol == -1)
|
||||
lastCol = col;
|
||||
}
|
||||
if (AlwaysSetPosition && !SetCursorPosition (col, row)) {
|
||||
return;
|
||||
}
|
||||
var rune = (char)contents [row, col, 0];
|
||||
outputWidth += Math.Max (Rune.ColumnWidth (rune), 1);
|
||||
if (AlwaysSetPosition) {
|
||||
Console.Write ($"{output}{(char)contents [row, col, 0]}");
|
||||
Console.Write ($"{output}{rune}");
|
||||
output.Clear ();
|
||||
} else {
|
||||
output.Append ((char)contents [row, col, 0]);
|
||||
if (lastCol == -1)
|
||||
lastCol = col;
|
||||
output.Append (rune);
|
||||
}
|
||||
contents [row, col, 2] = 0;
|
||||
if (!AlwaysSetPosition && col == cols - 1) {
|
||||
Console.Write (output);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (output.Length > 0) {
|
||||
Console.CursorLeft = lastCol;
|
||||
Console.CursorTop = row;
|
||||
Console.Write (output);
|
||||
}
|
||||
}
|
||||
Console.CursorVisible = savedCursorVisible;
|
||||
}
|
||||
|
||||
System.Text.StringBuilder WriteAttributes (int attr)
|
||||
|
||||
@@ -1480,15 +1480,22 @@ namespace Terminal.Gui {
|
||||
OutputBuffer [prevPosition].Char.UnicodeChar = ' ';
|
||||
contents [crow, ccol - 1, 0] = (int)(uint)' ';
|
||||
|
||||
} else if (runeWidth < 2 && ccol < Cols - 1 && Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
|
||||
} else if (runeWidth < 2 && ccol <= Clip.Right - 1
|
||||
&& Rune.ColumnWidth ((char)contents [crow, ccol, 0]) > 1) {
|
||||
|
||||
var prevPosition = crow * Cols + ccol + 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;
|
||||
OutputBuffer [position].Char.UnicodeChar = (char)rune;
|
||||
contents [crow, ccol, 0] = (int)(uint)rune;
|
||||
contents [crow, ccol, 1] = currentAttribute;
|
||||
contents [crow, ccol, 2] = 1;
|
||||
WindowsConsole.SmallRect.Update (ref damageRegion, (short)ccol, (short)crow);
|
||||
@@ -1496,7 +1503,7 @@ namespace Terminal.Gui {
|
||||
|
||||
ccol++;
|
||||
if (runeWidth > 1) {
|
||||
if (validClip) {
|
||||
if (validClip && ccol < Clip.Right) {
|
||||
position = crow * Cols + ccol;
|
||||
OutputBuffer [position].Attributes = (ushort)currentAttribute;
|
||||
OutputBuffer [position].Char.UnicodeChar = (char)0x00;
|
||||
|
||||
151
UICatalog/Scenarios/RuneWidthGreaterThanOne.cs
Normal file
151
UICatalog/Scenarios/RuneWidthGreaterThanOne.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace UICatalog.Scenarios {
|
||||
[ScenarioMetadata (Name: "RuneWidthGreaterThanOne", Description: "Test rune width greater than one")]
|
||||
[ScenarioCategory ("Controls")]
|
||||
public class RuneWidthGreaterThanOne : Scenario {
|
||||
private Label _label;
|
||||
private TextField _text;
|
||||
private Button _button;
|
||||
private Label _labelR;
|
||||
private Label _labelV;
|
||||
private Window _win;
|
||||
|
||||
public override void Init (Toplevel top, ColorScheme colorScheme)
|
||||
{
|
||||
Application.Init ();
|
||||
|
||||
var menu = new MenuBar (new MenuBarItem [] {
|
||||
new MenuBarItem ("Margin", new MenuItem [] {
|
||||
new MenuItem ("With margin", "", WithMargin),
|
||||
new MenuItem ("Without margin", "", WithoutMargin)
|
||||
}),
|
||||
new MenuBarItem ("Draw Margin Frame", new MenuItem [] {
|
||||
new MenuItem ("With draw", "", WithDrawMargin),
|
||||
new MenuItem ("Without draw", "", WithoutDrawMargin)
|
||||
}),
|
||||
new MenuBarItem ("Runes length", new MenuItem [] {
|
||||
new MenuItem ("Wide", "", WideRunes),
|
||||
new MenuItem ("Narrow", "", NarrowRunes),
|
||||
new MenuItem ("Mixed", "", MixedRunes)
|
||||
})
|
||||
});
|
||||
|
||||
_label = new Label (text: "あなたの名前を入力してください:") {
|
||||
X = Pos.Center (),
|
||||
Y = 0,
|
||||
ColorScheme = new ColorScheme () {
|
||||
Normal = Colors.Base.Focus
|
||||
}
|
||||
};
|
||||
_text = new TextField ("ティラミス") {
|
||||
X = Pos.Center (),
|
||||
Y = 2,
|
||||
Width = 20
|
||||
};
|
||||
_button = new Button (text: "こんにちはと言う") {
|
||||
X = Pos.Center (),
|
||||
Y = 4
|
||||
};
|
||||
_button.Clicked += () => MessageBox.Query ("こんにちはと言う", $"こんにちは {_text.Text}", "Ok");
|
||||
_labelR = new Label (text: "あなたの名前を入力してください") {
|
||||
X = Pos.AnchorEnd (30),
|
||||
Y = 18
|
||||
};
|
||||
_labelV = new Label (text: "あなたの名前を入力してください", TextDirection.TopBottom_RightLeft) {
|
||||
X = Pos.AnchorEnd (30),
|
||||
Y = Pos.Bottom (_labelR)
|
||||
};
|
||||
_win = new Window ("デモエムポンズ") {
|
||||
X = 5,
|
||||
Y = 5,
|
||||
Width = Dim.Fill (22),
|
||||
Height = Dim.Fill (5)
|
||||
};
|
||||
_win.Add (_label, _text, _button, _labelR, _labelV);
|
||||
Application.Top.Add (menu, _win);
|
||||
Application.Run ();
|
||||
}
|
||||
|
||||
private void MixedRunes ()
|
||||
{
|
||||
_label.Text = "Enter your name 你:";
|
||||
_text.Text = "gui.cs 你:";
|
||||
_button.Text = "Say Hello 你";
|
||||
_button.Clicked += () => MessageBox.Query ("Say Hello 你", $"Hello {_text.Text}", "Ok");
|
||||
_labelR.X = Pos.AnchorEnd (21);
|
||||
_labelR.Y = 18;
|
||||
_labelR.Text = "This is a test text 你";
|
||||
_labelV.X = Pos.AnchorEnd (21);
|
||||
_labelV.Y = Pos.Bottom (_labelR);
|
||||
_labelV.Text = "This is a test text 你";
|
||||
_win.Title = "HACC Demo 你";
|
||||
}
|
||||
|
||||
private void NarrowRunes ()
|
||||
{
|
||||
_label.Text = "Enter your name:";
|
||||
_text.Text = "gui.cs";
|
||||
_button.Text = "Say Hello";
|
||||
_button.Clicked += () => MessageBox.Query ("Say Hello", $"Hello {_text.Text}", "Ok");
|
||||
_labelR.X = Pos.AnchorEnd (19);
|
||||
_labelR.Y = 18;
|
||||
_labelR.Text = "This is a test text";
|
||||
_labelV.X = Pos.AnchorEnd (19);
|
||||
_labelV.Y = Pos.Bottom (_labelR);
|
||||
_labelV.Text = "This is a test text";
|
||||
_win.Title = "HACC Demo";
|
||||
}
|
||||
|
||||
private void WideRunes ()
|
||||
{
|
||||
_label.Text = "あなたの名前を入力してください:";
|
||||
_text.Text = "ティラミス";
|
||||
_button.Text = "こんにちはと言う";
|
||||
_button.Clicked += () => MessageBox.Query ("こんにちはと言う", $"こんにちは {_text.Text}", "Ok");
|
||||
_labelR.X = Pos.AnchorEnd (29);
|
||||
_labelR.Y = 18;
|
||||
_labelR.Text = "あなたの名前を入力してください";
|
||||
_labelV.X = Pos.AnchorEnd (29);
|
||||
_labelV.Y = Pos.Bottom (_labelR);
|
||||
_labelV.Text = "あなたの名前を入力してください";
|
||||
_win.Title = "デモエムポンズ";
|
||||
}
|
||||
|
||||
private void WithoutDrawMargin ()
|
||||
{
|
||||
_win.Border.BorderStyle = BorderStyle.None;
|
||||
_win.Border.DrawMarginFrame = false;
|
||||
}
|
||||
|
||||
private void WithDrawMargin ()
|
||||
{
|
||||
_win.Border.DrawMarginFrame = true;
|
||||
_win.Border.BorderStyle = BorderStyle.Single;
|
||||
}
|
||||
|
||||
private void WithoutMargin ()
|
||||
{
|
||||
_win.X = 0;
|
||||
_win.Y = 0;
|
||||
_win.Width = Dim.Fill ();
|
||||
_win.Height = Dim.Fill ();
|
||||
}
|
||||
|
||||
private void WithMargin ()
|
||||
{
|
||||
_win.X = 5;
|
||||
_win.Y = 5;
|
||||
_win.Width = Dim.Fill (22);
|
||||
_win.Height = Dim.Fill (5);
|
||||
}
|
||||
|
||||
public override void Run ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,23 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Terminal.Gui;
|
||||
using Terminal.Gui.Views;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
// Alias Console to MockConsole so we don't accidentally use Console
|
||||
using Console = Terminal.Gui.FakeConsole;
|
||||
|
||||
namespace Terminal.Gui.ConsoleDrivers {
|
||||
public class ConsoleDriverTests {
|
||||
readonly ITestOutputHelper output;
|
||||
|
||||
public ConsoleDriverTests (ITestOutputHelper output)
|
||||
{
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Init_Inits ()
|
||||
{
|
||||
@@ -503,5 +512,101 @@ namespace Terminal.Gui.ConsoleDrivers {
|
||||
Assert.True (closed);
|
||||
Assert.Empty (FakeConsole.MockKeyPresses);
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void AddRune_On_Clip_Left_Or_Right_Replace_Previous_Or_Next_Wide_Rune_With_Space ()
|
||||
{
|
||||
var tv = new TextView () {
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill (),
|
||||
Text = @"これは広いルーンラインです。
|
||||
これは広いルーンラインです。
|
||||
これは広いルーンラインです。
|
||||
これは広いルーンラインです。
|
||||
これは広いルーンラインです。
|
||||
これは広いルーンラインです。
|
||||
これは広いルーンラインです。
|
||||
これは広いルーンラインです。"
|
||||
};
|
||||
var win = new Window ("ワイドルーン") { Width = Dim.Fill (), Height = Dim.Fill () };
|
||||
win.Add (tv);
|
||||
Application.Top.Add (win);
|
||||
var lbl = new Label ("ワイドルーン。");
|
||||
var dg = new Dialog ("テスト", 14, 4, new Button ("選ぶ"));
|
||||
dg.Add (lbl);
|
||||
Application.Begin (Application.Top);
|
||||
Application.Begin (dg);
|
||||
((FakeDriver)Application.Driver).SetBufferSize (30, 10);
|
||||
|
||||
var expected = @"
|
||||
┌ ワイドルーン ──────────────┐
|
||||
│これは広いルーンラインです。│
|
||||
│これは広いルーンラインです。│
|
||||
│これは ┌ テスト ────┐ です。│
|
||||
│これは │ワイドルーン│ です。│
|
||||
│これは │ [ 選ぶ ] │ です。│
|
||||
│これは └────────────┘ です。│
|
||||
│これは広いルーンラインです。│
|
||||
│これは広いルーンラインです。│
|
||||
└────────────────────────────┘
|
||||
";
|
||||
|
||||
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
|
||||
Assert.Equal (new Rect (0, 0, 30, 10), pos);
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void Write_Do_Not_Change_On_ProcessKey ()
|
||||
{
|
||||
var win = new Window ();
|
||||
Application.Begin (win);
|
||||
((FakeDriver)Application.Driver).SetBufferSize (20, 8);
|
||||
|
||||
System.Threading.Tasks.Task.Run (() => {
|
||||
System.Threading.Tasks.Task.Delay (500).Wait ();
|
||||
Application.MainLoop.Invoke (() => {
|
||||
var lbl = new Label ("Hello World") { X = Pos.Center () };
|
||||
var dlg = new Dialog ("Test", new Button ("Ok"));
|
||||
dlg.Add (lbl);
|
||||
Application.Begin (dlg);
|
||||
|
||||
var expected = @"
|
||||
┌──────────────────┐
|
||||
│┌ Test ─────────┐ │
|
||||
││ Hello World │ │
|
||||
││ │ │
|
||||
││ │ │
|
||||
││ [ Ok ] │ │
|
||||
│└───────────────┘ │
|
||||
└──────────────────┘
|
||||
";
|
||||
|
||||
var pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
|
||||
Assert.Equal (new Rect (0, 0, 20, 8), pos);
|
||||
|
||||
Assert.True (dlg.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ())));
|
||||
dlg.Redraw (dlg.Bounds);
|
||||
|
||||
expected = @"
|
||||
┌──────────────────┐
|
||||
│┌ Test ─────────┐ │
|
||||
││ Hello World │ │
|
||||
││ │ │
|
||||
││ │ │
|
||||
││ [ Ok ] │ │
|
||||
│└───────────────┘ │
|
||||
└──────────────────┘
|
||||
";
|
||||
|
||||
pos = GraphViewTests.AssertDriverContentsWithFrameAre (expected, output);
|
||||
Assert.Equal (new Rect (0, 0, 20, 8), pos);
|
||||
|
||||
win.RequestStop ();
|
||||
});
|
||||
});
|
||||
|
||||
Application.Run (win);
|
||||
Application.Shutdown ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,8 +159,10 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
|
||||
// Remove unnecessary empty lines
|
||||
for (int r = lines.Count - 1; r > h - 1; r--) {
|
||||
lines.RemoveAt (r);
|
||||
if (lines.Count > 0) {
|
||||
for (int r = lines.Count - 1; r > h - 1; r--) {
|
||||
lines.RemoveAt (r);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove trailing whitespace on each line
|
||||
|
||||
Reference in New Issue
Block a user