diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 069b0ba67..0a75db93a 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -1186,7 +1186,6 @@ namespace Terminal.Gui { public NetWinVTConsole NetWinConsole { get; } public bool IsWinPlatform { get; } - public bool AlwaysSetPosition { get; set; } public override IClipboard Clipboard { get; } internal override int [,,] Contents => contents; @@ -1474,7 +1473,7 @@ namespace Terminal.Gui { int rows = Math.Min (Console.WindowHeight + top, Rows); int cols = Cols; System.Text.StringBuilder output = new System.Text.StringBuilder (); - var lastCol = left; + var lastCol = -1; Console.CursorVisible = false; for (int row = top; row < rows; row++) { @@ -1487,54 +1486,53 @@ namespace Terminal.Gui { if (Console.WindowHeight > 0 && !SetCursorPosition (col, row)) { return; } - lastCol = left; + lastCol = -1; var outputWidth = 0; for (; col < cols; col++) { 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++; + //Console.CursorLeft = lastCol; + //Console.CursorTop = row; + SetVirtualCursorPosition (lastCol, row); + Console.Write (output); + output.Clear (); + lastCol += outputWidth; + outputWidth = 0; + } else if (lastCol == -1) { + lastCol = col; } + if (lastCol + 1 < cols) + lastCol++; continue; } + if (lastCol == -1) + lastCol = col; + var attr = contents [row, col, 1]; if (attr != redrawAttr) { output.Append (WriteAttributes (attr)); } - 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}{rune}"); - output.Clear (); - } else { - output.Append (rune); - } + outputWidth++; + output.Append ((char)contents [row, col, 0]); contents [row, col, 2] = 0; } } if (output.Length > 0) { - Console.CursorLeft = lastCol; - Console.CursorTop = row; + //Console.CursorLeft = lastCol; + //Console.CursorTop = row; + SetVirtualCursorPosition (lastCol, row); Console.Write (output); } } } + void SetVirtualCursorPosition (int lastCol, int row) + { + Console.Out.Write ($"\x1b[{row + 1};{lastCol + 1}H"); + Console.Out.Flush (); + } + System.Text.StringBuilder WriteAttributes (int attr) { const string CSI = "\x1b["; diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs index 8b06bf229..e87f615ac 100644 --- a/Terminal.Gui/Core/Application.cs +++ b/Terminal.Gui/Core/Application.cs @@ -123,24 +123,6 @@ namespace Terminal.Gui { } } - /// - /// Used only by to forcing always moving the cursor position when writing to the screen. - /// - public static bool AlwaysSetPosition { - get { - if (Driver is NetDriver) { - return (Driver as NetDriver).AlwaysSetPosition; - } - return false; - } - set { - if (Driver is NetDriver) { - (Driver as NetDriver).AlwaysSetPosition = value; - Driver.Refresh (); - } - } - } - static Key alternateForwardKey = Key.PageDown | Key.CtrlMask; /// diff --git a/UICatalog/Scenarios/RuneWidthGreaterThanOne.cs b/UICatalog/Scenarios/RuneWidthGreaterThanOne.cs index 4d09b8c7e..a6bd140f0 100644 --- a/UICatalog/Scenarios/RuneWidthGreaterThanOne.cs +++ b/UICatalog/Scenarios/RuneWidthGreaterThanOne.cs @@ -14,6 +14,7 @@ namespace UICatalog.Scenarios { private Label _labelR; private Label _labelV; private Window _win; + private string _lastRunesUsed; public override void Init (Toplevel top, ColorScheme colorScheme) { @@ -35,32 +36,32 @@ namespace UICatalog.Scenarios { }) }); - _label = new Label (text: "あなたの名前を入力してください:") { + _label = new Label () { X = Pos.Center (), Y = 0, ColorScheme = new ColorScheme () { Normal = Colors.Base.Focus } }; - _text = new TextField ("ティラミス") { + _text = new TextField () { X = Pos.Center (), Y = 2, Width = 20 }; - _button = new Button (text: "こんにちはと言う") { + _button = new Button () { X = Pos.Center (), Y = 4 }; - _button.Clicked += () => MessageBox.Query ("こんにちはと言う", $"こんにちは {_text.Text}", "Ok"); - _labelR = new Label (text: "あなたの名前を入力してください") { + _labelR = new Label () { X = Pos.AnchorEnd (30), Y = 18 }; - _labelV = new Label (text: "あなたの名前を入力してください", TextDirection.TopBottom_RightLeft) { + _labelV = new Label () { + TextDirection = TextDirection.TopBottom_LeftRight, X = Pos.AnchorEnd (30), Y = Pos.Bottom (_labelR) }; - _win = new Window ("デモエムポンズ") { + _win = new Window () { X = 5, Y = 5, Width = Dim.Fill (22), @@ -68,15 +69,50 @@ namespace UICatalog.Scenarios { }; _win.Add (_label, _text, _button, _labelR, _labelV); Application.Top.Add (menu, _win); + + WideRunes (); + //NarrowRunes (); + //MixedRunes (); Application.Run (); } + private void UnsetClickedEvent () + { + switch (_lastRunesUsed) { + case "Narrow": + _button.Clicked -= NarrowMessage; + break; + case "Mixed": + _button.Clicked -= MixedMessage; + break; + case "Wide": + _button.Clicked -= WideMessage; + break; + } + } + + private void MixedMessage () + { + MessageBox.Query ("Say Hello 你", $"Hello {_text.Text}", "Ok"); + } + + private void NarrowMessage () + { + MessageBox.Query ("Say Hello", $"Hello {_text.Text}", "Ok"); + } + + private void WideMessage () + { + MessageBox.Query ("こんにちはと言う", $"こんにちは {_text.Text}", "Ok"); + } + private void MixedRunes () { + UnsetClickedEvent (); _label.Text = "Enter your name 你:"; _text.Text = "gui.cs 你:"; _button.Text = "Say Hello 你"; - _button.Clicked += () => MessageBox.Query ("Say Hello 你", $"Hello {_text.Text}", "Ok"); + _button.Clicked += MixedMessage; _labelR.X = Pos.AnchorEnd (21); _labelR.Y = 18; _labelR.Text = "This is a test text 你"; @@ -84,14 +120,17 @@ namespace UICatalog.Scenarios { _labelV.Y = Pos.Bottom (_labelR); _labelV.Text = "This is a test text 你"; _win.Title = "HACC Demo 你"; + _lastRunesUsed = "Mixed"; + Application.Refresh (); } private void NarrowRunes () { + UnsetClickedEvent (); _label.Text = "Enter your name:"; _text.Text = "gui.cs"; _button.Text = "Say Hello"; - _button.Clicked += () => MessageBox.Query ("Say Hello", $"Hello {_text.Text}", "Ok"); + _button.Clicked += NarrowMessage; _labelR.X = Pos.AnchorEnd (19); _labelR.Y = 18; _labelR.Text = "This is a test text"; @@ -99,14 +138,17 @@ namespace UICatalog.Scenarios { _labelV.Y = Pos.Bottom (_labelR); _labelV.Text = "This is a test text"; _win.Title = "HACC Demo"; + _lastRunesUsed = "Narrow"; + Application.Refresh (); } private void WideRunes () { + UnsetClickedEvent (); _label.Text = "あなたの名前を入力してください:"; _text.Text = "ティラミス"; _button.Text = "こんにちはと言う"; - _button.Clicked += () => MessageBox.Query ("こんにちはと言う", $"こんにちは {_text.Text}", "Ok"); + _button.Clicked += WideMessage; _labelR.X = Pos.AnchorEnd (29); _labelR.Y = 18; _labelR.Text = "あなたの名前を入力してください"; @@ -114,6 +156,8 @@ namespace UICatalog.Scenarios { _labelV.Y = Pos.Bottom (_labelR); _labelV.Text = "あなたの名前を入力してください"; _win.Title = "デモエムポンズ"; + _lastRunesUsed = "Wide"; + Application.Refresh (); } private void WithoutDrawMargin () diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 399f13cf0..68fc3b35f 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -66,7 +66,6 @@ namespace UICatalog { private static bool _useSystemConsole = false; private static ConsoleDriver.DiagnosticFlags _diagnosticFlags; private static bool _heightAsBuffer = false; - private static bool _alwaysSetPosition; private static bool _isFirstRunning = true; static void Main (string [] args) @@ -152,7 +151,6 @@ namespace UICatalog { Application.UseSystemConsole = _useSystemConsole; Application.Init (); Application.HeightAsBuffer = _heightAsBuffer; - Application.AlwaysSetPosition = _alwaysSetPosition; // Set this here because not initialized until driver is loaded _baseColorScheme = Colors.Base; @@ -311,7 +309,6 @@ namespace UICatalog { menuItems.Add (CreateDiagnosticFlagsMenuItems ()); menuItems.Add (new MenuItem [] { null }); menuItems.Add (CreateSizeStyle ()); - menuItems.Add (CreateAlwaysSetPosition ()); menuItems.Add (CreateDisabledEnabledMouse ()); menuItems.Add (CreateKeybindings ()); return menuItems; @@ -349,23 +346,6 @@ namespace UICatalog { return menuItems.ToArray (); } - static MenuItem [] CreateAlwaysSetPosition () - { - List menuItems = new List (); - var item = new MenuItem (); - item.Title = "_Always set position (NetDriver only)"; - item.Shortcut = Key.CtrlMask | Key.AltMask | (Key)item.Title.ToString ().Substring (1, 1) [0]; - item.CheckType |= MenuItemCheckStyle.Checked; - item.Checked = Application.AlwaysSetPosition; - item.Action += () => { - Application.AlwaysSetPosition = !item.Checked; - item.Checked = _alwaysSetPosition = Application.AlwaysSetPosition; - }; - menuItems.Add (item); - - return menuItems.ToArray (); - } - static MenuItem [] CreateSizeStyle () { List menuItems = new List (); diff --git a/UnitTests/ApplicationTests.cs b/UnitTests/ApplicationTests.cs index 84b658861..e48b4aec8 100644 --- a/UnitTests/ApplicationTests.cs +++ b/UnitTests/ApplicationTests.cs @@ -44,7 +44,6 @@ namespace Terminal.Gui.Core { Assert.Null (Application.Top); Assert.Null (Application.Current); Assert.Throws (() => Application.HeightAsBuffer == true); - Assert.False (Application.AlwaysSetPosition); Assert.Null (Application.MainLoop); Assert.Null (Application.Iteration); Assert.Null (Application.RootMouseEvent); @@ -57,7 +56,6 @@ namespace Terminal.Gui.Core { Assert.NotNull (Application.Top); Assert.NotNull (Application.Current); Assert.False (Application.HeightAsBuffer); - Assert.False (Application.AlwaysSetPosition); Assert.NotNull (Application.MainLoop); Assert.Null (Application.Iteration); Assert.Null (Application.RootMouseEvent);