mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* Initial plan * Replace direct Driver access with ViewBase helper methods Co-authored-by: tig <585482+tig@users.noreply.github.com> * Update documentation to reference View methods instead of Driver Co-authored-by: tig <585482+tig@users.noreply.github.com> * Fix documentation wording to avoid driver reference * Fix missed Driver accesses in Slider.cs Co-authored-by: tig <585482+tig@users.noreply.github.com> * Use Application.Screen instead of ScreenRows/ScreenCols, keep MoveToScreen/FillRectScreen internal for ViewBase only Co-authored-by: tig <585482+tig@users.noreply.github.com> * Remove MoveToScreen and FillRectScreen helper methods, use Driver directly in ViewBase classes Co-authored-by: tig <585482+tig@users.noreply.github.com> * Improve documentation clarity and grammar per CONTRIBUTING.md guidelines Co-authored-by: tig <585482+tig@users.noreply.github.com> * Add MoveToScreenPosition helper to eliminate Driver.Move calls in View subclasses Co-authored-by: tig <585482+tig@users.noreply.github.com> * Remove MoveToScreenPosition helper method, Menu.cs accesses Driver directly Co-authored-by: tig <585482+tig@users.noreply.github.com> * Replace Driver.Move with View.Move in Menu.cs Co-authored-by: tig <585482+tig@users.noreply.github.com> * Update documentation to reflect Driver encapsulation changes Co-authored-by: tig <585482+tig@users.noreply.github.com> * Add PR warnings policy to CONTRIBUTING.md Co-authored-by: tig <585482+tig@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Tig <tig@users.noreply.github.com> Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
@@ -241,6 +241,11 @@ dotnet run --project Examples/UICatalog/UICatalog.csproj
|
||||
- **Tests**: Add tests for new functionality (see [Testing Requirements](#testing-requirements))
|
||||
- **Coverage**: Maintain or increase code coverage
|
||||
- **Scenarios**: Update UICatalog scenarios when adding features
|
||||
- **Warnings**: **CRITICAL - PRs must not introduce any new warnings**
|
||||
- Any file modified in a PR that currently generates warnings **MUST** be fixed to remove those warnings
|
||||
- Exception: Warnings caused by `[Obsolete]` attributes can remain
|
||||
- Expected baseline: ~326 warnings (mostly nullable reference warnings, unused variables, xUnit suggestions)
|
||||
- Action: Before submitting a PR, verify your changes don't add new warnings and fix any warnings in files you modify
|
||||
|
||||
---
|
||||
|
||||
@@ -396,6 +401,7 @@ Key documentation:
|
||||
- ❌ Don't decrease code coverage
|
||||
- ❌ **Don't use `var` for anything but built-in simple types** (use explicit types)
|
||||
- ❌ **Don't use redundant type names with `new`** (**ALWAYS PREFER** target-typed `new ()`)
|
||||
- ❌ **Don't introduce new warnings** (fix warnings in files you modify; exception: `[Obsolete]` warnings)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -95,12 +95,12 @@ internal class ShadowView : View
|
||||
{
|
||||
for (int c = Math.Max (0, screen.X + 1); c < screen.X + screen.Width; c++)
|
||||
{
|
||||
Driver?.Move (c, r);
|
||||
Driver.Move (c, r);
|
||||
SetAttribute (GetAttributeUnderLocation (new (c, r)));
|
||||
|
||||
if (c < Driver?.Contents!.GetLength (1) && r < Driver?.Contents?.GetLength (0))
|
||||
if (c < ScreenContents?.GetLength (1) && r < ScreenContents?.GetLength (0))
|
||||
{
|
||||
Driver.AddRune (Driver.Contents [r, c].Rune);
|
||||
AddRune (ScreenContents [r, c].Rune);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,12 +129,12 @@ internal class ShadowView : View
|
||||
{
|
||||
for (int r = Math.Max (0, screen.Y); r < screen.Y + viewport.Height; r++)
|
||||
{
|
||||
Driver?.Move (c, r);
|
||||
Driver.Move (c, r);
|
||||
SetAttribute (GetAttributeUnderLocation (new (c, r)));
|
||||
|
||||
if (Driver?.Contents is { } && screen.X < Driver.Contents.GetLength (1) && r < Driver.Contents.GetLength (0))
|
||||
if (ScreenContents is { } && screen.X < ScreenContents.GetLength (1) && r < ScreenContents.GetLength (0))
|
||||
{
|
||||
Driver.AddRune (Driver.Contents [r, c].Rune);
|
||||
AddRune (ScreenContents [r, c].Rune);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,14 +151,14 @@ internal class ShadowView : View
|
||||
return Attribute.Default;
|
||||
}
|
||||
|
||||
if (Driver?.Contents == null ||
|
||||
location.Y < 0 || location.Y >= Driver.Contents.GetLength (0) ||
|
||||
location.X < 0 || location.X >= Driver.Contents.GetLength (1))
|
||||
if (ScreenContents == null ||
|
||||
location.Y < 0 || location.Y >= ScreenContents.GetLength (0) ||
|
||||
location.X < 0 || location.X >= ScreenContents.GetLength (1))
|
||||
{
|
||||
return Attribute.Default;
|
||||
}
|
||||
|
||||
Attribute attr = Driver!.Contents! [location.Y, location.X].Attribute!.Value;
|
||||
Attribute attr = ScreenContents [location.Y, location.X].Attribute!.Value;
|
||||
|
||||
var newAttribute =
|
||||
new Attribute (
|
||||
|
||||
@@ -658,7 +658,7 @@ public partial class View // Drawing APIs
|
||||
Driver.Move (p.Key.X, p.Key.Y);
|
||||
|
||||
// TODO: #2616 - Support combining sequences that don't normalize
|
||||
Driver.AddRune (p.Value.Value.Rune);
|
||||
AddRune (p.Value.Value.Rune);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,9 @@ public partial class View : IDisposable, ISupportInitializeNotification
|
||||
set => _driver = value;
|
||||
}
|
||||
|
||||
/// <summary>Gets the screen buffer contents. This is a convenience property for Views that need direct access to the screen buffer.</summary>
|
||||
protected Cell [,]? ScreenContents => Driver?.Contents;
|
||||
|
||||
/// <summary>Initializes a new instance of <see cref="View"/>.</summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
|
||||
@@ -92,7 +92,7 @@ internal abstract class ColorBar : View, IColorBar
|
||||
{
|
||||
Move (0, 0);
|
||||
SetAttribute (HasFocus ? GetAttributeForRole (VisualRole.Focus) : GetAttributeForRole (VisualRole.Normal));
|
||||
Driver?.AddStr (Text);
|
||||
AddStr (Text);
|
||||
|
||||
// TODO: is there a better method than this? this is what it is in TableView
|
||||
xOffset = Text.EnumerateRunes ().Sum (c => c.GetColumns ());
|
||||
|
||||
@@ -427,9 +427,9 @@ public class FileDialog : Dialog, IDesignable
|
||||
Move (0, Viewport.Height / 2);
|
||||
|
||||
SetAttribute (new (Color.Red, GetAttributeForRole (VisualRole.Normal).Background));
|
||||
Driver!.AddStr (new (' ', feedbackPadLeft));
|
||||
Driver.AddStr (_feedback);
|
||||
Driver.AddStr (new (' ', feedbackPadRight));
|
||||
AddStr (new (' ', feedbackPadLeft));
|
||||
AddStr (_feedback);
|
||||
AddStr (new (' ', feedbackPadRight));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -507,7 +507,7 @@ public class FileDialog : Dialog, IDesignable
|
||||
_allowedTypeMenuBar.DrawingContent += (s, e) =>
|
||||
{
|
||||
_allowedTypeMenuBar.Move (e.NewViewport.Width - 1, 0);
|
||||
Driver!.AddRune (Glyphs.DownArrow);
|
||||
AddRune (Glyphs.DownArrow);
|
||||
};
|
||||
|
||||
Add (_allowedTypeMenuBar);
|
||||
|
||||
@@ -213,7 +213,7 @@ public class GraphView : View, IDesignable
|
||||
for (var i = 0; i < Viewport.Height; i++)
|
||||
{
|
||||
Move (0, i);
|
||||
Driver?.AddStr (new (' ', Viewport.Width));
|
||||
AddStr (new (' ', Viewport.Width));
|
||||
}
|
||||
|
||||
// If there is no data do not display a graph
|
||||
|
||||
@@ -18,7 +18,7 @@ public interface IAnnotation
|
||||
|
||||
/// <summary>
|
||||
/// Called once after series have been rendered (or before if <see cref="BeforeSeries"/> is true). Use
|
||||
/// <see cref="View.Driver"/> to draw and <see cref="View.Viewport"/> to avoid drawing outside of graph
|
||||
/// methods like <see cref="View.AddStr(string)"/> and <see cref="View.AddRune(Rune)"/> to draw. Use <see cref="View.Viewport"/> to avoid drawing outside of graph.
|
||||
/// </summary>
|
||||
/// <param name="graph"></param>
|
||||
void Render (GraphView graph);
|
||||
|
||||
@@ -68,11 +68,11 @@ public class TextAnnotation : IAnnotation
|
||||
|
||||
if (Text.Length < availableWidth)
|
||||
{
|
||||
graph.Driver?.AddStr (Text);
|
||||
graph.AddStr (Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
graph.Driver?.AddStr (Text.Substring (0, availableWidth));
|
||||
graph.AddStr (Text.Substring (0, availableWidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ public class ListView : View, IDesignable
|
||||
{
|
||||
for (var c = 0; c < f.Width; c++)
|
||||
{
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
AddRune ((Rune)' ');
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -766,11 +766,11 @@ public class ListView : View, IDesignable
|
||||
|
||||
if (_allowsMarking)
|
||||
{
|
||||
Driver?.AddRune (
|
||||
AddRune (
|
||||
_source.IsMarked (item) ? AllowsMultipleSelection ? Glyphs.CheckStateChecked : Glyphs.Selected :
|
||||
AllowsMultipleSelection ? Glyphs.CheckStateUnChecked : Glyphs.UnSelected
|
||||
);
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
AddRune ((Rune)' ');
|
||||
}
|
||||
|
||||
Source.Render (this, isSelected, item, col, row, f.Width - col, start);
|
||||
|
||||
@@ -847,7 +847,7 @@ internal sealed class Menu : View
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ViewportToScreen (Viewport).Y + i >= Driver.Rows)
|
||||
if (ViewportToScreen (Viewport).Y + i >= Application.Screen.Height)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -863,11 +863,10 @@ internal sealed class Menu : View
|
||||
|
||||
if (item is null && BorderStyle != LineStyle.None)
|
||||
{
|
||||
Point s = ViewportToScreen (new Point (-1, i));
|
||||
Driver.Move (s.X, s.Y);
|
||||
Driver.AddRune (Glyphs.LeftTee);
|
||||
Move (-1, i);
|
||||
AddRune (Glyphs.LeftTee);
|
||||
}
|
||||
else if (Frame.X < Driver.Cols)
|
||||
else if (Frame.X < Application.Screen.Width)
|
||||
{
|
||||
Move (0, i);
|
||||
}
|
||||
@@ -882,28 +881,28 @@ internal sealed class Menu : View
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ViewportToScreen (Viewport).X + p >= Driver.Cols)
|
||||
if (ViewportToScreen (Viewport).X + p >= Application.Screen.Width)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (item is null)
|
||||
{
|
||||
Driver.AddRune (Glyphs.HLine);
|
||||
AddRune (Glyphs.HLine);
|
||||
}
|
||||
else if (i == 0 && p == 0 && _host.UseSubMenusSingleFrame && item.Parent!.Parent is { })
|
||||
{
|
||||
Driver.AddRune (Glyphs.LeftArrow);
|
||||
AddRune (Glyphs.LeftArrow);
|
||||
}
|
||||
|
||||
// This `- 3` is left border + right border + one row in from right
|
||||
else if (p == Frame.Width - 3 && _barItems?.SubMenu (_barItems.Children [i]!) is { })
|
||||
{
|
||||
Driver.AddRune (Glyphs.RightArrow);
|
||||
AddRune (Glyphs.RightArrow);
|
||||
}
|
||||
else
|
||||
{
|
||||
Driver.AddRune ((Rune)' ');
|
||||
AddRune ((Rune)' ');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -911,9 +910,8 @@ internal sealed class Menu : View
|
||||
{
|
||||
if (BorderStyle != LineStyle.None && SuperView?.Frame.Right - Frame.X > Frame.Width)
|
||||
{
|
||||
Point s = ViewportToScreen (new Point (Frame.Width - 2, i));
|
||||
Driver.Move (s.X, s.Y);
|
||||
Driver.AddRune (Glyphs.RightTee);
|
||||
Move (Frame.Width - 2, i);
|
||||
AddRune (Glyphs.RightTee);
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -950,9 +948,9 @@ internal sealed class Menu : View
|
||||
|
||||
Point screen = ViewportToScreen (new Point (0, i));
|
||||
|
||||
if (screen.X < Driver.Cols)
|
||||
if (screen.X < Application.Screen.Width)
|
||||
{
|
||||
Driver.Move (screen.X + 1, screen.Y);
|
||||
Move (1, i);
|
||||
|
||||
if (!item.IsEnabled ())
|
||||
{
|
||||
@@ -991,16 +989,16 @@ internal sealed class Menu : View
|
||||
int col = Frame.Width - l - 3;
|
||||
screen = ViewportToScreen (new Point (col, i));
|
||||
|
||||
if (screen.X < Driver.Cols)
|
||||
if (screen.X < Application.Screen.Width)
|
||||
{
|
||||
Driver.Move (screen.X, screen.Y);
|
||||
Driver.AddStr (item.Help);
|
||||
Move (col, i);
|
||||
AddStr (item.Help);
|
||||
|
||||
// The shortcut tag string
|
||||
if (!string.IsNullOrEmpty (item.ShortcutTag))
|
||||
{
|
||||
Driver.Move (screen.X + l - item.ShortcutTag.GetColumns (), screen.Y);
|
||||
Driver.AddStr (item.ShortcutTag);
|
||||
Move (col + l - item.ShortcutTag.GetColumns (), i);
|
||||
AddStr (item.ShortcutTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -697,7 +697,7 @@ public class MenuBar : View, IDesignable
|
||||
internal Point GetScreenOffset ()
|
||||
{
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
if (Driver is null)
|
||||
if (Application.Screen.Height == 0)
|
||||
{
|
||||
return Point.Empty;
|
||||
}
|
||||
|
||||
@@ -144,11 +144,11 @@ public class ProgressBar : View, IDesignable
|
||||
{
|
||||
if (Array.IndexOf (_activityPos!, i) != -1)
|
||||
{
|
||||
Driver?.AddRune (SegmentCharacter);
|
||||
AddRune (SegmentCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
AddRune ((Rune)' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,12 +159,12 @@ public class ProgressBar : View, IDesignable
|
||||
|
||||
for (i = 0; (i < mid) & (i < Viewport.Width); i++)
|
||||
{
|
||||
Driver?.AddRune (SegmentCharacter);
|
||||
AddRune (SegmentCharacter);
|
||||
}
|
||||
|
||||
for (; i < Viewport.Width; i++)
|
||||
{
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
AddRune ((Rune)' ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@ public class RadioGroup : View, IDesignable, IOrientation
|
||||
|
||||
string rl = _radioLabels [i];
|
||||
SetAttribute (GetAttributeForRole (VisualRole.Normal));
|
||||
Driver?.AddStr ($"{(i == _selected ? Glyphs.Selected : Glyphs.UnSelected)} ");
|
||||
AddStr ($"{(i == _selected ? Glyphs.Selected : Glyphs.UnSelected)} ");
|
||||
TextFormatter.FindHotKey (rl, HotKeySpecifier, out int hotPos, out Key hotKey);
|
||||
|
||||
if (hotPos != -1 && hotKey != Key.Empty)
|
||||
|
||||
@@ -441,13 +441,13 @@ public class Slider<T> : View, IOrientation
|
||||
private void MoveAndAdd (int x, int y, Rune rune)
|
||||
{
|
||||
Move (x, y);
|
||||
Driver?.AddRune (rune);
|
||||
AddRune (rune);
|
||||
}
|
||||
|
||||
private void MoveAndAdd (int x, int y, string str)
|
||||
{
|
||||
Move (x, y);
|
||||
Driver?.AddStr (str);
|
||||
AddStr (str);
|
||||
}
|
||||
|
||||
/// <summary>Sets the dimensions of the Slider to the ideal values.</summary>
|
||||
|
||||
@@ -187,7 +187,7 @@ public class SpinnerView : View, IDesignable
|
||||
if (Sequence is { Length: > 0 } && _currentIdx < Sequence.Length)
|
||||
{
|
||||
Move (Viewport.X, Viewport.Y);
|
||||
Driver?.AddStr (Sequence [_currentIdx]);
|
||||
AddStr (Sequence [_currentIdx]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -943,7 +943,7 @@ public class TableView : View, IDesignable
|
||||
SetAttribute (GetAttributeForRole (VisualRole.Normal));
|
||||
|
||||
//invalidate current row (prevents scrolling around leaving old characters in the frame
|
||||
Driver?.AddStr (new (' ', Viewport.Width));
|
||||
AddStr (new (' ', Viewport.Width));
|
||||
|
||||
var line = 0;
|
||||
|
||||
@@ -1289,12 +1289,11 @@ public class TableView : View, IDesignable
|
||||
protected virtual void OnSelectedCellChanged (SelectedCellChangedEventArgs args) { SelectedCellChanged?.Invoke (this, args); }
|
||||
|
||||
/// <summary>
|
||||
/// Override to provide custom multi colouring to cells. Use <see cref="View.Driver"/> to with
|
||||
/// <see cref="IConsoleDriver.AddStr(string)"/>. The driver will already be in the correct place when rendering and
|
||||
/// you
|
||||
/// must render the full <paramref name="render"/> or the view will not look right. For simpler provision of color use
|
||||
/// <see cref="ColumnStyle.ColorGetter"/> For changing the content that is rendered use
|
||||
/// <see cref="ColumnStyle.RepresentationGetter"/>
|
||||
/// Override to provide custom multi-coloring to cells. Use methods like <see cref="View.AddStr(string)"/>.
|
||||
/// The cursor will already be in the correct position when rendering. You must render the full
|
||||
/// <paramref name="render"/> or the view will not look right. For simpler color provision use
|
||||
/// <see cref="ColumnStyle.ColorGetter"/>. For changing the content that is rendered use
|
||||
/// <see cref="ColumnStyle.RepresentationGetter"/>.
|
||||
/// </summary>
|
||||
/// <param name="cellAttribute"></param>
|
||||
/// <param name="render"></param>
|
||||
@@ -1310,19 +1309,19 @@ public class TableView : View, IDesignable
|
||||
{
|
||||
// invert the color of the current cell for the first character
|
||||
SetAttribute (new (cellAttribute.Foreground, cellAttribute.Background, TextStyle.Reverse));
|
||||
Driver?.AddRune ((Rune)render [0]);
|
||||
AddRune ((Rune)render [0]);
|
||||
|
||||
if (render.Length > 1)
|
||||
{
|
||||
SetAttribute (cellAttribute);
|
||||
Driver?.AddStr (render.Substring (1));
|
||||
AddStr (render.Substring (1));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAttribute (cellAttribute);
|
||||
Driver?.AddStr (render);
|
||||
AddStr (render);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1349,10 +1348,10 @@ public class TableView : View, IDesignable
|
||||
/// <returns></returns>
|
||||
internal int GetHeaderHeightIfAny () { return ShouldRenderHeaders () ? GetHeaderHeight () : 0; }
|
||||
|
||||
private void AddRuneAt (IConsoleDriver d, int col, int row, Rune ch)
|
||||
private void AddRuneAt (int col, int row, Rune ch)
|
||||
{
|
||||
Move (col, row);
|
||||
d?.AddRune (ch);
|
||||
AddRune (ch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1534,14 +1533,14 @@ public class TableView : View, IDesignable
|
||||
/// <param name="width"></param>
|
||||
private void ClearLine (int row, int width)
|
||||
{
|
||||
if (Driver is null)
|
||||
if (Application.Screen.Height == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Move (0, row);
|
||||
SetAttribute (GetAttributeForRole (VisualRole.Normal));
|
||||
Driver.AddStr (new (' ', width));
|
||||
AddStr (new (' ', width));
|
||||
}
|
||||
|
||||
private void ClearMultiSelectedRegions (bool keepToggledSelections)
|
||||
@@ -1734,7 +1733,7 @@ public class TableView : View, IDesignable
|
||||
}
|
||||
}
|
||||
|
||||
AddRuneAt (Driver, c, row, rune);
|
||||
AddRuneAt (c, row, rune);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1762,7 +1761,7 @@ public class TableView : View, IDesignable
|
||||
|
||||
Move (current.X, row);
|
||||
|
||||
Driver?.AddStr (TruncateOrPad (colName, colName, current.Width, colStyle));
|
||||
AddStr (TruncateOrPad (colName, colName, current.Width, colStyle));
|
||||
|
||||
if (Style.ExpandLastColumn == false && current.IsVeryLast)
|
||||
{
|
||||
@@ -1810,9 +1809,9 @@ public class TableView : View, IDesignable
|
||||
}
|
||||
}
|
||||
|
||||
if (Driver is { })
|
||||
if (Application.Screen.Height > 0)
|
||||
{
|
||||
AddRuneAt (Driver, c, row, rune);
|
||||
AddRuneAt (c, row, rune);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1906,7 +1905,7 @@ public class TableView : View, IDesignable
|
||||
}
|
||||
}
|
||||
|
||||
AddRuneAt (Driver, c, row, rune);
|
||||
AddRuneAt (c, row, rune);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1934,7 +1933,7 @@ public class TableView : View, IDesignable
|
||||
}
|
||||
|
||||
SetAttribute (attribute.Value);
|
||||
Driver?.AddStr (new (' ', Viewport.Width));
|
||||
AddStr (new (' ', Viewport.Width));
|
||||
|
||||
// Render cells for each visible header for the current row
|
||||
for (var i = 0; i < columnsToRender.Length; i++)
|
||||
|
||||
@@ -178,7 +178,7 @@ public class TreeTableSource<T> : IEnumerableTableSource<T>, IDisposable where T
|
||||
|
||||
Branch<T> branch = RowToBranch (hit.Value.Y);
|
||||
|
||||
if (branch.IsHitOnExpandableSymbol (Application.Driver, offsetX.Value))
|
||||
if (branch.IsHitOnExpandableSymbol (offsetX.Value))
|
||||
{
|
||||
T m = branch.Model;
|
||||
|
||||
|
||||
@@ -973,7 +973,7 @@ public class TextField : View, IDesignable
|
||||
|
||||
if (col + cols <= width)
|
||||
{
|
||||
Driver?.AddRune (Secret ? Glyphs.Dot : rune);
|
||||
AddRune (Secret ? Glyphs.Dot : rune);
|
||||
}
|
||||
|
||||
if (!TextModel.SetCol (ref col, width, cols))
|
||||
@@ -992,7 +992,7 @@ public class TextField : View, IDesignable
|
||||
// Fill rest of line with spaces
|
||||
for (int i = col; i < width; i++)
|
||||
{
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
AddRune ((Rune)' ');
|
||||
}
|
||||
|
||||
PositionCursor ();
|
||||
@@ -1717,7 +1717,7 @@ public class TextField : View, IDesignable
|
||||
render = render [..Viewport.Width];
|
||||
}
|
||||
|
||||
Driver?.AddStr (render);
|
||||
AddStr (render);
|
||||
}
|
||||
|
||||
private void SetClipboard (IEnumerable<Rune> text)
|
||||
|
||||
@@ -177,7 +177,7 @@ public class TextValidateField : View, IDesignable
|
||||
if (_provider is null)
|
||||
{
|
||||
Move (0, 0);
|
||||
Driver?.AddStr ("Error: ITextValidateProvider not set!");
|
||||
AddStr ("Error: ITextValidateProvider not set!");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -194,7 +194,7 @@ public class TextValidateField : View, IDesignable
|
||||
|
||||
for (var i = 0; i < marginLeft; i++)
|
||||
{
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
AddRune ((Rune)' ');
|
||||
}
|
||||
|
||||
// Content
|
||||
@@ -203,7 +203,7 @@ public class TextValidateField : View, IDesignable
|
||||
// Content
|
||||
for (var i = 0; i < _provider.DisplayText.Length; i++)
|
||||
{
|
||||
Driver?.AddRune ((Rune)_provider.DisplayText [i]);
|
||||
AddRune ((Rune)_provider.DisplayText [i]);
|
||||
}
|
||||
|
||||
// Right Margin
|
||||
@@ -211,7 +211,7 @@ public class TextValidateField : View, IDesignable
|
||||
|
||||
for (var i = 0; i < marginRight; i++)
|
||||
{
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
AddRune ((Rune)' ');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -454,7 +454,7 @@ internal class Branch<T> where T : class
|
||||
/// <param name="driver"></param>
|
||||
/// <param name="x"></param>
|
||||
/// <returns></returns>
|
||||
internal bool IsHitOnExpandableSymbol (IConsoleDriver driver, int x)
|
||||
internal bool IsHitOnExpandableSymbol (int x)
|
||||
{
|
||||
// if leaf node then we cannot expand
|
||||
if (!CanExpand ())
|
||||
|
||||
@@ -1065,7 +1065,7 @@ public class TreeView<T> : View, ITreeView where T : class
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isExpandToggleAttempt = clickedBranch.IsHitOnExpandableSymbol (Driver, me.Position.X);
|
||||
bool isExpandToggleAttempt = clickedBranch.IsHitOnExpandableSymbol (me.Position.X);
|
||||
|
||||
// If we are already selected (double click)
|
||||
if (Equals (SelectedObject, clickedBranch.Model))
|
||||
@@ -1157,7 +1157,7 @@ public class TreeView<T> : View, ITreeView where T : class
|
||||
if (TreeBuilder is null)
|
||||
{
|
||||
Move (0, 0);
|
||||
Driver?.AddStr (NoBuilderError);
|
||||
AddStr (NoBuilderError);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1179,7 +1179,7 @@ public class TreeView<T> : View, ITreeView where T : class
|
||||
// Else clear the line to prevent stale symbols due to scrolling etc
|
||||
Move (0, line);
|
||||
SetAttribute (GetAttributeForRole (VisualRole.Normal));
|
||||
Driver?.AddStr (new (' ', Viewport.Width));
|
||||
AddStr (new (' ', Viewport.Width));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ See the [Layout Deep Dive](layout.md) and the [Arrangement Deep Dive](arrangemen
|
||||
|
||||
See the [Drawing Deep Dive](drawing.md).
|
||||
|
||||
Views should use viewport-relative coordinates for all drawing operations. The `View.Move(col, row)` method positions the cursor using viewport-relative coordinates. For screen dimensions, use @Terminal.Gui.App.Application.Screen instead of accessing the driver directly.
|
||||
|
||||
### Navigation
|
||||
|
||||
See the [Navigation Deep Dive](navigation.md).
|
||||
|
||||
@@ -151,7 +151,7 @@ When `Application.Shutdown()` is called:
|
||||
|
||||
### IConsoleDriver
|
||||
|
||||
The main driver interface that applications interact with. Provides:
|
||||
The main driver interface that the framework uses internally. Provides:
|
||||
|
||||
- **Screen Management**: `Screen`, `Cols`, `Rows`, `Contents`
|
||||
- **Drawing Operations**: `AddRune()`, `AddStr()`, `Move()`, `FillRect()`
|
||||
@@ -161,6 +161,12 @@ The main driver interface that applications interact with. Provides:
|
||||
- **Events**: `KeyDown`, `KeyUp`, `MouseEvent`, `SizeChanged`
|
||||
- **Platform Features**: `SupportsTrueColor`, `Force16Colors`, `Clipboard`
|
||||
|
||||
**Note:** The driver is internal to Terminal.Gui. View classes should not access `Driver` directly. Instead:
|
||||
- Use @Terminal.Gui.App.Application.Screen to get screen dimensions
|
||||
- Use @Terminal.Gui.ViewBase.View.Move for positioning (with viewport-relative coordinates)
|
||||
- Use @Terminal.Gui.ViewBase.View.AddRune and @Terminal.Gui.ViewBase.View.AddStr for drawing
|
||||
- ViewBase infrastructure classes (in `Terminal.Gui/ViewBase/`) can access Driver when needed for framework implementation
|
||||
|
||||
### IConsoleDriverFacade
|
||||
|
||||
Extended interface for v2 drivers that exposes the internal components:
|
||||
@@ -215,18 +221,23 @@ This ensures Terminal.Gui applications can be debugged directly in Visual Studio
|
||||
- Captures output for verification
|
||||
- Always used when `Application._forceFakeConsole` is true
|
||||
|
||||
## Example: Accessing Driver Components
|
||||
## Example: Checking Driver Capabilities
|
||||
|
||||
```csharp
|
||||
Application.Init();
|
||||
|
||||
// Access the driver
|
||||
IConsoleDriver driver = Application.Driver;
|
||||
// The driver is internal - access through Application properties
|
||||
// Check screen dimensions
|
||||
var screenWidth = Application.Screen.Width;
|
||||
var screenHeight = Application.Screen.Height;
|
||||
|
||||
// Check if it's a v2 driver with facade
|
||||
if (driver is IConsoleDriverFacade facade)
|
||||
// Check if 24-bit color is supported
|
||||
bool supportsTrueColor = Application.Driver?.SupportsTrueColor ?? false;
|
||||
|
||||
// Access advanced components (for framework/infrastructure code only)
|
||||
if (Application.Driver is IConsoleDriverFacade facade)
|
||||
{
|
||||
// Access individual components
|
||||
// Access individual components for advanced scenarios
|
||||
IInputProcessor inputProcessor = facade.InputProcessor;
|
||||
IOutputBuffer outputBuffer = facade.OutputBuffer;
|
||||
IWindowSizeMonitor sizeMonitor = facade.WindowSizeMonitor;
|
||||
@@ -239,6 +250,11 @@ if (driver is IConsoleDriverFacade facade)
|
||||
}
|
||||
```
|
||||
|
||||
**Important:** View subclasses should not access `Application.Driver`. Use the View APIs instead:
|
||||
- `View.Move(col, row)` for positioning
|
||||
- `View.AddRune()` and `View.AddStr()` for drawing
|
||||
- `Application.Screen` for screen dimensions
|
||||
|
||||
## Custom Drivers
|
||||
|
||||
To create a custom driver, implement `IComponentFactory<T>`:
|
||||
|
||||
@@ -225,7 +225,7 @@ The cursor and focus system has been redesigned in v2 to be more consistent and
|
||||
|
||||
### Cursor
|
||||
|
||||
In v1, whether the cursor (the flashing caret) was visible or not was controlled by `View.CursorVisibility` which was an enum extracted from Ncruses/Terminfo. It only works in some cases on Linux, and only partially with `WindowsDriver`. The position of the cursor was the same as `ConsoleDriver.Row`/`Col` and determined by the last call to `ConsoleDriver.Move`. `View.PositionCursor()` could be overridden by views to cause `Application` to call `ConsoleDriver.Move` on behalf of the app and to manage setting `CursorVisibility`. This API was confusing and bug-prone.
|
||||
In v1, whether the cursor (the flashing caret) was visible or not was controlled by `View.CursorVisibility` which was an enum extracted from Ncruses/Terminfo. It only works in some cases on Linux, and only partially with `WindowsDriver`. The position of the cursor was determined by the last call to the driver's Move method. `View.PositionCursor()` could be overridden by views to cause `Application` to call the driver's positioning method on behalf of the app and to manage setting `CursorVisibility`. This API was confusing and bug-prone.
|
||||
|
||||
In v2, the API is (NOT YET IMPLEMENTED) simplified. A view simply reports the style of cursor it wants and the Viewport-relative location:
|
||||
|
||||
@@ -237,7 +237,7 @@ In v2, the API is (NOT YET IMPLEMENTED) simplified. A view simply reports the st
|
||||
- If `null` the default cursor style is used.
|
||||
- If `{}` specifies the style of cursor. See [cursor.md](cursor.md) for more.
|
||||
* `Application` now has APIs for querying available cursor styles.
|
||||
* The details in `ConsoleDriver` are no longer available to applications.
|
||||
* The driver details are no longer directly accessible to View subclasses.
|
||||
|
||||
#### How to Fix (Cursor API)
|
||||
|
||||
@@ -245,6 +245,26 @@ In v2, the API is (NOT YET IMPLEMENTED) simplified. A view simply reports the st
|
||||
* Set @Terminal.Gui.ViewBase.View.CursorVisibility to the cursor style you want to use.
|
||||
* Remove any overrides of `OnEnter` and `OnLeave` that explicitly change the cursor.
|
||||
|
||||
### Driver Access
|
||||
|
||||
In v1, Views could access `Driver` directly (e.g., `Driver.Move()`, `Driver.Rows`, `Driver.Cols`). In v2, `Driver` is internal and View subclasses should not access it directly. ViewBase provides all necessary abstractions for Views to function without needing direct driver access.
|
||||
|
||||
#### How to Fix (Driver Access)
|
||||
|
||||
* Replace `Driver.Rows` and `Driver.Cols` with @Terminal.Gui.App.Application.Screen.Height and @Terminal.Gui.App.Application.Screen.Width
|
||||
* Replace direct `Driver.Move(screenX, screenY)` calls with @Terminal.Gui.ViewBase.View.Move using viewport-relative coordinates
|
||||
* Use @Terminal.Gui.ViewBase.View.AddRune and @Terminal.Gui.ViewBase.View.AddStr for drawing
|
||||
* ViewBase infrastructure classes (in `Terminal.Gui/ViewBase/`) can still access Driver for framework implementation needs
|
||||
|
||||
```diff
|
||||
- if (x >= Driver.Cols) return;
|
||||
+ if (x >= Application.Screen.Width) return;
|
||||
|
||||
- Point screenPos = ViewportToScreen(new Point(col, row));
|
||||
- Driver.Move(screenPos.X, screenPos.Y);
|
||||
+ Move(col, row); // Move handles viewport-to-screen conversion
|
||||
```
|
||||
|
||||
### Focus
|
||||
|
||||
See [navigation.md](navigation.md) for more details.
|
||||
|
||||
Reference in New Issue
Block a user