RectangleF.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. // Copied from https://github.com/dotnet/corefx/tree/master/src/System.Drawing.Primitives/src/System/Drawing
  5. using System.ComponentModel;
  6. namespace Terminal.Gui;
  7. /// <summary>Stores the location and size of a rectangular region.</summary>
  8. public struct RectangleF : IEquatable<RectangleF>
  9. {
  10. /// <summary>Initializes a new instance of the <see cref='Terminal.Gui.RectangleF'/> class.</summary>
  11. public static readonly RectangleF Empty;
  12. /// <summary>
  13. /// Initializes a new instance of the <see cref='Terminal.Gui.RectangleF'/> class with the specified location and
  14. /// size.
  15. /// </summary>
  16. public RectangleF (float x, float y, float width, float height)
  17. {
  18. X = x;
  19. Y = y;
  20. Width = width;
  21. Height = height;
  22. }
  23. /// <summary>
  24. /// Initializes a new instance of the <see cref='Terminal.Gui.RectangleF'/> class with the specified location and
  25. /// size.
  26. /// </summary>
  27. public RectangleF (PointF location, SizeF size)
  28. {
  29. X = location.X;
  30. Y = location.Y;
  31. Width = size.Width;
  32. Height = size.Height;
  33. }
  34. /// <summary>Creates a new <see cref='Terminal.Gui.RectangleF'/> with the specified location and size.</summary>
  35. public static RectangleF FromLTRB (float left, float top, float right, float bottom) { return new RectangleF (left, top, right - left, bottom - top); }
  36. /// <summary>
  37. /// Gets or sets the coordinates of the upper-left corner of the rectangular region represented by this
  38. /// <see cref='Terminal.Gui.RectangleF'/>.
  39. /// </summary>
  40. [Browsable (false)]
  41. public PointF Location
  42. {
  43. get => new (X, Y);
  44. set
  45. {
  46. X = value.X;
  47. Y = value.Y;
  48. }
  49. }
  50. /// <summary>Gets or sets the size of this <see cref='Terminal.Gui.RectangleF'/>.</summary>
  51. [Browsable (false)]
  52. public SizeF Size
  53. {
  54. get => new (Width, Height);
  55. set
  56. {
  57. Width = value.Width;
  58. Height = value.Height;
  59. }
  60. }
  61. /// <summary>
  62. /// Gets or sets the x-coordinate of the upper-left corner of the rectangular region defined by this
  63. /// <see cref='Terminal.Gui.RectangleF'/>.
  64. /// </summary>
  65. public float X { get; set; }
  66. /// <summary>
  67. /// Gets or sets the y-coordinate of the upper-left corner of the rectangular region defined by this
  68. /// <see cref='Terminal.Gui.RectangleF'/>.
  69. /// </summary>
  70. public float Y { get; set; }
  71. /// <summary>Gets or sets the width of the rectangular region defined by this <see cref='Terminal.Gui.RectangleF'/>.</summary>
  72. public float Width { get; set; }
  73. /// <summary>Gets or sets the height of the rectangular region defined by this <see cref='Terminal.Gui.RectangleF'/>.</summary>
  74. public float Height { get; set; }
  75. /// <summary>
  76. /// Gets the x-coordinate of the upper-left corner of the rectangular region defined by this
  77. /// <see cref='Terminal.Gui.RectangleF'/> .
  78. /// </summary>
  79. [Browsable (false)]
  80. public float Left => X;
  81. /// <summary>
  82. /// Gets the y-coordinate of the upper-left corner of the rectangular region defined by this
  83. /// <see cref='Terminal.Gui.RectangleF'/>.
  84. /// </summary>
  85. [Browsable (false)]
  86. public float Top => Y;
  87. /// <summary>
  88. /// Gets the x-coordinate of the lower-right corner of the rectangular region defined by this
  89. /// <see cref='Terminal.Gui.RectangleF'/>.
  90. /// </summary>
  91. [Browsable (false)]
  92. public float Right => X + Width;
  93. /// <summary>
  94. /// Gets the y-coordinate of the lower-right corner of the rectangular region defined by this
  95. /// <see cref='Terminal.Gui.RectangleF'/>.
  96. /// </summary>
  97. [Browsable (false)]
  98. public float Bottom => Y + Height;
  99. /// <summary>
  100. /// Tests whether this <see cref='Terminal.Gui.RectangleF'/> has a <see cref='Terminal.Gui.RectangleF.Width'/> or
  101. /// a <see cref='Terminal.Gui.RectangleF.Height'/> of 0.
  102. /// </summary>
  103. [Browsable (false)]
  104. public bool IsEmpty => Width <= 0 || Height <= 0;
  105. /// <summary>
  106. /// Tests whether <paramref name="obj"/> is a <see cref='Terminal.Gui.RectangleF'/> with the same location and
  107. /// size of this <see cref='Terminal.Gui.RectangleF'/>.
  108. /// </summary>
  109. public override bool Equals (object obj) { return obj is RectangleF && Equals ((RectangleF)obj); }
  110. /// <summary>Returns true if two <see cref='Terminal.Gui.RectangleF'/> objects have equal location and size.</summary>
  111. /// <param name="other"></param>
  112. /// <returns></returns>
  113. public bool Equals (RectangleF other) { return this == other; }
  114. /// <summary>Tests whether two <see cref='Terminal.Gui.RectangleF'/> objects have equal location and size.</summary>
  115. public static bool operator == (RectangleF left, RectangleF right)
  116. {
  117. return left.X == right.X && left.Y == right.Y && left.Width == right.Width && left.Height == right.Height;
  118. }
  119. /// <summary>Tests whether two <see cref='Terminal.Gui.RectangleF'/> objects differ in location or size.</summary>
  120. public static bool operator != (RectangleF left, RectangleF right) { return !(left == right); }
  121. /// <summary>
  122. /// Determines if the specified point is contained within the rectangular region defined by this
  123. /// <see cref='Rectangle'/> .
  124. /// </summary>
  125. public bool Contains (float x, float y) { return X <= x && x < X + Width && Y <= y && y < Y + Height; }
  126. /// <summary>
  127. /// Determines if the specified point is contained within the rectangular region defined by this
  128. /// <see cref='Rectangle'/> .
  129. /// </summary>
  130. public bool Contains (PointF pt) { return Contains (pt.X, pt.Y); }
  131. /// <summary>
  132. /// Determines if the rectangular region represented by <paramref name="rect"/> is entirely contained within the
  133. /// rectangular region represented by this <see cref='Rectangle'/> .
  134. /// </summary>
  135. public bool Contains (RectangleF rect)
  136. {
  137. return X <= rect.X
  138. && rect.X + rect.Width <= X + Width
  139. && Y <= rect.Y
  140. && rect.Y + rect.Height <= Y + Height;
  141. }
  142. /// <summary>Gets the hash code for this <see cref='Terminal.Gui.RectangleF'/>.</summary>
  143. public override int GetHashCode () { return (Height.GetHashCode () + Width.GetHashCode ()) ^ (X.GetHashCode () + Y.GetHashCode ()); }
  144. /// <summary>Inflates this <see cref='Rectangle'/> by the specified amount.</summary>
  145. public void Inflate (float x, float y)
  146. {
  147. X -= x;
  148. Y -= y;
  149. Width += 2 * x;
  150. Height += 2 * y;
  151. }
  152. /// <summary>Inflates this <see cref='Rectangle'/> by the specified amount.</summary>
  153. public void Inflate (SizeF size) { Inflate (size.Width, size.Height); }
  154. /// <summary>Creates a <see cref='Rectangle'/> that is inflated by the specified amount.</summary>
  155. public static RectangleF Inflate (RectangleF rect, float x, float y)
  156. {
  157. RectangleF r = rect;
  158. r.Inflate (x, y);
  159. return r;
  160. }
  161. /// <summary>Creates a Rectangle that represents the intersection between this Rectangle and rect.</summary>
  162. public void Intersect (RectangleF rect)
  163. {
  164. RectangleF result = Intersect (rect, this);
  165. X = result.X;
  166. Y = result.Y;
  167. Width = result.Width;
  168. Height = result.Height;
  169. }
  170. /// <summary>
  171. /// Creates a rectangle that represents the intersection between a and b. If there is no intersection, an empty
  172. /// rectangle is returned.
  173. /// </summary>
  174. public static RectangleF Intersect (RectangleF a, RectangleF b)
  175. {
  176. float x1 = Math.Max (a.X, b.X);
  177. float x2 = Math.Min (a.X + a.Width, b.X + b.Width);
  178. float y1 = Math.Max (a.Y, b.Y);
  179. float y2 = Math.Min (a.Y + a.Height, b.Y + b.Height);
  180. if (x2 >= x1 && y2 >= y1)
  181. {
  182. return new RectangleF (x1, y1, x2 - x1, y2 - y1);
  183. }
  184. return Empty;
  185. }
  186. /// <summary>Determines if this rectangle intersects with rect.</summary>
  187. public bool IntersectsWith (RectangleF rect)
  188. {
  189. return rect.X < X + Width
  190. && X < rect.X + rect.Width
  191. && rect.Y < Y + Height
  192. && Y < rect.Y + rect.Height;
  193. }
  194. /// <summary>Creates a rectangle that represents the union between a and b.</summary>
  195. public static RectangleF Union (RectangleF a, RectangleF b)
  196. {
  197. float x1 = Math.Min (a.X, b.X);
  198. float x2 = Math.Max (a.X + a.Width, b.X + b.Width);
  199. float y1 = Math.Min (a.Y, b.Y);
  200. float y2 = Math.Max (a.Y + a.Height, b.Y + b.Height);
  201. return new RectangleF (x1, y1, x2 - x1, y2 - y1);
  202. }
  203. /// <summary>Adjusts the location of this rectangle by the specified amount.</summary>
  204. public void Offset (PointF pos) { Offset (pos.X, pos.Y); }
  205. /// <summary>Adjusts the location of this rectangle by the specified amount.</summary>
  206. public void Offset (float x, float y)
  207. {
  208. X += x;
  209. Y += y;
  210. }
  211. /// <summary>Converts the specified <see cref='Rectangle'/> to a <see cref='Terminal.Gui.RectangleF'/>.</summary>
  212. public static implicit operator RectangleF (Rectangle r) { return new RectangleF (r.X, r.Y, r.Width, r.Height); }
  213. /// <summary>
  214. /// Converts the <see cref='Terminal.Gui.RectangleF.Location'/> and <see cref='Terminal.Gui.RectangleF.Size'/> of
  215. /// this <see cref='Terminal.Gui.RectangleF'/> to a human-readable string.
  216. /// </summary>
  217. public override string ToString () { return "{X=" + X + ",Y=" + Y + ",Width=" + Width + ",Height=" + Height + "}"; }
  218. }