#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2010 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#endregion
using System;
using System.Globalization;
using Microsoft.Xna.Framework;
namespace Nuclex.UserInterface {
/// Two-dimensional rectangle using floating point coordinates
#if !NO_SERIALIZATION
[Serializable]
#endif
public struct RectangleF : IEquatable {
/// Initializes a floating point rectangle
/// The x-coordinate of the rectangle's lower right corner
/// The y-coordinate of the rectangle's lower right corner
/// Width of the rectangle
/// Height of the rectangle
public RectangleF(float x, float y, float width, float height) {
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
/// Changes the position of the Rectangle
/// The values to adjust the position of the rectangle by
public void Offset(Vector2 amount) {
Offset(amount.X, amount.Y);
}
/// Changes the position of the Rectangle
/// Change in the x-position
/// Change in the y-position
public void Offset(float offsetX, float offsetY) {
this.X += offsetX;
this.Y += offsetY;
}
///
/// Pushes the edges of the Rectangle out by the horizontal and
/// vertical values specified
///
/// Value to push the sides out by
/// Value to push the top and bottom out by
public void Inflate(float horizontalAmount, float verticalAmount) {
this.X -= horizontalAmount;
this.Y -= verticalAmount;
this.Width += horizontalAmount * 2;
this.Height += verticalAmount * 2;
}
/// Determines whether the rectangle contains a specified Point
/// The point to evaluate
///
/// True if the specified point is contained within this rectangle; false otherwise
///
public bool Contains(Vector2 point) {
return Contains(point.X, point.Y);
}
/// Determines whether the rectangle contains a specified Point
/// The point to evaluate
///
/// True if the specified point is contained within this rectangle; false otherwise
///
public void Contains(ref Vector2 point, out bool result) {
result = Contains(point.X, point.Y);
}
///
/// Determines whether this Rectangle contains a specified point represented by
/// its x- and y-coordinates
///
/// The x-coordinate of the specified point
/// The y-coordinate of the specified point
///
/// True if the specified point is contained within this rectangle; false otherwise
///
public bool Contains(float x, float y) {
return
(x >= this.X) &&
(y >= this.Y) &&
(x < this.X + this.Width) &&
(y < this.Y + this.Height);
}
///
/// Determines whether the rectangle contains another rectangle in its entirety
///
/// The rectangle to evaluate
///
/// True if the rectangle entirely contains the specified rectangle; false otherwise
///
public bool Contains(RectangleF other) {
bool result;
Contains(ref other, out result);
return result;
}
///
/// Determines whether this rectangle entirely contains a specified rectangle
///
/// The rectangle to evaluate
///
/// On exit, is true if this rectangle entirely contains the specified rectangle,
/// or false if not
///
public void Contains(ref RectangleF other, out bool result) {
result =
(other.X >= this.X) &&
(other.Y >= this.Y) &&
((other.X + other.Width) <= (this.X + this.Width)) &&
((other.Y + other.Height) <= (this.Y + this.Height));
}
///
/// Determines whether a specified rectangle intersects with this rectangle
///
/// The rectangle to evaluate
///
/// True if the specified rectangle intersects with this one; false otherwise
///
public bool Intersects(RectangleF rectangle) {
bool result;
Intersects(ref rectangle, out result);
return result;
}
///
/// Determines whether a specified rectangle intersects with this rectangle
///
/// The rectangle to evaluate
///
/// True if the specified rectangle intersects with this one; false otherwise
///
public void Intersects(ref RectangleF rectangle, out bool result) {
result =
(rectangle.X < (this.X + this.Width)) &&
(rectangle.Y < (this.Y + this.Height)) &&
((rectangle.X + rectangle.Width) > this.X) &&
((rectangle.Y + rectangle.Height) > this.Y);
}
///
/// Determines whether the specified rectangle is equal to this rectangle
///
/// The rectangle to compare with this rectangle
///
/// True if the specified rectangle is equal to the this rectangle; false otherwise
///
public bool Equals(RectangleF other) {
return
(this.X == other.X) &&
(this.Y == other.Y) &&
(this.Width == other.Width) &&
(this.Height == other.Height);
}
///
/// Returns a value that indicates whether the current instance is equal to a
/// specified object
///
/// Object to make the comparison with
///
/// True if the current instance is equal to the specified object; false otherwise
///
public override bool Equals(object other) {
if(!(other is RectangleF)) {
return false;
}
return Equals((RectangleF)other);
}
/// Retrieves a string representation of the current object
/// String that represents the object
public override string ToString() {
CultureInfo currentCulture = CultureInfo.CurrentCulture;
return string.Format(
currentCulture, "{{X:{0} Y:{1} Width:{2} Height:{3}}}",
this.X.ToString(currentCulture),
this.Y.ToString(currentCulture),
this.Width.ToString(currentCulture),
this.Height.ToString(currentCulture)
);
}
/// Gets the hash code for this object
/// Hash code for this object
public override int GetHashCode() {
return
this.X.GetHashCode() ^
this.Y.GetHashCode() ^
this.Width.GetHashCode() ^
this.Height.GetHashCode();
}
/// Compares two rectangles for equality
/// Source rectangle
/// Source rectangle
/// True if the rectangles are equal; false otherwise
public static bool operator ==(RectangleF first, RectangleF second) {
return
(first.X == second.X) &&
(first.Y == second.Y) &&
(first.Width == second.Width) &&
(first.Height == second.Height);
}
/// Compares two rectangles for inequality
/// Source rectangle
/// Source rectangle
/// True if the rectangles are not equal; false otherwise
public static bool operator !=(RectangleF first, RectangleF second) {
return
(first.X != second.X) ||
(first.Y != second.Y) ||
(first.Width != second.Width) ||
(first.Height != second.Height);
}
/// Returns the x-coordinate of the left side of the rectangle
/// The x-coordinate of the left side of the rectangle
public float Left {
get { return this.X; }
}
/// Returns the x-coordinate of the right side of the rectangle
/// The x-coordinate of the right side of the rectangle
public float Right {
get { return (this.X + this.Width); }
}
/// Returns the y-coordinate of the top of the rectangle
/// The y-coordinate of the top of the rectangle
public float Top {
get { return this.Y; }
}
/// Returns the y-coordinate of the bottom of the rectangle
/// The y-coordinate of the bottom of the rectangle
public float Bottom {
get { return (this.Y + this.Height); }
}
/// Returns a Rectangle with all of its values set to zero
/// An empty Rectangle
public static RectangleF Empty {
get { return empty; }
}
/// Specifies the x-coordinate of the rectangle
public float X;
/// Specifies the y-coordinate of the rectangle
public float Y;
/// Specifies the width of the rectangle
public float Width;
/// Specifies the height of the rectangle
public float Height;
/// An empty rectangle
private static RectangleF empty = new RectangleF();
}
} // namespace Nuclex.UserInterface