// 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 () + "}"; } }