From e6da3db22d90d79bc6e0d0ca838ac67e274b2552 Mon Sep 17 00:00:00 2001 From: Tig Date: Fri, 26 Apr 2024 13:19:11 -0600 Subject: [PATCH] Prototype/WIP for revamping how cursor handling works. Views should not have to do complex cursor logic just to position / show a cursor. Application should take care of more of the heavy liftig. Advanced cursor handling should be possible. ProcessCursor is poorly designed and fragile. --- Terminal.Gui/Application.cs | 94 +++++- Terminal.Gui/View/Layout/ViewLayout.cs | 30 -- Terminal.Gui/View/ViewSubViews.cs | 45 ++- Terminal.Gui/Views/Button.cs | 6 +- Terminal.Gui/Views/CheckBox.cs | 2 +- Terminal.Gui/Views/HexView.cs | 15 +- Terminal.Gui/Views/ListView.cs | 15 +- Terminal.Gui/Views/Menu/Menu.cs | 11 +- Terminal.Gui/Views/Menu/MenuBar.cs | 5 +- Terminal.Gui/Views/RadioGroup.cs | 14 +- Terminal.Gui/Views/ScrollView.cs | 14 +- Terminal.Gui/Views/Slider.cs | 5 +- Terminal.Gui/Views/TableView/TableView.cs | 9 +- Terminal.Gui/Views/TextField.cs | 88 +---- Terminal.Gui/Views/TextValidateField.cs | 6 +- Terminal.Gui/Views/TextView.cs | 383 ++++++++++------------ Terminal.Gui/Views/TileView.cs | 3 +- Terminal.Gui/Views/Toplevel.cs | 14 +- Terminal.Gui/Views/TreeView/TreeView.cs | 14 +- UICatalog/Scenarios/CharacterMap.cs | 5 +- UnitTests/View/Layout/ViewportTests.cs | 168 +++++----- 21 files changed, 440 insertions(+), 506 deletions(-) diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index 7ef986d40..44aaa6fa2 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -1,7 +1,10 @@ +using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; +using System.Reflection.Metadata.Ecma335; using System.Text.Json.Serialization; +using static Unix.Terminal.Curses; namespace Terminal.Gui; @@ -542,8 +545,11 @@ public static partial class Application toplevel.OnLoaded (); toplevel.SetNeedsDisplay (); toplevel.Draw (); - toplevel.PositionCursor (); - Driver.Refresh (); + Driver.UpdateScreen (); + if (PositionCursor (toplevel)) + { + Driver.UpdateCursor (); + } } NotifyNewRunState?.Invoke (toplevel, new (rs)); @@ -551,6 +557,66 @@ public static partial class Application return rs; } + /// + /// Calls on the most focused view in the view starting with . + /// + /// + /// Does nothing if is or if the most focused view is not visible or enabled. + /// + /// If the most focused view is not visible within it's superview, the cursor will be hidden. + /// + /// + /// if a view positioned the cursor and the position is visible. + internal static bool PositionCursor (View view) + { + if (view is null) + { + return false; + } + + // Find the most focused view and position the cursor there. + View mostFocused = view.MostFocused; + + if (mostFocused is null) + { + return false; + } + + // If the view is not visible or enabled, don't position the cursor + if (!mostFocused.Visible || !mostFocused.Enabled) + { + return false; + } + + // If the view is not visible within it's superview, don't position the cursor + Rectangle mostFocusedViewport = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = Point.Empty }); + Rectangle superViewViewport = mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver.Screen; + if (!superViewViewport.IntersectsWith (mostFocusedViewport)) + { + return false; + } + + Point? prevCursor = new (Driver.Row, Driver.Col); + Point? cursor = mostFocused.PositionCursor (); + + // If the cursor is not in a visible location in the SuperView, hide it + if (cursor is { }) + { + // Convert cursor to screen coords + cursor = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = cursor.Value }).Location; + if (!superViewViewport.Contains (cursor.Value)) + { + Driver.SetCursorVisibility (CursorVisibility.Invisible); + + return false; + } + + return prevCursor != cursor; + } + + return false; + } + /// /// Runs the application by creating a object and calling /// . @@ -764,7 +830,6 @@ public static partial class Application last = v; } - last?.PositionCursor (); Driver.Refresh (); } @@ -877,12 +942,22 @@ public static partial class Application if (state.Toplevel.NeedsDisplay || state.Toplevel.SubViewNeedsDisplay || state.Toplevel.LayoutNeeded || OverlappedChildNeedsDisplay ()) { state.Toplevel.Draw (); - state.Toplevel.PositionCursor (); - Driver.Refresh (); + Driver.UpdateScreen (); + //Driver.UpdateCursor (); } - else + + if (PositionCursor (state.Toplevel)) { - Driver.UpdateCursor (); + Driver.UpdateCursor(); + } + + // else + { + //if (PositionCursor (state.Toplevel)) + //{ + // Driver.Refresh (); + //} + //Driver.UpdateCursor (); } if (state.Toplevel != Top && !state.Toplevel.Modal && (Top.NeedsDisplay || Top.SubViewNeedsDisplay || Top.LayoutNeeded)) @@ -1315,6 +1390,11 @@ public static partial class Application t.LayoutSubviews (); t.PositionToplevels (); t.OnSizeChanging (new (args.Size)); + + if (PositionCursor (t)) + { + Driver.UpdateCursor (); + } } Refresh (); diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs index 1c9f39d27..1afa0994b 100644 --- a/Terminal.Gui/View/Layout/ViewLayout.cs +++ b/Terminal.Gui/View/Layout/ViewLayout.cs @@ -689,36 +689,6 @@ public partial class View #nullable restore - /// - /// Determines if this view is currently visible in the visible area, - /// given the passed x and y location coordinates. - /// - /// The x location. - /// The y location. - /// if it's visible, otherwise. - public bool IsViewLocationVisibleInViewport (int x, int y) - { - Rectangle thisFrame = ViewportToScreen (Viewport); - Rectangle thisOffset = ViewportToScreen (new (new (x, y), new (Viewport.Width, Viewport.Height ))); - View view; - - if (Application.Current is { }) - { - view = FindDeepestView (Application.Current, thisOffset.X, thisOffset.Y); - } - else if (SuperView is { }) - { - Rectangle containerFrame = SuperView.ViewportToScreen (SuperView.Viewport); - view = containerFrame.IntersectsWith (thisOffset) ? this : null; - } - else - { - view = thisFrame.IntersectsWith (thisOffset) ? this : null; - } - - return view == this; - } - /// /// Gets a new location of the that is within the Viewport of the 's /// (e.g. for dragging a Window). The `out` parameters are the new X and Y coordinates. diff --git a/Terminal.Gui/View/ViewSubViews.cs b/Terminal.Gui/View/ViewSubViews.cs index 9df4fee4d..34c9f5fee 100644 --- a/Terminal.Gui/View/ViewSubViews.cs +++ b/Terminal.Gui/View/ViewSubViews.cs @@ -493,7 +493,7 @@ public partial class View { return true; } - + return false; } @@ -511,7 +511,9 @@ public partial class View return true; } - Driver?.SetCursorVisibility (CursorVisibility.Invisible); + // BUGBUG: This is a hack to ensure that the cursor is hidden when the view loses focus. + // BUGBUG: This is not needed as the minloop will take care of this. + //Driver?.SetCursorVisibility (CursorVisibility.Invisible); return false; } @@ -856,35 +858,30 @@ public partial class View /// a way of hiding the cursor, so it can be distracting to have the cursor left at /// the last focused view. Views should make sure that they place the cursor /// in a visually sensible place. - public virtual void PositionCursor () + /// Viewport-relative cursor position. + public virtual Point? PositionCursor () { - if (!CanBeVisible (this) || !Enabled) + if (!IsInitialized) { - return; + return null; } - // BUGBUG: v2 - This needs to support Subviews of Adornments too + // TODO: v2 - This needs to support Subviews of Adornments too - if (Focused is null && SuperView is { }) + // By default we will position the cursor at the top left corner of the Viewport. + // Overrides should return the position where the cursor has been placed. + Point location = Viewport.Location; + + if (CanFocus && HasFocus && ContentSize != Size.Empty) { - SuperView.EnsureFocus (); - } - else if (Focused is { Visible: true, Enabled: true, Frame: { Width: > 0, Height: > 0 } }) - { - Focused.PositionCursor (); - } - else if (Focused?.Visible == true && Focused?.Enabled == false) - { - Focused = null; - } - else if (CanFocus && HasFocus && Visible && Frame.Width > 0 && Frame.Height > 0) - { - Move (TextFormatter.HotKeyPos == -1 ? 0 : TextFormatter.CursorPosition, 0); - } - else - { - Move (_frame.X, _frame.Y); + location.X = TextFormatter.HotKeyPos == -1 ? 0 : TextFormatter.CursorPosition; + location.Y = 0; + Move (location.X, location.Y); + return location; } + + return null; + } #endregion Focus diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index 53916fa17..8ffb1d636 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -147,7 +147,7 @@ public class Button : View } /// - public override void PositionCursor () + public override Point? PositionCursor () { if (HotKey.IsValid && Text != "") { @@ -157,12 +157,12 @@ public class Button : View { Move (i, 0); - return; + return new (i,0); } } } - base.PositionCursor (); + return base.PositionCursor (); } /// diff --git a/Terminal.Gui/Views/CheckBox.cs b/Terminal.Gui/Views/CheckBox.cs index 7b8dc08a8..d9d22e565 100644 --- a/Terminal.Gui/Views/CheckBox.cs +++ b/Terminal.Gui/Views/CheckBox.cs @@ -152,7 +152,7 @@ public class CheckBox : View } /// - public override void PositionCursor () { Move (0, 0); } + public override Point? PositionCursor () { Move (0, 0); return Point.Empty; } /// Toggled event, raised when the is toggled. /// diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index 2d166db3c..4c7068927 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -547,7 +547,7 @@ public class HexView : View public event EventHandler PositionChanged; /// - public override void PositionCursor () + public override Point? PositionCursor () { var delta = (int)(position - displayStart); int line = delta / bytesPerLine; @@ -555,14 +555,15 @@ public class HexView : View int block = item / bsize; int column = item % bsize * 3; - if (leftSide) + int x = displayWidth + block * 14 + column + (firstNibble ? 0 : 1); + int y = line; + if (!leftSide) { - Move (displayWidth + block * 14 + column + (firstNibble ? 0 : 1), line); - } - else - { - Move (displayWidth + bytesPerLine / bsize * 14 + item - 1, line); + x = displayWidth + bytesPerLine / bsize * 14 + item - 1; } + + Move (x, y); + return new (x, y); } internal void SetDisplayStart (long value) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 0fb229afe..aef82e959 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -781,16 +781,17 @@ public class ListView : View public event EventHandler OpenSelectedItem; /// - public override void PositionCursor () + public override Point? PositionCursor () { - if (_allowsMarking) + int x = 0; + int y = _selected - Viewport.Y; + if (!_allowsMarking) { - Move (0, _selected - Viewport.Y); - } - else - { - Move (Viewport.Width - 1, _selected - Viewport.Y); + x = Viewport.Width - 1; } + + Move (x, y); + return new Point (x, y); } /// This event is invoked when this is being drawn before rendering. diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index 62d847c65..1908da811 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -945,23 +945,22 @@ internal sealed class Menu : View } } - public override void PositionCursor () + public override Point? PositionCursor () { if (_host?.IsMenuOpen != false) { if (_barItems.IsTopLevel) { - _host?.PositionCursor (); + return _host?.PositionCursor (); } else { Move (2, 1 + _currentChild); + return new (2, 1 + _currentChild); } } - else - { - _host?.PositionCursor (); - } + + return _host?.PositionCursor (); } public void Run (Action action) diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs index de8f9f9d7..4cf861ad4 100644 --- a/Terminal.Gui/Views/Menu/MenuBar.cs +++ b/Terminal.Gui/Views/Menu/MenuBar.cs @@ -605,7 +605,7 @@ public class MenuBar : View } /// - public override void PositionCursor () + public override Point? PositionCursor () { if (_selected == -1 && HasFocus && Menus.Length > 0) { @@ -621,7 +621,7 @@ public class MenuBar : View pos++; Move (pos + 1, 0); - return; + return new (pos +1, 0); } pos += _leftPadding @@ -631,6 +631,7 @@ public class MenuBar : View : 0) + _rightPadding; } + return null; } // Activates the menu, handles either first focus, or activating an entry when it was already active diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index 5c9d6b477..d102dd573 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -351,19 +351,27 @@ public class RadioGroup : View public event EventHandler OrientationChanged; /// - public override void PositionCursor () + public override Point? PositionCursor () { + int x = 0; + int y = 0; switch (Orientation) { case Orientation.Vertical: - Move (0, _cursor); + y = _cursor; break; case Orientation.Horizontal: - Move (_horizontal [_cursor].pos, 0); + x = _horizontal [_cursor].pos; break; + + default: + return null; } + + Move (x, y); + return new Point (x, y); } /// Allow to invoke the after their creation. diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index a41ae12df..b33a2a80e 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -138,7 +138,7 @@ public class ScrollView : View private void ScrollViewContentSizeChanged (object sender, SizeChangedEventArgs e) { - _contentView.Frame = new Rectangle (ContentOffset, e.Size with {Width = e.Size.Width-1, Height = e.Size.Height-1}); + _contentView.Frame = new Rectangle (ContentOffset, e.Size with { Width = e.Size.Width - 1, Height = e.Size.Height - 1 }); _vertical.Size = e.Size.Height; _horizontal.Size = e.Size.Width; } @@ -410,7 +410,7 @@ public class ScrollView : View } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected internal override bool OnMouseEvent (MouseEvent me) { if (!Enabled) { @@ -447,20 +447,18 @@ public class ScrollView : View Application.UngrabMouse (); } - return base.OnMouseEvent(me); + return base.OnMouseEvent (me); } /// - public override void PositionCursor () + public override Point? PositionCursor () { if (InternalSubviews.Count == 0) { Move (0, 0); + return Point.Empty; } - else - { - base.PositionCursor (); - } + return base.PositionCursor (); } /// Removes the view from the scrollview. diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index 3d0ea3fb0..2feb5da91 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -973,7 +973,7 @@ public class Slider : View #region Cursor and Drawing /// - public override void PositionCursor () + public override Point? PositionCursor () { //base.PositionCursor (); @@ -991,8 +991,11 @@ public class Slider : View if (IsInitialized && Viewport.Contains (position.x, position.y)) { Move (position.x, position.y); + + return new (position.x, position.x); } } + return null; } /// diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index e82a00666..0465d6e0d 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -1017,13 +1017,11 @@ public class TableView : View /// Positions the cursor in the area of the screen in which the start of the active cell is rendered. Calls base /// implementation if active cell is not visible due to scrolling or table is loaded etc /// - public override void PositionCursor () + public override Point? PositionCursor () { if (TableIsNullOrInvisible ()) { - base.PositionCursor (); - - return; + return base.PositionCursor (); } Point? screenPoint = CellToScreen (SelectedColumn, SelectedRow); @@ -1031,7 +1029,10 @@ public class TableView : View if (screenPoint is { }) { Move (screenPoint.Value.X, screenPoint.Value.Y); + return screenPoint; } + + return null; } /// diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 07c010104..dc755289f 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -9,10 +9,8 @@ namespace Terminal.Gui; public class TextField : View { private readonly HistoryText _historyText; - private readonly CursorVisibility _savedCursorVisibility; private CultureInfo _currentCulture; private int _cursorPosition; - private CursorVisibility _desiredCursorVisibility; private bool _isButtonPressed; private bool _isButtonReleased; private bool _isDrawing; @@ -21,7 +19,6 @@ public class TextField : View private string _selectedText; private int _start; private List _text; - private CursorVisibility _visibility; /// /// Initializes a new instance of the class using @@ -30,7 +27,6 @@ public class TextField : View public TextField () { _historyText = new HistoryText (); - _desiredCursorVisibility = CursorVisibility.Default; _isButtonReleased = true; _selectedStart = -1; _text = new List (); @@ -42,7 +38,6 @@ public class TextField : View CanFocus = true; Used = true; WantMousePositionReports = true; - _savedCursorVisibility = _desiredCursorVisibility; _historyText.ChangeText += HistoryText_ChangeText; @@ -469,21 +464,6 @@ public class TextField : View } } - /// Get / Set the wished cursor when the field is focused - public CursorVisibility DesiredCursorVisibility - { - get => _desiredCursorVisibility; - set - { - if ((_desiredCursorVisibility != value || _visibility != value) && HasFocus) - { - Application.Driver.SetCursorVisibility (value); - } - - _desiredCursorVisibility = _visibility = value; - } - } - /// /// Indicates whatever the text has history changes or not. if the text has history changes /// otherwise. @@ -1060,7 +1040,7 @@ public class TextField : View { if (IsInitialized) { - Application.Driver.SetCursorVisibility (DesiredCursorVisibility); + Application.Driver.SetCursorVisibility (CursorVisibility.Default); } return base.OnEnter (view); @@ -1172,13 +1152,8 @@ public class TextField : View } /// Sets the cursor position. - public override void PositionCursor () + public override Point? PositionCursor () { - if (!IsInitialized) - { - return; - } - ProcessAutocomplete (); var col = 0; @@ -1195,30 +1170,8 @@ public class TextField : View } int pos = _cursorPosition - ScrollOffset + Math.Min (Frame.X, 0); - int offB = OffSetBackground (); - bool isVisibleInViewport = IsViewLocationVisibleInViewport (col, Viewport.Y); - - if (isVisibleInViewport - && pos > -1 - && col >= pos - && pos < Frame.Width + offB) - { - RestoreCursorVisibility (); - Move (col, 0); - } - else - { - HideCursorVisibility (); - - if (pos < 0) - { - Move (pos, 0); - } - else - { - Move (pos - offB, 0); - } - } + Move (pos, 0); + return new Point (pos, 0); } /// Redoes the latest changes. @@ -1230,21 +1183,6 @@ public class TextField : View } _historyText.Redo (); - - //if (string.IsNullOrEmpty (Clipboard.Contents)) - // return true; - //var clip = TextModel.ToRunes (Clipboard.Contents); - //if (clip is null) - // return true; - - //if (point == text.Count) { - // point = text.Count; - // SetText(text.Concat(clip).ToList()); - //} else { - // point += clip.Count; - // SetText(text.GetRange(0, oldCursorPos).Concat(clip).Concat(text.GetRange(oldCursorPos, text.Count - oldCursorPos))); - //} - //Adjust (); } /// Selects all text. @@ -1464,14 +1402,6 @@ public class TextField : View return new Attribute (cs.Disabled.Foreground, cs.Focus.Background); } - private void HideCursorVisibility () - { - if (_desiredCursorVisibility != CursorVisibility.Invisible) - { - DesiredCursorVisibility = CursorVisibility.Invisible; - } - } - private void HistoryText_ChangeText (object sender, HistoryText.HistoryTextItem obj) { if (obj is null) @@ -1885,16 +1815,6 @@ public class TextField : View Driver.AddStr (render); } - private void RestoreCursorVisibility () - { - Application.Driver.GetCursorVisibility (out _visibility); - - if (_desiredCursorVisibility != _savedCursorVisibility || _visibility != _savedCursorVisibility) - { - DesiredCursorVisibility = _savedCursorVisibility; - } - } - private void SetClipboard (IEnumerable text) { if (!Secret) diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index a62fa4a54..f421fb931 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -640,7 +640,7 @@ namespace Terminal.Gui } /// - public override void PositionCursor () + public override Point? PositionCursor () { (int left, _) = GetMargins (Viewport.Width); @@ -652,13 +652,12 @@ namespace Terminal.Gui if (_provider?.Fixed == false && TextAlignment == TextAlignment.Right) { curPos = _cursorPosition + left - 1; - Move (curPos, 0); } else { curPos = _cursorPosition + left; - Move (curPos, 0); } + Move (curPos, 0); if (curPos < 0 || curPos >= Viewport.Width) { @@ -668,6 +667,7 @@ namespace Terminal.Gui { Application.Driver.SetCursorVisibility (CursorVisibility.Default); } + return new (curPos, 0); } /// Delete char at cursor position - 1, moving the cursor. diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index a8d05888e..241d27353 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -67,7 +67,7 @@ internal class TextModel } FilePath = null; - _lines = new List> (); + _lines = new (); return true; } @@ -89,7 +89,7 @@ internal class TextModel return _lines [Count - 1]; } - _lines.Add (new List ()); + _lines.Add (new ()); return _lines [0]; } @@ -153,7 +153,7 @@ internal class TextModel throw new ArgumentNullException (nameof (input)); } - _lines = new List> (); + _lines = new (); var buff = new BufferedStream (input); int v; List line = new (); @@ -215,7 +215,7 @@ internal class TextModel { if (_lines.Count > 0 && pos < _lines.Count) { - _lines [pos] = new List (runes); + _lines [pos] = new (runes); } else if (_lines.Count == 0 || (_lines.Count > 0 && pos >= _lines.Count)) { @@ -243,7 +243,7 @@ internal class TextModel foreach (Rune rune in str.EnumerateRunes ()) { - cells.Add (new RuneCell { Rune = rune, ColorScheme = colorScheme }); + cells.Add (new() { Rune = rune, ColorScheme = colorScheme }); } return cells; @@ -759,7 +759,7 @@ internal class TextModel _lines.Count - 1, matchCase, matchWholeWord, - new Point (_lines [_lines.Count - 1].Count, _lines.Count) + new (_lines [_lines.Count - 1].Count, _lines.Count) ); } @@ -850,7 +850,7 @@ internal class TextModel _lines [i] = ToRuneCellList (ReplaceText (x, textToReplace!, matchText, col)); x = _lines [i]; txt = GetText (x); - pos = new Point (col, i); + pos = new (col, i); col += textToReplace!.Length - matchText.Length; } @@ -906,7 +906,7 @@ internal class TextModel foreach (Rune rune in str.ToRunes ()) { - cells.Add (new RuneCell { Rune = rune, ColorScheme = colorScheme }); + cells.Add (new() { Rune = rune, ColorScheme = colorScheme }); } return cells; @@ -918,7 +918,7 @@ internal class TextModel foreach (Rune rune in runes) { - cells.Add (new RuneCell { Rune = rune, ColorScheme = colorScheme }); + cells.Add (new() { Rune = rune, ColorScheme = colorScheme }); } return cells; @@ -981,7 +981,7 @@ internal class TextModel if (col > -1 && ((i == start.Y && col >= start.X) || i > start.Y) && txt.Contains (matchText)) { - return (new Point (col, i), true); + return (new (col, i), true); } if (col == -1 && start.X > 0) @@ -1026,7 +1026,7 @@ internal class TextModel if (col > -1 && ((i <= linesCount && col <= start.X) || i < start.Y) && txt.Contains (matchText)) { - return (new Point (col, i), true); + return (new (col, i), true); } } @@ -1292,7 +1292,7 @@ internal partial class HistoryText ); } - _historyTextItems.Add (new HistoryTextItem (lines, curPos, lineStatus)); + _historyTextItems.Add (new (lines, curPos, lineStatus)); _idxHistoryText++; } @@ -1370,7 +1370,7 @@ internal partial class HistoryText _idxHistoryText--; } - historyTextItem = new HistoryTextItem (_historyTextItems [_idxHistoryText]); + historyTextItem = new (_historyTextItems [_idxHistoryText]); historyTextItem.IsUndoing = true; historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition; } @@ -1378,7 +1378,7 @@ internal partial class HistoryText if (historyTextItem.LineStatus == LineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Added) { historyTextItem.RemovedOnAdded = - new HistoryTextItem (_historyTextItems [_idxHistoryText + 1]); + new (_historyTextItems [_idxHistoryText + 1]); } if ((historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Original) @@ -1390,7 +1390,7 @@ internal partial class HistoryText && historyTextItem.CursorPosition == _historyTextItems [_idxHistoryText - 1].CursorPosition) { historyTextItem.Lines [0] = - new List (_historyTextItems [_idxHistoryText - 1].Lines [0]); + new (_historyTextItems [_idxHistoryText - 1].Lines [0]); } if (historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Removed) @@ -1425,7 +1425,7 @@ internal partial class HistoryText || _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Removed)) { _idxHistoryText++; - historyTextItem = new HistoryTextItem (_historyTextItems [_idxHistoryText]); + historyTextItem = new (_historyTextItems [_idxHistoryText]); historyTextItem.IsUndoing = false; historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition; } @@ -1433,7 +1433,7 @@ internal partial class HistoryText if (historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Removed) { historyTextItem.RemovedOnAdded = - new HistoryTextItem (_historyTextItems [_idxHistoryText - 1]); + new (_historyTextItems [_idxHistoryText - 1]); } if ((historyTextItem.LineStatus == LineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Replaced) @@ -1445,7 +1445,7 @@ internal partial class HistoryText .SequenceEqual (_historyTextItems [_idxHistoryText + 1].Lines [0])) { historyTextItem.Lines [0] = - new List (_historyTextItems [_idxHistoryText + 1].Lines [0]); + new (_historyTextItems [_idxHistoryText + 1].Lines [0]); } historyTextItem.FinalCursorPosition = @@ -1962,7 +1962,6 @@ public class TextView : View private bool _copyWithoutSelection; private string? _currentCaller; private CultureInfo? _currentCulture; - private CursorVisibility _desiredCursorVisibility = CursorVisibility.Default; private bool _isButtonShift; private bool _isButtonReleased; private bool _isDrawing; @@ -1971,7 +1970,6 @@ public class TextView : View private int _leftColumn; private TextModel _model = new (); private bool _multiline = true; - private CursorVisibility _savedCursorVisibility; private Dim? _savedHeight; private int _selectionStartColumn, _selectionStartRow; private bool _shiftSelecting; @@ -1981,6 +1979,10 @@ public class TextView : View private WordWrapManager? _wrapManager; private bool _wrapNeeded; + /// Get or sets the cursor to be used when the text view has focus. + + public CursorVisibility DesiredCursorVisibility { get; set; } = CursorVisibility.Default; + /// /// Initializes a on the specified area, with dimensions controlled with the X, Y, Width /// and Height properties. @@ -2399,10 +2401,10 @@ public class TextView : View Command.ShowContextMenu, () => { - ContextMenu!.Position = new Point ( - CursorPosition.X - _leftColumn + 2, - CursorPosition.Y - _topRow + 2 - ); + ContextMenu!.Position = new ( + CursorPosition.X - _leftColumn + 2, + CursorPosition.Y - _topRow + 2 + ); ShowContextMenu (); return true; @@ -2510,7 +2512,7 @@ public class TextView : View _currentCulture = Thread.CurrentThread.CurrentUICulture; - ContextMenu = new ContextMenu { MenuItems = BuildContextMenuBarItem () }; + ContextMenu = new() { MenuItems = BuildContextMenuBarItem () }; ContextMenu.KeyChanged += ContextMenu_KeyChanged!; KeyBindings.Add ((KeyCode)ContextMenu.Key, KeyBindingScope.HotKey, Command.ShowContextMenu); @@ -2627,21 +2629,6 @@ public class TextView : View } } - /// Get / Set the wished cursor when the field is focused - public CursorVisibility DesiredCursorVisibility - { - get => _desiredCursorVisibility; - set - { - if (HasFocus) - { - Application.Driver.SetCursorVisibility (value); - } - - _desiredCursorVisibility = value; - SetNeedsDisplay (); - } - } /// /// Indicates whatever the text has history changes or not. if the text has history changes @@ -2863,17 +2850,17 @@ public class TextView : View } set { - var old = Text; + string old = Text; ResetPosition (); _model.LoadString (value); if (_wordWrap) { - _wrapManager = new WordWrapManager (_model); + _wrapManager = new (_model); _model = _wrapManager.WrapModel (_frameWidth, out _, out _, out _, out _); } - OnTextChanged (old,Text); + OnTextChanged (old, Text); SetNeedsDisplay (); _historyText.Clear (Text); @@ -2914,7 +2901,7 @@ public class TextView : View if (_wordWrap) { - _wrapManager = new WordWrapManager (_model); + _wrapManager = new (_model); _model = _wrapManager.WrapModel (_frameWidth, out _, out _, out _, out _); } else if (!_wordWrap && _wrapManager is { }) @@ -2983,7 +2970,7 @@ public class TextView : View ClearRegion (); _historyText.Add ( - new List> { new (GetCurrentLine ()) }, + new() { new (GetCurrentLine ()) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -3022,14 +3009,14 @@ public class TextView : View if (Selecting) { - _historyText.Add (new List> { new (GetCurrentLine ()) }, CursorPosition); + _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition); ClearSelectedRegion (); List currentLine = GetCurrentLine (); _historyText.Add ( - new List> { new (currentLine) }, + new() { new (currentLine) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -3066,14 +3053,14 @@ public class TextView : View if (Selecting) { - _historyText.Add (new List> { new (GetCurrentLine ()) }, CursorPosition); + _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition); ClearSelectedRegion (); List currentLine = GetCurrentLine (); _historyText.Add ( - new List> { new (currentLine) }, + new() { new (currentLine) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -3205,7 +3192,7 @@ public class TextView : View if (ColorScheme is null) { - cs = new ColorScheme (); + cs = new (); } return Enabled ? cs.Focus : cs.Disabled; @@ -3224,7 +3211,7 @@ public class TextView : View try { - key = new Key (ch); + key = new (ch); } catch (Exception) { @@ -3313,7 +3300,7 @@ public class TextView : View } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected internal override bool OnMouseEvent (MouseEvent ev) { if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked) && !ev.Flags.HasFlag (MouseFlags.Button1Pressed) @@ -3553,7 +3540,7 @@ public class TextView : View } else if (ev.Flags == ContextMenu!.MouseFlags) { - ContextMenu.Position = new Point (ev.X + 2, ev.Y + 2); + ContextMenu.Position = new (ev.X + 2, ev.Y + 2); ShowContextMenu (); } @@ -3588,7 +3575,7 @@ public class TextView : View /// public virtual void OnContentsChanged () { - ContentsChanged?.Invoke (this, new ContentsChangedEventArgs (CurrentRow, CurrentColumn)); + ContentsChanged?.Invoke (this, new (CurrentRow, CurrentColumn)); ProcessInheritsPreviousColorScheme (CurrentRow, CurrentColumn); ProcessAutocomplete (); @@ -3771,7 +3758,7 @@ public class TextView : View col = _wrapManager.GetModelColFromWrappedLines (CurrentRow, CurrentColumn); } - UnwrappedCursorPosition?.Invoke (this, new PointEventArgs (new Point ((int)col, (int)row))); + UnwrappedCursorPosition?.Invoke (this, new (new ((int)col, (int)row))); } /// Paste the clipboard contents into the current selected position. @@ -3787,15 +3774,15 @@ public class TextView : View if (_copyWithoutSelection && contents.FirstOrDefault (x => x == '\n' || x == '\r') == 0) { - List runeList = contents is null ? new List () : TextModel.ToRuneCellList (contents); + List runeList = contents is null ? new () : TextModel.ToRuneCellList (contents); List currentLine = GetCurrentLine (); - _historyText.Add (new List> { new (currentLine) }, CursorPosition); + _historyText.Add (new() { new (currentLine) }, CursorPosition); - List> addedLine = new () { new List (currentLine), runeList }; + List> addedLine = new () { new (currentLine), runeList }; _historyText.Add ( - new List> (addedLine), + new (addedLine), CursorPosition, HistoryText.LineStatus.Added ); @@ -3804,7 +3791,7 @@ public class TextView : View CurrentRow++; _historyText.Add ( - new List> { new (GetCurrentLine ()) }, + new() { new (GetCurrentLine ()) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -3825,7 +3812,7 @@ public class TextView : View if (Selecting) { _historyText.ReplaceLast ( - new List> { new (GetCurrentLine ()) }, + new() { new (GetCurrentLine ()) }, CursorPosition, HistoryText.LineStatus.Original ); @@ -3840,13 +3827,13 @@ public class TextView : View } /// Positions the cursor on the current row and column - public override void PositionCursor () + public override Point? PositionCursor () { ProcessAutocomplete (); if (!CanFocus || !Enabled || Application.Driver is null) { - return; + return null; } if (Selecting) @@ -3888,17 +3875,17 @@ public class TextView : View int posX = CurrentColumn - _leftColumn; int posY = CurrentRow - _topRow; - bool isVisibleInViewport = IsViewLocationVisibleInViewport (col, posY); - if (isVisibleInViewport && posX > -1 && col >= posX && posX < Frame.Width - RightOffset && _topRow <= CurrentRow && posY < Frame.Height - BottomOffset) + if (posX > -1 && col >= posX && posX < Frame.Width - RightOffset && _topRow <= CurrentRow && posY < Frame.Height - BottomOffset) { - ResetCursorVisibility (); Move (col, CurrentRow - _topRow); + return new (col, CurrentRow - _topRow); } else { - SaveCursorVisibility (); + return null; } + } /// Redoes the latest changes. @@ -4052,11 +4039,11 @@ public class TextView : View if (colorScheme!.Disabled.Foreground == colorScheme.Focus.Background) { - attribute = new Attribute (colorScheme.Focus.Foreground, colorScheme.Focus.Background); + attribute = new (colorScheme.Focus.Foreground, colorScheme.Focus.Background); } else { - attribute = new Attribute (colorScheme.Disabled.Foreground, colorScheme.Focus.Background); + attribute = new (colorScheme.Disabled.Foreground, colorScheme.Focus.Background); } Driver.SetAttribute (attribute); @@ -4082,16 +4069,16 @@ public class TextView : View ColorScheme? colorScheme = line [idxCol].ColorScheme; Driver.SetAttribute ( - new Attribute (colorScheme!.Focus.Background, colorScheme.Focus.Foreground) + new (colorScheme!.Focus.Background, colorScheme.Focus.Foreground) ); } else { Driver.SetAttribute ( - new Attribute ( - ColorScheme.Focus.Background, - ColorScheme.Focus.Foreground - ) + new ( + ColorScheme.Focus.Background, + ColorScheme.Focus.Foreground + ) ); } } @@ -4200,67 +4187,67 @@ public class TextView : View private MenuBarItem BuildContextMenuBarItem () { - return new MenuBarItem ( - new MenuItem [] - { - new ( - Strings.ctxSelectAll, - "", - SelectAll, - null, - null, - (KeyCode)KeyBindings.GetKeyFromCommands (Command.SelectAll) - ), - new ( - Strings.ctxDeleteAll, - "", - DeleteAll, - null, - null, - (KeyCode)KeyBindings.GetKeyFromCommands (Command.DeleteAll) - ), - new ( - Strings.ctxCopy, - "", - Copy, - null, - null, - (KeyCode)KeyBindings.GetKeyFromCommands (Command.Copy) - ), - new ( - Strings.ctxCut, - "", - Cut, - null, - null, - (KeyCode)KeyBindings.GetKeyFromCommands (Command.Cut) - ), - new ( - Strings.ctxPaste, - "", - Paste, - null, - null, - (KeyCode)KeyBindings.GetKeyFromCommands (Command.Paste) - ), - new ( - Strings.ctxUndo, - "", - Undo, - null, - null, - (KeyCode)KeyBindings.GetKeyFromCommands (Command.Undo) - ), - new ( - Strings.ctxRedo, - "", - Redo, - null, - null, - (KeyCode)KeyBindings.GetKeyFromCommands (Command.Redo) - ) - } - ); + return new ( + new MenuItem [] + { + new ( + Strings.ctxSelectAll, + "", + SelectAll, + null, + null, + (KeyCode)KeyBindings.GetKeyFromCommands (Command.SelectAll) + ), + new ( + Strings.ctxDeleteAll, + "", + DeleteAll, + null, + null, + (KeyCode)KeyBindings.GetKeyFromCommands (Command.DeleteAll) + ), + new ( + Strings.ctxCopy, + "", + Copy, + null, + null, + (KeyCode)KeyBindings.GetKeyFromCommands (Command.Copy) + ), + new ( + Strings.ctxCut, + "", + Cut, + null, + null, + (KeyCode)KeyBindings.GetKeyFromCommands (Command.Cut) + ), + new ( + Strings.ctxPaste, + "", + Paste, + null, + null, + (KeyCode)KeyBindings.GetKeyFromCommands (Command.Paste) + ), + new ( + Strings.ctxUndo, + "", + Undo, + null, + null, + (KeyCode)KeyBindings.GetKeyFromCommands (Command.Undo) + ), + new ( + Strings.ctxRedo, + "", + Redo, + null, + null, + (KeyCode)KeyBindings.GetKeyFromCommands (Command.Redo) + ) + } + ); } private void ClearRegion (int left, int top, int right, int bottom) @@ -4292,13 +4279,13 @@ public class TextView : View var endCol = (int)(end & 0xffffffff); List line = _model.GetLine (startRow); - _historyText.Add (new List> { new (line) }, new Point (startCol, startRow)); + _historyText.Add (new() { new (line) }, new (startCol, startRow)); List> removedLines = new (); if (startRow == maxrow) { - removedLines.Add (new List (line)); + removedLines.Add (new (line)); line.RemoveRange (startCol, endCol - startCol); CurrentColumn = startCol; @@ -4316,7 +4303,7 @@ public class TextView : View } _historyText.Add ( - new List> (removedLines), + new (removedLines), CursorPosition, HistoryText.LineStatus.Removed ); @@ -4326,7 +4313,7 @@ public class TextView : View return; } - removedLines.Add (new List (line)); + removedLines.Add (new (line)); line.RemoveRange (startCol, line.Count - startCol); List line2 = _model.GetLine (maxrow); @@ -4334,7 +4321,7 @@ public class TextView : View for (int row = startRow + 1; row <= maxrow; row++) { - removedLines.Add (new List (_model.GetLine (startRow + 1))); + removedLines.Add (new (_model.GetLine (startRow + 1))); _model.RemoveLine (startRow + 1); } @@ -4347,7 +4334,7 @@ public class TextView : View CurrentColumn = startCol; _historyText.Add ( - new List> (removedLines), + new (removedLines), CursorPosition, HistoryText.LineStatus.Removed ); @@ -4382,7 +4369,7 @@ public class TextView : View // Delete backwards List currentLine = GetCurrentLine (); - _historyText.Add (new List> { new (currentLine) }, CursorPosition); + _historyText.Add (new() { new (currentLine) }, CursorPosition); currentLine.RemoveAt (CurrentColumn - 1); @@ -4394,7 +4381,7 @@ public class TextView : View CurrentColumn--; _historyText.Add ( - new List> { new (currentLine) }, + new() { new (currentLine) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -4422,15 +4409,15 @@ public class TextView : View int prowIdx = CurrentRow - 1; List prevRow = _model.GetLine (prowIdx); - _historyText.Add (new List> { new (prevRow) }, CursorPosition); + _historyText.Add (new() { new (prevRow) }, CursorPosition); - List> removedLines = new () { new List (prevRow) }; + List> removedLines = new () { new (prevRow) }; - removedLines.Add (new List (GetCurrentLine ())); + removedLines.Add (new (GetCurrentLine ())); _historyText.Add ( removedLines, - new Point (CurrentColumn, prowIdx), + new (CurrentColumn, prowIdx), HistoryText.LineStatus.Removed ); @@ -4446,8 +4433,8 @@ public class TextView : View CurrentRow--; _historyText.Add ( - new List> { GetCurrentLine () }, - new Point (CurrentColumn, prowIdx), + new() { GetCurrentLine () }, + new (CurrentColumn, prowIdx), HistoryText.LineStatus.Replaced ); @@ -4475,13 +4462,13 @@ public class TextView : View return true; } - _historyText.Add (new List> { new (currentLine) }, CursorPosition); + _historyText.Add (new() { new (currentLine) }, CursorPosition); - List> removedLines = new () { new List (currentLine) }; + List> removedLines = new () { new (currentLine) }; List nextLine = _model.GetLine (CurrentRow + 1); - removedLines.Add (new List (nextLine)); + removedLines.Add (new (nextLine)); _historyText.Add (removedLines, CursorPosition, HistoryText.LineStatus.Removed); @@ -4489,7 +4476,7 @@ public class TextView : View _model.RemoveLine (CurrentRow + 1); _historyText.Add ( - new List> { new (currentLine) }, + new() { new (currentLine) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -4596,13 +4583,13 @@ public class TextView : View List currentLine = GetCurrentLine (); int cursorPosition = Math.Min (CurrentColumn, currentLine.Count); - Autocomplete.Context = new AutocompleteContext ( - currentLine, - cursorPosition, - Autocomplete.Context != null - ? Autocomplete.Context.Canceled - : false - ); + Autocomplete.Context = new ( + currentLine, + cursorPosition, + Autocomplete.Context != null + ? Autocomplete.Context.Canceled + : false + ); Autocomplete.GenerateSuggestions ( Autocomplete.Context @@ -4840,7 +4827,7 @@ public class TextView : View List line = GetCurrentLine (); - _historyText.Add (new List> { new (line) }, CursorPosition); + _historyText.Add (new() { new (line) }, CursorPosition); // Optimize single line if (lines.Count == 1) @@ -4849,7 +4836,7 @@ public class TextView : View CurrentColumn += lines [0].Count; _historyText.Add ( - new List> { new (line) }, + new() { new (line) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -4893,13 +4880,13 @@ public class TextView : View //model.AddLine (currentRow, lines [0]); - List> addedLines = new () { new List (line) }; + List> addedLines = new () { new (line) }; for (var i = 1; i < lines.Count; i++) { _model.AddLine (CurrentRow + i, lines [i]); - addedLines.Add (new List (lines [i])); + addedLines.Add (new (lines [i])); } if (rest is { }) @@ -4919,7 +4906,7 @@ public class TextView : View Adjust (); _historyText.Add ( - new List> { new (line) }, + new() { new (line) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -4938,7 +4925,7 @@ public class TextView : View SetWrapModel (); - _historyText.Add (new List> { new (GetCurrentLine ()) }, CursorPosition); + _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition); if (Selecting) { @@ -4947,7 +4934,7 @@ public class TextView : View if ((uint)a.KeyCode == '\n') { - _model.AddLine (CurrentRow + 1, new List ()); + _model.AddLine (CurrentRow + 1, new ()); CurrentRow++; CurrentColumn = 0; } @@ -4959,7 +4946,7 @@ public class TextView : View { if (Used) { - Insert (new RuneCell { Rune = a.AsRune, ColorScheme = colorScheme }); + Insert (new() { Rune = a.AsRune, ColorScheme = colorScheme }); CurrentColumn++; if (CurrentColumn >= _leftColumn + Frame.Width) @@ -4970,13 +4957,13 @@ public class TextView : View } else { - Insert (new RuneCell { Rune = a.AsRune, ColorScheme = colorScheme }); + Insert (new() { Rune = a.AsRune, ColorScheme = colorScheme }); CurrentColumn++; } } _historyText.Add ( - new List> { new (GetCurrentLine ()) }, + new() { new (GetCurrentLine ()) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5014,20 +5001,20 @@ public class TextView : View return; } - _historyText.Add (new List> { new (currentLine) }, CursorPosition); + _historyText.Add (new() { new (currentLine) }, CursorPosition); if (currentLine.Count == 0) { if (CurrentRow < _model.Count - 1) { - List> removedLines = new () { new List (currentLine) }; + List> removedLines = new () { new (currentLine) }; _model.RemoveLine (CurrentRow); - removedLines.Add (new List (GetCurrentLine ())); + removedLines.Add (new (GetCurrentLine ())); _historyText.Add ( - new List> (removedLines), + new (removedLines), CursorPosition, HistoryText.LineStatus.Removed ); @@ -5681,13 +5668,13 @@ public class TextView : View if (currentLine.Count > 0 && currentLine [CurrentColumn - 1].Rune.Value == '\t') { - _historyText.Add (new List> { new (currentLine) }, CursorPosition); + _historyText.Add (new() { new (currentLine) }, CursorPosition); currentLine.RemoveAt (CurrentColumn - 1); CurrentColumn--; _historyText.Add ( - new List> { new (GetCurrentLine ()) }, + new() { new (GetCurrentLine ()) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -6128,7 +6115,7 @@ public class TextView : View List currentLine = GetCurrentLine (); - _historyText.Add (new List> { new (currentLine) }, CursorPosition); + _historyText.Add (new() { new (currentLine) }, CursorPosition); if (Selecting) { @@ -6140,11 +6127,11 @@ public class TextView : View List rest = currentLine.GetRange (CurrentColumn, restCount); currentLine.RemoveRange (CurrentColumn, restCount); - List> addedLines = new () { new List (currentLine) }; + List> addedLines = new () { new (currentLine) }; _model.AddLine (CurrentRow + 1, rest); - addedLines.Add (new List (_model.GetLine (CurrentRow + 1))); + addedLines.Add (new (_model.GetLine (CurrentRow + 1))); _historyText.Add (addedLines, CursorPosition, HistoryText.LineStatus.Added); @@ -6161,7 +6148,7 @@ public class TextView : View CurrentColumn = 0; _historyText.Add ( - new List> { new (GetCurrentLine ()) }, + new() { new (GetCurrentLine ()) }, CursorPosition, HistoryText.LineStatus.Replaced ); @@ -6241,7 +6228,7 @@ public class TextView : View { int col = Selecting ? _selectionStartColumn : CurrentColumn; int row = Selecting ? _selectionStartRow : CurrentRow; - _model.ResetContinuousFind (new Point (col, row)); + _model.ResetContinuousFind (new (col, row)); } } @@ -6253,41 +6240,11 @@ public class TextView : View _continuousFind = false; } - private void ResetCursorVisibility () - { - if (_savedCursorVisibility != 0) - { - DesiredCursorVisibility = _savedCursorVisibility; - _savedCursorVisibility = 0; - } - else if (Application.Driver is { }) - { - Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility); - if (cursorVisibility == CursorVisibility.Invisible) - { - DesiredCursorVisibility = CursorVisibility.Default; - } - } - } private void ResetPosition () { _topRow = _leftColumn = CurrentRow = CurrentColumn = 0; StopSelecting (); - ResetCursorVisibility (); - } - - private void SaveCursorVisibility () - { - if (_desiredCursorVisibility != CursorVisibility.Invisible) - { - if (_savedCursorVisibility == 0) - { - _savedCursorVisibility = _desiredCursorVisibility; - } - - DesiredCursorVisibility = CursorVisibility.Invisible; - } } private void SetClipboard (string text) @@ -6360,7 +6317,7 @@ public class TextView : View { // BUGBUG: (v2 truecolor) This code depends on 8-bit color names; disabling for now //if ((colorScheme!.HotNormal.Foreground & colorScheme.Focus.Background) == colorScheme.Focus.Foreground) { - Driver.SetAttribute (new Attribute (colorScheme.Focus.Background, colorScheme.Focus.Foreground)); + Driver.SetAttribute (new (colorScheme.Focus.Background, colorScheme.Focus.Foreground)); } /// Restore from original model. @@ -6576,6 +6533,6 @@ public class TextViewAutocomplete : PopupAutocomplete protected override void SetCursorPosition (int column) { ((TextView)HostControl).CursorPosition = - new Point (column, ((TextView)HostControl).CurrentRow); + new (column, ((TextView)HostControl).CurrentRow); } } diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index cbc2b9f22..b3608b668 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -987,12 +987,13 @@ public class TileView : View return base.OnEnter (view); } - public override void PositionCursor () + public override Point? PositionCursor () { base.PositionCursor (); Point location = moveRuneRenderLocation ?? new Point (Viewport.Width / 2, Viewport.Height / 2); Move (location.X, location.Y); + return location; } /// diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index e5f4b64b1..5bbdbf7a7 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -333,12 +333,10 @@ public partial class Toplevel : View } /// - public override void PositionCursor () + public override Point? PositionCursor () { if (!IsOverlappedContainer) { - base.PositionCursor (); - if (Focused is null) { EnsureFocus (); @@ -349,28 +347,32 @@ public partial class Toplevel : View } } - return; + return null; } + // This code path only happens when the Toplevel is an Overlapped container + if (Focused is null) { + // TODO: this is an Overlapped hack foreach (Toplevel top in Application.OverlappedChildren) { if (top != this && top.Visible) { top.SetFocus (); - return; + return null; } } } - base.PositionCursor (); + var cursor2 = base.PositionCursor (); if (Focused is null) { Driver.SetCursorVisibility (CursorVisibility.Invisible); } + return cursor2; } /// diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 2eb67267c..1b8ad7d48 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -1002,7 +1002,7 @@ public class TreeView : View, ITreeView where T : class public bool IsSelected (T model) { return Equals (SelectedObject, model) || (MultiSelect && multiSelectedRegions.Any (s => s.Contains (model))); } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected internal override bool OnMouseEvent (MouseEvent me) { // If it is not an event we care about if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) @@ -1239,7 +1239,7 @@ public class TreeView : View, ITreeView where T : class } /// Positions the cursor at the start of the selected objects line (if visible). - public override void PositionCursor () + public override Point? PositionCursor () { if (CanFocus && HasFocus && Visible && SelectedObject is { }) { @@ -1250,16 +1250,10 @@ public class TreeView : View, ITreeView where T : class if (idx - ScrollOffsetVertical >= 0 && idx - ScrollOffsetVertical < Viewport.Height) { Move (0, idx - ScrollOffsetVertical); - } - else - { - base.PositionCursor (); + return new Point (0, idx - ScrollOffsetVertical); } } - else - { - base.PositionCursor (); - } + return base.PositionCursor (); } /// diff --git a/UICatalog/Scenarios/CharacterMap.cs b/UICatalog/Scenarios/CharacterMap.cs index 43abbb716..96287152e 100644 --- a/UICatalog/Scenarios/CharacterMap.cs +++ b/UICatalog/Scenarios/CharacterMap.cs @@ -824,7 +824,7 @@ internal class CharMap : View return base.OnLeave (view); } - public override void PositionCursor () + public override Point? PositionCursor () { if (HasFocus && Cursor.X >= RowLabelWidth @@ -839,6 +839,8 @@ internal class CharMap : View { Driver.SetCursorVisibility (CursorVisibility.Invisible); } + + return Cursor; } public event EventHandler SelectedCodePointChanged; @@ -910,7 +912,6 @@ internal class CharMap : View if (me.Flags == MouseFlags.Button1Clicked) { SelectedCodePoint = val; - return; } diff --git a/UnitTests/View/Layout/ViewportTests.cs b/UnitTests/View/Layout/ViewportTests.cs index 3c0e0fd62..cd576c210 100644 --- a/UnitTests/View/Layout/ViewportTests.cs +++ b/UnitTests/View/Layout/ViewportTests.cs @@ -359,97 +359,97 @@ public class ViewportTests (ITestOutputHelper output) Assert.Equal (view.Viewport.Size, view.ContentSize); } - [Theory] - [InlineData (0, 0, true)] - [InlineData (-1, 0, true)] - [InlineData (0, -1, true)] - [InlineData (-1, -1, true)] - [InlineData (-2, -2, true)] - [InlineData (-3, -3, true)] - [InlineData (-4, -4, true)] - [InlineData (-5, -4, false)] - [InlineData (-4, -5, false)] - [InlineData (-5, -5, false)] + //[Theory] + //[InlineData (0, 0, true)] + //[InlineData (-1, 0, true)] + //[InlineData (0, -1, true)] + //[InlineData (-1, -1, true)] + //[InlineData (-2, -2, true)] + //[InlineData (-3, -3, true)] + //[InlineData (-4, -4, true)] + //[InlineData (-5, -4, false)] + //[InlineData (-4, -5, false)] + //[InlineData (-5, -5, false)] - [InlineData (1, 1, true)] - [InlineData (2, 2, true)] - [InlineData (3, 3, true)] - [InlineData (4, 4, true)] - [InlineData (5, 4, false)] - [InlineData (4, 5, false)] - [InlineData (5, 5, false)] - public void IsViewVisibleInViewport_No_Driver_No_SuperView (int x, int y, bool expected) - { - var view = new View { X = 1, Y = 1, Width = 5, Height = 5 }; - Assert.True (view.IsViewLocationVisibleInViewport (x, y) == expected); - } + //[InlineData (1, 1, true)] + //[InlineData (2, 2, true)] + //[InlineData (3, 3, true)] + //[InlineData (4, 4, true)] + //[InlineData (5, 4, false)] + //[InlineData (4, 5, false)] + //[InlineData (5, 5, false)] + //public void IsVisibleInSuperView_No_Driver_No_SuperView (int x, int y, bool expected) + //{ + // var view = new View { X = 1, Y = 1, Width = 5, Height = 5 }; + // Assert.True (view.IsVisibleInSuperView (x, y) == expected); + //} - [Theory] - [InlineData (0, 0, true)] - [InlineData (-1, 0, true)] - [InlineData (0, -1, true)] - [InlineData (-1, -1, true)] - [InlineData (-2, -2, true)] - [InlineData (-3, -3, true)] - [InlineData (-4, -4, true)] - [InlineData (-5, -4, true)] - [InlineData (-4, -5, true)] - [InlineData (-5, -5, true)] - [InlineData (-6, -5, false)] - [InlineData (-5, -6, false)] - [InlineData (-6, -6, false)] + //[Theory] + //[InlineData (0, 0, true)] + //[InlineData (-1, 0, true)] + //[InlineData (0, -1, true)] + //[InlineData (-1, -1, true)] + //[InlineData (-2, -2, true)] + //[InlineData (-3, -3, true)] + //[InlineData (-4, -4, true)] + //[InlineData (-5, -4, true)] + //[InlineData (-4, -5, true)] + //[InlineData (-5, -5, true)] + //[InlineData (-6, -5, false)] + //[InlineData (-5, -6, false)] + //[InlineData (-6, -6, false)] - [InlineData (1, 1, true)] - [InlineData (2, 2, true)] - [InlineData (3, 3, true)] - [InlineData (4, 4, true)] - [InlineData (5, 4, true)] - [InlineData (4, 5, true)] - [InlineData (5, 5, true)] - [InlineData (6, 5, true)] - [InlineData (6, 6, true)] - [InlineData (7, 7, true)] - [InlineData (8, 8, true)] - [InlineData (9, 8, false)] - [InlineData (8, 9, false)] - [InlineData (9, 9, false)] - public void IsViewVisibleInViewport_No_Driver_With_SuperView (int x, int y, bool expected) - { - var view = new View { X = 1, Y = 1, Width = 5, Height = 5 }; - var top = new Toplevel { Width = 10, Height = 10 }; - top.Add (view); + //[InlineData (1, 1, true)] + //[InlineData (2, 2, true)] + //[InlineData (3, 3, true)] + //[InlineData (4, 4, true)] + //[InlineData (5, 4, true)] + //[InlineData (4, 5, true)] + //[InlineData (5, 5, true)] + //[InlineData (6, 5, true)] + //[InlineData (6, 6, true)] + //[InlineData (7, 7, true)] + //[InlineData (8, 8, true)] + //[InlineData (9, 8, false)] + //[InlineData (8, 9, false)] + //[InlineData (9, 9, false)] + //public void IsVisibleInSuperView_No_Driver_With_SuperView (int x, int y, bool expected) + //{ + // var view = new View { X = 1, Y = 1, Width = 5, Height = 5 }; + // var top = new Toplevel { Width = 10, Height = 10 }; + // top.Add (view); - Assert.True (view.IsViewLocationVisibleInViewport (x, y) == expected); - } + // Assert.True (view.IsVisibleInSuperView (x, y) == expected); + //} - [SetupFakeDriver] - [Theory] - [InlineData (0, 0, true)] - [InlineData (-1, 0, false)] - [InlineData (0, -1, false)] - [InlineData (-1, -1, false)] + //[SetupFakeDriver] + //[Theory] + //[InlineData (0, 0, true)] + //[InlineData (-1, 0, false)] + //[InlineData (0, -1, false)] + //[InlineData (-1, -1, false)] - [InlineData (1, 0, true)] - [InlineData (0, 1, true)] - [InlineData (1, 1, true)] - [InlineData (2, 2, true)] - [InlineData (3, 3, true)] - [InlineData (4, 4, true)] - [InlineData (5, 4, false)] - [InlineData (4, 5, false)] - [InlineData (5, 5, false)] - public void IsViewVisibleInViewport_With_Driver (int x, int y, bool expected) - { - ((FakeDriver)Application.Driver).SetBufferSize (10, 10); + //[InlineData (1, 0, true)] + //[InlineData (0, 1, true)] + //[InlineData (1, 1, true)] + //[InlineData (2, 2, true)] + //[InlineData (3, 3, true)] + //[InlineData (4, 4, true)] + //[InlineData (5, 4, false)] + //[InlineData (4, 5, false)] + //[InlineData (5, 5, false)] + //public void IsVisibleInSuperView_With_Driver (int x, int y, bool expected) + //{ + // ((FakeDriver)Application.Driver).SetBufferSize (10, 10); - var view = new View { X = 1, Y = 1, Width = 5, Height = 5 }; - var top = new Toplevel (); - top.Add (view); - Application.Begin (top); + // var view = new View { X = 1, Y = 1, Width = 5, Height = 5 }; + // var top = new Toplevel (); + // top.Add (view); + // Application.Begin (top); - Assert.True (view.IsViewLocationVisibleInViewport (x, y) == expected); + // Assert.True (view.IsVisibleInSuperView (x, y) == expected); - top.Dispose (); - Application.Shutdown (); - } + // top.Dispose (); + // Application.Shutdown (); + //} }