diff --git a/src/Avalonia.Visuals/CornerRadius.cs b/src/Avalonia.Visuals/CornerRadius.cs
index 09163a2dac..5445c5a200 100644
--- a/src/Avalonia.Visuals/CornerRadius.cs
+++ b/src/Avalonia.Visuals/CornerRadius.cs
@@ -8,7 +8,10 @@ using Avalonia.Utilities;
namespace Avalonia
{
- public struct CornerRadius
+ ///
+ /// Represents the radii of a rectangle's corners.
+ ///
+ public readonly struct CornerRadius : IEquatable
{
static CornerRadius()
{
@@ -33,20 +36,60 @@ namespace Avalonia
BottomLeft = bottomLeft;
}
+ ///
+ /// Radius of the top left corner.
+ ///
public double TopLeft { get; }
+
+ ///
+ /// Radius of the top right corner.
+ ///
public double TopRight { get; }
+
+ ///
+ /// Radius of the bottom right corner.
+ ///
public double BottomRight { get; }
+
+ ///
+ /// Radius of the bottom left corner.
+ ///
public double BottomLeft { get; }
+
+ ///
+ /// Gets a value indicating whether all corner radii are set to 0.
+ ///
public bool IsEmpty => TopLeft.Equals(0) && IsUniform;
+
+ ///
+ /// Gets a value indicating whether all corner radii are equal.
+ ///
public bool IsUniform => TopLeft.Equals(TopRight) && BottomLeft.Equals(BottomRight) && TopRight.Equals(BottomRight);
+ ///
+ /// Returns a boolean indicating whether the corner radius is equal to the other given corner radius.
+ ///
+ /// The other corner radius to test equality against.
+ /// True if this corner radius is equal to other; False otherwise.
+ public bool Equals(CornerRadius other)
+ {
+ // ReSharper disable CompareOfFloatsByEqualityOperator
+ return TopLeft == other.TopLeft &&
+
+ TopRight == other.TopRight &&
+ BottomRight == other.BottomRight &&
+ BottomLeft == other.BottomLeft;
+ // ReSharper restore CompareOfFloatsByEqualityOperator
+ }
+
public override bool Equals(object obj)
{
- if (obj is CornerRadius)
+ if (!(obj is CornerRadius))
{
- return this == (CornerRadius)obj;
+ return false;
}
- return false;
+
+ return Equals((CornerRadius)obj);
}
public override int GetHashCode()
@@ -61,7 +104,9 @@ namespace Avalonia
public static CornerRadius Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Thickness"))
+ const string exceptionMessage = "Invalid CornerRadius.";
+
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage))
{
if (tokenizer.TryReadDouble(out var a))
{
@@ -78,21 +123,18 @@ namespace Avalonia
return new CornerRadius(a);
}
- throw new FormatException("Invalid CornerRadius.");
+ throw new FormatException(exceptionMessage);
}
}
- public static bool operator ==(CornerRadius cr1, CornerRadius cr2)
+ public static bool operator ==(CornerRadius left, CornerRadius right)
{
- return cr1.TopLeft.Equals(cr2.TopLeft)
- && cr1.TopRight.Equals(cr2.TopRight)
- && cr1.BottomRight.Equals(cr2.BottomRight)
- && cr1.BottomLeft.Equals(cr2.BottomLeft);
+ return left.Equals(right);
}
- public static bool operator !=(CornerRadius cr1, CornerRadius cr2)
+ public static bool operator !=(CornerRadius left, CornerRadius right)
{
- return !(cr1 == cr2);
+ return !(left == right);
}
}
}
diff --git a/src/Avalonia.Visuals/Matrix.cs b/src/Avalonia.Visuals/Matrix.cs
index d083a2aaf8..6f9839b6a1 100644
--- a/src/Avalonia.Visuals/Matrix.cs
+++ b/src/Avalonia.Visuals/Matrix.cs
@@ -10,7 +10,7 @@ namespace Avalonia
///
/// A 2x3 matrix.
///
- public readonly struct Matrix
+ public readonly struct Matrix : IEquatable
{
private readonly double _m11;
private readonly double _m12;
@@ -235,12 +235,14 @@ namespace Avalonia
/// True if this matrix is equal to other; False otherwise.
public bool Equals(Matrix other)
{
+ // ReSharper disable CompareOfFloatsByEqualityOperator
return _m11 == other.M11 &&
_m12 == other.M12 &&
_m21 == other.M21 &&
_m22 == other.M22 &&
_m31 == other.M31 &&
_m32 == other.M32;
+ // ReSharper restore CompareOfFloatsByEqualityOperator
}
///
@@ -316,7 +318,7 @@ namespace Avalonia
/// The .
public static Matrix Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Matrix"))
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Matrix."))
{
return new Matrix(
tokenizer.ReadDouble(),
diff --git a/src/Avalonia.Visuals/Media/PixelPoint.cs b/src/Avalonia.Visuals/Media/PixelPoint.cs
index d62c2a2e55..5a329d0238 100644
--- a/src/Avalonia.Visuals/Media/PixelPoint.cs
+++ b/src/Avalonia.Visuals/Media/PixelPoint.cs
@@ -10,7 +10,7 @@ namespace Avalonia
///
/// Represents a point in device pixels.
///
- public readonly struct PixelPoint
+ public readonly struct PixelPoint : IEquatable
{
///
/// A point representing 0,0.
@@ -46,7 +46,7 @@ namespace Avalonia
/// True if the points are equal; otherwise false.
public static bool operator ==(PixelPoint left, PixelPoint right)
{
- return left.X == right.X && left.Y == right.Y;
+ return left.Equals(right);
}
///
@@ -120,7 +120,7 @@ namespace Avalonia
/// The .
public static PixelPoint Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelPoint"))
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelPoint."))
{
return new PixelPoint(
tokenizer.ReadInt32(),
@@ -128,6 +128,18 @@ namespace Avalonia
}
}
+ ///
+ /// Returns a boolean indicating whether the point is equal to the other given point.
+ ///
+ /// The other point to test equality against.
+ /// True if this point is equal to other; False otherwise.
+ public bool Equals(PixelPoint other)
+ {
+ // ReSharper disable CompareOfFloatsByEqualityOperator
+ return X == other.X && Y == other.Y;
+ // ReSharper restore CompareOfFloatsByEqualityOperator
+ }
+
///
/// Checks for equality between a point and an object.
///
@@ -139,7 +151,7 @@ namespace Avalonia
{
if (obj is PixelPoint other)
{
- return this == other;
+ return Equals(other);
}
return false;
diff --git a/src/Avalonia.Visuals/Media/PixelRect.cs b/src/Avalonia.Visuals/Media/PixelRect.cs
index 0e2094da07..b830f4b4b4 100644
--- a/src/Avalonia.Visuals/Media/PixelRect.cs
+++ b/src/Avalonia.Visuals/Media/PixelRect.cs
@@ -10,7 +10,7 @@ namespace Avalonia
///
/// Represents a rectangle in device pixels.
///
- public readonly struct PixelRect
+ public readonly struct PixelRect : IEquatable
{
///
/// An empty rectangle.
@@ -148,7 +148,7 @@ namespace Avalonia
/// True if the rects are equal; otherwise false.
public static bool operator ==(PixelRect left, PixelRect right)
{
- return left.Position == right.Position && left.Size == right.Size;
+ return left.Equals(right);
}
///
@@ -196,6 +196,16 @@ namespace Avalonia
rect.Height);
}
+ ///
+ /// Returns a boolean indicating whether the rect is equal to the other given rect.
+ ///
+ /// The other rect to test equality against.
+ /// True if this rect is equal to other; False otherwise.
+ public bool Equals(PixelRect other)
+ {
+ return Position == other.Position && Size == other.Size;
+ }
+
///
/// Returns a boolean indicating whether the given object is equal to this rectangle.
///
@@ -205,7 +215,7 @@ namespace Avalonia
{
if (obj is PixelRect other)
{
- return this == other;
+ return Equals(other);
}
return false;
@@ -432,7 +442,7 @@ namespace Avalonia
/// The parsed .
public static PixelRect Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelRect"))
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelRect."))
{
return new PixelRect(
tokenizer.ReadInt32(),
diff --git a/src/Avalonia.Visuals/Media/PixelSize.cs b/src/Avalonia.Visuals/Media/PixelSize.cs
index b903b804f9..e2d6b46225 100644
--- a/src/Avalonia.Visuals/Media/PixelSize.cs
+++ b/src/Avalonia.Visuals/Media/PixelSize.cs
@@ -10,7 +10,7 @@ namespace Avalonia
///
/// Represents a size in device pixels.
///
- public readonly struct PixelSize
+ public readonly struct PixelSize : IEquatable
{
///
/// A size representing zero
@@ -51,7 +51,7 @@ namespace Avalonia
/// True if the sizes are equal; otherwise false.
public static bool operator ==(PixelSize left, PixelSize right)
{
- return left.Width == right.Width && left.Height == right.Height;
+ return left.Equals(right);
}
///
@@ -72,7 +72,7 @@ namespace Avalonia
/// The .
public static PixelSize Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelSize"))
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid PixelSize."))
{
return new PixelSize(
tokenizer.ReadInt32(),
@@ -80,6 +80,16 @@ namespace Avalonia
}
}
+ ///
+ /// Returns a boolean indicating whether the size is equal to the other given size.
+ ///
+ /// The other size to test equality against.
+ /// True if this size is equal to other; False otherwise.
+ public bool Equals(PixelSize other)
+ {
+ return Width == other.Width && Height == other.Height;
+ }
+
///
/// Checks for equality between a size and an object.
///
@@ -91,7 +101,7 @@ namespace Avalonia
{
if (obj is PixelSize other)
{
- return this == other;
+ return Equals(other);
}
return false;
diff --git a/src/Avalonia.Visuals/Point.cs b/src/Avalonia.Visuals/Point.cs
index 0d3e354615..0d4dcb7c73 100644
--- a/src/Avalonia.Visuals/Point.cs
+++ b/src/Avalonia.Visuals/Point.cs
@@ -1,6 +1,7 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using System;
using System.Globalization;
using Avalonia.Animation.Animators;
using Avalonia.Utilities;
@@ -10,7 +11,7 @@ namespace Avalonia
///
/// Defines a point.
///
- public readonly struct Point
+ public readonly struct Point : IEquatable
{
static Point()
{
@@ -75,7 +76,7 @@ namespace Avalonia
/// True if the points are equal; otherwise false.
public static bool operator ==(Point left, Point right)
{
- return left.X == right.X && left.Y == right.Y;
+ return left.Equals(right);
}
///
@@ -177,7 +178,7 @@ namespace Avalonia
/// The .
public static Point Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Point"))
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Point."))
{
return new Point(
tokenizer.ReadDouble(),
@@ -186,6 +187,19 @@ namespace Avalonia
}
}
+ ///
+ /// Returns a boolean indicating whether the point is equal to the other given point.
+ ///
+ /// The other point to test equality against.
+ /// True if this point is equal to other; False otherwise.
+ public bool Equals(Point other)
+ {
+ // ReSharper disable CompareOfFloatsByEqualityOperator
+ return _x == other._x &&
+ _y == other._y;
+ // ReSharper enable CompareOfFloatsByEqualityOperator
+ }
+
///
/// Checks for equality between a point and an object.
///
@@ -195,13 +209,12 @@ namespace Avalonia
///
public override bool Equals(object obj)
{
- if (obj is Point)
+ if (!(obj is Point))
{
- var other = (Point)obj;
- return X == other.X && Y == other.Y;
+ return false;
}
- return false;
+ return Equals((Point)obj);
}
///
diff --git a/src/Avalonia.Visuals/Rect.cs b/src/Avalonia.Visuals/Rect.cs
index 8f08f7f51f..94fd2afb3d 100644
--- a/src/Avalonia.Visuals/Rect.cs
+++ b/src/Avalonia.Visuals/Rect.cs
@@ -11,7 +11,7 @@ namespace Avalonia
///
/// Defines a rectangle.
///
- public readonly struct Rect
+ public readonly struct Rect : IEquatable
{
static Rect()
{
@@ -164,7 +164,9 @@ namespace Avalonia
///
/// Gets a value that indicates whether the rectangle is empty.
///
+ // ReSharper disable CompareOfFloatsByEqualityOperator
public bool IsEmpty => _width == 0 && _height == 0;
+ // ReSharper restore CompareOfFloatsByEqualityOperator
///
/// Checks for equality between two s.
@@ -174,7 +176,7 @@ namespace Avalonia
/// True if the rects are equal; otherwise false.
public static bool operator ==(Rect left, Rect right)
{
- return left.Position == right.Position && left.Size == right.Size;
+ return left.Equals(right);
}
///
@@ -297,6 +299,21 @@ namespace Avalonia
Size.Deflate(thickness));
}
+ ///
+ /// Returns a boolean indicating whether the rect is equal to the other given rect.
+ ///
+ /// The other rect to test equality against.
+ /// True if this rect is equal to other; False otherwise.
+ public bool Equals(Rect other)
+ {
+ // ReSharper disable CompareOfFloatsByEqualityOperator
+ return _x == other._x &&
+ _y == other._y &&
+ _width == other._width &&
+ _height == other._height;
+ // ReSharper enable CompareOfFloatsByEqualityOperator
+ }
+
///
/// Returns a boolean indicating whether the given object is equal to this rectangle.
///
@@ -304,13 +321,12 @@ namespace Avalonia
/// True if the object is equal to this rectangle; false otherwise.
public override bool Equals(object obj)
{
- if (obj is Rect)
+ if (!(obj is Rect))
{
- var other = (Rect)obj;
- return Position == other.Position && Size == other.Size;
+ return false;
}
- return false;
+ return Equals((Rect)obj);
}
///
@@ -422,10 +438,10 @@ namespace Avalonia
}
else
{
- var x1 = Math.Min(this.X, rect.X);
- var x2 = Math.Max(this.Right, rect.Right);
- var y1 = Math.Min(this.Y, rect.Y);
- var y2 = Math.Max(this.Bottom, rect.Bottom);
+ var x1 = Math.Min(X, rect.X);
+ var x2 = Math.Max(Right, rect.Right);
+ var y1 = Math.Min(Y, rect.Y);
+ var y2 = Math.Max(Bottom, rect.Bottom);
return new Rect(new Point(x1, y1), new Point(x2, y2));
}
@@ -493,7 +509,7 @@ namespace Avalonia
/// The parsed .
public static Rect Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Rect"))
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Rect."))
{
return new Rect(
tokenizer.ReadDouble(),
diff --git a/src/Avalonia.Visuals/RelativePoint.cs b/src/Avalonia.Visuals/RelativePoint.cs
index d38bb1d496..c822486767 100644
--- a/src/Avalonia.Visuals/RelativePoint.cs
+++ b/src/Avalonia.Visuals/RelativePoint.cs
@@ -130,10 +130,7 @@ namespace Avalonia
{
unchecked
{
- int hash = 17;
- hash = (hash * 23) + Unit.GetHashCode();
- hash = (hash * 23) + Point.GetHashCode();
- return hash;
+ return (_point.GetHashCode() * 397) ^ (int)_unit;
}
}
@@ -156,7 +153,7 @@ namespace Avalonia
/// The parsed .
public static RelativePoint Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid RelativePoint"))
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid RelativePoint."))
{
var x = tokenizer.ReadString();
var y = tokenizer.ReadString();
diff --git a/src/Avalonia.Visuals/RelativeRect.cs b/src/Avalonia.Visuals/RelativeRect.cs
index 927ec3ef75..c69dab3c42 100644
--- a/src/Avalonia.Visuals/RelativeRect.cs
+++ b/src/Avalonia.Visuals/RelativeRect.cs
@@ -139,10 +139,7 @@ namespace Avalonia
{
unchecked
{
- int hash = 17;
- hash = (hash * 23) + Unit.GetHashCode();
- hash = (hash * 23) + Rect.GetHashCode();
- return hash;
+ return ((int)Unit * 397) ^ Rect.GetHashCode();
}
}
@@ -161,7 +158,7 @@ namespace Avalonia
Rect.Width * size.Width,
Rect.Height * size.Height);
}
-
+
///
/// Parses a string.
///
@@ -169,7 +166,7 @@ namespace Avalonia
/// The parsed .
public static RelativeRect Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, exceptionMessage: "Invalid RelativeRect"))
+ using (var tokenizer = new StringTokenizer(s, exceptionMessage: "Invalid RelativeRect."))
{
var x = tokenizer.ReadString();
var y = tokenizer.ReadString();
diff --git a/src/Avalonia.Visuals/Size.cs b/src/Avalonia.Visuals/Size.cs
index 782c5ea67b..9d524d6fa7 100644
--- a/src/Avalonia.Visuals/Size.cs
+++ b/src/Avalonia.Visuals/Size.cs
@@ -11,7 +11,7 @@ namespace Avalonia
///
/// Defines a size.
///
- public readonly struct Size
+ public readonly struct Size : IEquatable
{
static Size()
{
@@ -72,7 +72,7 @@ namespace Avalonia
/// True if the sizes are equal; otherwise false.
public static bool operator ==(Size left, Size right)
{
- return left._width == right._width && left._height == right._height;
+ return left.Equals(right);
}
///
@@ -158,7 +158,7 @@ namespace Avalonia
/// The .
public static Size Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Size"))
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Size."))
{
return new Size(
tokenizer.ReadDouble(),
@@ -191,6 +191,19 @@ namespace Avalonia
Math.Max(0, _height - thickness.Top - thickness.Bottom));
}
+ ///
+ /// Returns a boolean indicating whether the size is equal to the other given size.
+ ///
+ /// The other size to test equality against.
+ /// True if this size is equal to other; False otherwise.
+ public bool Equals(Size other)
+ {
+ // ReSharper disable CompareOfFloatsByEqualityOperator
+ return _width == other._width &&
+ _height == other._height;
+ // ReSharper enable CompareOfFloatsByEqualityOperator
+ }
+
///
/// Checks for equality between a size and an object.
///
@@ -200,13 +213,12 @@ namespace Avalonia
///
public override bool Equals(object obj)
{
- if (obj is Size)
+ if (!(obj is Size))
{
- var other = (Size)obj;
- return Width == other.Width && Height == other.Height;
+ return false;
}
- return false;
+ return Equals((Size)obj);
}
///
diff --git a/src/Avalonia.Visuals/Thickness.cs b/src/Avalonia.Visuals/Thickness.cs
index 830ee4666e..d0fc63e254 100644
--- a/src/Avalonia.Visuals/Thickness.cs
+++ b/src/Avalonia.Visuals/Thickness.cs
@@ -3,7 +3,6 @@
using System;
using System.Globalization;
-using Avalonia.Animation;
using Avalonia.Animation.Animators;
using Avalonia.Utilities;
@@ -12,7 +11,7 @@ namespace Avalonia
///
/// Describes the thickness of a frame around a rectangle.
///
- public readonly struct Thickness
+ public readonly struct Thickness : IEquatable
{
static Thickness()
{
@@ -204,7 +203,9 @@ namespace Avalonia
/// The .
public static Thickness Parse(string s)
{
- using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: "Invalid Thickness"))
+ const string exceptionMessage = "Invalid Thickness.";
+
+ using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage))
{
if (tokenizer.TryReadDouble(out var a))
{
@@ -221,10 +222,25 @@ namespace Avalonia
return new Thickness(a);
}
- throw new FormatException("Invalid Thickness.");
+ throw new FormatException(exceptionMessage);
}
}
+ ///
+ /// Returns a boolean indicating whether the thickness is equal to the other given point.
+ ///
+ /// The other thickness to test equality against.
+ /// True if this thickness is equal to other; False otherwise.
+ public bool Equals(Thickness other)
+ {
+ // ReSharper disable CompareOfFloatsByEqualityOperator
+ return _left == other._left &&
+ _top == other._top &&
+ _right == other._right &&
+ _bottom == other._bottom;
+ // ReSharper restore CompareOfFloatsByEqualityOperator
+ }
+
///
/// Checks for equality between a thickness and an object.
///
@@ -234,16 +250,12 @@ namespace Avalonia
///
public override bool Equals(object obj)
{
- if (obj is Thickness)
+ if (!(obj is Thickness))
{
- Thickness other = (Thickness)obj;
- return Left == other.Left &&
- Top == other.Top &&
- Right == other.Right &&
- Bottom == other.Bottom;
+ return false;
}
- return false;
+ return Equals((Thickness)obj);
}
///
diff --git a/src/Avalonia.Visuals/Vector.cs b/src/Avalonia.Visuals/Vector.cs
index 11bda8b00e..bd2dfdc828 100644
--- a/src/Avalonia.Visuals/Vector.cs
+++ b/src/Avalonia.Visuals/Vector.cs
@@ -11,7 +11,7 @@ namespace Avalonia
///
/// Defines a vector.
///
- public readonly struct Vector
+ public readonly struct Vector : IEquatable
{
static Vector()
{
diff --git a/src/Avalonia.Visuals/VisualTree/TransformedBounds.cs b/src/Avalonia.Visuals/VisualTree/TransformedBounds.cs
index 39b328adc2..5fb22680dc 100644
--- a/src/Avalonia.Visuals/VisualTree/TransformedBounds.cs
+++ b/src/Avalonia.Visuals/VisualTree/TransformedBounds.cs
@@ -1,13 +1,14 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using System;
namespace Avalonia.VisualTree
{
///
/// Holds information about the bounds of a control, together with a transform and a clip.
///
- public readonly struct TransformedBounds
+ public readonly struct TransformedBounds : IEquatable
{
///
/// Initializes a new instance of the struct.