diff --git a/Directory.Build.targets b/Directory.Build.targets
new file mode 100644
index 0000000000..79faf752f2
--- /dev/null
+++ b/Directory.Build.targets
@@ -0,0 +1,5 @@
+
+
+ $(DefineConstants);DIMAUTO
+
+
\ No newline at end of file
diff --git a/ReactiveExample/LoginView.cs b/ReactiveExample/LoginView.cs
index 4f057cb17a..154bfbeced 100644
--- a/ReactiveExample/LoginView.cs
+++ b/ReactiveExample/LoginView.cs
@@ -79,7 +79,7 @@ private Label LoginProgressLabel (View previous)
var loginProgressLabel = new Label
{
- AutoSize = false, X = Pos.Left (previous), Y = Pos.Top (previous) + 1, Width = 40, Height = 1, Text = idle
+ X = Pos.Left (previous), Y = Pos.Top (previous) + 1, Width = 40, Height = 1, Text = idle
};
ViewModel
diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs
index 1009236a41..28322e916f 100644
--- a/Terminal.Gui/Application.cs
+++ b/Terminal.Gui/Application.cs
@@ -557,8 +557,6 @@ public static RunState Begin (Toplevel toplevel)
return rs;
}
- private static CursorVisibility _cachedCursorVisibility;
-
///
/// Calls on the most focused view in the view starting with .
///
@@ -571,29 +569,21 @@ public static RunState Begin (Toplevel toplevel)
/// 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;
+ View mostFocused = view?.MostFocused;
if (mostFocused is null)
{
return false;
}
- CursorVisibility cachedCursorVisibility;
// If the view is not visible or enabled, don't position the cursor
if (!mostFocused.Visible || !mostFocused.Enabled)
{
- Driver.GetCursorVisibility (out cachedCursorVisibility);
-
- if (cachedCursorVisibility != CursorVisibility.Invisible)
+ Driver.GetCursorVisibility (out CursorVisibility current);
+ if (current != CursorVisibility.Invisible)
{
- _cachedCursorVisibility = cachedCursorVisibility;
Driver.SetCursorVisibility (CursorVisibility.Invisible);
}
@@ -611,40 +601,35 @@ internal static bool PositionCursor (View view)
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
+ Driver.GetCursorVisibility (out CursorVisibility currentCursorVisibility);
+
if (cursor is { })
{
// Convert cursor to screen coords
cursor = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = cursor.Value }).Location;
+
+ // If the cursor is not in a visible location in the SuperView, hide it
if (!superViewViewport.Contains (cursor.Value))
{
- Driver.GetCursorVisibility (out cachedCursorVisibility);
-
- if (cachedCursorVisibility != CursorVisibility.Invisible)
+ if (currentCursorVisibility != CursorVisibility.Invisible)
{
- _cachedCursorVisibility = cachedCursorVisibility;
+ Driver.SetCursorVisibility (CursorVisibility.Invisible);
}
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
return false;
}
- Driver.GetCursorVisibility (out cachedCursorVisibility);
-
- if (cachedCursorVisibility == CursorVisibility.Invisible)
+ // Show it
+ if (currentCursorVisibility == CursorVisibility.Invisible)
{
- Driver.SetCursorVisibility (_cachedCursorVisibility);
+ Driver.SetCursorVisibility (mostFocused.CursorVisibility);
}
- return prevCursor != cursor;
+ return true;
}
- Driver.GetCursorVisibility (out cachedCursorVisibility);
-
- if (cachedCursorVisibility != CursorVisibility.Invisible)
+ if (currentCursorVisibility != CursorVisibility.Invisible)
{
- _cachedCursorVisibility = cachedCursorVisibility;
Driver.SetCursorVisibility (CursorVisibility.Invisible);
}
@@ -1413,14 +1398,14 @@ public static bool OnSizeChanging (SizeChangedEventArgs args)
{
SizeChanging?.Invoke (null, args);
- if (args.Cancel)
+ if (args.Cancel || args.Size is null)
{
return false;
}
foreach (Toplevel t in _topLevels)
{
- t.SetRelativeLayout (args.Size);
+ t.SetRelativeLayout (args.Size.Value);
t.LayoutSubviews ();
t.PositionToplevels ();
t.OnSizeChanging (new (args.Size));
diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
index d372c52d43..e0ab6fff61 100644
--- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
@@ -214,9 +214,13 @@ public override void UpdateCursor ()
if (!RunningUnitTests && Col >= 0 && Col < Cols && Row >= 0 && Row < Rows)
{
Curses.move (Row, Col);
+ Curses.raw ();
+ Curses.noecho ();
+ Curses.refresh ();
}
}
+
public override void UpdateScreen ()
{
for (var row = 0; row < Rows; row++)
@@ -606,6 +610,12 @@ internal void ProcessInput ()
k = KeyCode.Enter;
}
+ // Strip the KeyCode.Space flag off if it's set
+ if (k != KeyCode.Space && k.HasFlag (KeyCode.Space))
+ {
+ k &= ~KeyCode.Space;
+ }
+
OnKeyDown (new Key (k));
OnKeyUp (new Key (k));
}
diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs
index 22cd0b9872..26d543b3c3 100644
--- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs
@@ -1137,7 +1137,7 @@ private void ProcessInput (InputResult inputEvent)
break;
case EventType.Mouse:
MouseEvent me = ToDriverMouse (inputEvent.MouseEvent);
- Debug.WriteLine ($"NetDriver: ({me.X},{me.Y}) - {me.Flags}");
+ //Debug.WriteLine ($"NetDriver: ({me.X},{me.Y}) - {me.Flags}");
OnMouseEvent (me);
break;
@@ -1591,10 +1591,7 @@ private KeyCode MapKey (ConsoleKeyInfo keyInfo)
return KeyCode.Tab;
}
- if (keyInfo.Key == ConsoleKey.Tab)
- {
- return MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)((uint)keyInfo.Key));
- }
+ return MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)((uint)keyInfo.Key));
}
// Handle control keys (e.g. CursorUp)
@@ -1648,7 +1645,7 @@ private KeyCode MapKey (ConsoleKeyInfo keyInfo)
}
- return MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)((uint)keyInfo.Key));
+ return MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)((uint)keyInfo.KeyChar));
}
#endregion Keyboard Handling
diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
index 7b67c31f7a..896487ac30 100644
--- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
+++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
@@ -20,6 +20,7 @@
using System.Runtime.InteropServices;
using System.Text;
using static Terminal.Gui.ConsoleDrivers.ConsoleKeyMapping;
+using static Terminal.Gui.SpinnerStyle;
namespace Terminal.Gui;
@@ -156,10 +157,7 @@ public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window
}
}
- if (!_initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility))
- {
- _initialCursorVisibility = visibility;
- }
+ SetInitialCursorVisibility();
if (!SetConsoleActiveScreenBuffer (_screenBuffer))
{
@@ -216,11 +214,11 @@ public bool GetCursorVisibility (out CursorVisibility visibility)
}
else if (info.dwSize > 50)
{
- visibility = CursorVisibility.Box;
+ visibility = CursorVisibility.Default;
}
else
{
- visibility = CursorVisibility.Underline;
+ visibility = CursorVisibility.Default;
}
return true;
@@ -815,6 +813,11 @@ object lpReserved
[StructLayout (LayoutKind.Sequential)]
public struct ConsoleCursorInfo
{
+ ///
+ /// The percentage of the character cell that is filled by the cursor.This value is between 1 and 100.
+ /// The cursor appearance varies, ranging from completely filling the cell to showing up as a horizontal
+ /// line at the bottom of the cell.
+ ///
public uint dwSize;
public bool bVisible;
}
@@ -1436,6 +1439,8 @@ internal override MainLoop Init ()
#if HACK_CHECK_WINCHANGED
_mainLoopDriver.WinChanged = ChangeWin;
#endif
+
+ WinConsole?.SetInitialCursorVisibility ();
return new MainLoop (_mainLoopDriver);
}
@@ -1517,23 +1522,28 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent)
#if HACK_CHECK_WINCHANGED
private void ChangeWin (object s, SizeChangedEventArgs e)
{
- int w = e.Size.Width;
+ if (e.Size is null)
+ {
+ return;
+ }
+
+ int w = e.Size.Value.Width;
- if (w == Cols - 3 && e.Size.Height < Rows)
+ if (w == Cols - 3 && e.Size.Value.Height < Rows)
{
w += 3;
}
Left = 0;
Top = 0;
- Cols = e.Size.Width;
- Rows = e.Size.Height;
+ Cols = e.Size.Value.Width;
+ Rows = e.Size.Value.Height;
if (!RunningUnitTests)
{
Size newSize = WinConsole.SetConsoleWindow (
(short)Math.Max (w, 16),
- (short)Math.Max (e.Size.Height, 0));
+ (short)Math.Max (e.Size.Value.Height, 0));
Cols = newSize.Width;
Rows = newSize.Height;
diff --git a/Terminal.Gui/Directory.Build.props b/Terminal.Gui/Directory.Build.props
index 6bf2f2e2c6..f22179be1e 100644
--- a/Terminal.Gui/Directory.Build.props
+++ b/Terminal.Gui/Directory.Build.props
@@ -7,5 +7,4 @@
-->
Miguel de Icaza, Charlie Kindel (@tig), @BDisp
-
\ No newline at end of file
diff --git a/Terminal.Gui/Drawing/Justification.cs b/Terminal.Gui/Drawing/Justification.cs
new file mode 100644
index 0000000000..16c76c372c
--- /dev/null
+++ b/Terminal.Gui/Drawing/Justification.cs
@@ -0,0 +1,332 @@
+namespace Terminal.Gui;
+
+///
+/// Controls how the justifies items within a container.
+///
+public enum Justification
+{
+ ///
+ /// The items will be aligned to the left.
+ /// Set to to ensure at least one space between
+ /// each item.
+ ///
+ ///
+ ///
+ /// 111 2222 33333
+ ///
+ ///
+ Left,
+
+ ///
+ /// The items will be aligned to the right.
+ /// Set to to ensure at least one space between
+ /// each item.
+ ///
+ ///
+ ///
+ /// 111 2222 33333
+ ///
+ ///
+ Right,
+
+ ///
+ /// The group will be centered in the container.
+ /// If centering is not possible, the group will be left-justified.
+ /// Set to to ensure at least one space between
+ /// each item.
+ ///
+ ///
+ ///
+ /// 111 2222 33333
+ ///
+ ///
+ Centered,
+
+ ///
+ /// The items will be justified. Space will be added between the items such that the first item
+ /// is at the start and the right side of the last item against the end.
+ /// Set to to ensure at least one space between
+ /// each item.
+ ///
+ ///
+ ///
+ /// 111 2222 33333
+ ///
+ ///
+ Justified,
+
+ ///
+ /// The first item will be aligned to the left and the remaining will aligned to the right.
+ /// Set to to ensure at least one space between
+ /// each item.
+ ///
+ ///
+ ///
+ /// 111 2222 33333
+ ///
+ ///
+ FirstLeftRestRight,
+
+ ///
+ /// The last item will be aligned to the right and the remaining will aligned to the left.
+ /// Set to to ensure at least one space between
+ /// each item.
+ ///
+ ///
+ ///
+ /// 111 2222 33333
+ ///
+ ///
+ LastRightRestLeft
+}
+
+///
+/// Justifies items within a container based on the specified .
+///
+public class Justifier
+{
+ ///
+ /// Gets or sets how the justifies items within a container.
+ ///
+ public Justification Justification { get; set; }
+
+ ///
+ /// The size of the container.
+ ///
+ public int ContainerSize { get; set; }
+
+ ///
+ /// Gets or sets whether puts a space is placed between items. Default is . If , a space will be
+ /// placed between each item, which is useful for justifying text.
+ ///
+ public bool PutSpaceBetweenItems { get; set; }
+
+ ///
+ /// Takes a list of items and returns their positions when justified within a container wide based on the specified
+ /// .
+ ///
+ /// The sizes of the items to justify.
+ /// The locations of the items, from left to right.
+ public int [] Justify (int [] sizes)
+ {
+ return Justify (Justification, PutSpaceBetweenItems, ContainerSize, sizes);
+ }
+
+ ///
+ /// Takes a list of items and returns their positions when justified within a container wide based on the specified
+ /// .
+ ///
+ /// The sizes of the items to justify.
+ /// The justification style.
+ /// The size of the container.
+ /// The locations of the items, from left to right.
+ public static int [] Justify (Justification justification, bool putSpaceBetweenItems, int containerSize, int [] sizes)
+ {
+ if (sizes.Length == 0)
+ {
+ return new int [] { };
+ }
+
+ int maxSpaceBetweenItems = putSpaceBetweenItems ? 1 : 0;
+
+ var positions = new int [sizes.Length]; // positions of the items. the return value.
+ int totalItemsSize = sizes.Sum ();
+ int totalGaps = sizes.Length - 1; // total gaps between items
+ int totalItemsAndSpaces = totalItemsSize + totalGaps * maxSpaceBetweenItems; // total size of items and spaces if we had enough room
+
+ int spaces = totalGaps * maxSpaceBetweenItems; // We'll decrement this below to place one space between each item until we run out
+ if (totalItemsSize >= containerSize)
+ {
+ spaces = 0;
+ }
+ else if (totalItemsAndSpaces > containerSize)
+ {
+ spaces = containerSize - totalItemsSize;
+ }
+
+ switch (justification)
+ {
+ case Justification.Left:
+ var currentPosition = 0;
+
+ for (var i = 0; i < sizes.Length; i++)
+ {
+ if (sizes [i] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ if (i == 0)
+ {
+ positions [0] = 0; // first item position
+
+ continue;
+ }
+
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+
+ // subsequent items are placed one space after the previous item
+ positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
+ }
+
+ break;
+ case Justification.Right:
+ currentPosition = Math.Max (0, containerSize - totalItemsSize - spaces);
+
+ for (var i = 0; i < sizes.Length; i++)
+ {
+ if (sizes [i] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+
+ positions [i] = currentPosition;
+ currentPosition += sizes [i] + spaceBefore;
+ }
+
+ break;
+
+ case Justification.Centered:
+ if (sizes.Length > 1)
+ {
+ // remaining space to be distributed before first and after the items
+ int remainingSpace = Math.Max (0, containerSize - totalItemsSize - spaces);
+
+ for (var i = 0; i < sizes.Length; i++)
+ {
+ if (sizes [i] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ if (i == 0)
+ {
+ positions [i] = remainingSpace / 2; // first item position
+
+ continue;
+ }
+
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+
+ // subsequent items are placed one space after the previous item
+ positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
+ }
+ }
+ else if (sizes.Length == 1)
+ {
+ if (sizes [0] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ positions [0] = (containerSize - sizes [0]) / 2; // single item is centered
+ }
+
+ break;
+
+ case Justification.Justified:
+ int spaceBetween = sizes.Length > 1 ? (containerSize - totalItemsSize) / (sizes.Length - 1) : 0;
+ int remainder = sizes.Length > 1 ? (containerSize - totalItemsSize) % (sizes.Length - 1) : 0;
+ currentPosition = 0;
+
+ for (var i = 0; i < sizes.Length; i++)
+ {
+ if (sizes [i] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ positions [i] = currentPosition;
+ int extraSpace = i < remainder ? 1 : 0;
+ currentPosition += sizes [i] + spaceBetween + extraSpace;
+ }
+
+ break;
+
+ // 111 2222 33333
+ case Justification.LastRightRestLeft:
+ if (sizes.Length > 1)
+ {
+ currentPosition = 0;
+
+ for (var i = 0; i < sizes.Length; i++)
+ {
+ if (sizes [i] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ if (i < sizes.Length - 1)
+ {
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+
+ positions [i] = currentPosition;
+ currentPosition += sizes [i] + spaceBefore;
+ }
+ }
+
+ positions [sizes.Length - 1] = containerSize - sizes [sizes.Length - 1];
+ }
+ else if (sizes.Length == 1)
+ {
+ if (sizes [0] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ positions [0] = containerSize - sizes [0]; // single item is flush right
+ }
+
+ break;
+
+ // 111 2222 33333
+ case Justification.FirstLeftRestRight:
+ if (sizes.Length > 1)
+ {
+ currentPosition = 0;
+ positions [0] = currentPosition; // first item is flush left
+
+ for (int i = sizes.Length - 1; i >= 0; i--)
+ {
+ if (sizes [i] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ if (i == sizes.Length - 1)
+ {
+ // start at right
+ currentPosition = containerSize - sizes [i];
+ positions [i] = currentPosition;
+ }
+
+ if (i < sizes.Length - 1 && i > 0)
+ {
+ int spaceBefore = spaces-- > 0 ? maxSpaceBetweenItems : 0;
+
+ positions [i] = currentPosition - sizes [i] - spaceBefore;
+ currentPosition = positions [i];
+ }
+ }
+ }
+ else if (sizes.Length == 1)
+ {
+ if (sizes [0] < 0)
+ {
+ throw new ArgumentException ("The size of an item cannot be negative.");
+ }
+
+ positions [0] = 0; // single item is flush left
+ }
+
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException (nameof (justification), justification, null);
+ }
+
+ return positions;
+ }
+}
diff --git a/Terminal.Gui/Drawing/Thickness.cs b/Terminal.Gui/Drawing/Thickness.cs
index ffe8b3f708..40a30d590c 100644
--- a/Terminal.Gui/Drawing/Thickness.cs
+++ b/Terminal.Gui/Drawing/Thickness.cs
@@ -233,7 +233,8 @@ rect with
{
Text = label is null ? string.Empty : $"{label} {this}",
Alignment = TextAlignment.Centered,
- VerticalAlignment = VerticalTextAlignment.Bottom
+ VerticalAlignment = VerticalTextAlignment.Bottom,
+ AutoSize = true
};
tf.Draw (rect, Application.Driver.CurrentAttribute, Application.Driver.CurrentAttribute, rect);
}
diff --git a/Terminal.Gui/Text/TextFormatter.cs b/Terminal.Gui/Text/TextFormatter.cs
index db13b5930b..5d60ba89ad 100644
--- a/Terminal.Gui/Text/TextFormatter.cs
+++ b/Terminal.Gui/Text/TextFormatter.cs
@@ -30,7 +30,7 @@ public TextAlignment Alignment
/// Gets or sets whether the should be automatically changed to fit the .
///
- /// Used by to resize the view's to fit .
+ /// Used when is using to resize the view's to fit .
///
/// AutoSize is ignored if and
/// are used.
@@ -43,13 +43,54 @@ public bool AutoSize
{
_autoSize = EnableNeedsFormat (value);
- if (_autoSize && Alignment != TextAlignment.Justified && VerticalAlignment != VerticalTextAlignment.Justified)
+ if (_autoSize)
{
- Size = CalcRect (0, 0, _text, Direction, TabWidth).Size;
+ Size = GetAutoSize ();
}
}
}
+ private Size GetAutoSize ()
+ {
+ Size size = CalcRect (0, 0, Text, Direction, TabWidth).Size;
+ return size with
+ {
+ Width = size.Width - GetHotKeySpecifierLength (),
+ Height = size.Height - GetHotKeySpecifierLength (false)
+ };
+
+ }
+ ///
+ /// Gets the width or height of the characters
+ /// in the property.
+ ///
+ ///
+ /// Only the first HotKey specifier found in is supported.
+ ///
+ ///
+ /// If (the default) the width required for the HotKey specifier is returned. Otherwise the
+ /// height
+ /// is returned.
+ ///
+ ///
+ /// The number of characters required for the . If the text
+ /// direction specified
+ /// by does not match the parameter, 0 is returned.
+ ///
+ public int GetHotKeySpecifierLength (bool isWidth = true)
+ {
+ if (isWidth)
+ {
+ return TextFormatter.IsHorizontalDirection (Direction) && Text?.Contains ((char)HotKeySpecifier.Value) == true
+ ? Math.Max (HotKeySpecifier.GetColumns (), 0)
+ : 0;
+ }
+
+ return TextFormatter.IsVerticalDirection (Direction) && Text?.Contains ((char)HotKeySpecifier.Value) == true
+ ? Math.Max (HotKeySpecifier.GetColumns (), 0)
+ : 0;
+ }
+
///
/// Gets the cursor position of the . If the is defined, the cursor will
/// be positioned over it.
@@ -65,13 +106,14 @@ public TextDirection Direction
{
_textDirection = EnableNeedsFormat (value);
- if (AutoSize && Alignment != TextAlignment.Justified && VerticalAlignment != VerticalTextAlignment.Justified)
+ if (AutoSize)
{
- Size = CalcRect (0, 0, Text, Direction, TabWidth).Size;
+ Size = GetAutoSize ();
}
}
}
+
///
/// Determines if the viewport width will be used or only the text width will be used,
/// If all the viewport area will be filled with whitespaces and the same background color
@@ -148,9 +190,9 @@ public Size Size
get => _size;
set
{
- if (AutoSize && Alignment != TextAlignment.Justified && VerticalAlignment != VerticalTextAlignment.Justified)
+ if (AutoSize)
{
- _size = EnableNeedsFormat (CalcRect (0, 0, Text, Direction, TabWidth).Size);
+ _size = EnableNeedsFormat (GetAutoSize());
}
else
{
@@ -172,12 +214,11 @@ public virtual string Text
get => _text;
set
{
- bool textWasNull = _text is null && value != null;
_text = EnableNeedsFormat (value);
- if ((AutoSize && Alignment != TextAlignment.Justified && VerticalAlignment != VerticalTextAlignment.Justified) || (textWasNull && Size.IsEmpty))
+ if (AutoSize)
{
- Size = CalcRect (0, 0, _text, Direction, TabWidth).Size;
+ Size = GetAutoSize (); ;
}
}
}
@@ -228,17 +269,6 @@ public void Draw (
List linesFormatted = GetLines ();
- switch (Direction)
- {
- case TextDirection.TopBottom_RightLeft:
- case TextDirection.LeftRight_BottomTop:
- case TextDirection.RightLeft_BottomTop:
- case TextDirection.BottomTop_RightLeft:
- linesFormatted.Reverse ();
-
- break;
- }
-
bool isVertical = IsVerticalDirection (Direction);
Rectangle maxScreen = screen;
@@ -286,25 +316,16 @@ public void Draw (
Rune [] runes = linesFormatted [line].ToRunes ();
- runes = Direction switch
- {
- TextDirection.RightLeft_BottomTop => runes.Reverse ().ToArray (),
- TextDirection.RightLeft_TopBottom => runes.Reverse ().ToArray (),
- TextDirection.BottomTop_LeftRight => runes.Reverse ().ToArray (),
- TextDirection.BottomTop_RightLeft => runes.Reverse ().ToArray (),
- _ => runes
- };
-
// When text is justified, we lost left or right, so we use the direction to align.
int x, y;
// Horizontal Alignment
- if (Alignment == TextAlignment.Right || (Alignment == TextAlignment.Justified && !IsLeftToRight (Direction)))
+ if (Alignment is TextAlignment.Right)
{
if (isVertical)
{
- int runesWidth = GetWidestLineLength (linesFormatted, line, TabWidth);
+ int runesWidth = GetColumnsRequiredForVerticalText (linesFormatted, line, linesFormatted.Count - line, TabWidth);
x = screen.Right - runesWidth;
CursorPosition = screen.Width - runesWidth + (_hotKeyPos > -1 ? _hotKeyPos : 0);
}
@@ -315,12 +336,12 @@ public void Draw (
CursorPosition = screen.Width - runesWidth + (_hotKeyPos > -1 ? _hotKeyPos : 0);
}
}
- else if (Alignment is TextAlignment.Left or TextAlignment.Justified)
+ else if (Alignment is TextAlignment.Left)
{
if (isVertical)
{
int runesWidth = line > 0
- ? GetWidestLineLength (linesFormatted, 0, line, TabWidth)
+ ? GetColumnsRequiredForVerticalText (linesFormatted, 0, line, TabWidth)
: 0;
x = screen.Left + runesWidth;
}
@@ -331,12 +352,36 @@ public void Draw (
CursorPosition = _hotKeyPos > -1 ? _hotKeyPos : 0;
}
- else if (Alignment == TextAlignment.Centered)
+ else if (Alignment is TextAlignment.Justified)
+ {
+ if (isVertical)
+ {
+ int runesWidth = GetColumnsRequiredForVerticalText (linesFormatted, 0, linesFormatted.Count, TabWidth);
+ int prevLineWidth = line > 0 ? GetColumnsRequiredForVerticalText (linesFormatted, line - 1, 1, TabWidth) : 0;
+ int firstLineWidth = GetColumnsRequiredForVerticalText (linesFormatted, 0, 1, TabWidth);
+ int lastLineWidth = GetColumnsRequiredForVerticalText (linesFormatted, linesFormatted.Count - 1, 1, TabWidth);
+ var interval = (int)Math.Round ((double)(screen.Width + firstLineWidth + lastLineWidth) / linesFormatted.Count);
+
+ x = line == 0
+ ? screen.Left
+ : line < linesFormatted.Count - 1
+ ? screen.Width - runesWidth <= lastLineWidth ? screen.Left + prevLineWidth : screen.Left + line * interval
+ : screen.Right - lastLineWidth;
+ }
+ else
+ {
+ x = screen.Left;
+ }
+
+ CursorPosition = _hotKeyPos > -1 ? _hotKeyPos : 0;
+ }
+ else if (Alignment is TextAlignment.Centered)
{
if (isVertical)
{
- int runesWidth = GetWidestLineLength (linesFormatted, line, TabWidth);
- x = screen.Left + line + (screen.Width - runesWidth) / 2;
+ int runesWidth = GetColumnsRequiredForVerticalText (linesFormatted, 0, linesFormatted.Count, TabWidth);
+ int linesWidth = GetColumnsRequiredForVerticalText (linesFormatted, 0, line, TabWidth);
+ x = screen.Left + linesWidth + (screen.Width - runesWidth) / 2;
CursorPosition = (screen.Width - runesWidth) / 2 + (_hotKeyPos > -1 ? _hotKeyPos : 0);
}
@@ -354,7 +399,7 @@ public void Draw (
}
// Vertical Alignment
- if (VerticalAlignment == VerticalTextAlignment.Bottom || (VerticalAlignment == VerticalTextAlignment.Justified && !IsTopToBottom (Direction)))
+ if (VerticalAlignment is VerticalTextAlignment.Bottom)
{
if (isVertical)
{
@@ -365,7 +410,7 @@ public void Draw (
y = screen.Bottom - linesFormatted.Count + line;
}
}
- else if (VerticalAlignment is VerticalTextAlignment.Top or VerticalTextAlignment.Justified)
+ else if (VerticalAlignment is VerticalTextAlignment.Top)
{
if (isVertical)
{
@@ -376,7 +421,21 @@ public void Draw (
y = screen.Top + line;
}
}
- else if (VerticalAlignment == VerticalTextAlignment.Middle)
+ else if (VerticalAlignment is VerticalTextAlignment.Justified)
+ {
+ if (isVertical)
+ {
+ y = screen.Top;
+ }
+ else
+ {
+ var interval = (int)Math.Round ((double)(screen.Height + 2) / linesFormatted.Count);
+
+ y = line == 0 ? screen.Top :
+ line < linesFormatted.Count - 1 ? screen.Height - interval <= 1 ? screen.Top + 1 : screen.Top + line * interval : screen.Bottom - 1;
+ }
+ }
+ else if (VerticalAlignment is VerticalTextAlignment.Middle)
{
if (isVertical)
{
@@ -410,7 +469,10 @@ public void Draw (
if (lastZeroWidthPos is null)
{
- if (idx < 0 || x + current + colOffset < 0)
+ if (idx < 0
+ || (isVertical
+ ? VerticalAlignment != VerticalTextAlignment.Bottom && current < 0
+ : Alignment != TextAlignment.Right && x + current + colOffset < 0))
{
current++;
@@ -422,8 +484,8 @@ public void Draw (
break;
}
- if ((!isVertical && current - start > maxScreen.Left + maxScreen.Width - screen.X + colOffset)
- || (isVertical && idx > maxScreen.Top + maxScreen.Height - screen.Y))
+ if ((!isVertical && (current - start > maxScreen.Left + maxScreen.Width - screen.X + colOffset || (idx < runes.Length && runes [idx].GetColumns () > screen.Width)))
+ || (isVertical && ((current > start + size + zeroLengthCount && idx > maxScreen.Top + maxScreen.Height - screen.Y) || (idx < runes.Length && runes [idx].GetColumns () > screen.Width))))
{
break;
}
@@ -642,7 +704,8 @@ public List GetLines ()
PreserveTrailingSpaces,
TabWidth,
Direction,
- MultiLine
+ MultiLine,
+ this
);
if (!AutoSize)
@@ -665,7 +728,8 @@ public List GetLines ()
PreserveTrailingSpaces,
TabWidth,
Direction,
- MultiLine
+ MultiLine,
+ this
);
if (!AutoSize && _lines.Count > Size.Height)
@@ -700,48 +764,48 @@ private T EnableNeedsFormat (T value)
public static bool IsHorizontalDirection (TextDirection textDirection)
{
return textDirection switch
- {
- TextDirection.LeftRight_TopBottom => true,
- TextDirection.LeftRight_BottomTop => true,
- TextDirection.RightLeft_TopBottom => true,
- TextDirection.RightLeft_BottomTop => true,
- _ => false
- };
+ {
+ TextDirection.LeftRight_TopBottom => true,
+ TextDirection.LeftRight_BottomTop => true,
+ TextDirection.RightLeft_TopBottom => true,
+ TextDirection.RightLeft_BottomTop => true,
+ _ => false
+ };
}
/// Check if it is a vertical direction
public static bool IsVerticalDirection (TextDirection textDirection)
{
return textDirection switch
- {
- TextDirection.TopBottom_LeftRight => true,
- TextDirection.TopBottom_RightLeft => true,
- TextDirection.BottomTop_LeftRight => true,
- TextDirection.BottomTop_RightLeft => true,
- _ => false
- };
+ {
+ TextDirection.TopBottom_LeftRight => true,
+ TextDirection.TopBottom_RightLeft => true,
+ TextDirection.BottomTop_LeftRight => true,
+ TextDirection.BottomTop_RightLeft => true,
+ _ => false
+ };
}
/// Check if it is Left to Right direction
public static bool IsLeftToRight (TextDirection textDirection)
{
return textDirection switch
- {
- TextDirection.LeftRight_TopBottom => true,
- TextDirection.LeftRight_BottomTop => true,
- _ => false
- };
+ {
+ TextDirection.LeftRight_TopBottom => true,
+ TextDirection.LeftRight_BottomTop => true,
+ _ => false
+ };
}
/// Check if it is Top to Bottom direction
public static bool IsTopToBottom (TextDirection textDirection)
{
return textDirection switch
- {
- TextDirection.TopBottom_LeftRight => true,
- TextDirection.TopBottom_RightLeft => true,
- _ => false
- };
+ {
+ TextDirection.TopBottom_LeftRight => true,
+ TextDirection.TopBottom_RightLeft => true,
+ _ => false
+ };
}
// TODO: Move to StringExtensions?
@@ -932,6 +996,7 @@ public static string ClipOrPad (string text, int width)
///
/// The number of columns used for a tab.
/// The text direction.
+ /// instance to access any of his objects.
/// A list of word wrapped lines.
///
/// This method does not do any justification.
@@ -947,7 +1012,8 @@ public static List WordWrapText (
int width,
bool preserveTrailingSpaces = false,
int tabWidth = 0,
- TextDirection textDirection = TextDirection.LeftRight_TopBottom
+ TextDirection textDirection = TextDirection.LeftRight_TopBottom,
+ TextFormatter textFormatter = null
)
{
if (width < 0)
@@ -955,7 +1021,6 @@ public static List WordWrapText (
throw new ArgumentOutOfRangeException ($"{nameof (width)} cannot be negative.");
}
- int start = 0, end;
List lines = new ();
if (string.IsNullOrEmpty (text))
@@ -965,6 +1030,13 @@ public static List WordWrapText (
List runes = StripCRLF (text).ToRuneList ();
+ int start = Math.Max (
+ !runes.Contains ((Rune)' ') && textFormatter is { VerticalAlignment: VerticalTextAlignment.Bottom } && IsVerticalDirection (textDirection)
+ ? runes.Count - width
+ : 0,
+ 0);
+ int end;
+
if (preserveTrailingSpaces)
{
while ((end = start) < runes.Count)
@@ -997,7 +1069,8 @@ public static List WordWrapText (
+ GetLengthThatFits (
runes.GetRange (start, runes.Count - start),
width,
- tabWidth
+ tabWidth,
+ textDirection
))
< runes.Count)
{
@@ -1012,13 +1085,15 @@ public static List WordWrapText (
+ GetLengthThatFits (
runes.GetRange (end, runes.Count - end),
width,
- tabWidth
+ tabWidth,
+ textDirection
);
}
var str = StringExtensions.ToString (runes.GetRange (start, end - start));
+ int zeroLength = text.EnumerateRunes ().Sum (r => r.GetColumns () == 0 ? 1 : 0);
- if (end > start && GetRuneWidth (str, tabWidth) <= width)
+ if (end > start && GetRuneWidth (str, tabWidth, textDirection) <= width + zeroLength)
{
lines.Add (str);
start = end;
@@ -1122,21 +1197,21 @@ int GetNextWhiteSpace (int from, int cWidth, out bool incomplete, int cLength =
case ' ':
return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length);
case '\t':
- {
- length += tabWidth + 1;
-
- if (length == tabWidth && tabWidth > cWidth)
{
- return to + 1;
- }
+ length += tabWidth + 1;
- if (length > cWidth && tabWidth > cWidth)
- {
- return to;
- }
+ if (length == tabWidth && tabWidth > cWidth)
+ {
+ return to + 1;
+ }
- return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length);
- }
+ if (length > cWidth && tabWidth > cWidth)
+ {
+ return to;
+ }
+
+ return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length);
+ }
default:
to++;
@@ -1145,11 +1220,11 @@ int GetNextWhiteSpace (int from, int cWidth, out bool incomplete, int cLength =
}
return cLength switch
- {
- > 0 when to < runes.Count && runes [to].Value != ' ' && runes [to].Value != '\t' => from,
- > 0 when to < runes.Count && (runes [to].Value == ' ' || runes [to].Value == '\t') => from,
- _ => to
- };
+ {
+ > 0 when to < runes.Count && runes [to].Value != ' ' && runes [to].Value != '\t' => from,
+ > 0 when to < runes.Count && (runes [to].Value == ' ' || runes [to].Value == '\t') => from,
+ _ => to
+ };
}
if (start < text.GetRuneCount ())
@@ -1177,16 +1252,18 @@ int GetNextWhiteSpace (int from, int cWidth, out bool incomplete, int cLength =
/// Alignment.
/// The text direction.
/// The number of columns used for a tab.
+ /// instance to access any of his objects.
/// Justified and clipped text.
public static string ClipAndJustify (
string text,
int width,
TextAlignment talign,
TextDirection textDirection = TextDirection.LeftRight_TopBottom,
- int tabWidth = 0
+ int tabWidth = 0,
+ TextFormatter textFormatter = null
)
{
- return ClipAndJustify (text, width, talign == TextAlignment.Justified, textDirection, tabWidth);
+ return ClipAndJustify (text, width, talign == TextAlignment.Justified, textDirection, tabWidth, textFormatter);
}
/// Justifies text within a specified width.
@@ -1198,13 +1275,15 @@ public static string ClipAndJustify (
/// Justify.
/// The text direction.
/// The number of columns used for a tab.
+ /// instance to access any of his objects.
/// Justified and clipped text.
public static string ClipAndJustify (
string text,
int width,
bool justify,
TextDirection textDirection = TextDirection.LeftRight_TopBottom,
- int tabWidth = 0
+ int tabWidth = 0,
+ TextFormatter textFormatter = null
)
{
if (width < 0)
@@ -1219,20 +1298,39 @@ public static string ClipAndJustify (
text = ReplaceTABWithSpaces (text, tabWidth);
List runes = text.ToRuneList ();
+ int zeroLength = runes.Sum (r => r.GetColumns () == 0 ? 1 : 0);
- if (runes.Count > width)
+ if (runes.Count - zeroLength > width)
{
if (IsHorizontalDirection (textDirection))
{
- return StringExtensions.ToString (
- runes.GetRange (
- 0,
- GetLengthThatFits (text, width, tabWidth)
- )
- );
+ if (textFormatter is { Alignment: TextAlignment.Right })
+ {
+ return GetRangeThatFits (runes, runes.Count - width, text, width, tabWidth, textDirection);
+ }
+
+ if (textFormatter is { Alignment: TextAlignment.Centered })
+ {
+ return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
+ }
+
+ return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
}
- int zeroLength = runes.Sum (r => r.GetColumns () == 0 ? 1 : 0);
+ if (IsVerticalDirection (textDirection))
+ {
+ if (textFormatter is { VerticalAlignment: VerticalTextAlignment.Bottom })
+ {
+ return GetRangeThatFits (runes, runes.Count - width, text, width, tabWidth, textDirection);
+ }
+
+ if (textFormatter is { VerticalAlignment: VerticalTextAlignment.Middle })
+ {
+ return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
+ }
+
+ return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
+ }
return StringExtensions.ToString (runes.GetRange (0, width + zeroLength));
}
@@ -1242,19 +1340,57 @@ public static string ClipAndJustify (
return Justify (text, width, ' ', textDirection, tabWidth);
}
- if (IsHorizontalDirection (textDirection) && GetRuneWidth (text, tabWidth) > width)
+ if (IsHorizontalDirection (textDirection))
{
- return StringExtensions.ToString (
- runes.GetRange (
- 0,
- GetLengthThatFits (text, width, tabWidth)
- )
- );
+ if (textFormatter is { Alignment: TextAlignment.Right })
+ {
+ if (GetRuneWidth (text, tabWidth, textDirection) > width)
+ {
+ return GetRangeThatFits (runes, runes.Count - width, text, width, tabWidth, textDirection);
+ }
+ }
+ else if (textFormatter is { Alignment: TextAlignment.Centered })
+ {
+ return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
+ }
+ else if (GetRuneWidth (text, tabWidth, textDirection) > width)
+ {
+ return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
+ }
+ }
+
+ if (IsVerticalDirection (textDirection))
+ {
+ if (textFormatter is { VerticalAlignment: VerticalTextAlignment.Bottom })
+ {
+ if (runes.Count - zeroLength > width)
+ {
+ return GetRangeThatFits (runes, runes.Count - width, text, width, tabWidth, textDirection);
+ }
+ }
+ else if (textFormatter is { VerticalAlignment: VerticalTextAlignment.Middle })
+ {
+ return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
+ }
+ else if (runes.Count - zeroLength > width)
+ {
+ return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
+ }
}
return text;
}
+ private static string GetRangeThatFits (List runes, int index, string text, int width, int tabWidth, TextDirection textDirection)
+ {
+ return StringExtensions.ToString (
+ runes.GetRange (
+ Math.Max (index, 0),
+ GetLengthThatFits (text, width, tabWidth, textDirection)
+ )
+ );
+ }
+
///
/// Justifies the text to fill the width provided. Space will be added between words to make the text just fit
/// width. Spaces will not be added to the start or end.
@@ -1289,7 +1425,7 @@ public static string Justify (
if (IsHorizontalDirection (textDirection))
{
- textCount = words.Sum (arg => GetRuneWidth (arg, tabWidth));
+ textCount = words.Sum (arg => GetRuneWidth (arg, tabWidth, textDirection));
}
else
{
@@ -1352,6 +1488,7 @@ public static string Justify (
/// The number of columns used for a tab.
/// The text direction.
/// If new lines are allowed.
+ /// instance to access any of his objects.
/// A list of word wrapped lines.
///
/// An empty string will result in one empty line.
@@ -1366,7 +1503,8 @@ public static List Format (
bool preserveTrailingSpaces = false,
int tabWidth = 0,
TextDirection textDirection = TextDirection.LeftRight_TopBottom,
- bool multiLine = false
+ bool multiLine = false,
+ TextFormatter textFormatter = null
)
{
return Format (
@@ -1377,7 +1515,8 @@ public static List Format (
preserveTrailingSpaces,
tabWidth,
textDirection,
- multiLine
+ multiLine,
+ textFormatter
);
}
@@ -1397,6 +1536,7 @@ public static List Format (
/// The number of columns used for a tab.
/// The text direction.
/// If new lines are allowed.
+ /// instance to access any of his objects.
/// A list of word wrapped lines.
///
/// An empty string will result in one empty line.
@@ -1411,7 +1551,8 @@ public static List Format (
bool preserveTrailingSpaces = false,
int tabWidth = 0,
TextDirection textDirection = TextDirection.LeftRight_TopBottom,
- bool multiLine = false
+ bool multiLine = false,
+ TextFormatter textFormatter = null
)
{
if (width < 0)
@@ -1457,16 +1598,17 @@ public static List Format (
foreach (string line in lines)
{
- lineResult.Add (ClipAndJustify (line, width, justify, textDirection, tabWidth));
+
+ lineResult.Add (ClipAndJustify (PerformCorrectFormatDirection (textDirection, line), width, justify, textDirection, tabWidth, textFormatter));
}
- return lineResult;
+ return PerformCorrectFormatDirection (textDirection, lineResult);
}
text = ReplaceCRLFWithSpace (text);
- lineResult.Add (ClipAndJustify (text, width, justify, textDirection, tabWidth));
+ lineResult.Add (ClipAndJustify (PerformCorrectFormatDirection (textDirection, text), width, justify, textDirection, tabWidth, textFormatter));
- return lineResult;
+ return PerformCorrectFormatDirection (textDirection, lineResult);
}
List runes = StripCRLF (text, true).ToRuneList ();
@@ -1481,11 +1623,12 @@ public static List Format (
{
List wrappedLines =
WordWrapText (
- StringExtensions.ToString (runes.GetRange (lp, i - lp)),
+ StringExtensions.ToString (PerformCorrectFormatDirection (textDirection, runes.GetRange (lp, i - lp))),
width,
preserveTrailingSpaces,
tabWidth,
- textDirection
+ textDirection,
+ textFormatter
);
foreach (string line in wrappedLines)
@@ -1503,17 +1646,47 @@ public static List Format (
}
foreach (string line in WordWrapText (
- StringExtensions.ToString (runes.GetRange (lp, runeCount - lp)),
+ StringExtensions.ToString (PerformCorrectFormatDirection (textDirection, runes.GetRange (lp, runeCount - lp))),
width,
preserveTrailingSpaces,
tabWidth,
- textDirection
+ textDirection,
+ textFormatter
))
{
lineResult.Add (ClipAndJustify (line, width, justify, textDirection, tabWidth));
}
- return lineResult;
+ return PerformCorrectFormatDirection (textDirection, lineResult);
+ }
+
+ private static string PerformCorrectFormatDirection (TextDirection textDirection, string line)
+ {
+ return textDirection switch
+ {
+ TextDirection.RightLeft_BottomTop
+ or TextDirection.RightLeft_TopBottom
+ or TextDirection.BottomTop_LeftRight
+ or TextDirection.BottomTop_RightLeft => StringExtensions.ToString (line.EnumerateRunes ().Reverse ()),
+ _ => line
+ };
+ }
+
+ private static List PerformCorrectFormatDirection (TextDirection textDirection, List runes)
+ {
+ return PerformCorrectFormatDirection (textDirection, StringExtensions.ToString (runes)).ToRuneList ();
+ }
+
+ private static List PerformCorrectFormatDirection (TextDirection textDirection, List lines)
+ {
+ return textDirection switch
+ {
+ TextDirection.TopBottom_RightLeft
+ or TextDirection.LeftRight_BottomTop
+ or TextDirection.RightLeft_BottomTop
+ or TextDirection.BottomTop_RightLeft => lines.ToArray ().Reverse ().ToList (),
+ _ => lines
+ };
}
/// Returns the number of lines needed to render the specified text given the width.
@@ -1529,35 +1702,36 @@ public static int GetLineCount (string text, int width)
}
///
- /// Returns the maximum number of columns needed to render the text (single line or multiple lines, word wrapped)
- /// given a number of columns to constrain the text to.
+ /// Returns the number of columns required to render oriented vertically.
///
///
- /// Calls . This API will return incorrect results if the text includes glyphs who's width
- /// is dependent on surrounding glyphs (e.g. Arabic).
+ /// This API will return incorrect results if the text includes glyphs whose width is dependent on surrounding
+ /// glyphs (e.g. Arabic).
///
- /// Width of the longest line after formatting the text constrained by .
- /// Text, may contain newlines.
- /// The number of columns to constrain the text to for formatting.
+ /// The lines.
+ /// The line in the list to start with (any lines before will be ignored).
+ /// The number of lines to process (if less than lines.Count, any lines after will be ignored).
/// The number of columns used for a tab.
- public static int GetWidestLineLength (string text, int maxColumns, int tabWidth = 0)
+ /// The width required.
+ public static int GetColumnsRequiredForVerticalText (
+ List lines,
+ int startLine = -1,
+ int linesCount = -1,
+ int tabWidth = 0
+ )
{
- List result = Format (text, maxColumns, false, true);
var max = 0;
- result.ForEach (
- s =>
- {
- var m = 0;
- s.ToRuneList ().ForEach (r => m += GetRuneWidth (r, tabWidth));
-
- if (m > max)
- {
- max = m;
- }
- }
- );
-
+ for (int i = startLine == -1 ? 0 : startLine;
+ i < (linesCount == -1 ? lines.Count : startLine + linesCount);
+ i++)
+ {
+ string runes = lines [i];
+ if (runes.Length > 0)
+ {
+ max += runes.EnumerateRunes ().Max (r => GetRuneWidth (r, tabWidth));
+ }
+ }
return max;
}
@@ -1579,43 +1753,6 @@ public static int GetWidestLineLength (string text, int tabWidth = 0)
return result.Max (x => GetRuneWidth (x, tabWidth));
}
- ///
- /// Returns the number of columns in the widest line in the list based on the and
- /// the .
- ///
- ///
- /// This API will return incorrect results if the text includes glyphs who's width is dependent on surrounding
- /// glyphs (e.g. Arabic).
- ///
- /// The lines.
- /// The start index.
- /// The length.
- /// The number of columns used for a tab.
- /// The maximum characters width.
- public static int GetWidestLineLength (
- List lines,
- int startIndex = -1,
- int length = -1,
- int tabWidth = 0
- )
- {
- var max = 0;
-
- for (int i = startIndex == -1 ? 0 : startIndex;
- i < (length == -1 ? lines.Count : startIndex + length);
- i++)
- {
- string runes = lines [i];
-
- if (runes.Length > 0)
- {
- max += runes.EnumerateRunes ().Max (r => GetRuneWidth (r, tabWidth));
- }
- }
-
- return max;
- }
-
///
/// Gets the maximum number of columns from the text based on the and the
/// .
@@ -1644,27 +1781,32 @@ public static int GetSumMaxCharWidth (string text, int startIndex = -1, int leng
return max;
}
- /// Gets the number of the Runes in the text that will fit in .
+ /// Gets the number of the Runes in the text that will fit in .
///
/// This API will return incorrect results if the text includes glyphs who's width is dependent on surrounding
/// glyphs (e.g. Arabic).
///
/// The text.
- /// The width.
- /// The number of columns used for a tab.
+ /// The width.
+ /// The width used for a tab.
+ /// The text direction.
/// The index of the text that fit the width.
- public static int GetLengthThatFits (string text, int columns, int tabWidth = 0) { return GetLengthThatFits (text?.ToRuneList (), columns, tabWidth); }
+ public static int GetLengthThatFits (string text, int width, int tabWidth = 0, TextDirection textDirection = TextDirection.LeftRight_TopBottom)
+ {
+ return GetLengthThatFits (text?.ToRuneList (), width, tabWidth, textDirection);
+ }
- /// Gets the number of the Runes in a list of Runes that will fit in .
+ /// Gets the number of the Runes in a list of Runes that will fit in .
///
/// This API will return incorrect results if the text includes glyphs who's width is dependent on surrounding
/// glyphs (e.g. Arabic).
///
/// The list of runes.
- /// The width.
- /// The number of columns used for a tab.
- /// The index of the last Rune in that fit in .
- public static int GetLengthThatFits (List runes, int columns, int tabWidth = 0)
+ /// The width.
+ /// The width used for a tab.
+ /// The text direction.
+ /// The index of the last Rune in that fit in .
+ public static int GetLengthThatFits (List runes, int width, int tabWidth = 0, TextDirection textDirection = TextDirection.LeftRight_TopBottom)
{
if (runes is null || runes.Count == 0)
{
@@ -1676,9 +1818,9 @@ public static int GetLengthThatFits (List runes, int columns, int tabWidth
for (; runeIdx < runes.Count; runeIdx++)
{
- int runeWidth = GetRuneWidth (runes [runeIdx], tabWidth);
+ int runeWidth = GetRuneWidth (runes [runeIdx], tabWidth, textDirection);
- if (runesLength + runeWidth > columns)
+ if (runesLength + runeWidth > width)
{
break;
}
@@ -1689,12 +1831,12 @@ public static int GetLengthThatFits (List runes, int columns, int tabWidth
return runeIdx;
}
- private static int GetRuneWidth (string str, int tabWidth) { return GetRuneWidth (str.EnumerateRunes ().ToList (), tabWidth); }
- private static int GetRuneWidth (List runes, int tabWidth) { return runes.Sum (r => GetRuneWidth (r, tabWidth)); }
+ private static int GetRuneWidth (string str, int tabWidth, TextDirection textDirection = TextDirection.LeftRight_TopBottom) { return GetRuneWidth (str.EnumerateRunes ().ToList (), tabWidth, textDirection); }
+ private static int GetRuneWidth (List runes, int tabWidth, TextDirection textDirection = TextDirection.LeftRight_TopBottom) { return runes.Sum (r => GetRuneWidth (r, tabWidth, textDirection)); }
- private static int GetRuneWidth (Rune rune, int tabWidth)
+ private static int GetRuneWidth (Rune rune, int tabWidth, TextDirection textDirection = TextDirection.LeftRight_TopBottom)
{
- int runeWidth = rune.GetColumns ();
+ int runeWidth = IsHorizontalDirection (textDirection) ? rune.GetColumns () : 1;
if (rune.Value == '\t')
{
@@ -2040,4 +2182,4 @@ public static string RemoveHotKeySpecifier (string text, int hotPos, Rune hotKey
}
#endregion // Static Members
-}
+}
\ No newline at end of file
diff --git a/Terminal.Gui/View/Layout/PosDim.cs b/Terminal.Gui/View/Layout/PosDim.cs
index 8a171f8c7f..2bd0cb0add 100644
--- a/Terminal.Gui/View/Layout/PosDim.cs
+++ b/Terminal.Gui/View/Layout/PosDim.cs
@@ -1,4 +1,4 @@
-using static Terminal.Gui.Dialog;
+using System.Diagnostics;
namespace Terminal.Gui;
@@ -339,14 +339,27 @@ public static Pos Percent (float percent)
/// height for y-coordinate calculation.
///
/// The dimension of the View. It could be the current width or height.
- /// Obsolete; to be deprecated.
- /// Obsolete; to be deprecated.
+ /// The View that holds this Pos object.
+ /// Width or Height
///
/// The calculated position of the View. The way this position is calculated depends on the specific subclass of Pos
/// that
/// is used.
///
- internal virtual int Calculate (int superviewDimension, Dim dim, int autosize, bool autoSize) { return Anchor (superviewDimension); }
+ internal virtual int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension)
+ {
+ return Anchor (superviewDimension);
+ }
+
+
+ ///
+ /// Diagnostics API to determine if this Pos object references other views.
+ ///
+ ///
+ internal virtual bool ReferencesOtherViews ()
+ {
+ return false;
+ }
internal class PosAbsolute (int n) : Pos
{
@@ -382,7 +395,7 @@ internal override int Anchor (int width)
return width - _offset;
}
- internal override int Calculate (int superviewDimension, Dim dim, int autosize, bool autoSize)
+ internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension)
{
int newLocation = Anchor (superviewDimension);
@@ -400,9 +413,9 @@ internal class PosCenter : Pos
public override string ToString () { return "Center"; }
internal override int Anchor (int width) { return width / 2; }
- internal override int Calculate (int superviewDimension, Dim dim, int autosize, bool autoSize)
+ internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension)
{
- int newDimension = Math.Max (dim.Calculate (0, superviewDimension, autosize, autoSize), 0);
+ int newDimension = Math.Max (dim.Calculate (0, superviewDimension, us, dimension), 0);
return Anchor (superviewDimension - newDimension);
}
@@ -428,11 +441,11 @@ internal override int Anchor (int width)
return la - ra;
}
- internal override int Calculate (int superviewDimension, Dim dim, int autosize, bool autoSize)
+ internal override int Calculate (int superviewDimension, Dim dim, View us, Dim.Dimension dimension)
{
- int newDimension = dim.Calculate (0, superviewDimension, autosize, autoSize);
- int left = _left.Calculate (superviewDimension, dim, autosize, autoSize);
- int right = _right.Calculate (superviewDimension, dim, autosize, autoSize);
+ int newDimension = dim.Calculate (0, superviewDimension, us, dimension);
+ int left = _left.Calculate (superviewDimension, dim, us, dimension);
+ int right = _right.Calculate (superviewDimension, dim, us, dimension);
if (_add)
{
@@ -441,6 +454,25 @@ internal override int Calculate (int superviewDimension, Dim dim, int autosize,
return left - right;
}
+
+ ///
+ /// Diagnostics API to determine if this Pos object references other views.
+ ///
+ ///
+ internal override bool ReferencesOtherViews ()
+ {
+ if (_left.ReferencesOtherViews ())
+ {
+ return true;
+ }
+
+ if (_right.ReferencesOtherViews ())
+ {
+ return true;
+ }
+
+ return false;
+ }
}
internal class PosFactor (float factor) : Pos
@@ -525,6 +557,15 @@ internal override int Anchor (int width)
_ => 0
};
}
+
+ ///
+ /// Diagnostics API to determine if this Pos object references other views.
+ ///
+ ///
+ internal override bool ReferencesOtherViews ()
+ {
+ return true;
+ }
}
}
@@ -548,6 +589,15 @@ internal override int Anchor (int width)
///
/// -
///
+///
+///
+///
+/// Creates a object that automatically sizes the view to fit
+/// the view's Text, SubViews, or ContentArea.
+///
+///
+/// -
+///
///
///
///
@@ -597,6 +647,104 @@ internal override int Anchor (int width)
///
public class Dim
{
+ ///
+ /// Specifies how will compute the dimension.
+ ///
+ [Flags]
+ public enum DimAutoStyle
+ {
+ ///
+ /// The dimension will be computed using both the view's and
+ /// (whichever is larger).
+ ///
+ Auto = Content | Text,
+
+ ///
+ /// The dimensions will be computed based on the View's non-Text content.
+ ///
+ /// If is explicitly set (is not ) then
+ /// will be used to determine the dimension.
+ ///
+ ///
+ /// Otherwise, the Subview in with the largest corresponding position plus dimension
+ /// will determine the dimension.
+ ///
+ ///
+ /// The corresponding dimension of the view's will be ignored.
+ ///
+ ///
+ Content = 1,
+
+ ///
+ ///
+ /// The corresponding dimension of the view's , formatted using the
+ /// settings,
+ /// will be used to determine the dimension.
+ ///
+ ///
+ /// The corresponding dimensions of the will be ignored.
+ ///
+ ///
+ Text = 2
+ }
+
+
+ ///
+ ///
+ ///
+ public enum Dimension
+ {
+ ///
+ /// No dimension specified.
+ ///
+ None = 0,
+
+ ///
+ /// The height dimension.
+ ///
+ Height = 1,
+
+ ///
+ /// The width dimension.
+ ///
+ Width = 2
+ }
+
+
+ ///
+ /// Creates a object that automatically sizes the view to fit all the view's SubViews and/or Text.
+ ///
+ ///
+ ///
+ /// See .
+ ///
+ ///
+ ///
+ /// This initializes a with two SubViews. The view will be automatically sized to fit the two
+ /// SubViews.
+ ///
+ /// var button = new Button () { Text = "Click Me!", X = 1, Y = 1, Width = 10, Height = 1 };
+ /// var textField = new TextField { Text = "Type here", X = 1, Y = 2, Width = 20, Height = 1 };
+ /// var view = new Window () { Title = "MyWindow", X = 0, Y = 0, Width = Dim.Auto (), Height = Dim.Auto () };
+ /// view.Add (button, textField);
+ ///
+ ///
+ /// The object.
+ ///
+ /// Specifies how will compute the dimension. The default is .
+ ///
+ /// Specifies the minimum dimension that view will be automatically sized to.
+ /// Specifies the maximum dimension that view will be automatically sized to. NOT CURRENTLY SUPPORTED.
+ public static Dim Auto (DimAutoStyle style = DimAutoStyle.Auto, Dim min = null, Dim max = null)
+ {
+ if (max != null)
+ {
+ throw new NotImplementedException (@"max is not implemented");
+ }
+
+ return new DimAuto (style, min, max);
+ }
+
/// Determines whether the specified object is equal to the current object.
/// The object to compare with the current object.
///
@@ -727,24 +875,31 @@ public static Dim Percent (float percent, bool usePosition = false)
///
/// Calculates and returns the dimension of a object. It takes into account the location of the
- /// , its current size, and whether it should automatically adjust its size based on its content.
+ /// , it's SuperView's ContentSize, and whether it should automatically adjust its size based on its content.
///
///
/// The starting point from where the size calculation begins. It could be the left edge for width calculation or the
/// top edge for height calculation.
///
- /// The current size of the View. It could be the current width or height.
- /// Obsolete; To be deprecated.
- /// Obsolete; To be deprecated.
+ /// The size of the SuperView's content. It could be width or height.
+ /// The View that holds this Pos object.
+ /// Width or Height
///
/// The calculated size of the View. The way this size is calculated depends on the specific subclass of Dim that
/// is used.
///
- internal virtual int Calculate (int location, int dimension, int autosize, bool autoSize)
+ internal virtual int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
{
- int newDimension = Math.Max (Anchor (dimension - location), 0);
+ return Math.Max (Anchor (superviewContentSize - location), 0);
+ }
- return autoSize && autosize > newDimension ? autosize : newDimension;
+ ///
+ /// Diagnostics API to determine if this Dim object references other views.
+ ///
+ ///
+ internal virtual bool ReferencesOtherViews ()
+ {
+ return false;
}
internal class DimAbsolute (int n) : Dim
@@ -755,15 +910,129 @@ internal class DimAbsolute (int n) : Dim
public override string ToString () { return $"Absolute({_n})"; }
internal override int Anchor (int width) { return _n; }
- internal override int Calculate (int location, int dimension, int autosize, bool autoSize)
+ internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
{
// DimAbsolute.Anchor (int width) ignores width and returns n
- int newDimension = Math.Max (Anchor (0), 0);
-
- return autoSize && autosize > newDimension ? autosize : newDimension;
+ return Math.Max (Anchor (0), 0);
}
}
+ ///
+ /// A object that automatically sizes the view to fit all the view's SubViews and/or Text.
+ ///
+ ///
+ ///
+ /// See .
+ ///
+ ///
+ ///
+ /// Specifies how will compute the dimension. The default is .
+ ///
+ /// Specifies the minimum dimension that view will be automatically sized to.
+ /// Specifies the maximum dimension that view will be automatically sized to. NOT CURRENTLY SUPPORTED.
+ public class DimAuto (DimAutoStyle style, Dim min, Dim max) : Dim
+ {
+ internal readonly Dim _max = max;
+ internal readonly Dim _min = min;
+ internal readonly DimAutoStyle _style = style;
+ internal int _size;
+
+ ///
+ public override bool Equals (object other) { return other is DimAuto auto && auto._min == _min && auto._max == _max && auto._style == _style; }
+ ///
+ public override int GetHashCode () { return HashCode.Combine (base.GetHashCode (), _min, _max, _style); }
+ ///
+ public override string ToString () { return $"Auto({_style},{_min},{_max})"; }
+
+ internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
+ {
+ if (us == null)
+ {
+ return _max?.Anchor (0) ?? 0;
+ }
+
+ var textSize = 0;
+ var subviewsSize = 0;
+
+ int autoMin = _min?.Anchor (superviewContentSize) ?? 0;
+
+ if (superviewContentSize < autoMin)
+ {
+ Debug.WriteLine ($"WARNING: DimAuto specifies a min size ({autoMin}), but the SuperView's bounds are smaller ({superviewContentSize}).");
+
+ return superviewContentSize;
+ }
+
+ if (_style.HasFlag (Dim.DimAutoStyle.Text))
+ {
+ textSize = int.Max (autoMin, dimension == Dimension.Width ? us.TextFormatter.Size.Width : us.TextFormatter.Size.Height);
+ }
+
+ if (_style.HasFlag (DimAutoStyle.Content))
+ {
+ if (us._contentSize is { })
+ {
+ subviewsSize = dimension == Dimension.Width ? us.ContentSize!.Value.Width : us.ContentSize!.Value.Height;
+ }
+ else
+ {
+ // TODO: AnchorEnd needs work
+ // TODO: If _min > 0 we can SetRelativeLayout for the subviews?
+ subviewsSize = 0;
+ if (us.Subviews.Count > 0)
+ {
+ for (int i = 0; i < us.Subviews.Count; i++)
+ {
+ var v = us.Subviews [i];
+ bool isNotPosAnchorEnd = dimension == Dim.Dimension.Width ? v.X is not Pos.PosAnchorEnd : v.Y is not Pos.PosAnchorEnd;
+
+ //if (!isNotPosAnchorEnd)
+ //{
+ // v.SetRelativeLayout(dimension == Dim.Dimension.Width ? (new Size (autoMin, 0)) : new Size (0, autoMin));
+ //}
+
+ if (isNotPosAnchorEnd)
+ {
+ int size = dimension == Dim.Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
+ if (size > subviewsSize)
+ {
+ subviewsSize = size;
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ int max = int.Max (textSize, subviewsSize);
+
+ Thickness thickness = us.GetAdornmentsThickness ();
+
+ if (dimension == Dimension.Width)
+ {
+ max += thickness.Horizontal;
+ }
+ else
+ {
+ max += thickness.Vertical;
+ }
+
+ max = int.Max (max, autoMin);
+ return int.Min (max, _max?.Anchor (superviewContentSize) ?? superviewContentSize);
+ }
+
+ ///
+ /// Diagnostics API to determine if this Dim object references other views.
+ ///
+ ///
+ internal override bool ReferencesOtherViews ()
+ {
+ // BUGBUG: This is not correct. _contentSize may be null.
+ return _style.HasFlag (Dim.DimAutoStyle.Content);
+ }
+
+ }
internal class DimCombine (bool add, Dim left, Dim right) : Dim
{
internal bool _add = add;
@@ -784,10 +1053,10 @@ internal override int Anchor (int width)
return la - ra;
}
- internal override int Calculate (int location, int dimension, int autosize, bool autoSize)
+ internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
{
- int leftNewDim = _left.Calculate (location, dimension, autosize, autoSize);
- int rightNewDim = _right.Calculate (location, dimension, autosize, autoSize);
+ int leftNewDim = _left.Calculate (location, superviewContentSize, us, dimension);
+ int rightNewDim = _right.Calculate (location, superviewContentSize, us, dimension);
int newDimension;
@@ -800,7 +1069,27 @@ internal override int Calculate (int location, int dimension, int autosize, bool
newDimension = Math.Max (0, leftNewDim - rightNewDim);
}
- return autoSize && autosize > newDimension ? autosize : newDimension;
+ return newDimension;
+ }
+
+
+ ///
+ /// Diagnostics API to determine if this Dim object references other views.
+ ///
+ ///
+ internal override bool ReferencesOtherViews ()
+ {
+ if (_left.ReferencesOtherViews ())
+ {
+ return true;
+ }
+
+ if (_right.ReferencesOtherViews ())
+ {
+ return true;
+ }
+
+ return false;
}
}
@@ -815,11 +1104,9 @@ internal class DimFactor (float factor, bool remaining = false) : Dim
public override string ToString () { return $"Factor({_factor},{_remaining})"; }
internal override int Anchor (int width) { return (int)(width * _factor); }
- internal override int Calculate (int location, int dimension, int autosize, bool autoSize)
+ internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
{
- int newDimension = _remaining ? Math.Max (Anchor (dimension - location), 0) : Anchor (dimension);
-
- return autoSize && autosize > newDimension ? autosize : newDimension;
+ return _remaining ? Math.Max (Anchor (superviewContentSize - location), 0) : Anchor (superviewContentSize);
}
}
@@ -842,22 +1129,6 @@ internal class DimFunc (Func n) : Dim
internal override int Anchor (int width) { return _function (); }
}
- ///
- ///
- ///
- public enum Dimension
- {
- ///
- /// The height dimension.
- ///
- Height = 0,
-
- ///
- /// The width dimension.
- ///
- Width = 1
- }
-
internal class DimView : Dim
{
private readonly Dimension _side;
@@ -898,5 +1169,10 @@ internal override int Anchor (int width)
_ => 0
};
}
+
+ internal override bool ReferencesOtherViews ()
+ {
+ return true;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/Terminal.Gui/View/Layout/SizeChangedEventArgs.cs b/Terminal.Gui/View/Layout/SizeChangedEventArgs.cs
index 6ceeb08917..4e2f202970 100644
--- a/Terminal.Gui/View/Layout/SizeChangedEventArgs.cs
+++ b/Terminal.Gui/View/Layout/SizeChangedEventArgs.cs
@@ -5,11 +5,11 @@ public class SizeChangedEventArgs : EventArgs
{
/// Creates a new instance of the class.
///
- public SizeChangedEventArgs (Size size) { Size = size; }
+ public SizeChangedEventArgs (Size? size) { Size = size; }
/// Set to to cause the resize to be cancelled, if appropriate.
public bool Cancel { get; set; }
/// Gets the size the event describes. This should reflect the new/current size after the event resolved.
- public Size Size { get; }
+ public Size? Size { get; }
}
diff --git a/Terminal.Gui/View/Layout/ViewLayout.cs b/Terminal.Gui/View/Layout/ViewLayout.cs
index 1afa0994bf..4178e63ef6 100644
--- a/Terminal.Gui/View/Layout/ViewLayout.cs
+++ b/Terminal.Gui/View/Layout/ViewLayout.cs
@@ -26,9 +26,12 @@ public enum LayoutStyle
///
/// Indicates one or more of the , , , or
- /// objects are relative to the and are computed at layout time.
- /// The position and size of the view will be computed based on these objects at layout time.
- /// will provide the absolute computed values.
+ ///
+ /// objects are relative to the and are computed at layout time. The position and size of
+ /// the
+ /// view
+ /// will be computed based on these objects at layout time. will provide the absolute computed
+ /// values.
///
Computed
}
@@ -88,16 +91,23 @@ public Rectangle Frame
private void SetFrame (Rectangle frame)
{
var oldViewport = Rectangle.Empty;
+ Size? oldContentSize = null;
if (IsInitialized)
{
oldViewport = Viewport;
+ oldContentSize = ContentSize;
}
// This is the only place where _frame should be set directly. Use Frame = or SetFrame instead.
_frame = frame;
OnViewportChanged (new (IsInitialized ? Viewport : Rectangle.Empty, oldViewport));
+
+ if (!TextFormatter.AutoSize)
+ {
+ TextFormatter.Size = ContentSize.GetValueOrDefault ();
+ }
}
/// Gets the with a screen-relative location.
@@ -271,26 +281,14 @@ public Dim Height
return;
}
- _height = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Height)} cannot be null");
-
- if (AutoSize)
+ if (_height is Dim.DimAuto)
{
- Debug.WriteLine (@$"Must set AutoSize to false before setting {nameof (Height)}.");
- AutoSize = false;
+ // Reset ContentSize to Viewport
+ _contentSize = null;
}
- //if (ValidatePosDim) {
- bool isValidNewAutoSize = AutoSize && IsValidAutoSizeHeight (_height);
-
- if (IsAdded && AutoSize && !isValidNewAutoSize)
- {
- Debug.WriteLine (
- @$"Must set AutoSize to false before setting the {nameof (Height)}."
- );
- AutoSize = false;
- }
+ _height = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Height)} cannot be null");
- //}
OnResizeNeeded ();
}
}
@@ -329,21 +327,13 @@ public Dim Width
return;
}
- _width = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Width)} cannot be null");
-
- if (AutoSize)
+ if (_width is Dim.DimAuto)
{
- Debug.WriteLine ($@"Must set AutoSize to false before setting {nameof (Width)}.");
- AutoSize = false;
+ // Reset ContentSize to Viewport
+ _contentSize = null;
}
- bool isValidNewAutoSize = AutoSize && IsValidAutoSizeWidth (_width);
-
- if (IsAdded && AutoSize && !isValidNewAutoSize)
- {
- Debug.WriteLine ($@"Must set AutoSize to false before setting {nameof (Width)}.");
- AutoSize = false;
- }
+ _width = value ?? throw new ArgumentNullException (nameof (value), @$"{nameof (Width)} cannot be null");
OnResizeNeeded ();
}
@@ -351,219 +341,19 @@ public Dim Width
#endregion Frame
- #region AutoSize
-
- private bool _autoSize;
-
- ///
- /// Gets or sets a flag that determines whether the View will be automatically resized to fit the
- /// within .
- ///
- /// The default is . Set to to turn on AutoSize. If
- /// then and will be used if can
- /// fit; if won't fit the view will be resized as needed.
- ///
- ///
- /// If is set to then and
- /// will be changed to if they are not already.
- ///
- ///
- /// If is set to then and
- /// will left unchanged.
- ///
- ///
- public virtual bool AutoSize
- {
- get => _autoSize;
- set
- {
- if (Width != Dim.Sized (0) && Height != Dim.Sized (0))
- {
- Debug.WriteLine (
- $@"WARNING: {GetType ().Name} - Setting {nameof (AutoSize)} invalidates {nameof (Width)} and {nameof (Height)}."
- );
- }
-
- bool v = ResizeView (value);
- TextFormatter.AutoSize = v;
-
- if (_autoSize != v)
- {
- _autoSize = v;
- TextFormatter.NeedsFormat = true;
- UpdateTextFormatterText ();
- OnResizeNeeded ();
- }
- }
- }
-
- /// If is true, resizes the view.
- ///
- ///
- private bool ResizeView (bool autoSize)
- {
- if (!autoSize)
- {
- return false;
- }
-
- var boundsChanged = true;
- Size newFrameSize = GetAutoSize ();
-
- if (IsInitialized && newFrameSize != Frame.Size)
- {
- if (ValidatePosDim)
- {
- // BUGBUG: This ain't right, obviously. We need to figure out how to handle this.
- boundsChanged = ResizeViewportToFit (newFrameSize);
- }
- else
- {
- Height = newFrameSize.Height;
- Width = newFrameSize.Width;
- }
- }
-
- return boundsChanged;
- }
-
- /// Determines if the View's can be set to a new value.
- /// TrySetHeight can only be called when AutoSize is true (or being set to true).
- ///
- ///
- /// Contains the width that would result if were set to
- /// "/>
- ///
- ///
- /// if the View's can be changed to the specified value. False
- /// otherwise.
- ///
- internal bool TrySetHeight (int desiredHeight, out int resultHeight)
- {
- int h = desiredHeight;
- bool canSetHeight;
-
- switch (Height)
- {
- case Dim.DimCombine _:
- case Dim.DimView _:
- case Dim.DimFill _:
- // It's a Dim.DimCombine and so can't be assigned. Let it have it's height anchored.
- h = Height.Anchor (h);
- canSetHeight = !ValidatePosDim;
-
- break;
- case Dim.DimFactor factor:
- // Tries to get the SuperView height otherwise the view height.
- int sh = SuperView is { } ? SuperView.Frame.Height : h;
-
- if (factor.IsFromRemaining ())
- {
- sh -= Frame.Y;
- }
-
- h = Height.Anchor (sh);
- canSetHeight = !ValidatePosDim;
-
- break;
- default:
- canSetHeight = true;
-
- break;
- }
-
- resultHeight = h;
-
- return canSetHeight;
- }
-
- /// Determines if the View's can be set to a new value.
- /// TrySetWidth can only be called when AutoSize is true (or being set to true).
- ///
- ///
- /// Contains the width that would result if were set to
- /// "/>
- ///
- ///
- /// if the View's can be changed to the specified value. False
- /// otherwise.
- ///
- internal bool TrySetWidth (int desiredWidth, out int resultWidth)
- {
- int w = desiredWidth;
- bool canSetWidth;
-
- switch (Width)
- {
- case Dim.DimCombine _:
- case Dim.DimView _:
- case Dim.DimFill _:
- // It's a Dim.DimCombine and so can't be assigned. Let it have it's Width anchored.
- w = Width.Anchor (w);
- canSetWidth = !ValidatePosDim;
-
- break;
- case Dim.DimFactor factor:
- // Tries to get the SuperView Width otherwise the view Width.
- int sw = SuperView is { } ? SuperView.Frame.Width : w;
-
- if (factor.IsFromRemaining ())
- {
- sw -= Frame.X;
- }
-
- w = Width.Anchor (sw);
- canSetWidth = !ValidatePosDim;
-
- break;
- default:
- canSetWidth = true;
-
- break;
- }
-
- resultWidth = w;
-
- return canSetWidth;
- }
-
- /// Resizes the View to fit the specified size. Factors in the HotKey.
- /// ResizeBoundsToFit can only be called when AutoSize is true (or being set to true).
- ///
- /// whether the Viewport was changed or not
- private bool ResizeViewportToFit (Size size)
- {
- //if (AutoSize == false) {
- // throw new InvalidOperationException ("ResizeViewportToFit can only be called when AutoSize is true");
- //}
-
- var changed = false;
- bool canSizeW = TrySetWidth (size.Width - GetHotKeySpecifierLength (), out int rW);
- bool canSizeH = TrySetHeight (size.Height - GetHotKeySpecifierLength (false), out int rH);
-
- if (canSizeW)
- {
- changed = true;
- _width = rW;
- }
-
- if (canSizeH)
- {
- changed = true;
- _height = rH;
- }
+ #region Layout Engine
- if (changed)
- {
- Viewport = new (Viewport.X, Viewport.Y, canSizeW ? rW : Viewport.Width, canSizeH ? rH : Viewport.Height);
- }
- return changed;
- }
+ // @tig Notes on layout flow. Ignore for now.
+ // BeginLayout
+ // If !LayoutNeeded return
+ // If !SizeNeeded return
+ // Call OnLayoutStarted
+ // Views and subviews can update things
+ //
- #endregion AutoSize
- #region Layout Engine
+ // EndLayout
///
/// Controls how the View's is computed during . If the style is
@@ -733,7 +523,7 @@ out StatusBar statusBar
superView = viewToMove.SuperView;
}
- if (superView.Margin is { } && superView == viewToMove.SuperView)
+ if (superView?.Margin is { } && superView == viewToMove.SuperView)
{
maxDimension -= superView.GetAdornmentsThickness ().Left + superView.GetAdornmentsThickness ().Right;
}
@@ -759,7 +549,7 @@ out StatusBar statusBar
if (viewToMove?.SuperView is null || viewToMove == Application.Top || viewToMove?.SuperView == Application.Top)
{
- menuVisible = Application.Top.MenuBar?.Visible == true;
+ menuVisible = Application.Top?.MenuBar?.Visible == true;
}
else
{
@@ -789,8 +579,8 @@ out StatusBar statusBar
if (viewToMove?.SuperView is null || viewToMove == Application.Top || viewToMove?.SuperView == Application.Top)
{
- statusVisible = Application.Top.StatusBar?.Visible == true;
- statusBar = Application.Top.StatusBar;
+ statusVisible = Application.Top?.StatusBar?.Visible == true;
+ statusBar = Application.Top?.StatusBar;
}
else
{
@@ -817,14 +607,14 @@ out StatusBar statusBar
maxDimension = statusVisible ? viewToMove.SuperView.Viewport.Height - 1 : viewToMove.SuperView.Viewport.Height;
}
- if (superView.Margin is { } && superView == viewToMove.SuperView)
+ if (superView?.Margin is { } && superView == viewToMove?.SuperView)
{
maxDimension -= superView.GetAdornmentsThickness ().Top + superView.GetAdornmentsThickness ().Bottom;
}
ny = Math.Min (ny, maxDimension);
- if (viewToMove.Frame.Height <= maxDimension)
+ if (viewToMove?.Frame.Height <= maxDimension)
{
ny = ny + viewToMove.Frame.Height > maxDimension
? Math.Max (maxDimension - viewToMove.Frame.Height, menuVisible ? 1 : 0)
@@ -856,8 +646,8 @@ out StatusBar statusBar
public event EventHandler LayoutStarted;
///
- /// Invoked when a view starts executing or when the dimensions of the view have changed, for example in response
- /// to the container view or terminal resizing.
+ /// Invoked when a view starts executing or when the dimensions of the view have changed, for example in response to
+ /// the container view or terminal resizing.
///
///
///
@@ -870,9 +660,7 @@ public virtual void LayoutSubviews ()
{
if (!IsInitialized)
{
- Debug.WriteLine (
- $"WARNING: LayoutSubviews called before view has been initialized. This is likely a bug in {this}"
- );
+ Debug.WriteLine ($"WARNING: LayoutSubviews called before view has been initialized. This is likely a bug in {this}");
}
if (!LayoutNeeded)
@@ -880,9 +668,11 @@ public virtual void LayoutSubviews ()
return;
}
+ CheckDimAuto ();
+
LayoutAdornments ();
- OnLayoutStarted (new (ContentSize));
+ OnLayoutStarted (new (ContentSize.GetValueOrDefault ()));
SetTextFormatterSize ();
@@ -894,26 +684,27 @@ public virtual void LayoutSubviews ()
foreach (View v in ordered)
{
- LayoutSubview (v, ContentSize);
+ LayoutSubview (v, Viewport.Size);
}
- // If the 'to' is rooted to 'from' and the layoutstyle is Computed it's a special-case.
- // Use LayoutSubview with the Frame of the 'from'
+ // If the 'to' is rooted to 'from' it's a special-case.
+ // Use LayoutSubview with the Frame of the 'from'.
if (SuperView is { } && GetTopSuperView () is { } && LayoutNeeded && edges.Count > 0)
{
foreach ((View from, View to) in edges)
{
- LayoutSubview (to, from.ContentSize);
+ LayoutSubview (to, from.ContentSize.GetValueOrDefault ());
}
}
LayoutNeeded = false;
- OnLayoutComplete (new (ContentSize));
+ OnLayoutComplete (new (ContentSize.GetValueOrDefault ()));
}
private void LayoutSubview (View v, Size contentSize)
{
+ // BUGBUG: Calling SetRelativeLayout before LayoutSubviews is problematic. Need to resolve.
v.SetRelativeLayout (contentSize);
v.LayoutSubviews ();
v.LayoutNeeded = false;
@@ -928,6 +719,9 @@ private void LayoutSubview (View v, Size contentSize)
///
internal virtual void OnLayoutComplete (LayoutEventArgs args) { LayoutComplete?.Invoke (this, args); }
+ // BUGBUG: We need an API/event that is called from SetRelativeLayout instead of/in addition to
+ // BUGBUG: OnLayoutStarted which is called from LayoutSubviews.
+
///
/// Raises the event. Called from before any subviews
/// have been laid out.
@@ -948,26 +742,24 @@ internal void OnResizeNeeded ()
{
// TODO: Identify a real-world use-case where this API should be virtual.
// TODO: Until then leave it `internal` and non-virtual
+
// First try SuperView.Viewport, then Application.Top, then Driver.Viewport.
// Finally, if none of those are valid, use int.MaxValue (for Unit tests).
- Size contentSize = SuperView is { IsInitialized: true } ? SuperView.ContentSize :
+ Size? contentSize = SuperView is { IsInitialized: true } ? SuperView.ContentSize :
Application.Top is { } && Application.Top != this && Application.Top.IsInitialized ? Application.Top.ContentSize :
Application.Driver?.Screen.Size ?? new (int.MaxValue, int.MaxValue);
- SetRelativeLayout (contentSize);
- // TODO: Determine what, if any of the below is actually needed here.
+ SetTextFormatterSize ();
+
+ SetRelativeLayout (contentSize.GetValueOrDefault ());
+
if (IsInitialized)
{
- if (AutoSize)
- {
- SetFrameToFitText ();
- SetTextFormatterSize ();
- }
-
LayoutAdornments ();
- SetNeedsDisplay ();
- SetNeedsLayout ();
}
+
+ SetNeedsDisplay ();
+ SetNeedsLayout ();
}
internal bool LayoutNeeded { get; private set; } = true;
@@ -1010,24 +802,23 @@ internal void SetNeedsLayout ()
///
/// The size of the SuperView's content (nominally the same as this.SuperView.ContentSize).
///
- internal void SetRelativeLayout (Size superviewContentSize)
+ internal void SetRelativeLayout (Size? superviewContentSize)
{
Debug.Assert (_x is { });
Debug.Assert (_y is { });
Debug.Assert (_width is { });
Debug.Assert (_height is { });
- var autoSize = Size.Empty;
-
- if (AutoSize)
+ if (superviewContentSize is null)
{
- autoSize = GetAutoSize ();
+ return;
}
- int newX = _x.Calculate (superviewContentSize.Width, _width, autoSize.Width, AutoSize);
- int newW = _width.Calculate (newX, superviewContentSize.Width, autoSize.Width, AutoSize);
- int newY = _y.Calculate (superviewContentSize.Height, _height, autoSize.Height, AutoSize);
- int newH = _height.Calculate (newY, superviewContentSize.Height, autoSize.Height, AutoSize);
+ CheckDimAuto ();
+ int newX = _x.Calculate (superviewContentSize.Value.Width, _width, this, Dim.Dimension.Width);
+ int newW = _width.Calculate (newX, superviewContentSize.Value.Width, this, Dim.Dimension.Width);
+ int newY = _y.Calculate (superviewContentSize.Value.Height, _height, this, Dim.Dimension.Height);
+ int newH = _height.Calculate (newY, superviewContentSize.Value.Height, this, Dim.Dimension.Height);
Rectangle newFrame = new (newX, newY, newW, newH);
@@ -1057,31 +848,9 @@ internal void SetRelativeLayout (Size superviewContentSize)
_height = Frame.Height;
}
- SetNeedsLayout ();
- SetNeedsDisplay ();
- }
-
- if (AutoSize)
- {
- if (autoSize.Width == 0 || autoSize.Height == 0)
+ if (!string.IsNullOrEmpty (Title))
{
- // Set the frame. Do NOT use `Frame` as it overwrites X, Y, Width, and Height, making
- // the view LayoutStyle.Absolute.
- SetFrame (_frame with { Size = autoSize });
-
- if (autoSize.Width == 0)
- {
- _width = 0;
- }
-
- if (autoSize.Height == 0)
- {
- _height = 0;
- }
- }
- else if (!SetFrameToFitText ())
- {
- SetTextFormatterSize ();
+ SetTitleTextFormatterSize ();
}
SetNeedsLayout ();
@@ -1234,12 +1003,14 @@ internal static List TopologicalSort (
if (ReferenceEquals (from.SuperView, to))
{
throw new InvalidOperationException (
- $"ComputedLayout for \"{superView}\": \"{to}\" references a SubView (\"{from}\")."
+ $"ComputedLayout for \"{superView}\": \"{to}\" "
+ + $"references a SubView (\"{from}\")."
);
}
throw new InvalidOperationException (
- $"ComputedLayout for \"{superView}\": \"{from}\" linked with \"{to}\" was not found. Did you forget to add it to {superView}?"
+ $"ComputedLayout for \"{superView}\": \"{from}\" "
+ + $"linked with \"{to}\" was not found. Did you forget to add it to {superView}?"
);
}
}
@@ -1248,34 +1019,35 @@ internal static List TopologicalSort (
return result;
} // TopologicalSort
- #region Diagnostics
-
- // Diagnostics to highlight when Width or Height is read before the view has been initialized
- private Dim VerifyIsInitialized (Dim dim, string member)
+ // Diagnostics to highlight when X or Y is read before the view has been initialized
+ private Pos VerifyIsInitialized (Pos pos, string member)
{
#if DEBUG
- if (LayoutStyle == LayoutStyle.Computed && !IsInitialized)
+ if ((pos.ReferencesOtherViews () || pos.ReferencesOtherViews ()) && !IsInitialized)
{
Debug.WriteLine (
- $"WARNING: \"{this}\" has not been initialized; {member} is indeterminate: {dim}. This is potentially a bug."
+ $"WARNING: The {pos} of {this} is dependent on other views and {member} "
+ + $"is being accessed before the View has been initialized. This is likely a bug."
);
}
-#endif // DEBUG
- return dim;
+#endif // DEBUG
+ return pos;
}
- // Diagnostics to highlight when X or Y is read before the view has been initialized
- private Pos VerifyIsInitialized (Pos pos, string member)
+ // Diagnostics to highlight when Width or Height is read before the view has been initialized
+ private Dim VerifyIsInitialized (Dim dim, string member)
{
#if DEBUG
- if (LayoutStyle == LayoutStyle.Computed && !IsInitialized)
+ if ((dim.ReferencesOtherViews () || dim.ReferencesOtherViews ()) && !IsInitialized)
{
Debug.WriteLine (
- $"WARNING: \"{this}\" has not been initialized; {member} is indeterminate {pos}. This is potentially a bug."
+ $"WARNING: The {member} of {this} is dependent on other views and is "
+ + $"is being accessed before the View has been initialized. This is likely a bug. "
+ + $"{member} is {dim}"
);
}
#endif // DEBUG
- return pos;
+ return dim;
}
/// Gets or sets whether validation of and occurs.
@@ -1287,5 +1059,76 @@ private Pos VerifyIsInitialized (Pos pos, string member)
///
public bool ValidatePosDim { get; set; }
- #endregion
+
+ // TODO: Move this logic into the Pos/Dim classes
+ ///
+ /// Throws an if any SubViews are using Dim objects that depend on this
+ /// Views dimensions.
+ ///
+ ///
+ private void CheckDimAuto ()
+ {
+ if (!ValidatePosDim || !IsInitialized || (Width is not Dim.DimAuto && Height is not Dim.DimAuto))
+ {
+ return;
+ }
+
+ // Verify none of the subviews are using Dim objects that depend on the SuperView's dimensions.
+ foreach (View view in Subviews)
+ {
+ if (Width is Dim.DimAuto { _min: null })
+ {
+ ThrowInvalid (view, view.Width, nameof (view.Width));
+ ThrowInvalid (view, view.X, nameof (view.X));
+ }
+
+ if (Height is Dim.DimAuto { _min: null })
+ {
+ ThrowInvalid (view, view.Height, nameof (view.Height));
+ ThrowInvalid (view, view.Y, nameof (view.Y));
+ }
+ }
+
+ return;
+
+ void ThrowInvalid (View view, object checkPosDim, string name)
+ {
+ object bad = null;
+
+ switch (checkPosDim)
+ {
+ case Pos pos and not Pos.PosAbsolute and not Pos.PosView and not Pos.PosCombine:
+ bad = pos;
+
+ break;
+
+ case Pos pos and Pos.PosCombine:
+ // Recursively check for not Absolute or not View
+ ThrowInvalid (view, (pos as Pos.PosCombine)._left, name);
+ ThrowInvalid (view, (pos as Pos.PosCombine)._right, name);
+
+ break;
+
+ case Dim dim and not Dim.DimAbsolute and not Dim.DimView and not Dim.DimCombine:
+ bad = dim;
+
+ break;
+
+ case Dim dim and Dim.DimCombine:
+ // Recursively check for not Absolute or not View
+ ThrowInvalid (view, (dim as Dim.DimCombine)._left, name);
+ ThrowInvalid (view, (dim as Dim.DimCombine)._right, name);
+
+ break;
+ }
+
+ if (bad != null)
+ {
+ throw new InvalidOperationException (
+ $"{view.GetType ().Name}.{name} = {bad.GetType ().Name} "
+ + $"which depends on the SuperView's dimensions and the SuperView uses Dim.Auto."
+ );
+ }
+ }
+ }
}
diff --git a/Terminal.Gui/View/View.cs b/Terminal.Gui/View/View.cs
index 8a04e51702..1632eca2f2 100644
--- a/Terminal.Gui/View/View.cs
+++ b/Terminal.Gui/View/View.cs
@@ -32,10 +32,11 @@ namespace Terminal.Gui;
/// , , and will receive focus.
///
///
-/// Views that are focusable should implement the to make sure that the cursor is
-/// placed in a location that makes sense. Unix terminals do not have a way of hiding the cursor, so it can be
+/// Views that are focusable should override to make sure that the cursor is
+/// placed in a location that makes sense. Some terminals do not have a way of hiding the cursor, so it can be
/// distracting to have the cursor left at the last focused view. So views should make sure that they place the
-/// cursor in a visually sensible place.
+/// cursor in a visually sensible place. The default implementation of will place the
+/// cursor at either the hotkey (if defined) or 0,0.
///
///
/// The View defines the base functionality for user interface elements in Terminal.Gui. Views can contain one or
@@ -139,6 +140,8 @@ public partial class View : Responder, ISupportInitializeNotification
///
public View ()
{
+ CreateAdornments ();
+
HotKeySpecifier = (Rune)'_';
TitleTextFormatter.HotKeyChanged += TitleTextFormatter_HotKeyChanged;
@@ -150,8 +153,6 @@ public View ()
TabStop = false;
AddCommands ();
-
- CreateAdornments ();
}
///
@@ -456,12 +457,7 @@ public string Title
_title = value;
TitleTextFormatter.Text = _title;
- TitleTextFormatter.Size = new (
- TextFormatter.GetWidestLineLength (TitleTextFormatter.Text)
- - (TitleTextFormatter.Text?.Contains ((char)HotKeySpecifier.Value) == true
- ? Math.Max (HotKeySpecifier.GetColumns (), 0)
- : 0),
- 1);
+ SetTitleTextFormatterSize ();
SetHotKeyFromTitle ();
SetNeedsDisplay ();
#if DEBUG
@@ -475,6 +471,16 @@ public string Title
}
}
+ private void SetTitleTextFormatterSize ()
+ {
+ TitleTextFormatter.Size = new (
+ TextFormatter.GetWidestLineLength (TitleTextFormatter.Text)
+ - (TitleTextFormatter.Text?.Contains ((char)HotKeySpecifier.Value) == true
+ ? Math.Max (HotKeySpecifier.GetColumns (), 0)
+ : 0),
+ 1);
+ }
+
/// Called when the has been changed. Invokes the event.
/// The that is/has been replaced.
/// The new to be replaced.
diff --git a/Terminal.Gui/View/ViewAdornments.cs b/Terminal.Gui/View/ViewAdornments.cs
index 4efd92b526..37355a2cf4 100644
--- a/Terminal.Gui/View/ViewAdornments.cs
+++ b/Terminal.Gui/View/ViewAdornments.cs
@@ -136,7 +136,14 @@ public LineStyle BorderStyle
/// Gets the thickness describing the sum of the Adornments' thicknesses.
///
/// A thickness that describes the sum of the Adornments' thicknesses.
- public Thickness GetAdornmentsThickness () { return Margin.Thickness + Border.Thickness + Padding.Thickness; }
+ public Thickness GetAdornmentsThickness ()
+ {
+ if (Margin is null)
+ {
+ return Thickness.Empty;
+ }
+ return Margin.Thickness + Border.Thickness + Padding.Thickness;
+ }
/// Lays out the Adornments of the View.
///
diff --git a/Terminal.Gui/View/ViewContent.cs b/Terminal.Gui/View/ViewContent.cs
index 90fa3ab4a5..ba17287b6d 100644
--- a/Terminal.Gui/View/ViewContent.cs
+++ b/Terminal.Gui/View/ViewContent.cs
@@ -120,27 +120,31 @@ public partial class View
{
#region Content Area
- private Size _contentSize;
+ internal Size? _contentSize;
///
- /// Gets or sets the size of the View's content. If not set, the value will be the same as the size of ,
+ /// Gets or sets the size of the View's content. If , the value will be the same as the size of ,
/// and Viewport.Location will always be 0, 0.
///
///
///
- /// If a positive size is provided, describes the portion of the content currently visible
+ /// If a size is provided, describes the portion of the content currently visible
/// to the view. This enables virtual scrolling.
///
///
+ /// If a size is provided, the behavior of will be to use the ContentSize
+ /// to determine the size of the view.
+ ///
+ ///
/// Negative sizes are not supported.
///
///
- public Size ContentSize
+ public Size? ContentSize
{
- get => _contentSize == Size.Empty ? Viewport.Size : _contentSize;
+ get => _contentSize ?? Viewport.Size;
set
{
- if (value.Width < 0 || value.Height < 0)
+ if (value?.Width < 0 || value?.Height < 0)
{
throw new ArgumentException (@"ContentSize cannot be negative.", nameof (value));
}
@@ -166,8 +170,9 @@ public Size ContentSize
if (e.Cancel != true)
{
- SetNeedsLayout ();
- SetNeedsDisplay ();
+ OnResizeNeeded ();
+ //SetNeedsLayout ();
+ //SetNeedsDisplay ();
}
return e.Cancel;
@@ -251,7 +256,8 @@ public ViewportSettings ViewportSettings
///
/// Gets or sets the rectangle describing the portion of the View's content that is visible to the user.
/// The viewport Location is relative to the top-left corner of the inner rectangle of .
- /// If the viewport Size is the same as the Location will be 0, 0.
+ /// If the viewport Size is the same as , or is
+ /// the Location will be 0, 0.
///
///
/// The rectangle describing the location and size of the viewport into the View's virtual content, described by
@@ -289,10 +295,10 @@ public virtual Rectangle Viewport
get
{
#if DEBUG
- if (LayoutStyle == LayoutStyle.Computed && !IsInitialized)
+ if ((_width.ReferencesOtherViews () || _height.ReferencesOtherViews ()) && !IsInitialized)
{
Debug.WriteLine (
- $"WARNING: Viewport is being accessed before the View has been initialized. This is likely a bug in {this}"
+ $"WARNING: The dimensions of {this} are dependent on other views and Viewport is being accessed before the View has been initialized. This is likely a bug."
);
}
#endif // DEBUG
@@ -303,8 +309,26 @@ public virtual Rectangle Viewport
return new (_viewportLocation, Frame.Size);
}
- Thickness thickness = GetAdornmentsThickness ();
+ // BUGBUG: This is a hack. Viewport_get should not have side effects.
+ if (Frame.Size == Size.Empty)
+ {
+ // The Frame has not been set yet (e.g. the view has not been added to a SuperView yet).
+ //
+ if ((Width is Dim.DimAuto widthAuto && widthAuto._style.HasFlag(Dim.DimAutoStyle.Text))
+ || (Height is Dim.DimAuto heightAuto && heightAuto._style.HasFlag (Dim.DimAutoStyle.Text)))
+ {
+ if (TextFormatter.NeedsFormat)
+ {
+ // This updates TextFormatter.Size to the text size
+ TextFormatter.AutoSize = true;
+
+ // Whenever DimAutoStyle.Text is set, ContentSize will match TextFormatter.Size.
+ ContentSize = TextFormatter.Size == Size.Empty ? null : TextFormatter.Size;
+ }
+ }
+ }
+ Thickness thickness = GetAdornmentsThickness ();
return new (
_viewportLocation,
new (
@@ -337,7 +361,6 @@ private void SetViewport (Rectangle viewport)
}
OnViewportChanged (new (IsInitialized ? Viewport : Rectangle.Empty, oldViewport));
-
return;
}
@@ -353,9 +376,9 @@ void ApplySettings (ref Rectangle newViewport)
{
if (!ViewportSettings.HasFlag (ViewportSettings.AllowXGreaterThanContentWidth))
{
- if (newViewport.X >= ContentSize.Width)
+ if (newViewport.X >= ContentSize.GetValueOrDefault ().Width)
{
- newViewport.X = ContentSize.Width - 1;
+ newViewport.X = ContentSize.GetValueOrDefault ().Width - 1;
}
}
@@ -370,9 +393,9 @@ void ApplySettings (ref Rectangle newViewport)
if (!ViewportSettings.HasFlag (ViewportSettings.AllowYGreaterThanContentHeight))
{
- if (newViewport.Y >= ContentSize.Height)
+ if (newViewport.Y >= ContentSize.GetValueOrDefault().Height)
{
- newViewport.Y = ContentSize.Height - 1;
+ newViewport.Y = ContentSize.GetValueOrDefault ().Height - 1;
}
}
@@ -397,7 +420,10 @@ void ApplySettings (ref Rectangle newViewport)
/// Called when the changes. Invokes the event.
///
///
- protected virtual void OnViewportChanged (DrawEventArgs e) { ViewportChanged?.Invoke (this, e); }
+ protected virtual void OnViewportChanged (DrawEventArgs e)
+ {
+ ViewportChanged?.Invoke (this, e);
+ }
///
/// Converts a -relative location to a screen-relative location.
diff --git a/Terminal.Gui/View/ViewDrawing.cs b/Terminal.Gui/View/ViewDrawing.cs
index cc7109a5bb..144c3d36f5 100644
--- a/Terminal.Gui/View/ViewDrawing.cs
+++ b/Terminal.Gui/View/ViewDrawing.cs
@@ -106,11 +106,11 @@ public void Clear ()
if (ViewportSettings.HasFlag (ViewportSettings.ClearContentOnly))
{
- Rectangle visibleContent = ViewportToScreen (new (new (-Viewport.X, -Viewport.Y), ContentSize));
+ Rectangle visibleContent = ViewportToScreen (new (new (-Viewport.X, -Viewport.Y), ContentSize.GetValueOrDefault ()));
toClear = Rectangle.Intersect (toClear, visibleContent);
}
- Attribute prev = Driver.SetAttribute (GetNormalColor());
+ Attribute prev = Driver.SetAttribute (GetNormalColor ());
Driver.FillRect (toClear);
Driver.SetAttribute (prev);
@@ -134,7 +134,7 @@ public void FillRect (Rectangle rect, Color? color = null)
Driver.Clip = Rectangle.Intersect (prevClip, ViewportToScreen (Viewport with { Location = new (0, 0) }));
- Attribute prev = Driver.SetAttribute (new (color ?? GetNormalColor().Background));
+ Attribute prev = Driver.SetAttribute (new (color ?? GetNormalColor ().Background));
Driver.FillRect (toClear);
Driver.SetAttribute (prev);
@@ -172,7 +172,7 @@ public Rectangle SetClip ()
if (ViewportSettings.HasFlag (ViewportSettings.ClipContentOnly))
{
// Clamp the Clip to the just content area that is within the viewport
- Rectangle visibleContent = ViewportToScreen (new (new (-Viewport.X, -Viewport.Y), ContentSize));
+ Rectangle visibleContent = ViewportToScreen (new (new (-Viewport.X, -Viewport.Y), ContentSize.GetValueOrDefault ()));
clip = Rectangle.Intersect (clip, visibleContent);
}
@@ -475,7 +475,7 @@ public virtual void OnDrawContent (Rectangle viewport)
// This should NOT clear
// TODO: If the output is not in the Viewport, do nothing
- var drawRect = new Rectangle (ContentToScreen (Point.Empty), ContentSize);
+ var drawRect = new Rectangle (ContentToScreen (Point.Empty), ContentSize.GetValueOrDefault ());
TextFormatter?.Draw (
drawRect,
@@ -577,10 +577,7 @@ public virtual bool OnRenderLineCanvas ()
///
public void SetNeedsDisplay ()
{
- if (IsInitialized)
- {
- SetNeedsDisplay (Viewport);
- }
+ SetNeedsDisplay (Viewport);
}
/// Expands the area of this view needing to be redrawn to include .
@@ -597,13 +594,6 @@ public void SetNeedsDisplay ()
/// The content-relative region that needs to be redrawn.
public void SetNeedsDisplay (Rectangle region)
{
- if (!IsInitialized)
- {
- _needsDisplayRect = region;
-
- return;
- }
-
if (_needsDisplayRect.IsEmpty)
{
_needsDisplayRect = region;
diff --git a/Terminal.Gui/View/ViewKeyboard.cs b/Terminal.Gui/View/ViewKeyboard.cs
index 52aa07da93..6874919970 100644
--- a/Terminal.Gui/View/ViewKeyboard.cs
+++ b/Terminal.Gui/View/ViewKeyboard.cs
@@ -205,7 +205,7 @@ public virtual Rune HotKeySpecifier
}
set
{
- TitleTextFormatter.HotKeySpecifier = value;
+ TitleTextFormatter.HotKeySpecifier = TextFormatter.HotKeySpecifier = value;
SetHotKeyFromTitle ();
}
}
diff --git a/Terminal.Gui/View/ViewSubViews.cs b/Terminal.Gui/View/ViewSubViews.cs
index 34c9f5fee0..ee161e3f78 100644
--- a/Terminal.Gui/View/ViewSubViews.cs
+++ b/Terminal.Gui/View/ViewSubViews.cs
@@ -31,14 +31,14 @@ public virtual View SuperView
/// Adds a subview (child) to this view.
///
- ///
- /// The Views that have been added to this view can be retrieved via the property. See also
- ///
- ///
- ///
- /// Subviews will be disposed when this View is disposed. In other-words, calling this method causes
- /// the lifecycle of the subviews to be transferred to this View.
- ///
+ ///
+ /// The Views that have been added to this view can be retrieved via the property. See also
+ ///
+ ///
+ ///
+ /// Subviews will be disposed when this View is disposed. In other-words, calling this method causes
+ /// the lifecycle of the subviews to be transferred to this View.
+ ///
///
public virtual void Add (View view)
{
@@ -49,12 +49,12 @@ public virtual void Add (View view)
if (_subviews is null)
{
- _subviews = new List ();
+ _subviews = new ();
}
if (_tabIndexes is null)
{
- _tabIndexes = new List ();
+ _tabIndexes = new ();
}
_subviews.Add (view);
@@ -83,7 +83,7 @@ public virtual void Add (View view)
view.Enabled = false;
}
- OnAdded (new SuperViewChangedEventArgs (this, view));
+ OnAdded (new (this, view));
if (IsInitialized && !view.IsInitialized)
{
@@ -91,6 +91,7 @@ public virtual void Add (View view)
view.EndInit ();
}
+ CheckDimAuto ();
SetNeedsLayout ();
SetNeedsDisplay ();
}
@@ -98,14 +99,14 @@ public virtual void Add (View view)
/// Adds the specified views (children) to the view.
/// Array of one or more views (can be optional parameter).
///
- ///
- /// The Views that have been added to this view can be retrieved via the property. See also
- /// and .
- ///
- ///
- /// Subviews will be disposed when this View is disposed. In other-words, calling this method causes
- /// the lifecycle of the subviews to be transferred to this View.
- ///
+ ///
+ /// The Views that have been added to this view can be retrieved via the property. See also
+ /// and .
+ ///
+ ///
+ /// Subviews will be disposed when this View is disposed. In other-words, calling this method causes
+ /// the lifecycle of the subviews to be transferred to this View.
+ ///
///
public void Add (params View [] views)
{
@@ -198,10 +199,11 @@ public virtual void OnRemoved (SuperViewChangedEventArgs e)
/// Removes a subview added via or from this View.
///
- ///
- /// Normally Subviews will be disposed when this View is disposed. Removing a Subview causes ownership of the Subview's
- /// lifecycle to be transferred to the caller; the caller muse call .
- ///
+ ///
+ /// Normally Subviews will be disposed when this View is disposed. Removing a Subview causes ownership of the
+ /// Subview's
+ /// lifecycle to be transferred to the caller; the caller muse call .
+ ///
///
public virtual void Remove (View view)
{
@@ -226,7 +228,7 @@ public virtual void Remove (View view)
}
}
- OnRemoved (new SuperViewChangedEventArgs (this, view));
+ OnRemoved (new (this, view));
if (Focused == view)
{
@@ -235,13 +237,15 @@ public virtual void Remove (View view)
}
///
- /// Removes all subviews (children) added via or from this View.
+ /// Removes all subviews (children) added via or from this View.
///
///
- ///
- /// Normally Subviews will be disposed when this View is disposed. Removing a Subview causes ownership of the Subview's
- /// lifecycle to be transferred to the caller; the caller must call on any Views that were added.
- ///
+ ///
+ /// Normally Subviews will be disposed when this View is disposed. Removing a Subview causes ownership of the
+ /// Subview's
+ /// lifecycle to be transferred to the caller; the caller must call on any Views that were
+ /// added.
+ ///
///
public virtual void RemoveAll ()
{
@@ -378,7 +382,6 @@ private void SetHasFocus (bool value, View view, bool force = false)
}
}
-
/// Event fired when the value is being changed.
public event EventHandler CanFocusChanged;
@@ -481,7 +484,9 @@ public bool CanFocus
}
}
- /// Method invoked when a view gets focus.
+ ///
+ /// Called when a view gets focus.
+ ///
/// The view that is losing focus.
/// true, if the event was handled, false otherwise.
public virtual bool OnEnter (View view)
@@ -497,7 +502,6 @@ public virtual bool OnEnter (View view)
return false;
}
-
/// Method invoked when a view loses focus.
/// The view that is getting focus.
/// true, if the event was handled, false otherwise.
@@ -511,18 +515,16 @@ public virtual bool OnLeave (View view)
return true;
}
- // 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;
}
- /// Returns the currently focused view inside this view, or null if nothing is focused.
+ // BUGBUG: This API is poorly defined and implemented. It does not specify what it means if THIS view is focused and has no subviews.
+ /// Returns the currently focused Subview inside this view, or null if nothing is focused.
/// The focused.
public View Focused { get; private set; }
- /// Returns the most focused view in the chain of subviews (the leaf view that has the focus).
+ // BUGBUG: This API is poorly defined and implemented. It does not specify what it means if THIS view is focused and has no subviews.
+ /// Returns the most focused Subview in the chain of subviews (the leaf view that has the focus).
/// The most focused View.
public View MostFocused
{
@@ -850,38 +852,37 @@ private View GetMostFocused (View view)
return view.Focused is { } ? GetMostFocused (view.Focused) : view;
}
- /// Positions the cursor in the right position based on the currently focused view in the chain.
- /// Views that are focusable should override
- ///
- /// to ensure
- /// the cursor is placed in a location that makes sense. Unix terminals do not have
- /// 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.
- /// Viewport-relative cursor position.
+ ///
+ /// Gets or sets the cursor style to be used when the view is focused. The default is .
+ ///
+ public CursorVisibility CursorVisibility { get; set; } = CursorVisibility.Invisible;
+
+ ///
+ /// Positions the cursor in the right position based on the currently focused view in the chain.
+ ///
+ ///
+ ///
+ /// Views that are focusable should override to make sure that the cursor is
+ /// placed in a location that makes sense. Some terminals do not have a way of hiding the cursor, so it can be
+ /// distracting to have the cursor left at the last focused view. So views should make sure that they place the
+ /// cursor in a visually sensible place. The default implementation of will place the
+ /// cursor at either the hotkey (if defined) or 0,0.
+ ///
+ ///
+ /// Viewport-relative cursor position. Return to ensure the cursor is not visible.
public virtual Point? PositionCursor ()
{
- if (!IsInitialized)
- {
- return null;
- }
-
- // TODO: v2 - This needs to support Subviews of Adornments too
-
- // 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)
+ if (IsInitialized && CanFocus && HasFocus && ContentSize.HasValue)
{
+ // By default, position the cursor at the hotkey (if any) or 0, 0.
+ Point location = Viewport.Location;
location.X = TextFormatter.HotKeyPos == -1 ? 0 : TextFormatter.CursorPosition;
location.Y = 0;
Move (location.X, location.Y);
- return location;
}
+ // Returning null will hide the cursor.
return null;
-
}
#endregion Focus
diff --git a/Terminal.Gui/View/ViewText.cs b/Terminal.Gui/View/ViewText.cs
index 96c33e56e6..63ad748c75 100644
--- a/Terminal.Gui/View/ViewText.cs
+++ b/Terminal.Gui/View/ViewText.cs
@@ -1,13 +1,16 @@
-namespace Terminal.Gui;
+using static Terminal.Gui.SpinnerStyle;
+
+namespace Terminal.Gui;
public partial class View
{
private string _text;
///
- /// Gets or sets whether trailing spaces at the end of word-wrapped lines are preserved or not when
- /// is enabled. If trailing spaces at the end of wrapped
- /// lines will be removed when is formatted for display. The default is .
+ /// Gets or sets whether trailing spaces at the end of word-wrapped lines are preserved
+ /// or not when is enabled.
+ /// If trailing spaces at the end of wrapped lines will be removed when
+ /// is formatted for display. The default is .
///
public virtual bool PreserveTrailingSpaces
{
@@ -22,18 +25,23 @@ public virtual bool PreserveTrailingSpaces
}
}
- /// The text displayed by the .
+ ///
+ /// The text displayed by the .
+ ///
///
- /// The text will be drawn before any subviews are drawn.
///
- /// The text will be drawn starting at the view origin (0, 0) and will be formatted according to
- /// and .
+ /// The text will be drawn before any subviews are drawn.
///
///
- /// The text will word-wrap to additional lines if it does not fit horizontally. If 's height
+ /// The text will be drawn starting at the view origin (0, 0) and will be formatted according
+ /// to and .
+ ///
+ ///
+ /// The text will word-wrap to additional lines if it does not fit horizontally. If 's height
/// is 1, the text will be clipped.
///
- /// If is true, the will be adjusted to fit the text.
+ /// If or are using ,
+ /// the will be adjusted to fit the text.
/// When the text changes, the is fired.
///
public virtual string Text
@@ -41,13 +49,9 @@ public virtual string Text
get => _text;
set
{
- if (value == _text)
- {
- return;
- }
-
string old = _text;
_text = value;
+
UpdateTextFormatterText ();
OnResizeNeeded ();
#if DEBUG
@@ -80,7 +84,7 @@ public void OnTextChanged (string oldValue, string newValue)
/// redisplay the .
///
///
- /// If is true, the will be adjusted to fit the text.
+ /// or are using , the will be adjusted to fit the text.
///
/// The text alignment.
public virtual TextAlignment TextAlignment
@@ -99,7 +103,7 @@ public virtual TextAlignment TextAlignment
/// .
///
///
- /// If is true, the will be adjusted to fit the text.
+ /// or are using , the will be adjusted to fit the text.
///
/// The text alignment.
public virtual TextDirection TextDirection
@@ -112,15 +116,18 @@ public virtual TextDirection TextDirection
}
}
- /// Gets the used to format .
- public TextFormatter TextFormatter { get; init; } = new ();
+ ///
+ /// Gets or sets the used to format .
+ ///
+ public TextFormatter TextFormatter { get; init; } = new () { };
///
/// Gets or sets how the View's is aligned vertically when drawn. Changing this property will
- /// redisplay the .
+ /// redisplay
+ /// the .
///
///
- /// If is true, the will be adjusted to fit the text.
+ /// or are using , the will be adjusted to fit the text.
///
/// The text alignment.
public virtual VerticalTextAlignment VerticalTextAlignment
@@ -134,78 +141,9 @@ public virtual VerticalTextAlignment VerticalTextAlignment
}
///
- /// Gets the Frame dimensions required to fit within using the text
- /// specified by the property and accounting for any
- /// characters.
+ /// Can be overridden if the has
+ /// different format than the default.
///
- /// The the needs to be set to fit the text.
- public Size GetAutoSize ()
- {
- var x = 0;
- var y = 0;
-
- if (IsInitialized)
- {
- x = Viewport.X;
- y = Viewport.Y;
- }
-
- Rectangle rect = TextFormatter.CalcRect (x, y, TextFormatter.Text, TextFormatter.Direction);
-
- int newWidth = rect.Size.Width
- - GetHotKeySpecifierLength ()
- + (Margin == null
- ? 0
- : Margin.Thickness.Horizontal
- + Border.Thickness.Horizontal
- + Padding.Thickness.Horizontal);
-
- int newHeight = rect.Size.Height
- - GetHotKeySpecifierLength (false)
- + (Margin == null
- ? 0
- : Margin.Thickness.Vertical + Border.Thickness.Vertical + Padding.Thickness.Vertical);
-
- return new (newWidth, newHeight);
- }
-
- ///
- /// Gets the width or height of the characters in the
- /// property.
- ///
- ///
- ///
- /// This is for , not . For to show the hotkey,
- /// set View. to the desired character.
- ///
- ///
- /// Only the first HotKey specifier found in is supported.
- ///
- ///
- ///
- /// If (the default) the width required for the HotKey specifier is returned.
- /// Otherwise the height is returned.
- ///
- ///
- /// The number of characters required for the . If the text direction
- /// specified by does not match the parameter, 0 is
- /// returned.
- ///
- public int GetHotKeySpecifierLength (bool isWidth = true)
- {
- if (isWidth)
- {
- return TextFormatter.IsHorizontalDirection (TextDirection) && TextFormatter.Text?.Contains ((char)TextFormatter.HotKeySpecifier.Value) == true
- ? Math.Max (TextFormatter.HotKeySpecifier.GetColumns (), 0)
- : 0;
- }
-
- return TextFormatter.IsVerticalDirection (TextDirection) && TextFormatter.Text?.Contains ((char)TextFormatter.HotKeySpecifier.Value) == true
- ? Math.Max (TextFormatter.HotKeySpecifier.GetColumns (), 0)
- : 0;
- }
-
- /// Can be overridden if the has different format than the default.
protected virtual void UpdateTextFormatterText ()
{
if (TextFormatter is { })
@@ -214,14 +152,15 @@ protected virtual void UpdateTextFormatterText ()
}
}
- /// Gets the dimensions required for ignoring a .
+ ///
+ /// Gets the dimensions required for ignoring a .
+ ///
///
internal Size GetSizeNeededForTextWithoutHotKey ()
{
- return new (
- TextFormatter.Size.Width - GetHotKeySpecifierLength (),
- TextFormatter.Size.Height - GetHotKeySpecifierLength (false)
- );
+ return new Size (
+ TextFormatter.Size.Width - TextFormatter.GetHotKeySpecifierLength (),
+ TextFormatter.Size.Height - TextFormatter.GetHotKeySpecifierLength (false));
}
///
@@ -229,171 +168,43 @@ internal Size GetSizeNeededForTextWithoutHotKey ()
/// .
///
///
- /// Use this API to set when the view has changed such that the size required to
- /// fit the text has changed. changes.
+ /// Use this API to set when the view has changed such that the
+ /// size required to fit the text has changed.
+ /// changes.
///
///
internal void SetTextFormatterSize ()
{
- if (!IsInitialized)
- {
- TextFormatter.Size = Size.Empty;
-
- return;
- }
+ UpdateTextFormatterText ();
- if (string.IsNullOrEmpty (TextFormatter.Text))
+ // TODO: This is a hack. Figure out how to move this into DimDimAuto
+ // Use _width & _height instead of Width & Height to avoid debug spew
+ if ((_width is Dim.DimAuto widthAuto && widthAuto._style.HasFlag (Dim.DimAutoStyle.Text))
+ || (_height is Dim.DimAuto heightAuto && heightAuto._style.HasFlag (Dim.DimAutoStyle.Text)))
{
- TextFormatter.Size = ContentSize;
+ // This updates TextFormatter.Size to the text size
+ TextFormatter.AutoSize = true;
+ // Whenever DimAutoStyle.Text is set, ContentSize will match TextFormatter.Size.
+ ContentSize = TextFormatter.Size == Size.Empty ? null : TextFormatter.Size;
return;
}
- TextFormatter.Size = new (
- ContentSize.Width + GetHotKeySpecifierLength (),
- ContentSize.Height + GetHotKeySpecifierLength (false)
- );
- }
-
- private bool IsValidAutoSize (out Size autoSize)
- {
- Rectangle rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection);
-
- autoSize = new (
- rect.Size.Width - GetHotKeySpecifierLength (),
- rect.Size.Height - GetHotKeySpecifierLength (false)
- );
-
- return !((ValidatePosDim && (!(Width is Dim.DimAbsolute) || !(Height is Dim.DimAbsolute)))
- || _frame.Size.Width != rect.Size.Width - GetHotKeySpecifierLength ()
- || _frame.Size.Height != rect.Size.Height - GetHotKeySpecifierLength (false));
- }
-
- private bool IsValidAutoSizeHeight (Dim height)
- {
- Rectangle rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection);
- int dimValue = height.Anchor (0);
-
- return !((ValidatePosDim && !(height is Dim.DimAbsolute))
- || dimValue != rect.Size.Height - GetHotKeySpecifierLength (false));
- }
-
- private bool IsValidAutoSizeWidth (Dim width)
- {
- Rectangle rect = TextFormatter.CalcRect (_frame.X, _frame.Y, TextFormatter.Text, TextDirection);
- int dimValue = width.Anchor (0);
-
- return !((ValidatePosDim && !(width is Dim.DimAbsolute))
- || dimValue != rect.Size.Width - GetHotKeySpecifierLength ());
- }
-
- /// Sets the size of the View to the minimum width or height required to fit .
- ///
- /// if the size was changed; if ==
- /// or will not fit.
- ///
- ///
- /// Always returns if is or if
- /// (Horizontal) or (Vertical) are not not set or zero. Does not take into
- /// account word wrapping.
- ///
- private bool SetFrameToFitText ()
- {
- if (AutoSize == false)
- {
- throw new InvalidOperationException ("SetFrameToFitText can only be called when AutoSize is true");
- }
-
- // BUGBUG: This API is broken - should not assume Frame.Height == Viewport.Height
- //
- // Gets the minimum dimensions required to fit the View's , factoring in .
- //
- // The minimum dimensions required.
- // if the dimensions fit within the View's , otherwise.
- //
- // Always returns if is or
- // if (Horizontal) or (Vertical) are not not set or zero.
- // Does not take into account word wrapping.
- //
- bool GetMinimumSizeOfText (out Size sizeRequired)
- {
- if (!IsInitialized)
- {
- sizeRequired = Size.Empty;
-
- return false;
- }
-
- sizeRequired = ContentSize;
-
- if (AutoSize || string.IsNullOrEmpty (TextFormatter.Text))
- {
- return false;
- }
-
- switch (TextFormatter.IsVerticalDirection (TextDirection))
- {
- case true:
- int colWidth = TextFormatter.GetWidestLineLength (new List { TextFormatter.Text }, 0, 1);
-
- // TODO: v2 - This uses frame.Width; it should only use Viewport
- if (_frame.Width < colWidth
- && (Width is null || (ContentSize.Width >= 0 && Width is Dim.DimAbsolute && Width.Anchor (0) >= 0 && Width.Anchor (0) < colWidth)))
- {
- sizeRequired = new (colWidth, ContentSize.Height);
-
- return true;
- }
-
- break;
- default:
- if (_frame.Height < 1 && (Height is null || (Height is Dim.DimAbsolute && Height.Anchor (0) == 0)))
- {
- sizeRequired = new (ContentSize.Width, 1);
-
- return true;
- }
-
- break;
- }
-
- return false;
- }
-
- if (GetMinimumSizeOfText (out Size size))
- {
- // TODO: This is a hack.
- //_width = size.Width;
- //_height = size.Height;
- SetFrame (new (_frame.Location, size));
-
- //throw new InvalidOperationException ("This is a hack.");
- return true;
- }
-
- return false;
+ TextFormatter.AutoSize = false;
+ TextFormatter.Size = new Size (ContentSize.GetValueOrDefault ().Width, ContentSize.GetValueOrDefault ().Height);
}
- // only called from EndInit
private void UpdateTextDirection (TextDirection newDirection)
{
- bool directionChanged = TextFormatter.IsHorizontalDirection (TextFormatter.Direction)
- != TextFormatter.IsHorizontalDirection (newDirection);
+ bool directionChanged = TextFormatter.IsHorizontalDirection (TextFormatter.Direction) != TextFormatter.IsHorizontalDirection (newDirection);
TextFormatter.Direction = newDirection;
- bool isValidOldAutoSize = AutoSize && IsValidAutoSize (out Size _);
-
UpdateTextFormatterText ();
- if ((!ValidatePosDim && directionChanged && AutoSize)
- || (ValidatePosDim && directionChanged && AutoSize && isValidOldAutoSize))
+ if (directionChanged)
{
OnResizeNeeded ();
}
- else if (AutoSize && directionChanged && IsAdded)
- {
- ResizeViewportToFit (Viewport.Size);
- }
SetTextFormatterSize ();
SetNeedsDisplay ();
diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs
index 8ffb1d6369..3639866ff4 100644
--- a/Terminal.Gui/Views/Button.cs
+++ b/Terminal.Gui/Views/Button.cs
@@ -45,11 +45,10 @@ public Button ()
_leftDefault = Glyphs.LeftDefaultIndicator;
_rightDefault = Glyphs.RightDefaultIndicator;
- // Ensures a height of 1 if AutoSize is set to false
Height = 1;
+ Width = Dim.Auto (Dim.DimAutoStyle.Text);
CanFocus = true;
- AutoSize = true;
HighlightStyle |= HighlightStyle.Pressed;
#if HOVER
HighlightStyle |= HighlightStyle.Hover;
@@ -138,14 +137,6 @@ public bool IsDefault
///
public bool NoPadding { get; set; }
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
-
///
public override Point? PositionCursor ()
{
@@ -156,8 +147,7 @@ public override bool OnEnter (View view)
if (TextFormatter.Text [i] == Text [0])
{
Move (i, 0);
-
- return new (i,0);
+ return null; // Don't show the cursor
}
}
}
diff --git a/Terminal.Gui/Views/CheckBox.cs b/Terminal.Gui/Views/CheckBox.cs
index d9d22e5659..0535f5f438 100644
--- a/Terminal.Gui/Views/CheckBox.cs
+++ b/Terminal.Gui/Views/CheckBox.cs
@@ -20,11 +20,10 @@ public CheckBox ()
_charChecked = Glyphs.Checked;
_charUnChecked = Glyphs.UnChecked;
- // Ensures a height of 1 if AutoSize is set to false
Height = 1;
+ Width = Dim.Auto (Dim.DimAutoStyle.Text);
CanFocus = true;
- AutoSize = true;
// Things this view knows how to do
AddCommand (Command.Accept, OnToggled);
@@ -95,14 +94,6 @@ public bool? Checked
}
}
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
-
/// Called when the property changes. Invokes the event.
///
///
@@ -151,9 +142,6 @@ public override bool OnEnter (View view)
return true;
}
- ///
- public override Point? PositionCursor () { Move (0, 0); return Point.Empty; }
-
/// Toggled event, raised when the is toggled.
///
///
@@ -192,11 +180,11 @@ private Rune GetCheckedState ()
private string GetFormatterText ()
{
- if (AutoSize || string.IsNullOrEmpty (Title) || Frame.Width <= 2)
+ if (Width is Dim.DimAuto || string.IsNullOrEmpty (Title) || ContentSize?.Width <= 2)
{
return Text;
}
- return Text [..Math.Min (Frame.Width - 2, Text.GetRuneCount ())];
+ return ContentSize is null ? Text : Text [..Math.Min (ContentSize.Value.Width - 2, Text.GetRuneCount ())];
}
}
diff --git a/Terminal.Gui/Views/ColorPicker.cs b/Terminal.Gui/Views/ColorPicker.cs
index f9f492874a..0510e3be59 100644
--- a/Terminal.Gui/Views/ColorPicker.cs
+++ b/Terminal.Gui/Views/ColorPicker.cs
@@ -188,13 +188,6 @@ public override void OnDrawContent (Rectangle viewport)
}
}
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
/// Add the commands.
private void AddCommands ()
diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs
index 5f1d25a9ee..135dde57dd 100644
--- a/Terminal.Gui/Views/ComboBox.cs
+++ b/Terminal.Gui/Views/ComboBox.cs
@@ -612,13 +612,14 @@ private void ProcessLayout ()
Height = _minimumHeight;
}
+ // BUGBUG: This uses Viewport. Should use ContentSize
if ((!_autoHide && Viewport.Width > 0 && _search.Frame.Width != Viewport.Width)
|| (_autoHide && Viewport.Width > 0 && _search.Frame.Width != Viewport.Width - 1))
{
_search.Width = _listview.Width = _autoHide ? Viewport.Width - 1 : Viewport.Width;
_listview.Height = CalculatetHeight ();
- _search.SetRelativeLayout (ContentSize);
- _listview.SetRelativeLayout (ContentSize);
+ _search.SetRelativeLayout (ContentSize.GetValueOrDefault());
+ _listview.SetRelativeLayout (ContentSize.GetValueOrDefault ());
}
}
diff --git a/Terminal.Gui/Views/DatePicker.cs b/Terminal.Gui/Views/DatePicker.cs
index 1b4c4c8412..075c9f890b 100644
--- a/Terminal.Gui/Views/DatePicker.cs
+++ b/Terminal.Gui/Views/DatePicker.cs
@@ -214,7 +214,6 @@ private void SetInitialProperties (DateTime date)
_previousMonthButton = new Button
{
- AutoSize = false,
X = Pos.Center () - 2,
Y = Pos.Bottom (_calendar) - 1,
Height = 1,
@@ -234,7 +233,6 @@ private void SetInitialProperties (DateTime date)
_nextMonthButton = new Button
{
- AutoSize = false,
X = Pos.Right (_previousMonthButton) + 2,
Y = Pos.Bottom (_calendar) - 1,
Height = 1,
diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs
index 46787265e2..5fcfd6b072 100644
--- a/Terminal.Gui/Views/Dialog.cs
+++ b/Terminal.Gui/Views/Dialog.cs
@@ -61,9 +61,8 @@ public Dialog ()
Y = Pos.Center ();
ValidatePosDim = true;
- Width = Dim.Percent (85); // Dim.Auto (min: Dim.Percent (10));
- Height = Dim.Percent (85); //Dim.Auto (min: Dim.Percent (50));
-
+ Width = Dim.Percent (85);
+ Height = Dim.Percent (85);
ColorScheme = Colors.ColorSchemes ["Dialog"];
Modal = true;
@@ -147,7 +146,6 @@ public void AddButton (Button button)
return;
}
- //button.AutoSize = false; // BUGBUG: v2 - Hack to get around autosize not accounting for Margin?
_buttons.Add (button);
Add (button);
diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs
index 37344abe5a..a9208578d7 100644
--- a/Terminal.Gui/Views/FrameView.cs
+++ b/Terminal.Gui/Views/FrameView.cs
@@ -39,15 +39,4 @@ private void FrameView_MouseClick (object sender, MouseEventEventArgs e)
[SerializableConfigurationProperty (Scope = typeof (ThemeScope))]
[JsonConverter (typeof (JsonStringEnumConverter))]
public static LineStyle DefaultBorderStyle { get; set; } = LineStyle.Single;
-
- ///
- public override bool OnEnter (View view)
- {
- if (Subviews.Count == 0 || !Subviews.Any (subview => subview.CanFocus))
- {
- Application.Driver?.SetCursorVisibility (CursorVisibility.Invisible);
- }
-
- return base.OnEnter (view);
- }
}
diff --git a/Terminal.Gui/Views/GraphView/GraphView.cs b/Terminal.Gui/Views/GraphView/GraphView.cs
index 6f4f05bf16..d810957dd5 100644
--- a/Terminal.Gui/Views/GraphView/GraphView.cs
+++ b/Terminal.Gui/Views/GraphView/GraphView.cs
@@ -277,15 +277,6 @@ public override void OnDrawContent (Rectangle viewport)
}
}
- ///
- /// Also ensures that cursor is invisible after entering the .
- public override bool OnEnter (View view)
- {
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
-
/// Scrolls the graph down 1 page.
public void PageDown () { Scroll (0, -1 * CellSize.Y * Viewport.Height); }
diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs
index 4c70689276..bdb3fb59b5 100644
--- a/Terminal.Gui/Views/HexView.cs
+++ b/Terminal.Gui/Views/HexView.cs
@@ -31,7 +31,6 @@ public class HexView : View
private const int displayWidth = 9;
private int bpl;
- private CursorVisibility desiredCursorVisibility = CursorVisibility.Default;
private long displayStart, pos;
private SortedDictionary edits = [];
private bool firstNibble, leftSide;
@@ -50,6 +49,7 @@ public HexView (Stream source)
// BUG: This will always call the most-derived definition of CanFocus.
// Either seal it or don't set it here.
CanFocus = true;
+ CursorVisibility = CursorVisibility.Default;
leftSide = true;
firstNibble = true;
@@ -129,21 +129,6 @@ public Point CursorPosition
}
}
- /// Get / Set the wished cursor when the field is focused
- public CursorVisibility DesiredCursorVisibility
- {
- get => desiredCursorVisibility;
- set
- {
- if (desiredCursorVisibility != value && HasFocus)
- {
- Application.Driver.SetCursorVisibility (value);
- }
-
- desiredCursorVisibility = value;
- }
- }
-
///
/// Sets or gets the offset into the that will displayed at the top of the
///
@@ -462,14 +447,6 @@ void SetAttribute (Attribute attribute)
/// The key value pair.
public virtual void OnEdited (HexViewEditEventArgs e) { Edited?.Invoke (this, e); }
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (DesiredCursorVisibility);
-
- return base.OnEnter (view);
- }
-
///
/// Method used to invoke the event passing the
/// arguments.
diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs
index 7b7b331c14..40861a9267 100644
--- a/Terminal.Gui/Views/Label.cs
+++ b/Terminal.Gui/Views/Label.cs
@@ -15,8 +15,9 @@ public class Label : View
///
public Label ()
{
- Height = 1;
- AutoSize = true;
+ Height = Dim.Auto (Dim.DimAutoStyle.Text);
+ Width = Dim.Auto (Dim.DimAutoStyle.Text);
+ TextFormatter.AutoSize = true;
// Things this view knows how to do
AddCommand (Command.HotKey, FocusNext);
@@ -63,11 +64,4 @@ public override Rune HotKeySpecifier
return true;
}
-
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
- return base.OnEnter (view);
- }
}
diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs
index aef82e9596..b91ede6cb1 100644
--- a/Terminal.Gui/Views/ListView.cs
+++ b/Terminal.Gui/Views/ListView.cs
@@ -700,11 +700,6 @@ public override void OnDrawContent (Rectangle viewport)
///
public override bool OnEnter (View view)
{
- if (IsInitialized)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
- }
-
if (_lastSelectedItem != _selected)
{
EnsureSelectedItemVisible ();
@@ -791,7 +786,8 @@ public virtual bool OnSelectedChanged ()
}
Move (x, y);
- return new Point (x, y);
+
+ return null; // Don't show the cursor
}
/// 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 1908da8117..6d0353f9b2 100644
--- a/Terminal.Gui/Views/Menu/Menu.cs
+++ b/Terminal.Gui/Views/Menu/Menu.cs
@@ -751,7 +751,7 @@ internal Attribute DetermineColorSchemeFor (MenuItem item, int index)
if (index == _currentChild)
{
- return ColorScheme.Focus;
+ return GetFocusColor ();
}
return !item.IsEnabled () ? ColorScheme.Disabled : GetNormalColor ();
@@ -787,7 +787,7 @@ public override void OnDrawContent (Rectangle viewport)
Driver.SetAttribute (
item is null ? GetNormalColor () :
- i == _currentChild ? ColorScheme.Focus : GetNormalColor ()
+ i == _currentChild ? GetFocusColor() : GetNormalColor ()
);
if (item is null && BorderStyle != LineStyle.None)
@@ -890,13 +890,14 @@ public override void OnDrawContent (Rectangle viewport)
{
var tf = new TextFormatter
{
+ AutoSize = true,
Alignment = TextAlignment.Centered, HotKeySpecifier = MenuBar.HotKeySpecifier, Text = textToDraw
};
// The -3 is left/right border + one space (not sure what for)
tf.Draw (
ViewportToScreen (new (1, i, Frame.Width - 3, 1)),
- i == _currentChild ? ColorScheme.Focus : GetNormalColor (),
+ i == _currentChild ? GetFocusColor () : GetNormalColor (),
i == _currentChild ? ColorScheme.HotFocus : ColorScheme.HotNormal,
SuperView?.ViewportToScreen (SuperView.Viewport) ?? Rectangle.Empty
);
@@ -906,7 +907,7 @@ public override void OnDrawContent (Rectangle viewport)
DrawHotString (
textToDraw,
i == _currentChild ? ColorScheme.HotFocus : ColorScheme.HotNormal,
- i == _currentChild ? ColorScheme.Focus : GetNormalColor ()
+ i == _currentChild ? GetFocusColor () : GetNormalColor ()
);
}
@@ -934,7 +935,7 @@ public override void OnDrawContent (Rectangle viewport)
Driver.Clip = savedClip;
- PositionCursor ();
+ // PositionCursor ();
}
private void Current_DrawContentComplete (object sender, DrawEventArgs e)
@@ -956,7 +957,9 @@ private void Current_DrawContentComplete (object sender, DrawEventArgs e)
else
{
Move (2, 1 + _currentChild);
- return new (2, 1 + _currentChild);
+
+ return null; // Don't show the cursor
+
}
}
@@ -1332,14 +1335,6 @@ private int GetSubMenuIndex (MenuBarItem subMenu)
return pos;
}
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
-
protected override void Dispose (bool disposing)
{
if (Application.Current is { })
diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs
index 4cf861ad4b..8ca8e3ba61 100644
--- a/Terminal.Gui/Views/Menu/MenuBar.cs
+++ b/Terminal.Gui/Views/Menu/MenuBar.cs
@@ -509,7 +509,7 @@ public override void OnDrawContent (Rectangle viewport)
+ _rightPadding;
}
- PositionCursor ();
+ //PositionCursor ();
}
/// Virtual method that will invoke the .
@@ -621,7 +621,7 @@ out openCurrentMenu._currentChild
pos++;
Move (pos + 1, 0);
- return new (pos +1, 0);
+ return null; // Don't show the cursor
}
pos += _leftPadding
@@ -631,7 +631,7 @@ out openCurrentMenu._currentChild
: 0)
+ _rightPadding;
}
- return null;
+ return null; // Don't show the cursor
}
// Activates the menu, handles either first focus, or activating an entry when it was already active
@@ -739,7 +739,7 @@ internal bool CloseMenu (bool reopen = false, bool isSubMenu = false, bool ignor
case false:
if (_openMenu is { })
{
- Application.Current.Remove (_openMenu);
+ Application.Current?.Remove (_openMenu);
}
SetNeedsDisplay ();
@@ -788,7 +788,7 @@ internal bool CloseMenu (bool reopen = false, bool isSubMenu = false, bool ignor
else
{
SetFocus ();
- PositionCursor ();
+ //PositionCursor ();
}
IsMenuOpen = false;
@@ -823,7 +823,12 @@ internal Point GetScreenOffset ()
Rectangle superViewFrame = SuperView is null ? Driver.Screen : SuperView.Frame;
View sv = SuperView is null ? Application.Current : SuperView;
- Point viewportOffset = sv.GetViewportOffsetFromFrame ();
+ if (sv is null)
+ {
+ // Support Unit Tests
+ return Point.Empty;
+ }
+ Point viewportOffset = sv?.GetViewportOffsetFromFrame () ?? Point.Empty;
return new (
superViewFrame.X - sv.Frame.X - viewportOffset.X,
@@ -965,7 +970,7 @@ internal void OpenMenu (int index, int sIndex = -1, MenuBarItem subMenu = null)
if (_openMenu is { })
{
- Application.Current.Remove (_openMenu);
+ Application.Current?.Remove (_openMenu);
_openMenu.Dispose ();
_openMenu = null;
}
@@ -1002,7 +1007,15 @@ internal void OpenMenu (int index, int sIndex = -1, MenuBarItem subMenu = null)
openCurrentMenu = _openMenu;
openCurrentMenu._previousSubFocused = _openMenu;
- Application.Current.Add (_openMenu);
+ if (Application.Current is { })
+ {
+ Application.Current.Add (_openMenu);
+ }
+ else
+ {
+ _openMenu.BeginInit();
+ _openMenu.EndInit();
+ }
_openMenu.SetFocus ();
break;
@@ -1060,7 +1073,14 @@ internal void OpenMenu (int index, int sIndex = -1, MenuBarItem subMenu = null)
openCurrentMenu._previousSubFocused = last._previousSubFocused;
_openSubMenu.Add (openCurrentMenu);
- Application.Current.Add (openCurrentMenu);
+ Application.Current?.Add (openCurrentMenu);
+
+ if (!openCurrentMenu.IsInitialized)
+ {
+ // Supports unit tests
+ openCurrentMenu.BeginInit ();
+ openCurrentMenu.EndInit ();
+ }
}
_selectedSub = _openSubMenu.Count - 1;
@@ -1631,13 +1651,6 @@ private bool FindShortcutInChildMenu (KeyCode key, MenuBarItem menuBarItem, out
#region Mouse Handling
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
///
public override bool OnLeave (View view)
diff --git a/Terminal.Gui/Views/MessageBox.cs b/Terminal.Gui/Views/MessageBox.cs
index ef7a33d10b..b65395abd8 100644
--- a/Terminal.Gui/Views/MessageBox.cs
+++ b/Terminal.Gui/Views/MessageBox.cs
@@ -369,14 +369,13 @@ params string [] buttons
var messageLabel = new Label
{
- AutoSize = !wrapMessage,
Text = message,
TextAlignment = TextAlignment.Centered,
X = Pos.Center (),
Y = 0
};
- if (!messageLabel.AutoSize)
+ if (wrapMessage)
{
messageLabel.Width = Dim.Fill ();
messageLabel.Height = Dim.Fill (1);
@@ -467,7 +466,7 @@ void Dialog_Loaded (object s, EventArgs e)
+ adornmentsThickness.Vertical);
}
- d.SetRelativeLayout (d.SuperView?.ContentSize ?? Application.Top.ContentSize);
+ d.SetRelativeLayout (d.SuperView?.ContentSize.GetValueOrDefault () ?? Application.Top.ContentSize.GetValueOrDefault ());
d.LayoutSubviews ();
}
}
diff --git a/Terminal.Gui/Views/ProgressBar.cs b/Terminal.Gui/Views/ProgressBar.cs
index cfddca1e00..fed490d692 100644
--- a/Terminal.Gui/Views/ProgressBar.cs
+++ b/Terminal.Gui/Views/ProgressBar.cs
@@ -198,14 +198,6 @@ public override void OnDrawContent (Rectangle viewport)
}
}
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
-
/// Notifies the that some progress has taken place.
///
/// If the is percentage mode, it switches to activity mode. If is in activity mode, the
diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs
index d102dd5738..83cc14c3c0 100644
--- a/Terminal.Gui/Views/RadioGroup.cs
+++ b/Terminal.Gui/Views/RadioGroup.cs
@@ -276,14 +276,6 @@ public override void OnDrawContent (Rectangle viewport)
}
}
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
-
///
public override bool? OnInvokingKeyBindings (Key keyEvent)
{
@@ -371,7 +363,7 @@ public virtual void OnSelectedItemChanged (int selectedItem, int previousSelecte
}
Move (x, y);
- return new Point (x, y);
+ return null; // Don't show the cursor
}
/// Allow to invoke the after their creation.
diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs
index 3f47a5cfa8..a695a3d5bf 100644
--- a/Terminal.Gui/Views/ScrollBarView.cs
+++ b/Terminal.Gui/Views/ScrollBarView.cs
@@ -667,13 +667,6 @@ public override void OnDrawContent (Rectangle viewport)
}
}
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
/// Only used for a hosted view that will update and redraw the scrollbars.
public virtual void Refresh () { ShowHideScrollBars (); }
@@ -944,7 +937,7 @@ private void SetWidthHeight ()
// BUGBUG: v2 - If Host is also the ScrollBarView's superview, this is all bogus because it's not
// supported that a view can reference it's superview's Dims. This code also assumes the host does
// not have a margin/borderframe/padding.
- if (!IsInitialized)
+ if (!IsInitialized || _otherScrollBarView is { IsInitialized: false })
{
return;
}
diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs
index b33a2a80ee..6e2361d53a 100644
--- a/Terminal.Gui/Views/ScrollView.cs
+++ b/Terminal.Gui/Views/ScrollView.cs
@@ -88,10 +88,10 @@ public ScrollView ()
AddCommand (Command.PageDown, () => ScrollDown (Viewport.Height));
AddCommand (Command.PageLeft, () => ScrollLeft (Viewport.Width));
AddCommand (Command.PageRight, () => ScrollRight (Viewport.Width));
- AddCommand (Command.TopHome, () => ScrollUp (ContentSize.Height));
- AddCommand (Command.BottomEnd, () => ScrollDown (ContentSize.Height));
- AddCommand (Command.LeftHome, () => ScrollLeft (ContentSize.Width));
- AddCommand (Command.RightEnd, () => ScrollRight (ContentSize.Width));
+ AddCommand (Command.TopHome, () => ScrollUp (ContentSize.Value.Height));
+ AddCommand (Command.BottomEnd, () => ScrollDown (ContentSize.Value.Height));
+ AddCommand (Command.LeftHome, () => ScrollLeft (ContentSize.Value.Width));
+ AddCommand (Command.RightEnd, () => ScrollRight (ContentSize.Value.Width));
// Default keybindings for this view
KeyBindings.Add (Key.CursorUp, Command.ScrollUp);
@@ -127,7 +127,7 @@ public ScrollView ()
}
SetContentOffset (_contentOffset);
- _contentView.Frame = new Rectangle (ContentOffset, ContentSize);
+ _contentView.Frame = new Rectangle (ContentOffset, ContentSize.GetValueOrDefault ());
// PERF: How about calls to Point.Offset instead?
_vertical.ChangedPosition += delegate { ContentOffset = new Point (ContentOffset.X, _vertical.Position); };
@@ -138,9 +138,13 @@ public ScrollView ()
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 });
- _vertical.Size = e.Size.Height;
- _horizontal.Size = e.Size.Width;
+ if (e.Size is null)
+ {
+ return;
+ }
+ _contentView.Frame = new Rectangle (ContentOffset, e.Size.Value with { Width = e.Size.Value.Width - 1, Height = e.Size.Value.Height - 1 });
+ _vertical.Size = e.Size.Value.Height;
+ _horizontal.Size = e.Size.Value.Width;
}
private void Application_UnGrabbedMouse (object sender, ViewEventArgs e)
@@ -240,26 +244,26 @@ public bool KeepContentAlwaysInViewport
_horizontal.OtherScrollBarView.KeepContentAlwaysInViewport = value;
Point p = default;
- if (value && -_contentOffset.X + Viewport.Width > ContentSize.Width)
+ if (value && -_contentOffset.X + Viewport.Width > ContentSize.GetValueOrDefault ().Width)
{
p = new Point (
- ContentSize.Width - Viewport.Width + (_showVerticalScrollIndicator ? 1 : 0),
+ ContentSize.GetValueOrDefault ().Width - Viewport.Width + (_showVerticalScrollIndicator ? 1 : 0),
-_contentOffset.Y
);
}
- if (value && -_contentOffset.Y + Viewport.Height > ContentSize.Height)
+ if (value && -_contentOffset.Y + Viewport.Height > ContentSize.GetValueOrDefault ().Height)
{
if (p == default (Point))
{
p = new Point (
-_contentOffset.X,
- ContentSize.Height - Viewport.Height + (_showHorizontalScrollIndicator ? 1 : 0)
+ ContentSize.GetValueOrDefault ().Height - Viewport.Height + (_showHorizontalScrollIndicator ? 1 : 0)
);
}
else
{
- p.Y = ContentSize.Height - Viewport.Height + (_showHorizontalScrollIndicator ? 1 : 0);
+ p.Y = ContentSize.GetValueOrDefault ().Height - Viewport.Height + (_showHorizontalScrollIndicator ? 1 : 0);
}
}
@@ -380,17 +384,6 @@ public override void OnDrawContent (Rectangle viewport)
DrawScrollBars ();
}
- ///
- public override bool OnEnter (View view)
- {
- if (Subviews.Count == 0 || !Subviews.Any (subview => subview.CanFocus))
- {
- Application.Driver?.SetCursorVisibility (CursorVisibility.Invisible);
- }
-
- return base.OnEnter (view);
- }
-
///
public override bool OnKeyDown (Key a)
{
@@ -456,7 +449,8 @@ protected internal override bool OnMouseEvent (MouseEvent me)
if (InternalSubviews.Count == 0)
{
Move (0, 0);
- return Point.Empty;
+
+ return null; // Don't show the cursor
}
return base.PositionCursor ();
}
@@ -613,7 +607,7 @@ private void SetContentOffset (Point offset)
{
// INTENT: Unclear intent. How about a call to Offset?
_contentOffset = new Point (-Math.Abs (offset.X), -Math.Abs (offset.Y));
- _contentView.Frame = new Rectangle (_contentOffset, ContentSize);
+ _contentView.Frame = new Rectangle (_contentOffset, ContentSize.GetValueOrDefault ());
int p = Math.Max (0, -_contentOffset.Y);
if (_vertical.Position != p)
@@ -644,7 +638,7 @@ private void ShowHideScrollBars ()
bool v = false, h = false;
var p = false;
- if (Viewport.Height == 0 || Viewport.Height > ContentSize.Height)
+ if (ContentSize is { } && (Viewport.Height == 0 || Viewport.Height > ContentSize.Value.Height))
{
if (ShowVerticalScrollIndicator)
{
@@ -653,7 +647,7 @@ private void ShowHideScrollBars ()
v = false;
}
- else if (Viewport.Height > 0 && Viewport.Height == ContentSize.Height)
+ else if (ContentSize is { } && Viewport.Height > 0 && Viewport.Height == ContentSize.Value.Height)
{
p = true;
}
@@ -667,7 +661,7 @@ private void ShowHideScrollBars ()
v = true;
}
- if (Viewport.Width == 0 || Viewport.Width > ContentSize.Width)
+ if (ContentSize is { } && (Viewport.Width == 0 || Viewport.Width > ContentSize.Value.Width))
{
if (ShowHorizontalScrollIndicator)
{
@@ -676,7 +670,7 @@ private void ShowHideScrollBars ()
h = false;
}
- else if (Viewport.Width > 0 && Viewport.Width == ContentSize.Width && p)
+ else if (ContentSize is { } && Viewport.Width > 0 && Viewport.Width == ContentSize.Value.Width && p)
{
if (ShowHorizontalScrollIndicator)
{
diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs
index 2feb5da91a..4a1c0ac577 100644
--- a/Terminal.Gui/Views/Slider.cs
+++ b/Terminal.Gui/Views/Slider.cs
@@ -150,7 +150,6 @@ public class SliderStyle
internal class SliderConfiguration
{
internal bool _allowEmpty;
- internal bool _autoSize;
internal int _endSpacing;
internal int _innerSpacing;
internal Orientation _legendsOrientation = Orientation.Horizontal;
@@ -243,7 +242,10 @@ private void SetInitialProperties (
Orientation orientation = Orientation.Horizontal
)
{
+ Width = Dim.Auto (Dim.DimAutoStyle.Content);
+ Height = Dim.Auto (Dim.DimAutoStyle.Content);
CanFocus = true;
+ CursorVisibility = CursorVisibility.Default;
_options = options ?? new List> ();
@@ -254,22 +256,19 @@ private void SetInitialProperties (
SetDefaultStyle ();
SetCommands ();
- // When we lose focus of the View(Slider), if we are range selecting we stop it.
- Leave += (s, e) =>
- {
- //if (_settingRange == true) {
- // _settingRange = false;
- //}
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
- };
-
Enter += (s, e) => { };
- LayoutComplete += (s, e) =>
+ // BUGBUG: This should not be needed - Need to ensure SetRelativeLayout gets called during EndInit
+ Initialized += (s, e) =>
+ {
+ SetContentSizeBestFit ();
+ };
+
+ LayoutStarted += (s, e) =>
{
- CalcSpacingConfig ();
- SetBoundsBestFit ();
+ SetContentSizeBestFit ();
};
+
}
#endregion
@@ -309,7 +308,7 @@ public virtual bool OnOptionFocused (int newFocusedOption, SliderEventArgs ar
{
_lastFocusedOption = FocusedOption;
FocusedOption = newFocusedOption;
- PositionCursor ();
+ //PositionCursor ();
}
return args.Cancel;
@@ -373,29 +372,6 @@ public bool AllowEmpty
}
}
- ///
- /// If the slider will be sized to fit the available space (the Viewport of the the
- /// SuperView).
- ///
- ///
- /// For testing, if there is no SuperView, the slider will be sized based on what is
- /// set to.
- ///
- public override bool AutoSize
- {
- get => _config._autoSize;
- set
- {
- _config._autoSize = value;
-
- if (IsInitialized)
- {
- CalcSpacingConfig ();
- SetBoundsBestFit ();
- }
- }
- }
-
/// Gets or sets the number of rows/columns between
public int InnerSpacing
{
@@ -404,11 +380,7 @@ public int InnerSpacing
{
_config._innerSpacing = value;
- if (IsInitialized)
- {
- CalcSpacingConfig ();
- SetBoundsBestFit ();
- }
+ SetContentSizeBestFit ();
}
}
@@ -452,11 +424,7 @@ public virtual bool OnOrientationChanged (Orientation newOrientation)
_config._sliderOrientation = newOrientation;
SetKeyBindings ();
- if (IsInitialized)
- {
- CalcSpacingConfig ();
- SetBoundsBestFit ();
- }
+ SetContentSizeBestFit ();
}
return args.Cancel;
@@ -470,11 +438,7 @@ public Orientation LegendsOrientation
{
_config._legendsOrientation = value;
- if (IsInitialized)
- {
- CalcSpacingConfig ();
- SetBoundsBestFit ();
- }
+ SetContentSizeBestFit ();
}
}
@@ -506,8 +470,7 @@ public List> Options
return;
}
- CalcSpacingConfig ();
- SetBoundsBestFit ();
+ SetContentSizeBestFit ();
}
}
@@ -536,7 +499,7 @@ public bool ShowLegends
set
{
_config._showLegends = value;
- SetBoundsBestFit ();
+ SetContentSizeBestFit ();
}
}
@@ -644,168 +607,110 @@ private void SetDefaultStyle ()
// Last = '┤',
}
- ///
- /// Calculates the spacing configuration (start, inner, end) as well as turning on/off legend abbreviation if
- /// needed. Behaves differently based on and .
- ///
- internal void CalcSpacingConfig ()
+ /// Adjust the dimensions of the Slider to the best value.
+ public void SetContentSizeBestFit ()
{
- var size = 0;
-
- if (_options.Count == 0 || !IsInitialized)
+ if (!IsInitialized || /*!(Height is Dim.DimAuto && Width is Dim.DimAuto) || */_options.Count == 0)
{
return;
}
- _config._innerSpacing = 0;
- _config._startSpacing = 0;
- _config._endSpacing = 0;
+ CalcSpacingConfig ();
- if (AutoSize)
- {
- // Max size is SuperView's Viewport. Min Size is size that will fit.
- if (SuperView is { })
- {
- // Calculate the size of the slider based on the size of the SuperView's Viewport.
- if (_config._sliderOrientation == Orientation.Horizontal)
- {
- size = int.Min (SuperView.Viewport.Width, CalcBestLength ());
- }
- else
- {
- size = int.Min (SuperView.Viewport.Height, CalcBestLength ());
- }
- }
- else
- {
- // Use the config values
- size = CalcMinLength ();
+ Thickness adornmentsThickness = GetAdornmentsThickness ();
- return;
- }
+ var svWidth = SuperView?.ContentSize?.Width ?? 0;
+ var svHeight = SuperView?.ContentSize?.Height ?? 0;
+
+ if (_config._sliderOrientation == Orientation.Horizontal)
+ {
+ ContentSize = new (int.Min (svWidth, CalcBestLength ()), int.Min (svHeight, CalcThickness ()));
}
else
{
- // Fit Slider to the Viewport
- if (_config._sliderOrientation == Orientation.Horizontal)
- {
- size = Viewport.Width;
- }
- else
- {
- size = Viewport.Height;
- }
+ ContentSize = new (int.Min (svWidth, CalcThickness ()), int.Min (svHeight, CalcBestLength ()));
}
- int max_legend; // Because the legends are centered, the longest one determines inner spacing
+ return;
- if (_config._sliderOrientation == _config._legendsOrientation)
+ void CalcSpacingConfig ()
{
- max_legend = int.Max (_options.Max (s => s.Legend?.Length ?? 1), 1);
- }
- else
- {
- max_legend = 1;
- }
+ _config._innerSpacing = 0;
+ _config._startSpacing = 0;
+ _config._endSpacing = 0;
- int min_size_that_fits_legends = _options.Count == 1 ? max_legend : max_legend / (_options.Count - 1);
+ int size = 0;
+ if (ContentSize is { })
+ {
+ size = _config._sliderOrientation == Orientation.Horizontal ? ContentSize.Value.Width : ContentSize.Value.Height;
+ }
- string first;
- string last;
+ int max_legend; // Because the legends are centered, the longest one determines inner spacing
- if (max_legend >= size)
- {
if (_config._sliderOrientation == _config._legendsOrientation)
{
- _config._showLegendsAbbr = true;
-
- foreach (SliderOption o in _options.Where (op => op.LegendAbbr == default (Rune)))
- {
- o.LegendAbbr = (Rune)(o.Legend?.Length > 0 ? o.Legend [0] : ' ');
- }
+ max_legend = int.Max (_options.Max (s => s.Legend?.Length ?? 1), 1);
+ }
+ else
+ {
+ max_legend = 1;
}
- first = "x";
- last = "x";
- }
- else
- {
- _config._showLegendsAbbr = false;
- first = _options.First ().Legend;
- last = _options.Last ().Legend;
- }
+ int min_size_that_fits_legends = _options.Count == 1 ? max_legend : max_legend / (_options.Count - 1);
- // --o--
- // Hello
- // Left = He
- // Right = lo
- int first_left = (first.Length - 1) / 2; // Chars count of the first option to the left.
- int last_right = last.Length / 2; // Chars count of the last option to the right.
+ string first;
+ string last;
- if (_config._sliderOrientation != _config._legendsOrientation)
- {
- first_left = 0;
- last_right = 0;
- }
+ if (max_legend >= size)
+ {
+ if (_config._sliderOrientation == _config._legendsOrientation)
+ {
+ _config._showLegendsAbbr = true;
- // -1 because it's better to have an extra space at right than to clip
- int width = size - first_left - last_right - 1;
+ foreach (SliderOption o in _options.Where (op => op.LegendAbbr == default (Rune)))
+ {
+ o.LegendAbbr = (Rune)(o.Legend?.Length > 0 ? o.Legend [0] : ' ');
+ }
+ }
- _config._startSpacing = first_left;
+ first = "x";
+ last = "x";
+ }
+ else
+ {
+ _config._showLegendsAbbr = false;
+ first = _options.First ().Legend;
+ last = _options.Last ().Legend;
+ }
- if (_options.Count == 1)
- {
- _config._innerSpacing = max_legend;
- }
- else
- {
- _config._innerSpacing = Math.Max (0, (int)Math.Floor ((double)width / (_options.Count - 1)) - 1);
- }
+ // --o--
+ // Hello
+ // Left = He
+ // Right = lo
+ int first_left = (first.Length - 1) / 2; // Chars count of the first option to the left.
+ int last_right = last.Length / 2; // Chars count of the last option to the right.
- _config._endSpacing = last_right;
- }
+ if (_config._sliderOrientation != _config._legendsOrientation)
+ {
+ first_left = 0;
+ last_right = 0;
+ }
- /// Adjust the dimensions of the Slider to the best value if is true.
- public void SetBoundsBestFit ()
- {
- if (!IsInitialized || AutoSize == false)
- {
- return;
- }
+ // -1 because it's better to have an extra space at right than to clip
+ int width = size - first_left - last_right - 1;
- Thickness adornmentsThickness = GetAdornmentsThickness ();
+ _config._startSpacing = first_left;
- if (_config._sliderOrientation == Orientation.Horizontal)
- {
- Viewport = new (
- Viewport.Location,
- new (
- int.Min (
- SuperView.Viewport.Width - adornmentsThickness.Horizontal,
- CalcBestLength ()
- ),
- int.Min (
- SuperView.Viewport.Height - adornmentsThickness.Vertical,
- CalcThickness ()
- )
- )
- );
- }
- else
- {
- Viewport = new (
- Viewport.Location,
- new (
- int.Min (
- SuperView.Viewport.Width - adornmentsThickness.Horizontal,
- CalcThickness ()
- ),
- int.Min (
- SuperView.Viewport.Height - adornmentsThickness.Vertical,
- CalcBestLength ()
- )
- )
- );
+ if (_options.Count == 1)
+ {
+ _config._innerSpacing = max_legend;
+ }
+ else
+ {
+ _config._innerSpacing = Math.Max (0, (int)Math.Floor ((double)width / (_options.Count - 1)) - 1);
+ }
+
+ _config._endSpacing = last_right;
}
}
@@ -975,17 +880,6 @@ internal bool TryGetOptionByPosition (int x, int y, int threshold, out int optio
///
public override Point? PositionCursor ()
{
- //base.PositionCursor ();
-
- if (HasFocus)
- {
- Driver?.SetCursorVisibility (CursorVisibility.Default);
- }
- else
- {
- Driver?.SetCursorVisibility (CursorVisibility.Invisible);
- }
-
if (TryGetPositionByOption (FocusedOption, out (int x, int y) position))
{
if (IsInitialized && Viewport.Contains (position.x, position.y))
@@ -995,7 +889,7 @@ internal bool TryGetOptionByPosition (int x, int y, int threshold, out int optio
return new (position.x, position.x);
}
}
- return null;
+ return base.PositionCursor ();
}
///
@@ -1525,7 +1419,7 @@ private void DrawLegends ()
private Point? _moveRenderPosition;
///
- protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
+ protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
{
// Note(jmperricone): Maybe we click to focus the cursor, and on next click we set the option.
// That will makes OptionFocused Event more relevant.
diff --git a/Terminal.Gui/Views/StatusBar.cs b/Terminal.Gui/Views/StatusBar.cs
index 6dc96f663d..a021ca5445 100644
--- a/Terminal.Gui/Views/StatusBar.cs
+++ b/Terminal.Gui/Views/StatusBar.cs
@@ -215,14 +215,6 @@ public override void OnDrawContent (Rectangle viewport)
}
}
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
-
///
public override bool? OnInvokingKeyBindings (Key keyEvent)
{
diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs
index 44375baf93..a3bde6eb26 100644
--- a/Terminal.Gui/Views/TabView.cs
+++ b/Terminal.Gui/Views/TabView.cs
@@ -1204,13 +1204,6 @@ public override void OnDrawContentComplete (Rectangle viewport)
}
}
- public override bool OnEnter (View view)
- {
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnEnter (view);
- }
-
private int GetUnderlineYPosition ()
{
if (_host.Style.TabsOnBottom)
diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs
index 0465d6e0d3..2ae46c7fdb 100644
--- a/Terminal.Gui/Views/TableView/TableView.cs
+++ b/Terminal.Gui/Views/TableView/TableView.cs
@@ -978,8 +978,6 @@ public override bool OnProcessKeyDown (Key keyEvent)
{
if (TableIsNullOrInvisible ())
{
- PositionCursor ();
-
return false;
}
@@ -1029,7 +1027,8 @@ public void PageUp (bool extend)
if (screenPoint is { })
{
Move (screenPoint.Value.X, screenPoint.Value.Y);
- return screenPoint;
+
+ return null;//screenPoint;
}
return null;
@@ -1529,7 +1528,6 @@ private bool CycleToNextTableEntryBeginningWith (Key keyEvent)
SelectedRow = match;
EnsureValidSelection ();
EnsureSelectedCellIsVisible ();
- PositionCursor ();
SetNeedsDisplay ();
return true;
diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs
index dc755289f0..9bb71b5232 100644
--- a/Terminal.Gui/Views/TextField.cs
+++ b/Terminal.Gui/Views/TextField.cs
@@ -36,6 +36,7 @@ public TextField ()
Height = 1;
CanFocus = true;
+ CursorVisibility = CursorVisibility.Default;
Used = true;
WantMousePositionReports = true;
@@ -756,11 +757,11 @@ public void InsertText (string toAdd, bool useOldCursorPos = true)
{
foreach (char ch in toAdd)
{
- KeyCode key;
+ Key key;
try
{
- key = (KeyCode)ch;
+ key = ch;
}
catch (Exception)
{
@@ -769,7 +770,7 @@ public void InsertText (string toAdd, bool useOldCursorPos = true)
);
}
- InsertText (new Key { KeyCode = key }, useOldCursorPos);
+ InsertText (key, useOldCursorPos);
}
}
@@ -819,7 +820,7 @@ public virtual void KillWordForwards ()
}
///
- protected internal override bool OnMouseEvent (MouseEvent ev)
+ protected internal override bool OnMouseEvent (MouseEvent ev)
{
if (!ev.Flags.HasFlag (MouseFlags.Button1Pressed)
&& !ev.Flags.HasFlag (MouseFlags.ReportMousePosition)
@@ -931,7 +932,7 @@ protected internal override bool OnMouseEvent (MouseEvent ev)
ShowContextMenu ();
}
- SetNeedsDisplay ();
+ //SetNeedsDisplay ();
return true;
@@ -1035,17 +1036,6 @@ public override void OnDrawContent (Rectangle viewport)
_isDrawing = false;
}
- ///
- public override bool OnEnter (View view)
- {
- if (IsInitialized)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Default);
- }
-
- return base.OnEnter (view);
- }
-
///
public override bool? OnInvokingKeyBindings (Key a)
{
diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs
index f421fb931d..a51e55e540 100644
--- a/Terminal.Gui/Views/TextValidateField.cs
+++ b/Terminal.Gui/Views/TextValidateField.cs
@@ -598,22 +598,6 @@ public override void OnDrawContent (Rectangle viewport)
}
}
- ///
- public override bool OnEnter (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Default);
-
- return base.OnEnter (view);
- }
-
- ///
- public override bool OnLeave (View view)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnLeave (view);
- }
-
///
public override bool OnProcessKeyDown (Key a)
{
@@ -659,14 +643,6 @@ public override bool OnProcessKeyDown (Key a)
}
Move (curPos, 0);
- if (curPos < 0 || curPos >= Viewport.Width)
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Invisible);
- }
- else
- {
- Application.Driver.SetCursorVisibility (CursorVisibility.Default);
- }
return new (curPos, 0);
}
diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs
index a83be01a32..22e487d723 100644
--- a/Terminal.Gui/Views/TextView.cs
+++ b/Terminal.Gui/Views/TextView.cs
@@ -243,7 +243,7 @@ public static List ToRuneCellList (string str, ColorScheme? colorSchem
foreach (Rune rune in str.EnumerateRunes ())
{
- cells.Add (new() { Rune = rune, ColorScheme = colorScheme });
+ cells.Add (new () { Rune = rune, ColorScheme = colorScheme });
}
return cells;
@@ -906,7 +906,7 @@ internal static List StringToRuneCells (string str, ColorScheme? color
foreach (Rune rune in str.ToRunes ())
{
- cells.Add (new() { Rune = rune, ColorScheme = colorScheme });
+ cells.Add (new () { Rune = rune, ColorScheme = colorScheme });
}
return cells;
@@ -918,7 +918,7 @@ internal static List ToRuneCells (IEnumerable runes, ColorScheme
foreach (Rune rune in runes)
{
- cells.Add (new() { Rune = rune, ColorScheme = colorScheme });
+ cells.Add (new () { Rune = rune, ColorScheme = colorScheme });
}
return cells;
@@ -1979,9 +1979,6 @@ 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
@@ -1990,6 +1987,7 @@ public class TextView : View
public TextView ()
{
CanFocus = true;
+ CursorVisibility = CursorVisibility.Default;
Used = true;
_model.LinesLoaded += Model_LinesLoaded!;
@@ -2512,7 +2510,7 @@ public TextView ()
_currentCulture = Thread.CurrentThread.CurrentUICulture;
- ContextMenu = new() { MenuItems = BuildContextMenuBarItem () };
+ ContextMenu = new () { MenuItems = BuildContextMenuBarItem () };
ContextMenu.KeyChanged += ContextMenu_KeyChanged!;
KeyBindings.Add ((KeyCode)ContextMenu.Key, KeyBindingScope.HotKey, Command.ShowContextMenu);
@@ -2782,7 +2780,7 @@ public string SelectedText
}
}
- /// Get or sets the selecting.
+ /// Get or sets whether the user is currently selecting text.
public bool Selecting { get; set; }
/// Start column position of the selected text.
@@ -2970,7 +2968,7 @@ public void Cut ()
ClearRegion ();
_historyText.Add (
- new() { new (GetCurrentLine ()) },
+ new () { new (GetCurrentLine ()) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -3009,14 +3007,14 @@ public void DeleteCharLeft ()
if (Selecting)
{
- _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition);
+ _historyText.Add (new () { new (GetCurrentLine ()) }, CursorPosition);
ClearSelectedRegion ();
List currentLine = GetCurrentLine ();
_historyText.Add (
- new() { new (currentLine) },
+ new () { new (currentLine) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -3053,14 +3051,14 @@ public void DeleteCharRight ()
if (Selecting)
{
- _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition);
+ _historyText.Add (new () { new (GetCurrentLine ()) }, CursorPosition);
ClearSelectedRegion ();
List currentLine = GetCurrentLine ();
_historyText.Add (
- new() { new (currentLine) },
+ new () { new (currentLine) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -3314,7 +3312,7 @@ protected internal override bool OnMouseEvent (MouseEvent ev)
&& !ev.Flags.HasFlag (MouseFlags.Button1TripleClicked)
&& !ev.Flags.HasFlag (ContextMenu!.MouseFlags))
{
- return false;
+ return base.OnMouseEvent (ev);
}
if (!CanFocus)
@@ -3671,20 +3669,11 @@ public override void OnDrawContent (Rectangle viewport)
ClearRegion (viewport.Left, row, right, bottom);
}
- PositionCursor ();
+ //PositionCursor ();
_isDrawing = false;
}
- ///
- public override bool OnEnter (View view)
- {
- //TODO: Improve it by handling read only mode of the text field
- Application.Driver.SetCursorVisibility (DesiredCursorVisibility);
-
- return base.OnEnter (view);
- }
-
///
public override bool? OnInvokingKeyBindings (Key a)
{
@@ -3777,7 +3766,7 @@ public void Paste ()
List runeList = contents is null ? new () : TextModel.ToRuneCellList (contents);
List currentLine = GetCurrentLine ();
- _historyText.Add (new() { new (currentLine) }, CursorPosition);
+ _historyText.Add (new () { new (currentLine) }, CursorPosition);
List> addedLine = new () { new (currentLine), runeList };
@@ -3791,7 +3780,7 @@ public void Paste ()
CurrentRow++;
_historyText.Add (
- new() { new (GetCurrentLine ()) },
+ new () { new (GetCurrentLine ()) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -3812,7 +3801,7 @@ public void Paste ()
if (Selecting)
{
_historyText.ReplaceLast (
- new() { new (GetCurrentLine ()) },
+ new () { new (GetCurrentLine ()) },
CursorPosition,
HistoryText.LineStatus.Original
);
@@ -3836,7 +3825,7 @@ public void Paste ()
return null;
}
- if (Selecting)
+ if (Application.MouseGrabView == this && Selecting)
{
// BUGBUG: customized rect aren't supported now because the Redraw isn't using the Intersect method.
//var minRow = Math.Min (Math.Max (Math.Min (selectionStartRow, currentRow) - topRow, 0), Frame.Height);
@@ -3882,7 +3871,7 @@ public void Paste ()
return new (col, CurrentRow - _topRow);
}
- return null;
+ return null; // Hide cursor
}
/// Redoes the latest changes.
@@ -4276,7 +4265,7 @@ private void ClearRegion ()
var endCol = (int)(end & 0xffffffff);
List line = _model.GetLine (startRow);
- _historyText.Add (new() { new (line) }, new (startCol, startRow));
+ _historyText.Add (new () { new (line) }, new (startCol, startRow));
List> removedLines = new ();
@@ -4366,7 +4355,7 @@ private bool DeleteTextBackwards ()
// Delete backwards
List currentLine = GetCurrentLine ();
- _historyText.Add (new() { new (currentLine) }, CursorPosition);
+ _historyText.Add (new () { new (currentLine) }, CursorPosition);
currentLine.RemoveAt (CurrentColumn - 1);
@@ -4378,7 +4367,7 @@ private bool DeleteTextBackwards ()
CurrentColumn--;
_historyText.Add (
- new() { new (currentLine) },
+ new () { new (currentLine) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -4406,7 +4395,7 @@ private bool DeleteTextBackwards ()
int prowIdx = CurrentRow - 1;
List prevRow = _model.GetLine (prowIdx);
- _historyText.Add (new() { new (prevRow) }, CursorPosition);
+ _historyText.Add (new () { new (prevRow) }, CursorPosition);
List> removedLines = new () { new (prevRow) };
@@ -4430,7 +4419,7 @@ private bool DeleteTextBackwards ()
CurrentRow--;
_historyText.Add (
- new() { GetCurrentLine () },
+ new () { GetCurrentLine () },
new (CurrentColumn, prowIdx),
HistoryText.LineStatus.Replaced
);
@@ -4459,7 +4448,7 @@ private bool DeleteTextForwards ()
return true;
}
- _historyText.Add (new() { new (currentLine) }, CursorPosition);
+ _historyText.Add (new () { new (currentLine) }, CursorPosition);
List> removedLines = new () { new (currentLine) };
@@ -4473,7 +4462,7 @@ private bool DeleteTextForwards ()
_model.RemoveLine (CurrentRow + 1);
_historyText.Add (
- new() { new (currentLine) },
+ new () { new (currentLine) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -4487,12 +4476,12 @@ private bool DeleteTextForwards ()
}
else
{
- _historyText.Add ([[..currentLine]], CursorPosition);
+ _historyText.Add ([ [.. currentLine]], CursorPosition);
currentLine.RemoveAt (CurrentColumn);
_historyText.Add (
- [[..currentLine]],
+ [ [.. currentLine]],
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -4824,7 +4813,7 @@ private void InsertAllText (string text)
List line = GetCurrentLine ();
- _historyText.Add (new() { new (line) }, CursorPosition);
+ _historyText.Add (new () { new (line) }, CursorPosition);
// Optimize single line
if (lines.Count == 1)
@@ -4833,7 +4822,7 @@ private void InsertAllText (string text)
CurrentColumn += lines [0].Count;
_historyText.Add (
- new() { new (line) },
+ new () { new (line) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -4903,7 +4892,7 @@ private void InsertAllText (string text)
Adjust ();
_historyText.Add (
- new() { new (line) },
+ new () { new (line) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -4922,7 +4911,7 @@ private bool InsertText (Key a, ColorScheme? colorScheme = null)
SetWrapModel ();
- _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition);
+ _historyText.Add (new () { new (GetCurrentLine ()) }, CursorPosition);
if (Selecting)
{
@@ -4943,7 +4932,7 @@ private bool InsertText (Key a, ColorScheme? colorScheme = null)
{
if (Used)
{
- Insert (new() { Rune = a.AsRune, ColorScheme = colorScheme });
+ Insert (new () { Rune = a.AsRune, ColorScheme = colorScheme });
CurrentColumn++;
if (CurrentColumn >= _leftColumn + Frame.Width)
@@ -4954,13 +4943,13 @@ private bool InsertText (Key a, ColorScheme? colorScheme = null)
}
else
{
- Insert (new() { Rune = a.AsRune, ColorScheme = colorScheme });
+ Insert (new () { Rune = a.AsRune, ColorScheme = colorScheme });
CurrentColumn++;
}
}
_historyText.Add (
- new() { new (GetCurrentLine ()) },
+ new () { new (GetCurrentLine ()) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -4998,7 +4987,7 @@ private void KillToEndOfLine ()
return;
}
- _historyText.Add (new() { new (currentLine) }, CursorPosition);
+ _historyText.Add (new () { new (currentLine) }, CursorPosition);
if (currentLine.Count == 0)
{
@@ -5057,7 +5046,7 @@ private void KillToEndOfLine ()
}
_historyText.Add (
- [[..GetCurrentLine ()]],
+ [ [.. GetCurrentLine ()]],
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -5097,7 +5086,7 @@ private void KillToStartOfLine ()
return;
}
- _historyText.Add ([[..currentLine]], CursorPosition);
+ _historyText.Add ([ [.. currentLine]], CursorPosition);
if (currentLine.Count == 0)
{
@@ -5135,7 +5124,7 @@ private void KillToStartOfLine ()
];
_historyText.Add (
- [..removedLine],
+ [.. removedLine],
CursorPosition,
HistoryText.LineStatus.Removed
);
@@ -5164,7 +5153,7 @@ private void KillToStartOfLine ()
}
_historyText.Add (
- [[..GetCurrentLine ()]],
+ [ [.. GetCurrentLine ()]],
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -5188,14 +5177,14 @@ private void KillWordBackward ()
List currentLine = GetCurrentLine ();
- _historyText.Add ([[..GetCurrentLine ()]], CursorPosition);
+ _historyText.Add ([ [.. GetCurrentLine ()]], CursorPosition);
if (CurrentColumn == 0)
{
DeleteTextBackwards ();
_historyText.ReplaceLast (
- [[..GetCurrentLine ()]],
+ [ [.. GetCurrentLine ()]],
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -5234,7 +5223,7 @@ private void KillWordBackward ()
}
_historyText.Add (
- [[..GetCurrentLine ()]],
+ [ [.. GetCurrentLine ()]],
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -5256,14 +5245,14 @@ private void KillWordForward ()
List currentLine = GetCurrentLine ();
- _historyText.Add ([[..GetCurrentLine ()]], CursorPosition);
+ _historyText.Add ([ [.. GetCurrentLine ()]], CursorPosition);
if (currentLine.Count == 0 || CurrentColumn == currentLine.Count)
{
DeleteTextForwards ();
_historyText.ReplaceLast (
- [[..GetCurrentLine ()]],
+ [ [.. GetCurrentLine ()]],
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -5293,7 +5282,7 @@ private void KillWordForward ()
}
_historyText.Add (
- [[..GetCurrentLine ()]],
+ [ [.. GetCurrentLine ()]],
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -5665,13 +5654,13 @@ private bool ProcessBackTab ()
if (currentLine.Count > 0 && currentLine [CurrentColumn - 1].Rune.Value == '\t')
{
- _historyText.Add (new() { new (currentLine) }, CursorPosition);
+ _historyText.Add (new () { new (currentLine) }, CursorPosition);
currentLine.RemoveAt (CurrentColumn - 1);
CurrentColumn--;
_historyText.Add (
- new() { new (GetCurrentLine ()) },
+ new () { new (GetCurrentLine ()) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
@@ -6112,7 +6101,7 @@ private bool ProcessReturn ()
List currentLine = GetCurrentLine ();
- _historyText.Add (new() { new (currentLine) }, CursorPosition);
+ _historyText.Add (new () { new (currentLine) }, CursorPosition);
if (Selecting)
{
@@ -6145,7 +6134,7 @@ private bool ProcessReturn ()
CurrentColumn = 0;
_historyText.Add (
- new() { new (GetCurrentLine ()) },
+ new () { new (GetCurrentLine ()) },
CursorPosition,
HistoryText.LineStatus.Replaced
);
diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs
index b3608b6689..c184969e93 100644
--- a/Terminal.Gui/Views/TileView.cs
+++ b/Terminal.Gui/Views/TileView.cs
@@ -979,21 +979,14 @@ public override void OnDrawContent (Rectangle viewport)
DrawSplitterSymbol ();
}
- public override bool OnEnter (View view)
- {
- Driver.SetCursorVisibility (CursorVisibility.Default);
- PositionCursor ();
-
- return base.OnEnter (view);
- }
-
public override Point? PositionCursor ()
{
base.PositionCursor ();
Point location = moveRuneRenderLocation ?? new Point (Viewport.Width / 2, Viewport.Height / 2);
Move (location.X, location.Y);
- return location;
+
+ return null; // Hide cursor
}
///
diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs
index 5bbdbf7a7f..2350348208 100644
--- a/Terminal.Gui/Views/Toplevel.cs
+++ b/Terminal.Gui/Views/Toplevel.cs
@@ -340,11 +340,6 @@ public virtual void OnQuitKeyChanged (KeyChangedEventArgs e)
if (Focused is null)
{
EnsureFocus ();
-
- if (Focused is null)
- {
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
- }
}
return null;
@@ -368,11 +363,7 @@ public virtual void OnQuitKeyChanged (KeyChangedEventArgs e)
var cursor2 = base.PositionCursor ();
- if (Focused is null)
- {
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
- }
- return cursor2;
+ return null;
}
///
@@ -391,6 +382,12 @@ public virtual void PositionToplevel (Toplevel top)
out int ny,
out StatusBar sb
);
+
+ if (superView is null)
+ {
+ return;
+ }
+
var layoutSubviews = false;
var maxWidth = 0;
diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs
index 1b8ad7d48f..db93da9a82 100644
--- a/Terminal.Gui/Views/TreeView/TreeView.cs
+++ b/Terminal.Gui/Views/TreeView/TreeView.cs
@@ -64,8 +64,6 @@ public class TreeView : View, ITreeView where T : class
/// Cached result of
private IReadOnlyCollection> cachedLineMap;
- private CursorVisibility desiredCursorVisibility = CursorVisibility.Invisible;
-
private KeyCode objectActivationKey = KeyCode.Enter;
private int scrollOffsetHorizontal;
private int scrollOffsetVertical;
@@ -325,27 +323,6 @@ public TreeView ()
/// The current number of rows in the tree (ignoring the controls bounds).
public int ContentHeight => BuildLineMap ().Count ();
- ///
- /// Get / Set the wished cursor when the tree is focused. Only applies when is true.
- /// Defaults to .
- ///
- public CursorVisibility DesiredCursorVisibility
- {
- get => MultiSelect ? desiredCursorVisibility : CursorVisibility.Invisible;
- set
- {
- if (desiredCursorVisibility != value)
- {
- desiredCursorVisibility = value;
-
- if (HasFocus)
- {
- Application.Driver.SetCursorVisibility (DesiredCursorVisibility);
- }
- }
- }
- }
-
///
/// Gets the that searches the collection as the user
/// types.
@@ -468,7 +445,6 @@ public void ClearObjects ()
// TODO: Should this be cancelable?
ObjectActivatedEventArgs e = new (this, o);
OnObjectActivated (e);
- PositionCursor ();
return true;
}
return false;
@@ -675,8 +651,6 @@ public void AdjustSelectionToNextItemBeginningWith (
// search for next branch that begins with that letter
var characterAsStr = character.ToString ();
AdjustSelectionToNext (b => AspectGetter (b.Model).StartsWith (characterAsStr, caseSensitivity));
-
- PositionCursor ();
}
///
@@ -1183,8 +1157,6 @@ public override void OnDrawContent (Rectangle viewport)
///
public override bool OnEnter (View view)
{
- Application.Driver.SetCursorVisibility (DesiredCursorVisibility);
-
if (SelectedObject is null && Objects.Any ())
{
SelectedObject = Objects.First ();
@@ -1201,37 +1173,27 @@ public override bool OnProcessKeyDown (Key keyEvent)
return false;
}
- try
+ // BUGBUG: this should move to OnInvokingKeyBindings
+ // If not a keybinding, is the key a searchable key press?
+ if (CollectionNavigatorBase.IsCompatibleKey (keyEvent) && AllowLetterBasedNavigation)
{
- // BUGBUG: this should move to OnInvokingKeyBindings
- // If not a keybinding, is the key a searchable key press?
- if (CollectionNavigatorBase.IsCompatibleKey (keyEvent) && AllowLetterBasedNavigation)
- {
- IReadOnlyCollection> map;
+ IReadOnlyCollection> map;
- // If there has been a call to InvalidateMap since the last time
- // we need a new one to reflect the new exposed tree state
- map = BuildLineMap ();
+ // If there has been a call to InvalidateMap since the last time
+ // we need a new one to reflect the new exposed tree state
+ map = BuildLineMap ();
- // Find the current selected object within the tree
- int current = map.IndexOf (b => b.Model == SelectedObject);
- int? newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)keyEvent);
+ // Find the current selected object within the tree
+ int current = map.IndexOf (b => b.Model == SelectedObject);
+ int? newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)keyEvent);
- if (newIndex is int && newIndex != -1)
- {
- SelectedObject = map.ElementAt ((int)newIndex).Model;
- EnsureVisible (selectedObject);
- SetNeedsDisplay ();
-
- return true;
- }
- }
- }
- finally
- {
- if (IsInitialized)
+ if (newIndex is int && newIndex != -1)
{
- PositionCursor ();
+ SelectedObject = map.ElementAt ((int)newIndex).Model;
+ EnsureVisible (selectedObject);
+ SetNeedsDisplay ();
+
+ return true;
}
}
@@ -1250,7 +1212,8 @@ public override bool OnProcessKeyDown (Key keyEvent)
if (idx - ScrollOffsetVertical >= 0 && idx - ScrollOffsetVertical < Viewport.Height)
{
Move (0, idx - ScrollOffsetVertical);
- return new Point (0, idx - ScrollOffsetVertical);
+
+ return MultiSelect ? new (0, idx - ScrollOffsetVertical) : null ;
}
}
return base.PositionCursor ();
diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs
index c3691b3e12..205739d44e 100644
--- a/Terminal.Gui/Views/Wizard/Wizard.cs
+++ b/Terminal.Gui/Views/Wizard/Wizard.cs
@@ -32,7 +32,7 @@ namespace Terminal.Gui;
/// var secondStep = new WizardStep ("Second Step");
/// wizard.AddStep(secondStep);
/// secondStep.HelpText = "This is the help text for the Second Step.";
-/// var lbl = new Label () { Text = "Name:", AutoSize = true };
+/// var lbl = new Label () { Text = "Name:" };
/// secondStep.Add(lbl);
///
/// var name = new TextField { X = Pos.Right (lbl) + 1, Width = Dim.Fill () - 1 };
@@ -93,10 +93,10 @@ public Wizard ()
Add (separator);
// BUGBUG: Space is to work around https://github.com/gui-cs/Terminal.Gui/issues/1812
- BackButton = new Button { AutoSize = true, Text = Strings.wzBack };
+ BackButton = new () { Text = Strings.wzBack };
AddButton (BackButton);
- NextFinishButton = new Button { AutoSize = true, Text = Strings.wzFinish };
+ NextFinishButton = new () { Text = Strings.wzFinish };
NextFinishButton.IsDefault = true;
AddButton (NextFinishButton);
@@ -417,10 +417,10 @@ public override bool OnProcessKeyDown (Key key)
{
if (key == Key.Esc)
{
- var args = new WizardButtonEventArgs ();
- Cancelled?.Invoke (this, args);
+ var args = new WizardButtonEventArgs ();
+ Cancelled?.Invoke (this, args);
- return false;
+ return false;
}
}
diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs
index a1c5695332..edc6d1b5be 100644
--- a/UICatalog/Scenarios/ASCIICustomButton.cs
+++ b/UICatalog/Scenarios/ASCIICustomButton.cs
@@ -82,8 +82,6 @@ public void CustomInitialize ()
{
_border = new FrameView { Width = Width, Height = Height };
- AutoSize = false;
-
var fillText = new StringBuilder ();
for (var i = 0; i < Viewport.Height; i++)
@@ -198,7 +196,6 @@ public ScrollViewTestWindow ()
var button = new ASCIICustomButton
{
- AutoSize = false,
Id = j.ToString (),
Text = $"section {j}",
Y = yPos,
@@ -217,7 +214,6 @@ public ScrollViewTestWindow ()
var closeButton = new ASCIICustomButton
{
- AutoSize = false,
Id = "close",
Text = "Close",
Y = Pos.Bottom (prevButton),
@@ -273,7 +269,7 @@ private void Button_KeyPress (object sender, Key obj)
case KeyCode.End:
_scrollView.ContentOffset = new Point (
_scrollView.ContentOffset.X,
- -(_scrollView.ContentSize.Height
+ -(_scrollView.ContentSize.GetValueOrDefault ().Height
- _scrollView.Frame.Height
+ (_scrollView.ShowHorizontalScrollIndicator ? 1 : 0))
);
@@ -291,7 +287,7 @@ private void Button_KeyPress (object sender, Key obj)
Math.Max (
_scrollView.ContentOffset.Y
- _scrollView.Frame.Height,
- -(_scrollView.ContentSize.Height
+ -(_scrollView.ContentSize.GetValueOrDefault ().Height
- _scrollView.Frame.Height
+ (_scrollView.ShowHorizontalScrollIndicator
? 1
diff --git a/UICatalog/Scenarios/Adornments.cs b/UICatalog/Scenarios/Adornments.cs
index ab68fb9611..8467ab784f 100644
--- a/UICatalog/Scenarios/Adornments.cs
+++ b/UICatalog/Scenarios/Adornments.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Linq;
using Terminal.Gui;
@@ -21,7 +20,7 @@ public override void Main ()
Window app = new ()
{
- Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}",
+ Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}"
};
var editor = new AdornmentsEditor ();
@@ -31,9 +30,9 @@ public override void Main ()
{
Title = "The _Window",
Arrangement = ViewArrangement.Movable,
- X = Pos.Right(editor),
+ X = Pos.Right (editor),
Width = Dim.Percent (60),
- Height = Dim.Percent (80),
+ Height = Dim.Percent (80)
};
app.Add (window);
@@ -72,10 +71,9 @@ public override void Main ()
var labelAnchorEnd = new Label
{
- AutoSize = false,
Y = Pos.AnchorEnd (),
Width = 40,
- Height = Dim.Percent(20),
+ Height = Dim.Percent (20),
Text = "Label\nY=AnchorEnd(),Height=Dim.Percent(10)",
ColorScheme = Colors.ColorSchemes ["Error"]
};
@@ -89,10 +87,9 @@ public override void Main ()
window.Padding.Data = "Padding";
window.Padding.Thickness = new (3);
- var longLabel = new Label ()
+ var longLabel = new Label
{
- X = 40, Y = 5, Title = "This is long text (in a label) that should clip.",
-
+ X = 40, Y = 5, Title = "This is long text (in a label) that should clip."
};
longLabel.TextFormatter.WordWrap = true;
window.Add (tf1, color, button, label, btnButtonInWindow, labelAnchorEnd, longLabel);
@@ -100,19 +97,20 @@ public override void Main ()
editor.Initialized += (s, e) => { editor.ViewToEdit = window; };
window.Initialized += (s, e) =>
- {
- var labelInPadding = new Label () { X = 1, Y = 0, Title = "_Text:" };
- window.Padding.Add (labelInPadding);
+ {
+ var labelInPadding = new Label { X = 1, Y = 0, Title = "_Text:" };
+ window.Padding.Add (labelInPadding);
- var textFieldInPadding = new TextField () { X = Pos.Right (labelInPadding) + 1, Y = Pos.Top (labelInPadding), Width = 15, Text = "some text" };
- textFieldInPadding.Accept += (s, e) => MessageBox.Query (20, 7, "TextField", textFieldInPadding.Text, "Ok");
- window.Padding.Add (textFieldInPadding);
+ var textFieldInPadding = new TextField
+ { X = Pos.Right (labelInPadding) + 1, Y = Pos.Top (labelInPadding), Width = 15, Text = "some text" };
+ textFieldInPadding.Accept += (s, e) => MessageBox.Query (20, 7, "TextField", textFieldInPadding.Text, "Ok");
+ window.Padding.Add (textFieldInPadding);
- var btnButtonInPadding = new Button { X = Pos.Center (), Y = 0, Text = "_Button in Padding" };
- btnButtonInPadding.Accept += (s, e) => MessageBox.Query (20, 7, "Hi", "Button in Padding Pressed!", "Ok");
- btnButtonInPadding.BorderStyle = LineStyle.Dashed;
- btnButtonInPadding.Border.Thickness = new (1, 1, 1, 1);
- window.Padding.Add (btnButtonInPadding);
+ var btnButtonInPadding = new Button { X = Pos.Center (), Y = 0, Text = "_Button in Padding" };
+ btnButtonInPadding.Accept += (s, e) => MessageBox.Query (20, 7, "Hi", "Button in Padding Pressed!", "Ok");
+ btnButtonInPadding.BorderStyle = LineStyle.Dashed;
+ btnButtonInPadding.Border.Thickness = new (1, 1, 1, 1);
+ window.Padding.Add (btnButtonInPadding);
#if SUBVIEW_BASED_BORDER
btnButtonInPadding.Border.CloseButton.Visible = true;
@@ -126,7 +124,7 @@ public override void Main ()
view.Accept += (s, e) => MessageBox.Query (20, 7, "Hi", "Window Close Button Pressed!", "Ok");
#endif
- };
+ };
app.Closed += (s, e) => View.Diagnostics = _diagnosticFlags;
@@ -137,7 +135,7 @@ public override void Main ()
}
///
- /// Provides a composable UI for editing the settings of an Adornment.
+ /// Provides a composable UI for editing the settings of an Adornment.
///
public class AdornmentEditor : View
{
@@ -172,6 +170,7 @@ public AdornmentEditor ()
BorderStyle = LineStyle.Double;
Initialized += AdornmentEditor_Initialized;
}
+
public Attribute Color
{
get => new (_foregroundColorPicker.SelectedColor, _backgroundColorPicker.SelectedColor);
@@ -338,7 +337,7 @@ private void Bottom_ValueChanging (object sender, StateEventArgs e)
}
///
- /// Provides an editor UI for the Margin, Border, and Padding of a View.
+ /// Provides an editor UI for the Margin, Border, and Padding of a View.
///
public class AdornmentsEditor : View
{
@@ -471,19 +470,19 @@ public View ViewToEdit
_paddingEditor.AttributeChanged += Editor_AttributeChanged;
Add (_paddingEditor);
- _diagCheckBox = new CheckBox { Text = "_Diagnostics", Y = Pos.Bottom (_paddingEditor) };
- _diagCheckBox.Checked = View.Diagnostics != ViewDiagnosticFlags.Off;
+ _diagCheckBox = new() { Text = "_Diagnostics", Y = Pos.Bottom (_paddingEditor) };
+ _diagCheckBox.Checked = Diagnostics != ViewDiagnosticFlags.Off;
_diagCheckBox.Toggled += (s, e) =>
{
if (e.NewValue == true)
{
- View.Diagnostics =
+ Diagnostics =
ViewDiagnosticFlags.Padding | ViewDiagnosticFlags.Ruler;
}
else
{
- View.Diagnostics = ViewDiagnosticFlags.Off;
+ Diagnostics = ViewDiagnosticFlags.Off;
}
};
diff --git a/UICatalog/Scenarios/AllViewsTester.cs b/UICatalog/Scenarios/AllViewsTester.cs
index b9b20377ea..2b8a6f37ef 100644
--- a/UICatalog/Scenarios/AllViewsTester.cs
+++ b/UICatalog/Scenarios/AllViewsTester.cs
@@ -12,7 +12,7 @@ namespace UICatalog.Scenarios;
[ScenarioCategory ("Top Level Windows")]
public class AllViewsTester : Scenario
{
- private readonly List _dimNames = new () { "Factor", "Fill", "Absolute" };
+ private readonly List _dimNames = new () { "Auto", "Factor", "Fill", "Absolute" };
// TODO: This is missing some
private readonly List _posNames = new () { "Factor", "AnchorEnd", "Center", "Absolute" };
@@ -208,7 +208,7 @@ public override void Init ()
Title = "Size (Dim)"
};
- radioItems = new [] { "_Percent(width)", "_Fill(width)", "_Sized(width)" };
+ radioItems = new [] { "Auto (min)", "_Percent(width)", "_Fill(width)", "_Sized(width)" };
label = new Label { X = 0, Y = 0, Text = "Width:" };
_sizeFrame.Add (label);
_wRadioGroup = new RadioGroup { X = 0, Y = Pos.Bottom (label), RadioLabels = radioItems };
@@ -221,12 +221,13 @@ public override void Init ()
{
switch (_wRadioGroup.SelectedItem)
{
- case 0:
+ case 1:
_wVal = Math.Min (int.Parse (_wText.Text), 100);
break;
- case 1:
+ case 0:
case 2:
+ case 3:
_wVal = int.Parse (_wText.Text);
break;
@@ -240,7 +241,7 @@ public override void Init ()
_sizeFrame.Add (_wText);
_sizeFrame.Add (_wRadioGroup);
- radioItems = new [] { "P_ercent(height)", "F_ill(height)", "Si_zed(height)" };
+ radioItems = new [] { "_Auto (min)", "P_ercent(height)", "F_ill(height)", "Si_zed(height)" };
label = new Label { X = Pos.Right (_wRadioGroup) + 1, Y = 0, Text = "Height:" };
_sizeFrame.Add (label);
_hText = new TextField { X = Pos.Right (label) + 1, Y = 0, Width = 4, Text = $"{_hVal}" };
@@ -251,12 +252,13 @@ public override void Init ()
{
switch (_hRadioGroup.SelectedItem)
{
- case 0:
+ case 1:
_hVal = Math.Min (int.Parse (_hText.Text), 100);
break;
- case 1:
+ case 0:
case 2:
+ case 3:
_hVal = int.Parse (_hText.Text);
break;
@@ -386,38 +388,40 @@ private void DimPosChanged (View view)
//view.LayoutStyle = LayoutStyle.Absolute;
view.X = _xRadioGroup.SelectedItem switch
- {
- 0 => Pos.Percent (_xVal),
- 1 => Pos.AnchorEnd (),
- 2 => Pos.Center (),
- 3 => Pos.At (_xVal),
- _ => view.X
- };
+ {
+ 0 => Pos.Percent (_xVal),
+ 1 => Pos.AnchorEnd (),
+ 2 => Pos.Center (),
+ 3 => Pos.At (_xVal),
+ _ => view.X
+ };
view.Y = _yRadioGroup.SelectedItem switch
- {
- 0 => Pos.Percent (_yVal),
- 1 => Pos.AnchorEnd (),
- 2 => Pos.Center (),
- 3 => Pos.At (_yVal),
- _ => view.Y
- };
+ {
+ 0 => Pos.Percent (_yVal),
+ 1 => Pos.AnchorEnd (),
+ 2 => Pos.Center (),
+ 3 => Pos.At (_yVal),
+ _ => view.Y
+ };
view.Width = _wRadioGroup.SelectedItem switch
- {
- 0 => Dim.Percent (_wVal),
- 1 => Dim.Fill (_wVal),
- 2 => Dim.Sized (_wVal),
- _ => view.Width
- };
+ {
+ 0 => Dim.Auto (min: _wVal),
+ 1 => Dim.Percent (_wVal),
+ 2 => Dim.Fill (_wVal),
+ 3 => Dim.Sized (_wVal),
+ _ => view.Width
+ };
view.Height = _hRadioGroup.SelectedItem switch
- {
- 0 => Dim.Percent (_hVal),
- 1 => Dim.Fill (_hVal),
- 2 => Dim.Sized (_hVal),
- _ => view.Height
- };
+ {
+ 0 => Dim.Auto (min: _hVal),
+ 1 => Dim.Percent (_hVal),
+ 2 => Dim.Fill (_hVal),
+ 3 => Dim.Sized (_hVal),
+ _ => view.Height
+ };
}
catch (Exception e)
{
@@ -474,16 +478,17 @@ private void UpdateSettings (View view)
private void View_Initialized (object sender, EventArgs e)
{
- var view = sender as View;
+ if (sender is not View view)
+ {
+ return;
+ }
- //view.X = Pos.Center ();
- //view.Y = Pos.Center ();
- if (view.Width == null || view.Frame.Width == 0)
+ if (view.Width is not Dim.DimAuto && (view.Width is null || view.Frame.Width == 0))
{
view.Width = Dim.Fill ();
}
- if (view.Height == null || view.Frame.Height == 0)
+ if (view.Width is not Dim.DimAuto && (view.Height is null || view.Frame.Height == 0))
{
view.Height = Dim.Fill ();
}
diff --git a/UICatalog/Scenarios/AutoSizeAndDirectionText.cs b/UICatalog/Scenarios/AutoSizeAndDirectionText.cs
deleted file mode 100644
index 2a54194616..0000000000
--- a/UICatalog/Scenarios/AutoSizeAndDirectionText.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using Terminal.Gui;
-
-namespace UICatalog.Scenarios;
-
-[ScenarioMetadata ("Text Direction and AutoSize", "Demos TextFormatter Direction and View AutoSize.")]
-[ScenarioCategory ("Text and Formatting")]
-public class AutoSizeAndDirectionText : Scenario
-{
- public override void Setup ()
- {
- var text = "Hello World";
- var wideText = "Hello World 你";
- ColorScheme color = Colors.ColorSchemes ["Dialog"];
-
- var labelH = new Label
- {
- X = 1,
- Y = 1,
-
- // Width = 11,
- // Height = 1,
- ColorScheme = color,
- Text = text,
- TextDirection = TextDirection.LeftRight_TopBottom
- };
- Win.Add (labelH);
-
- var labelV = new Label
- {
- X = 70,
- Y = 1,
-
- // Width = 1,
- // Height = 11,
- ColorScheme = color,
- Text = text,
- TextDirection = TextDirection.TopBottom_LeftRight
- };
- Win.Add (labelV);
-
- var editText = new TextView
- {
- X = Pos.Center (),
- Y = Pos.Center (),
- Width = 20,
- Height = 5,
- Text = text
- };
-
- editText.SetFocus ();
-
- Win.Add (editText);
-
- var ckbDirection = new CheckBox { Text = "Toggle Direction", X = Pos.Center (), Y = Pos.Center () + 3 };
-
- ckbDirection.Toggled += (s, e) =>
- {
- if (labelH.TextDirection == TextDirection.LeftRight_TopBottom)
- {
- labelH.TextDirection = TextDirection.TopBottom_LeftRight;
- labelV.TextDirection = TextDirection.LeftRight_TopBottom;
- }
- else
- {
- labelH.TextDirection = TextDirection.LeftRight_TopBottom;
- labelV.TextDirection = TextDirection.TopBottom_LeftRight;
- }
- };
- Win.Add (ckbDirection);
-
- var ckbAutoSize = new CheckBox
- {
- Text = "Auto Size", X = Pos.Center (), Y = Pos.Center () + 5, Checked = labelH.AutoSize = labelV.AutoSize
- };
- ckbAutoSize.Toggled += (s, e) => labelH.AutoSize = labelV.AutoSize = (bool)ckbAutoSize.Checked;
- Win.Add (ckbAutoSize);
-
- var ckbPreserveTrailingSpaces = new CheckBox
- {
- Text = "Preserve Trailing Spaces",
- X = Pos.Center (),
- Y = Pos.Center () + 7,
- Checked = labelH.PreserveTrailingSpaces =
- labelV.PreserveTrailingSpaces
- };
-
- ckbPreserveTrailingSpaces.Toggled += (s, e) =>
- labelH.PreserveTrailingSpaces = labelV.PreserveTrailingSpaces = (bool)ckbPreserveTrailingSpaces.Checked;
- Win.Add (ckbPreserveTrailingSpaces);
-
- var ckbWideText = new CheckBox { Text = "Use wide runes", X = Pos.Center (), Y = Pos.Center () + 9 };
-
- ckbWideText.Toggled += (s, e) =>
- {
- if (ckbWideText.Checked == true)
- {
- labelH.Text = labelV.Text = editText.Text = wideText;
- labelH.Width = 14;
- labelV.Height = 13;
- }
- else
- {
- labelH.Text = labelV.Text = editText.Text = text;
- labelH.Width = 11;
- labelV.Width = 1;
- labelV.Height = 11;
- }
- };
- Win.Add (ckbWideText);
-
- Win.KeyUp += (s, e) =>
- labelH.Text = labelV.Text = text = editText.Text;
- }
-}
diff --git a/UICatalog/Scenarios/BasicColors.cs b/UICatalog/Scenarios/BasicColors.cs
index e12e51284b..1780d7cbbc 100644
--- a/UICatalog/Scenarios/BasicColors.cs
+++ b/UICatalog/Scenarios/BasicColors.cs
@@ -28,7 +28,6 @@ public override void Main ()
var vl = new Label
{
- AutoSize = false,
X = vx,
Y = 0,
Width = 1,
@@ -42,7 +41,6 @@ public override void Main ()
var hl = new Label
{
- AutoSize = false,
X = 15,
Y = y,
Width = 13,
diff --git a/UICatalog/Scenarios/Buttons.cs b/UICatalog/Scenarios/Buttons.cs
index 33590a7e05..fb67063666 100644
--- a/UICatalog/Scenarios/Buttons.cs
+++ b/UICatalog/Scenarios/Buttons.cs
@@ -33,7 +33,14 @@ public override void Main ()
defaultButton.Accept += (s, e) => Application.RequestStop ();
main.Add (defaultButton);
- var swapButton = new Button { X = 50, Text = "S_wap Default (Absolute Layout)" };
+ var swapButton = new Button
+ {
+ X = 50,
+ Width = 45,
+ Height = 3,
+ Text = "S_wap Default (Size = 45, 3)",
+ ColorScheme = Colors.ColorSchemes ["Error"]
+ };
swapButton.Accept += (s, e) =>
{
@@ -51,29 +58,23 @@ static void DoMessage (Button button, string txt)
};
}
- var colorButtonsLabel = new Label { X = 0, Y = Pos.Bottom (editLabel) + 1, Text = "Color Buttons:" };
+ var colorButtonsLabel = new Label { X = 0, Y = Pos.Bottom (swapButton) + 1, Text = "Color Buttons: " };
main.Add (colorButtonsLabel);
View prev = colorButtonsLabel;
- //With this method there is no need to call Application.TopReady += () => Application.TopRedraw (Top.Bounds);
- Pos x = Pos.Right (colorButtonsLabel) + 2;
-
foreach (KeyValuePair colorScheme in Colors.ColorSchemes)
{
var colorButton = new Button
{
- ColorScheme = colorScheme.Value,
- X = Pos.Right (prev) + 2,
+ X = Pos.Right (prev),
Y = Pos.Y (colorButtonsLabel),
- Text = $"_{colorScheme.Key}"
+ Text = $"_{colorScheme.Key}",
+ ColorScheme = colorScheme.Value,
};
DoMessage (colorButton, colorButton.Text);
main.Add (colorButton);
prev = colorButton;
-
- // BUGBUG: AutoSize is true and the X doesn't change
- //x += colorButton.Frame.Width + 2;
}
Button button;
@@ -91,7 +92,7 @@ static void DoMessage (Button button, string txt)
// Note the 'N' in 'Newline' will be the hotkey
main.Add (
- button = new () { X = 2, Y = Pos.Bottom (button) + 1, Text = "a Newline\nin the button" }
+ button = new () { X = 2, Y = Pos.Bottom (button) + 1, Height = 2, Text = "a Newline\nin the button" }
);
button.Accept += (s, e) => MessageBox.Query ("Message", "Question?", "Yes", "No");
@@ -110,16 +111,14 @@ static void DoMessage (Button button, string txt)
var removeButton = new Button
{
- X = 2, Y = Pos.Bottom (button) + 1, ColorScheme = Colors.ColorSchemes ["Error"], Text = "Remove this button"
+ X = 2, Y = Pos.Bottom (button) + 1,
+ ColorScheme = Colors.ColorSchemes ["Error"], Text = "Remove this button"
};
main.Add (removeButton);
// This in interesting test case because `moveBtn` and below are laid out relative to this one!
removeButton.Accept += (s, e) =>
{
- // Now this throw a InvalidOperationException on the TopologicalSort method as is expected.
- //main.Remove (removeButton);
-
removeButton.Visible = false;
};
@@ -138,7 +137,6 @@ static void DoMessage (Button button, string txt)
{
X = 0,
Y = Pos.Center () - 1,
- AutoSize = false,
Width = 30,
Height = 1,
ColorScheme = Colors.ColorSchemes ["Error"],
@@ -148,29 +146,23 @@ static void DoMessage (Button button, string txt)
moveBtn.Accept += (s, e) =>
{
moveBtn.X = moveBtn.Frame.X + 5;
-
- // This is already fixed with the call to SetNeedDisplay() in the Pos Dim.
- //computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
};
computedFrame.Add (moveBtn);
// Demonstrates how changing the View.Frame property can SIZE Views (#583)
var sizeBtn = new Button
{
- X = 0,
Y = Pos.Center () + 1,
- AutoSize = false,
+ X = 0,
Width = 30,
Height = 1,
+ Text = "Grow This \u263a Button _via Pos",
ColorScheme = Colors.ColorSchemes ["Error"],
- Text = "Size This \u263a Button _via Pos"
};
sizeBtn.Accept += (s, e) =>
{
sizeBtn.Width = sizeBtn.Frame.Width + 5;
-
- //computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
};
computedFrame.Add (sizeBtn);
@@ -268,7 +260,6 @@ string MoveHotkey (string txt)
{
X = 2,
Y = Pos.Bottom (radioGroup) + 1,
- AutoSize = false,
Height = 1,
Width = Dim.Width (computedFrame) - 2,
ColorScheme = Colors.ColorSchemes ["TopLevel"],
@@ -283,7 +274,6 @@ string MoveHotkey (string txt)
{
X = Pos.Left (absoluteFrame) + 1,
Y = Pos.Bottom (radioGroup) + 1,
- AutoSize = false,
Height = 1,
Width = Dim.Width (absoluteFrame) - 2, // BUGBUG: Not always the width isn't calculated correctly.
ColorScheme = Colors.ColorSchemes ["TopLevel"],
@@ -434,7 +424,6 @@ public NumericUpDown ()
_down = new ()
{
- AutoSize = false,
Height = 1,
Width = 1,
NoPadding = true,
@@ -447,7 +436,6 @@ public NumericUpDown ()
_number = new ()
{
Text = Value.ToString (),
- AutoSize = false,
X = Pos.Right (_down),
Y = Pos.Top (_down),
Width = Dim.Function (() => Digits),
@@ -458,7 +446,6 @@ public NumericUpDown ()
_up = new ()
{
- AutoSize = false,
X = Pos.AnchorEnd (),
Y = Pos.Top (_number),
Height = 1,
diff --git a/UICatalog/Scenarios/CharacterMap.cs b/UICatalog/Scenarios/CharacterMap.cs
index 96287152ed..a3aa100a8c 100644
--- a/UICatalog/Scenarios/CharacterMap.cs
+++ b/UICatalog/Scenarios/CharacterMap.cs
@@ -315,7 +315,6 @@ private void JumpEdit_TextChanged (object sender, StateEventArgs e)
internal class CharMap : View
{
- private const CursorVisibility _cursor = CursorVisibility.Default;
private const int COLUMN_WIDTH = 3;
private ContextMenu _contextMenu = new ();
@@ -327,6 +326,7 @@ public CharMap ()
{
ColorScheme = Colors.ColorSchemes ["Dialog"];
CanFocus = true;
+ CursorVisibility = CursorVisibility.Default;
ContentSize = new (RowWidth, (MaxCodePoint / 16 + 2) * _rowHeight);
@@ -472,7 +472,6 @@ public CharMap ()
var up = new Button
{
- AutoSize = false,
X = Pos.AnchorEnd (1),
Y = 0,
Height = 1,
@@ -487,7 +486,6 @@ public CharMap ()
var down = new Button
{
- AutoSize = false,
X = Pos.AnchorEnd (1),
Y = Pos.AnchorEnd (2),
Height = 1,
@@ -502,7 +500,6 @@ public CharMap ()
var left = new Button
{
- AutoSize = false,
X = 0,
Y = Pos.AnchorEnd (1),
Height = 1,
@@ -517,7 +514,6 @@ public CharMap ()
var right = new Button
{
- AutoSize = false,
X = Pos.AnchorEnd (2),
Y = Pos.AnchorEnd (1),
Height = 1,
@@ -807,23 +803,6 @@ public override void OnDrawContent (Rectangle viewport)
}
}
- public override bool OnEnter (View view)
- {
- if (IsInitialized)
- {
- Application.Driver.SetCursorVisibility (_cursor);
- }
-
- return base.OnEnter (view);
- }
-
- public override bool OnLeave (View view)
- {
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
-
- return base.OnLeave (view);
- }
-
public override Point? PositionCursor ()
{
if (HasFocus
@@ -832,12 +811,11 @@ public override bool OnLeave (View view)
&& Cursor.Y > 0
&& Cursor.Y < Viewport.Height)
{
- Driver.SetCursorVisibility (_cursor);
Move (Cursor.X, Cursor.Y);
}
else
{
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
+ return null;
}
return Cursor;
@@ -976,7 +954,6 @@ private void ShowDetails ()
var errorLabel = new Label
{
Text = UcdApiClient.BaseUrl,
- AutoSize = false,
X = 0,
Y = 1,
Width = Dim.Fill (),
diff --git a/UICatalog/Scenarios/CollectionNavigatorTester.cs b/UICatalog/Scenarios/CollectionNavigatorTester.cs
index 9a0ed7687e..ef31ac6a7d 100644
--- a/UICatalog/Scenarios/CollectionNavigatorTester.cs
+++ b/UICatalog/Scenarios/CollectionNavigatorTester.cs
@@ -145,7 +145,6 @@ private void CreateListView ()
TextAlignment = TextAlignment.Centered,
X = 0,
Y = 1, // for menu
- AutoSize = false,
Width = Dim.Percent (50),
Height = 1
};
@@ -175,7 +174,6 @@ private void CreateTreeView ()
TextAlignment = TextAlignment.Centered,
X = Pos.Right (_listView) + 2,
Y = 1, // for menu
- AutoSize = false,
Width = Dim.Percent (50),
Height = 1
};
diff --git a/UICatalog/Scenarios/ComboBoxIteration.cs b/UICatalog/Scenarios/ComboBoxIteration.cs
index b7c387ae4d..a62fba18cc 100644
--- a/UICatalog/Scenarios/ComboBoxIteration.cs
+++ b/UICatalog/Scenarios/ComboBoxIteration.cs
@@ -12,7 +12,7 @@ public override void Setup ()
{
List items = new () { "one", "two", "three" };
- var lbListView = new Label { AutoSize = false, Width = 10, Height = 1 };
+ var lbListView = new Label { Width = 10, Height = 1 };
Win.Add (lbListView);
var listview = new ListView
@@ -25,7 +25,6 @@ public override void Setup ()
{
ColorScheme = Colors.ColorSchemes ["TopLevel"],
X = Pos.Right (lbListView) + 1,
- AutoSize = false,
Width = Dim.Percent (40)
};
diff --git a/UICatalog/Scenarios/ComputedLayout.cs b/UICatalog/Scenarios/ComputedLayout.cs
index c8013c46ac..6cfcb378cd 100644
--- a/UICatalog/Scenarios/ComputedLayout.cs
+++ b/UICatalog/Scenarios/ComputedLayout.cs
@@ -27,7 +27,6 @@ public override void Main ()
var horizontalRuler = new Label
{
- AutoSize = false,
X = 0,
Y = 0,
Width = Dim.Fill (),
@@ -43,7 +42,6 @@ public override void Main ()
var verticalRuler = new Label
{
- AutoSize = false,
X = 0,
Y = 0,
Width = 1,
@@ -93,7 +91,6 @@ public override void Main ()
new Label
{
TextAlignment = TextAlignment.Left,
- AutoSize = false,
Width = Dim.Fill (),
X = 0,
Y = Pos.Bottom (labelList.LastOrDefault ()),
@@ -106,7 +103,6 @@ public override void Main ()
new Label
{
TextAlignment = TextAlignment.Right,
- AutoSize = false,
Width = Dim.Fill (),
X = 0,
Y = Pos.Bottom (labelList.LastOrDefault ()),
@@ -119,7 +115,6 @@ public override void Main ()
new Label
{
TextAlignment = TextAlignment.Centered,
- AutoSize = false,
Width = Dim.Fill (),
X = 0,
Y = Pos.Bottom (labelList.LastOrDefault ()),
@@ -132,7 +127,6 @@ public override void Main ()
new Label
{
TextAlignment = TextAlignment.Justified,
- AutoSize = false,
Width = Dim.Fill (),
X = 0,
Y = Pos.Bottom (labelList.LastOrDefault ()),
@@ -159,7 +153,6 @@ public override void Main ()
new Label
{
TextAlignment = TextAlignment.Left,
- AutoSize = false,
Width = Dim.Fill (),
X = 0,
Y = Pos.Bottom (labelList.LastOrDefault ()),
@@ -172,7 +165,6 @@ public override void Main ()
new Label
{
TextAlignment = TextAlignment.Right,
- AutoSize = false,
Width = Dim.Fill (),
X = 0,
Y = Pos.Bottom (labelList.LastOrDefault ()),
@@ -185,7 +177,6 @@ public override void Main ()
new Label
{
TextAlignment = TextAlignment.Centered,
- AutoSize = false,
Width = Dim.Fill (),
X = 0,
Y = Pos.Bottom (labelList.LastOrDefault ()),
@@ -198,7 +189,6 @@ public override void Main ()
new Label
{
TextAlignment = TextAlignment.Justified,
- AutoSize = false,
Width = Dim.Fill (),
X = 0,
Y = Pos.Bottom (labelList.LastOrDefault ()),
@@ -335,7 +325,6 @@ public override void Main ()
Text = "This Label should be the 2nd to last line (AnchorEnd (2)).",
TextAlignment = TextAlignment.Centered,
ColorScheme = Colors.ColorSchemes ["Menu"],
- AutoSize = false,
Width = Dim.Fill (5),
X = 5,
Y = Pos.AnchorEnd (2)
@@ -350,7 +339,6 @@ public override void Main ()
"This TextField should be the 3rd to last line (AnchorEnd (2) - 1).",
TextAlignment = TextAlignment.Left,
ColorScheme = Colors.ColorSchemes ["Menu"],
- AutoSize = false,
Width = Dim.Fill (5),
X = 5,
Y = Pos.AnchorEnd (2) - 1 // Pos.Combine
diff --git a/UICatalog/Scenarios/ContentScrolling.cs b/UICatalog/Scenarios/ContentScrolling.cs
index 9a92b4bc46..8b7e9d9d81 100644
--- a/UICatalog/Scenarios/ContentScrolling.cs
+++ b/UICatalog/Scenarios/ContentScrolling.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Terminal.Gui;
@@ -45,7 +46,7 @@ public ScrollingDemoView ()
// Add a status label to the border that shows Viewport and ContentSize values. Bit of a hack.
// TODO: Move to Padding with controls
- Border.Add (new Label { AutoSize = false, X = 20 });
+ Border.Add (new Label { X = 20 });
LayoutComplete += VirtualDemoView_LayoutComplete;
MouseEvent += VirtualDemoView_MouseEvent;
@@ -114,7 +115,7 @@ public override void Main ()
var view = new ScrollingDemoView
{
Title = "Demo View",
- X = Pos.Right(editor),
+ X = Pos.Right (editor),
Width = Dim.Fill (),
Height = Dim.Fill ()
};
@@ -226,7 +227,7 @@ void AllowYGreaterThanContentHeight_Toggled (object sender, StateEventArgs
{
- Value = view.ContentSize.Width,
+ Value = view.ContentSize.GetValueOrDefault ().Width,
X = Pos.Right (labelContentSize) + 1,
Y = Pos.Top (labelContentSize)
};
@@ -241,7 +242,7 @@ void ContentSizeWidth_ValueChanged (object sender, StateEventArgs e)
return;
}
- view.ContentSize = view.ContentSize with { Width = e.NewValue };
+ view.ContentSize = view.ContentSize.GetValueOrDefault () with { Width = e.NewValue };
}
var labelComma = new Label
@@ -253,7 +254,7 @@ void ContentSizeWidth_ValueChanged (object sender, StateEventArgs e)
var contentSizeHeight = new Buttons.NumericUpDown
{
- Value = view.ContentSize.Height,
+ Value = view.ContentSize.GetValueOrDefault ().Height,
X = Pos.Right (labelComma) + 1,
Y = Pos.Top (labelContentSize),
CanFocus = false
@@ -269,7 +270,7 @@ void ContentSizeHeight_ValueChanged (object sender, StateEventArgs e)
return;
}
- view.ContentSize = view.ContentSize with { Height = e.NewValue };
+ view.ContentSize = view.ContentSize.GetValueOrDefault () with { Height = e.NewValue };
}
var cbClearOnlyVisible = new CheckBox
@@ -384,6 +385,19 @@ void ClipVisibleContentOnly_Toggled (object sender, StateEventArgs e)
longLabel.TextFormatter.WordWrap = true;
view.Add (longLabel);
+ List