diff --git a/Terminal.Gui/Drawing/Thickness.cs b/Terminal.Gui/Drawing/Thickness.cs
index ad684470b8..532c0af8a3 100644
--- a/Terminal.Gui/Drawing/Thickness.cs
+++ b/Terminal.Gui/Drawing/Thickness.cs
@@ -1,4 +1,5 @@
-using System.Text.Json.Serialization;
+using System.Numerics;
+using System.Text.Json.Serialization;
namespace Terminal.Gui;
@@ -13,28 +14,18 @@ namespace Terminal.Gui;
/// frame,
/// with the thickness widths subtracted.
///
-/// Use the helper API ( to draw the frame with the specified thickness.
+///
+/// Use the helper API ( to draw the frame with the specified thickness.
+///
+///
+/// Thickness uses intenrally. As a result, there is a potential precision loss for very
+/// large numbers. This is typically not an issue for UI dimensions but could be relevant in other contexts.
+///
///
-public class Thickness : IEquatable
+public record struct Thickness
{
- /// Gets or sets the width of the lower side of the rectangle.
- [JsonInclude]
- public int Bottom;
-
- /// Gets or sets the width of the left side of the rectangle.
- [JsonInclude]
- public int Left;
-
- /// Gets or sets the width of the right side of the rectangle.
- [JsonInclude]
- public int Right;
-
- /// Gets or sets the width of the upper side of the rectangle.
- [JsonInclude]
- public int Top;
-
/// Initializes a new instance of the class with all widths set to 0.
- public Thickness () { }
+ public Thickness () { _sides = Vector4.Zero; }
/// Initializes a new instance of the class with a uniform width to each side.
///
@@ -56,36 +47,24 @@ public Thickness (int left, int top, int right, int bottom)
Bottom = bottom;
}
- // TODO: add operator overloads
- /// Gets an empty thickness.
- public static Thickness Empty => new (0);
+ private Vector4 _sides;
///
- /// Gets the total width of the left and right sides of the rectangle. Sets the width of the left and rigth sides
- /// of the rectangle to half the specified value.
+ /// Adds the thickness widths of another to the current , returning a
+ /// new .
///
- public int Horizontal
- {
- get => Left + Right;
- set => Left = Right = value / 2;
- }
+ ///
+ ///
+ public readonly Thickness Add (Thickness other) { return new (Left + other.Left, Top + other.Top, Right + other.Right, Bottom + other.Bottom); }
- ///
- /// Gets the total height of the top and bottom sides of the rectangle. Sets the height of the top and bottom
- /// sides of the rectangle to half the specified value.
- ///
- public int Vertical
+ /// Gets or sets the width of the lower side of the rectangle.
+ [JsonInclude]
+ public int Bottom
{
- get => Top + Bottom;
- set => Top = Bottom = value / 2;
+ get => (int)_sides.W;
+ set => _sides.W = value;
}
- // IEquitable
- /// Indicates whether the current object is equal to another object of the same type.
- ///
- /// true if the current object is equal to the other parameter; otherwise, false.
- public bool Equals (Thickness other) { return other is { } && Left == other.Left && Right == other.Right && Top == other.Top && Bottom == other.Bottom; }
-
///
/// Gets whether the specified coordinates lie within the thickness (inside the bounding rectangle but outside
/// the rectangle described by .
@@ -100,22 +79,6 @@ public bool Contains (in Rectangle outside, in Point location)
return outside.Contains (location) && !inside.Contains (location);
}
- ///
- /// Adds the thickness widths of another to the current , returning a
- /// new .
- ///
- ///
- ///
- public Thickness Add (Thickness other) { return new (Left + other.Left, Top + other.Top, Right + other.Right, Bottom + other.Bottom); }
-
- ///
- /// Adds the thickness widths of another to another .
- ///
- ///
- ///
- ///
- public static Thickness operator + (Thickness a, Thickness b) { return a.Add (b); }
-
/// Draws the rectangle with an optional diagnostics label.
///
/// If is set to
@@ -240,31 +203,8 @@ rect with
return GetInside (rect);
}
- /// Determines whether the specified object is equal to the current object.
- /// The object to compare with the current object.
- /// true if the specified object is equal to the current object; otherwise, false.
- public override bool Equals (object obj)
- {
- //Check for null and compare run-time types.
- if (obj is null || !GetType ().Equals (obj.GetType ()))
- {
- return false;
- }
-
- return Equals ((Thickness)obj);
- }
-
- ///
- public override int GetHashCode ()
- {
- var hashCode = 1380952125;
- hashCode = hashCode * -1521134295 + Left.GetHashCode ();
- hashCode = hashCode * -1521134295 + Right.GetHashCode ();
- hashCode = hashCode * -1521134295 + Top.GetHashCode ();
- hashCode = hashCode * -1521134295 + Bottom.GetHashCode ();
-
- return hashCode;
- }
+ /// Gets an empty thickness.
+ public static Thickness Empty => new (0);
///
/// Returns a rectangle describing the location and size of the inside area of with the
@@ -289,23 +229,59 @@ public Rectangle GetInside (Rectangle rect)
return new (x, y, width, height);
}
- ///
- public static bool operator == (Thickness left, Thickness right) { return EqualityComparer.Default.Equals (left, right); }
+ ///
+ /// Gets the total width of the left and right sides of the rectangle. Sets the width of the left and rigth sides
+ /// of the rectangle to half the specified value.
+ ///
+ public int Horizontal
+ {
+ get => Left + Right;
+ set => Left = Right = value / 2;
+ }
- ///
- public static bool operator != (Thickness left, Thickness right) { return !(left == right); }
+ /// Gets or sets the width of the left side of the rectangle.
+ [JsonInclude]
+ public int Left
+ {
+ get => (int)_sides.X;
+ set => _sides.X = value;
+ }
+
+ ///
+ /// Adds the thickness widths of another to another .
+ ///
+ ///
+ ///
+ ///
+ public static Thickness operator + (Thickness a, Thickness b) { return a.Add (b); }
+
+ /// Gets or sets the width of the right side of the rectangle.
+ [JsonInclude]
+ public int Right
+ {
+ get => (int)_sides.Z;
+ set => _sides.Z = value;
+ }
+
+ /// Gets or sets the width of the upper side of the rectangle.
+ [JsonInclude]
+ public int Top
+ {
+ get => (int)_sides.Y;
+ set => _sides.Y = value;
+ }
/// Returns the thickness widths of the Thickness formatted as a string.
/// The thickness widths as a string.
public override string ToString () { return $"(Left={Left},Top={Top},Right={Right},Bottom={Bottom})"; }
- private int validate (int width)
+ ///
+ /// Gets the total height of the top and bottom sides of the rectangle. Sets the height of the top and bottom
+ /// sides of the rectangle to half the specified value.
+ ///
+ public int Vertical
{
- if (width < 0)
- {
- throw new ArgumentException ("Thickness widths cannot be negative.");
- }
-
- return width;
+ get => Top + Bottom;
+ set => Top = Bottom = value / 2;
}
}
diff --git a/UnitTests/View/Adornment/BorderTests.cs b/UnitTests/View/Adornment/BorderTests.cs
index d2f88916b1..387844dbe6 100644
--- a/UnitTests/View/Adornment/BorderTests.cs
+++ b/UnitTests/View/Adornment/BorderTests.cs
@@ -18,7 +18,7 @@ public void Border_Parent_HasFocus_Title_Uses_FocusAttribute ()
view.Border.Thickness = new (0, 1, 0, 0);
view.Border.LineStyle = LineStyle.Single;
- view.ColorScheme = new()
+ view.ColorScheme = new ()
{
Normal = new (Color.Red, Color.Green),
Focus = new (Color.Green, Color.Red)
@@ -53,7 +53,7 @@ public void Border_Uses_Parent_ColorScheme ()
view.Border.Thickness = new (0, 1, 0, 0);
view.Border.LineStyle = LineStyle.Single;
- view.ColorScheme = new()
+ view.ColorScheme = new ()
{
Normal = new (Color.Red, Color.Green), Focus = new (Color.Green, Color.Red)
};
@@ -90,7 +90,7 @@ public void Border_With_Title_Border_Double_Thickness_Top_Four_Size_Width (int w
{
Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double
};
- win.Border.Thickness.Top = 4;
+ win.Border.Thickness = win.Border.Thickness with { Top = 4 };
RunState rs = Application.Begin (win);
var firstIteration = false;
@@ -224,7 +224,7 @@ public void Border_With_Title_Border_Double_Thickness_Top_Three_Size_Width (int
{
Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double
};
- win.Border.Thickness.Top = 3;
+ win.Border.Thickness = win.Border.Thickness with { Top = 3 };
RunState rs = Application.Begin (win);
var firstIteration = false;
@@ -358,7 +358,7 @@ public void Border_With_Title_Border_Double_Thickness_Top_Two_Size_Width (int wi
{
Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double
};
- win.Border.Thickness.Top = 2;
+ win.Border.Thickness = win.Border.Thickness with { Top = 2 };
RunState rs = Application.Begin (win);
var firstIteration = false;