Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #3407. Border Subviews #3409

Draft
wants to merge 109 commits into
base: v2_develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
f6ff369
Reamed Bounds -> ViewPort to see how it feels
tig Mar 14, 2024
3a40dec
Reamed Bounds -> Viewport in comments
tig Mar 14, 2024
0900333
Reamed Bounds -> Viewport - more rename
tig Mar 14, 2024
b187a8e
Reamed Bounds -> Viewport - MOAR rename
tig Mar 14, 2024
ebc47de
Reamed Bounds -> Viewport test rename
tig Mar 14, 2024
ab021bf
Updated API docs
tig Mar 17, 2024
7767bd1
Made View.Move and View.AddRune constrain; added unit tests
tig Mar 17, 2024
0cde0e1
Fixed menu code that was using View.Move inproperly
tig Mar 17, 2024
1549d0d
Merge branch 'v2_3269_Bounds-ContentArea' of tig:tig/Terminal.Gui int…
tig Mar 17, 2024
9aec5b1
Merge branch 'v2_3269_Bounds-ContentArea' of tig:tig/Terminal.Gui int…
tig Mar 17, 2024
d915c4e
Fixed API doc typo
tig Mar 18, 2024
00c4680
Fixed Clipping scenario
tig Mar 18, 2024
6b1a429
Rebased with v2_develop
tig Mar 18, 2024
6f664c9
Added ContentSize property and first unit test
tig Mar 20, 2024
f55d9bb
ViewportToScreen now deals with + location. Updated unit tests.
tig Mar 20, 2024
fd4fdb8
More unit tests and code cleanup
tig Mar 20, 2024
90e3838
WIP towards scrolling working
tig Mar 21, 2024
df5f04b
Merged v2_develop
tig Mar 26, 2024
4f59a64
Merged v2_develop
tig Mar 26, 2024
d25f98f
Everything appears to work (except ScrollView which I broke but will …
tig Mar 29, 2024
465c04f
API doc updates
tig Mar 29, 2024
17efda9
Fixed ScrollViwe
tig Mar 29, 2024
2d5a99a
Clarified how Viewport works
tig Mar 30, 2024
5d7fe4c
Reverted temp changes to Scenario
tig Mar 30, 2024
2fe4e92
Added some TODOs
tig Mar 30, 2024
6f15dd9
Renamed ConsoleDriver.Viewport, Screen
tig Mar 30, 2024
0224712
Renamed ConsoleDriver.Viewport, Screen
tig Mar 30, 2024
8483e29
Removed ScrollView dependency from CharMap to validate new View scrol…
tig Mar 30, 2024
207c974
Fixed WindowsDriver cursor issue with true color
tig Mar 31, 2024
9b75eff
Backed out some changes and fixed unit tests
tig Mar 31, 2024
7c8b199
Removed flickering by minimizing layout/display
tig Mar 31, 2024
0c03096
Enabled charmap controls after debugging
tig Mar 31, 2024
7702564
Merge branch 'v2_3269_Bounds-ContentArea' of tig:tig/Terminal.Gui int…
tig Mar 31, 2024
22826e6
Merge branch 'v2_3269_Bounds-ContentArea' of tig:tig/Terminal.Gui int…
tig Mar 31, 2024
08d2716
Prototype scrollbuttons in Padding for CharMap
tig Apr 1, 2024
312dda3
Updated View.Add/Remove API docs
tig Apr 1, 2024
472dd0c
More Prototype scrollbuttons in Padding for CharMap
tig Apr 1, 2024
ed06338
Test button
tig Apr 1, 2024
ca5df08
fixed OnMouseClick logic
tig Apr 1, 2024
cf97b5b
Fixed some unit tests. Prepared for Issue #3368
tig Apr 1, 2024
bbba1e4
Adds Charmap to scrolling demo
tig Apr 3, 2024
1b21dd5
merged
tig Apr 3, 2024
7cc9fb9
merge fixes
tig Apr 3, 2024
2acc235
merge fixes2
tig Apr 3, 2024
68c0a6a
more merge fixes
tig Apr 3, 2024
50f9b35
Merge branch 'v2_3269_Bounds-ContentArea' of tig:tig/Terminal.Gui int…
tig Apr 5, 2024
ba429cf
Merged (Rebased) continous button PR
tig Apr 5, 2024
5c36db2
merge
tig Apr 9, 2024
6b80b23
Updated conceptual API documentation; added mouse.md
tig Apr 10, 2024
62f0156
Updated conceptual API documentation; added mouse.md
tig Apr 10, 2024
4a06074
Updated conceptual API documentation; added mouse.md
tig Apr 10, 2024
da55844
Rewrote ScreenToFrame to be clearer and more performant
tig Apr 10, 2024
a6ff562
Rewrote FindDeepestView to be clearer and more performant
tig Apr 10, 2024
e5d01bf
Fixed Button with WantContinuousPressed = true not responding to sing…
tig Apr 10, 2024
1d9b649
renamed viewscrollin.cs. updated api docs
tig Apr 10, 2024
f5c7448
Revert "Rewrote FindDeepestView to be clearer and more performant"
tig Apr 10, 2024
d964c9c
Reapply "Rewrote FindDeepestView to be clearer and more performant"
tig Apr 10, 2024
0983c69
Revert "Reapply "Rewrote FindDeepestView to be clearer and more perfo…
tig Apr 10, 2024
d8043cd
Reapply "Reapply "Rewrote FindDeepestView to be clearer and more perf…
tig Apr 10, 2024
4feff89
Revert "Reapply "Reapply "Rewrote FindDeepestView to be clearer and m…
tig Apr 10, 2024
907dc4d
Reapply "Reapply "Reapply "Rewrote FindDeepestView to be clearer and …
tig Apr 10, 2024
30e62a6
Revert "Reapply "Reapply "Reapply "Rewrote FindDeepestView to be clea…
tig Apr 10, 2024
d654c9c
Reapply "Reapply "Reapply "Reapply "Rewrote FindDeepestView to be cle…
tig Apr 10, 2024
e8640e9
Found and fixed bug in non-recursive FindDeepestView; added reltaed u…
tig Apr 10, 2024
5d85242
WIP fixing FrameToScreen
tig Apr 11, 2024
685e59f
ListView now uses ViewPort and ContentSize
tig Apr 11, 2024
ad411ce
Fixed FrameToScreen
tig Apr 11, 2024
f924ea3
Completed settings UI in demo scenario
tig Apr 11, 2024
9f93dea
TODOs
tig Apr 11, 2024
d49bc3c
Renamed ScrollSettings enum members to be more clear
tig Apr 11, 2024
7644f63
Refactored ViewportSettings - Now makes more sense and LixtView works…
tig Apr 11, 2024
25491bd
Fixed FindDeepestView bugg I caused by unravelling the recursion
tig Apr 11, 2024
c0b460e
Updated api docs
tig Apr 11, 2024
25a2e04
Updated scenario
tig Apr 11, 2024
248bbe0
Refactored Run_All_Scenarios to use theory data
tig Apr 12, 2024
1ffabac
Fixed latent bug in ScrollBarView
tig Apr 12, 2024
0684d11
Fixed latent bug in ScrollBarView x2
tig Apr 12, 2024
2203f0b
Fixed bug in SetViewport; added unit tests
tig Apr 12, 2024
86f05d1
Found and fixed FindDeepestView bug and added unit tests
tig Apr 12, 2024
8bfc468
Found and fixed double-doubleclick bug in Charmap
tig Apr 12, 2024
6dd349f
Doc improvements
tig Apr 12, 2024
8df0ea4
Scenario clean up
tig Apr 12, 2024
1a5bf0f
Modernized Scrolling scenario
tig Apr 12, 2024
7926781
Modernized Scrolling scenario
tig Apr 12, 2024
b83b392
Updated View and Event classes for viewport and content size handling
tig Apr 13, 2024
88222c4
Fixed clipping - mostly: Still an issue w/ subviews of adornments
tig Apr 14, 2024
513eb13
Fixed layout issue when contentsize changed.
tig Apr 14, 2024
32e79bd
Code and API doc cleanup
tig Apr 14, 2024
a655120
Merge branch 'v2_develop' into v2_3269_Bounds-ContentArea
tig Apr 14, 2024
dc4943f
Deleted temp scenario
tig Apr 14, 2024
2430088
Renamed scenario.
tig Apr 14, 2024
dc4ee29
Updated package versions in multiple projects
tig Apr 15, 2024
4ad3dc8
Made Buttons.NumericUpDown cooler
tig Apr 15, 2024
085fd63
Made Buttons.NumericUpDown even cooler. Updated Adornments scenario t…
tig Apr 15, 2024
012e7a3
Fixed Button.NumericUpDown focus issue
tig Apr 15, 2024
92e7bc6
Cleaned up AdornmentsEditor to fix Progress Styles scenario.
tig Apr 15, 2024
c34b237
Smarter focuscolor fix just for Border
tig Apr 15, 2024
00cc59a
Smarter focuscolor fix just for Border
tig Apr 15, 2024
68e37d0
Fixed ColorPicker scenario with Bdisp's suggested code
tig Apr 15, 2024
77f9830
Removed debug code
tig Apr 15, 2024
50fcb19
Keep Force16Colors set across apps to ease debugging of flicker issue
tig Apr 15, 2024
de1a844
Reimplemented Driver.FillRect to directly use Contnets vs calling Mov…
tig Apr 15, 2024
069089e
Made Arrangement = ViewArrangement.Fixed the default for Toplevels
tig Apr 15, 2024
b7547c4
If Parent isn't movable, border now cancels Highlight event
tig Apr 15, 2024
ceaa10c
Reverted debug stuff in Scrolling Scenario
tig Apr 15, 2024
97351c3
Test tweaks
tig Apr 16, 2024
8d2c64a
Console Driver code cleanup
tig Apr 16, 2024
3f1060b
Initial commit. Partially working prototype
tig Apr 16, 2024
9e2a3d5
prototyping
tig Apr 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![Terminal.Gui](https://socialify.git.ci/gui-cs/Terminal.GuiV2Docs/image?description=1&font=Rokkitt&forks=1&language=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2Fgui-cs%2FTerminal.Gui%2Fdevelop%2Fdocfx%2Fimages%2Flogo.png&name=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Auto)
![.NET Core](https://github.com/gui-cs/Terminal.GuiV2Docs/workflows/.NET%20Core/badge.svg?branch=develop)
![Code scanning - action](https://github.com/gui-cs/Terminal.GuiV2Docs/workflows/Code%20scanning%20-%20action/badge.svg)
![Terminal.Gui](https://socialify.git.ci/gui-cs/Terminal.Gui/image?description=1&font=Rokkitt&forks=1&language=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2Fgui-cs%2FTerminal.Gui%2Fdevelop%2Fdocfx%2Fimages%2Flogo.png&name=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Auto)
![.NET Core](https://github.com/gui-cs/Terminal.Gui/workflows/.NET%20Core/badge.svg?branch=develop)
![Code scanning - action](https://github.com/gui-cs/Terminal.Gui/workflows/Code%20scanning%20-%20action/badge.svg)
[![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui)
![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27/raw/code-coverage.json)
[![Downloads](https://img.shields.io/nuget/dt/Terminal.Gui)](https://www.nuget.org/packages/Terminal.Gui)
Expand Down Expand Up @@ -31,8 +31,10 @@ dotnet run

## Documentation

* [Documentation Home](https://gui-cs.github.io/Terminal.GuiV2Docs)
* [Getting Started](https://gui-cs.github.io/Terminal.GuiV2Docs/docs/getting-started.html)
* [What's new in v2](https://gui-cs.github.io/Terminal.GuiV2Docs/docs/newinv2.html)
* [API Documentation](https://gui-cs.github.io/Terminal.GuiV2Docs/api/Terminal.Gui.html)
* [Documentation Home](https://gui-cs.github.io/Terminal.GuiV2Docs)

## Showcase & Examples

Expand Down
2 changes: 1 addition & 1 deletion ReactiveExample/ReactiveExample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
<PackageReference Include="ReactiveUI" Version="19.5.41" />
<PackageReference Include="ReactiveUI" Version="19.6.1" />
<PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
Expand Down
72 changes: 51 additions & 21 deletions Terminal.Gui/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
#if DEBUG_IDISPOSABLE

// Don't dispose the toplevels. It's up to caller dispose them
Debug.Assert (t.WasDisposed);
//Debug.Assert (t.WasDisposed);
#endif
}

Expand All @@ -99,6 +99,7 @@
// Don't dispose the Top. It's up to caller dispose it
if (Top is { })
{

Debug.Assert (Top.WasDisposed);

// If End wasn't called _cachedRunStateToplevel may be null
Expand Down Expand Up @@ -132,7 +133,7 @@

// Don't reset ForceDriver; it needs to be set before Init is called.
//ForceDriver = string.Empty;
Force16Colors = false;
//Force16Colors = false;
_forceFakeConsole = false;

// Run State stuff
Expand Down Expand Up @@ -525,7 +526,10 @@
MoveCurrent (Current);
}

toplevel.SetRelativeLayout (Driver.Bounds);
//if (Toplevel.LayoutStyle == LayoutStyle.Computed) {
toplevel.SetRelativeLayout (Driver.Screen.Size);

//}

// BUGBUG: This call is likely not needed.
toplevel.LayoutSubviews ();
Expand Down Expand Up @@ -638,7 +642,7 @@
public static void Run (Toplevel view, Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null)
{
ArgumentNullException.ThrowIfNull (view);

if (_initialized)
{
if (Driver is null)
Expand Down Expand Up @@ -878,7 +882,7 @@
}
else
{
Driver.UpdateCursor ();
//Driver.UpdateCursor ();
}

if (state.Toplevel != Top && !state.Toplevel.Modal && (Top.NeedsDisplay || Top.SubViewNeedsDisplay || Top.LayoutNeeded))
Expand Down Expand Up @@ -1307,7 +1311,7 @@

foreach (Toplevel t in _topLevels)
{
t.SetRelativeLayout (Rectangle.Empty with { Size = args.Size });
t.SetRelativeLayout (args.Size);
t.LayoutSubviews ();
t.PositionToplevels ();
t.OnSizeChanging (new (args.Size));
Expand Down Expand Up @@ -1437,23 +1441,22 @@
/// <remarks>
/// <para>
/// Use this event to receive mouse events in screen coordinates. Use <see cref="MouseEvent"/> to
/// receive mouse events relative to a <see cref="View"/>'s bounds.
/// receive mouse events relative to a <see cref="View.Viewport"/>.
/// </para>
/// <para>The <see cref="MouseEvent.View"/> will contain the <see cref="View"/> that contains the mouse coordinates.</para>
/// </remarks>
public static event EventHandler<MouseEvent> MouseEvent;
public static event EventHandler<MouseEvent>? MouseEvent;

/// <summary>Called when a mouse event occurs. Raises the <see cref="MouseEvent"/> event.</summary>
/// <remarks>This method can be used to simulate a mouse event, e.g. in unit tests.</remarks>
/// <param name="a">The mouse event with coordinates relative to the screen.</param>
/// <param name="mouseEvent">The mouse event with coordinates relative to the screen.</param>
internal static void OnMouseEvent (MouseEvent mouseEvent)
{
if (IsMouseDisabled)
{
return;
}

// TODO: In PR #3273, FindDeepestView will return adornments. Update logic below to fix adornment mouse handling
var view = View.FindDeepestView (Current, mouseEvent.X, mouseEvent.Y);

if (view is { })
Expand All @@ -1472,18 +1475,18 @@
{
// If the mouse is grabbed, send the event to the view that grabbed it.
// The coordinates are relative to the Bounds of the view that grabbed the mouse.
Point boundsLoc = MouseGrabView.ScreenToBounds (mouseEvent.X, mouseEvent.Y);
Point frameLoc = MouseGrabView.ScreenToViewport (mouseEvent.X, mouseEvent.Y);

var viewRelativeMouseEvent = new MouseEvent
{
X = boundsLoc.X,
Y = boundsLoc.Y,
X = frameLoc.X,
Y = frameLoc.Y,
Flags = mouseEvent.Flags,
ScreenPosition = new (mouseEvent.X, mouseEvent.Y),
View = MouseGrabView
};

if (MouseGrabView.Bounds.Contains (viewRelativeMouseEvent.X, viewRelativeMouseEvent.Y) is false)
if ((MouseGrabView.Viewport with { Location = Point.Empty }).Contains (viewRelativeMouseEvent.X, viewRelativeMouseEvent.Y) is false)
{
// The mouse has moved outside the bounds of the view that grabbed the mouse
_mouseEnteredView?.NewMouseLeaveEvent (mouseEvent);
Expand Down Expand Up @@ -1521,7 +1524,7 @@

if (view is { } && view != OverlappedTop && top != Current)
{
MoveCurrent ((Toplevel)top);

Check warning on line 1527 in Terminal.Gui/Application.cs

View workflow job for this annotation

GitHub Actions / build_and_test

Converting null literal or possible null value to non-nullable type.
}
}
}
Expand All @@ -1546,14 +1549,14 @@
View = view
};
}
else if (view.BoundsToScreen (view.Bounds).Contains (mouseEvent.X, mouseEvent.Y))
else if (view.ViewportToScreen (Rectangle.Empty with { Size = view.Viewport.Size }).Contains (mouseEvent.X, mouseEvent.Y))
{
Point boundsPoint = view.ScreenToBounds (mouseEvent.X, mouseEvent.Y);
Point viewportLocation = view.ScreenToViewport (mouseEvent.X, mouseEvent.Y);

me = new ()
{
X = boundsPoint.X,
Y = boundsPoint.Y,
X = viewportLocation.X,
Y = viewportLocation.Y,
Flags = mouseEvent.Flags,
ScreenPosition = new (mouseEvent.X, mouseEvent.Y),
View = view
Expand Down Expand Up @@ -1586,10 +1589,37 @@

//Debug.WriteLine ($"OnMouseEvent: ({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags}");

if (view.NewMouseEvent (me) == false)
while (view.NewMouseEvent (me) != true)
{
// Should we bubble up the event, if it is not handled?
//return;
if (MouseGrabView is { })
{
break;
}

if (view is Adornment adornmentView)
{
view = adornmentView.Parent.SuperView;
}
else
{
view = view.SuperView;
}

if (view is null)
{
break;
}

Point boundsPoint = view.ScreenToViewport (mouseEvent.X, mouseEvent.Y);

me = new ()
{
X = boundsPoint.X,
Y = boundsPoint.Y,
Flags = mouseEvent.Flags,
ScreenPosition = new (mouseEvent.X, mouseEvent.Y),
View = view
};
}

BringOverlappedTopToFront ();
Expand Down
93 changes: 55 additions & 38 deletions Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,31 @@ public abstract class ConsoleDriver
// This is in addition to the dirty flag on each cell.
internal bool [] _dirtyLines;

/// <summary>Gets the dimensions of the terminal.</summary>
public Rectangle Bounds => new (0, 0, Cols, Rows);
// QUESTION: When non-full screen apps are supported, will this represent the app size, or will that be in Application?
/// <summary>Gets the location and size of the terminal screen.</summary>
public Rectangle Screen => new (0, 0, Cols, Rows);

private Rectangle _clip;

/// <summary>
/// Gets or sets the clip rectangle that <see cref="AddRune(Rune)"/> and <see cref="AddStr(string)"/> are subject
/// to.
/// </summary>
/// <value>The rectangle describing the bounds of <see cref="Clip"/>.</value>
public Rectangle Clip { get; set; }
/// <value>The rectangle describing the of <see cref="Clip"/> region.</value>
public Rectangle Clip
{
get => _clip;
set
{
if (_clip == value)
{
return;
}

// Don't ever let Clip be bigger than Screen
_clip = Rectangle.Intersect (Screen, value);
}
}

/// <summary>Get the operating system clipboard.</summary>
public IClipboard Clipboard { get; internal set; }
Expand Down Expand Up @@ -278,67 +294,63 @@ public void AddStr (string str)

for (var i = 0; i < runes.Count; i++)
{
//if (runes [i].IsCombiningMark()) {

// // Attempt to normalize
// string combined = runes [i-1] + runes [i].ToString();

// // Normalize to Form C (Canonical Composition)
// string normalized = combined.Normalize (NormalizationForm.FormC);

// runes [i-]
//}
AddRune (runes [i]);
}
}

/// <summary>Clears the <see cref="Contents"/> of the driver.</summary>
public void ClearContents ()
{
// TODO: This method is really "Clear Contents" now and should not be abstract (or virtual)
Contents = new Cell [Rows, Cols];
//CONCURRENCY: Unsynchronized access to Clip isn't safe.
Clip = new (0, 0, Cols, Rows);
// TODO: ClearContents should not clear the clip; it should only clear the contents. Move clearing it elsewhere.
Clip = Screen;
_dirtyLines = new bool [Rows];

lock (Contents)
{
// Can raise an exception while is still resizing.
try
for (var row = 0; row < Rows; row++)
{
for (var row = 0; row < Rows; row++)
for (var c = 0; c < Cols; c++)
{
for (var c = 0; c < Cols; c++)
Contents [row, c] = new Cell
{
Contents [row, c] = new Cell
{
Rune = (Rune)' ', Attribute = new Attribute (Color.White, Color.Black), IsDirty = true
};
_dirtyLines [row] = true;
}
Rune = (Rune)' ',
Attribute = new Attribute (Color.White, Color.Black),
IsDirty = true
};
_dirtyLines [row] = true;
}
}
catch (IndexOutOfRangeException)
{ }
}
}

/// <summary>Determines if the terminal cursor should be visible or not and sets it accordingly.</summary>
/// <returns><see langword="true"/> upon success</returns>
public abstract bool EnsureCursorVisibility ();

// TODO: Move FillRect to ./Drawing
/// <summary>Fills the specified rectangle with the specified rune.</summary>
/// <param name="rect"></param>
/// <param name="rune"></param>
/// <summary>Fills the specified rectangle with the specified rune, using <see cref="CurrentAttribute"/></summary>
/// <remarks>
/// The value of <see cref="Clip"/> is honored. Any parts of the rectangle not in the clip will not be drawn.
/// </remarks>
/// <param name="rect">The Screen-relative rectangle.</param>
/// <param name="rune">The Rune used to fill the rectangle</param>
public void FillRect (Rectangle rect, Rune rune = default)
{
for (int r = rect.Y; r < rect.Y + rect.Height; r++)
rect = Rectangle.Intersect (rect, Clip);
lock (Contents)
{
for (int c = rect.X; c < rect.X + rect.Width; c++)
for (int r = rect.Y; r < rect.Y + rect.Height; r++)
{
Application.Driver.Move (c, r);
Application.Driver.AddRune (rune == default (Rune) ? new Rune (' ') : rune);
for (int c = rect.X; c < rect.X + rect.Width; c++)
{
Contents [r, c] = new Cell
{
Rune = (rune != default ? rune : (Rune)' '),
Attribute = CurrentAttribute, IsDirty = true
};
_dirtyLines [r] = true;
}
}
}
}
Expand Down Expand Up @@ -372,10 +384,13 @@ public void FillRect (Rectangle rect, Rune rune = default)
/// <param name="col">The column.</param>
/// <param name="row">The row.</param>
/// <returns>
/// <see langword="false"/> if the coordinate is outside of the screen bounds or outside of <see cref="Clip"/>.
/// <see langword="false"/> if the coordinate is outside the screen bounds or outside of <see cref="Clip"/>.
/// <see langword="true"/> otherwise.
/// </returns>
public bool IsValidLocation (int col, int row) { return col >= 0 && row >= 0 && col < Cols && row < Rows && Clip.Contains (col, row); }
public bool IsValidLocation (int col, int row)
{
return col >= 0 && row >= 0 && col < Cols && row < Rows && Clip.Contains (col, row);
}

/// <summary>
/// Updates <see cref="Col"/> and <see cref="Row"/> to the specified column and row in <see cref="Contents"/>.
Expand Down Expand Up @@ -437,6 +452,7 @@ public virtual void Move (int col, int row)
/// <summary>Gets whether the <see cref="ConsoleDriver"/> supports TrueColor output.</summary>
public virtual bool SupportsTrueColor => true;

// TODO: This makes ConsoleDriver dependent on Application, which is not ideal. This should be moved to Application.
/// <summary>
/// Gets or sets whether the <see cref="ConsoleDriver"/> should use 16 colors instead of the default TrueColors.
/// See <see cref="Application.Force16Colors"/> to change this setting via <see cref="ConfigurationManager"/>.
Expand Down Expand Up @@ -466,6 +482,7 @@ public Attribute CurrentAttribute
get => _currentAttribute;
set
{
// TODO: This makes ConsoleDriver dependent on Application, which is not ideal. Once Attribute.PlatformColor is removed, this can be fixed.
if (Application.Driver is { })
{
_currentAttribute = new Attribute (value.Foreground, value.Background);
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/ConsoleDrivers/NetDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,7 @@ public override void UpdateCursor ()
{
EnsureCursorVisibility ();

if (Col >= 0 && Col < Cols && Row >= 0 && Row < Rows)
if (Col >= 0 && Col < Cols && Row >= 0 && Row <= Rows)
{
SetCursorPosition (Col, Row);
SetWindowPosition (0, Row);
Expand Down