// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Copied from https://github.com/dotnet/corefx/tree/master/src/System.Drawing.Primitives/src/System/Drawing
using System;
using System.ComponentModel;
namespace Terminal.Gui {
///
/// Stores the location and size of a rectangular region.
///
public struct RectangleF : IEquatable {
///
/// Initializes a new instance of the class.
///
public static readonly RectangleF Empty;
private float x; // Do not rename (binary serialization)
private float y; // Do not rename (binary serialization)
private float width; // Do not rename (binary serialization)
private float height; // Do not rename (binary serialization)
///
/// Initializes a new instance of the class with the specified location
/// and size.
///
public RectangleF (float x, float y, float width, float height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
///
/// Initializes a new instance of the class with the specified location
/// and size.
///
public RectangleF (PointF location, SizeF size)
{
x = location.X;
y = location.Y;
width = size.Width;
height = size.Height;
}
///
/// Creates a new with the specified location and size.
///
public static RectangleF FromLTRB (float left, float top, float right, float bottom) =>
new RectangleF (left, top, right - left, bottom - top);
///
/// Gets or sets the coordinates of the upper-left corner of the rectangular region represented by this
/// .
///
[Browsable (false)]
public PointF Location {
get => new PointF (X, Y);
set {
X = value.X;
Y = value.Y;
}
}
///
/// Gets or sets the size of this .
///
[Browsable (false)]
public SizeF Size {
get => new SizeF (Width, Height);
set {
Width = value.Width;
Height = value.Height;
}
}
///
/// Gets or sets the x-coordinate of the upper-left corner of the rectangular region defined by this
/// .
///
public float X {
get => x;
set => x = value;
}
///
/// Gets or sets the y-coordinate of the upper-left corner of the rectangular region defined by this
/// .
///
public float Y {
get => y;
set => y = value;
}
///
/// Gets or sets the width of the rectangular region defined by this .
///
public float Width {
get => width;
set => width = value;
}
///
/// Gets or sets the height of the rectangular region defined by this .
///
public float Height {
get => height;
set => height = value;
}
///
/// Gets the x-coordinate of the upper-left corner of the rectangular region defined by this
/// .
///
[Browsable (false)]
public float Left => X;
///
/// Gets the y-coordinate of the upper-left corner of the rectangular region defined by this
/// .
///
[Browsable (false)]
public float Top => Y;
///
/// Gets the x-coordinate of the lower-right corner of the rectangular region defined by this
/// .
///
[Browsable (false)]
public float Right => X + Width;
///
/// Gets the y-coordinate of the lower-right corner of the rectangular region defined by this
/// .
///
[Browsable (false)]
public float Bottom => Y + Height;
///
/// Tests whether this has a or a of 0.
///
[Browsable (false)]
public bool IsEmpty => (Width <= 0) || (Height <= 0);
///
/// Tests whether is a with the same location and
/// size of this .
///
public override bool Equals (object obj) => obj is RectangleF && Equals ((RectangleF)obj);
///
/// Returns true if two objects have equal location and size.
///
///
///
public bool Equals (RectangleF other) => this == other;
///
/// Tests whether two objects have equal location and size.
///
public static bool operator == (RectangleF left, RectangleF right) =>
left.X == right.X && left.Y == right.Y && left.Width == right.Width && left.Height == right.Height;
///
/// Tests whether two objects differ in location or size.
///
public static bool operator != (RectangleF left, RectangleF right) => !(left == right);
///
/// Determines if the specified point is contained within the rectangular region defined by this
/// .
///
public bool Contains (float x, float y) => X <= x && x < X + Width && Y <= y && y < Y + Height;
///
/// Determines if the specified point is contained within the rectangular region defined by this
/// .
///
public bool Contains (PointF pt) => Contains (pt.X, pt.Y);
///
/// Determines if the rectangular region represented by is entirely contained within
/// the rectangular region represented by this .
///
public bool Contains (RectangleF rect) =>
(X <= rect.X) && (rect.X + rect.Width <= X + Width) && (Y <= rect.Y) && (rect.Y + rect.Height <= Y + Height);
///
/// Gets the hash code for this .
///
public override int GetHashCode ()
{
return (Height.GetHashCode () + Width.GetHashCode ()) ^ X.GetHashCode () + Y.GetHashCode ();
}
///
/// Inflates this by the specified amount.
///
public void Inflate (float x, float y)
{
X -= x;
Y -= y;
Width += 2 * x;
Height += 2 * y;
}
///
/// Inflates this by the specified amount.
///
public void Inflate (SizeF size) => Inflate (size.Width, size.Height);
///
/// Creates a that is inflated by the specified amount.
///
public static RectangleF Inflate (RectangleF rect, float x, float y)
{
RectangleF r = rect;
r.Inflate (x, y);
return r;
}
///
/// Creates a Rectangle that represents the intersection between this Rectangle and rect.
///
public void Intersect (RectangleF rect)
{
RectangleF result = Intersect (rect, this);
X = result.X;
Y = result.Y;
Width = result.Width;
Height = result.Height;
}
///
/// Creates a rectangle that represents the intersection between a and b. If there is no intersection, an
/// empty rectangle is returned.
///
public static RectangleF Intersect (RectangleF a, RectangleF b)
{
float x1 = Math.Max (a.X, b.X);
float x2 = Math.Min (a.X + a.Width, b.X + b.Width);
float y1 = Math.Max (a.Y, b.Y);
float y2 = Math.Min (a.Y + a.Height, b.Y + b.Height);
if (x2 >= x1 && y2 >= y1) {
return new RectangleF (x1, y1, x2 - x1, y2 - y1);
}
return Empty;
}
///
/// Determines if this rectangle intersects with rect.
///
public bool IntersectsWith (RectangleF rect) =>
(rect.X < X + Width) && (X < rect.X + rect.Width) && (rect.Y < Y + Height) && (Y < rect.Y + rect.Height);
///
/// Creates a rectangle that represents the union between a and b.
///
public static RectangleF Union (RectangleF a, RectangleF b)
{
float x1 = Math.Min (a.X, b.X);
float x2 = Math.Max (a.X + a.Width, b.X + b.Width);
float y1 = Math.Min (a.Y, b.Y);
float y2 = Math.Max (a.Y + a.Height, b.Y + b.Height);
return new RectangleF (x1, y1, x2 - x1, y2 - y1);
}
///
/// Adjusts the location of this rectangle by the specified amount.
///
public void Offset (PointF pos) => Offset (pos.X, pos.Y);
///
/// Adjusts the location of this rectangle by the specified amount.
///
public void Offset (float x, float y)
{
X += x;
Y += y;
}
///
/// Converts the specified to a
/// .
///
public static implicit operator RectangleF (Rect r) => new RectangleF (r.X, r.Y, r.Width, r.Height);
///
/// Converts the and
/// of this to a human-readable string.
///
public override string ToString () =>
"{X=" + X.ToString () + ",Y=" + Y.ToString () +
",Width=" + Width.ToString () + ",Height=" + Height.ToString () + "}";
}
}