MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rect.h
1 //© Copyright 2010 - 2012 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _uirect_h
41 #define _uirect_h
42 
43 #include "vector2.h"
44 #include "exception.h"
45 #include "serialization.h"
46 
47 namespace Mezzanine
48 {
49  namespace UI
50  {
51  ///////////////////////////////////////////////////////////////////////////////
52  /// @class Rect
53  /// @headerfile rect.h
54  /// @brief This class represents a box shaped area on the screen.
55  /// @details
56  ///////////////////////////////////////
57  class MEZZ_LIB Rect
58  {
59  protected:
60  /// @brief Simple check to see if a point is within a given range.
61  /// @param Value The value to compare against the range.
62  /// @param Min The minimum value of the range.
63  /// @param Max The maximum value of the range.
64  /// @return Returns true if the provided value is within the provided range, false otherwise.
65  inline bool ValueInRange(const Real& Value, const Real& Min, const Real& Max) const
66  {
67  return (Value >= Min) && (Value <= Max);
68  }
69  public:
70  /// @brief Vector2 representing the top-left position of the rect.
72  /// @brief Vector2 representing the width and height of the rect.
74  /// @brief Bool representing whether this rect is represented in relative units or absolute units(pixels).
75  bool Relative;
76 
77  /// @brief Less Detailed Real Constructor.
78  /// @param PosX The position of this rect on the X axis.
79  /// @param PosY The position of this rect on the Y axis.
80  /// @param SizeX The size of this rect on the X axis.
81  /// @param SizeY The size of this rect on the Y axis.
82  Rect(const Real& PosX, const Real& PosY, const Real& SizeX, const Real& SizeY)
83  {
84  this->Position.SetValues(PosX,PosY);
85  this->Size.SetValues(SizeX,SizeY);
86  this->Relative = false;
87  }
88  /// @brief Real Constructor.
89  /// @param PosX The position of this rect on the X axis.
90  /// @param PosY The position of this rect on the Y axis.
91  /// @param SizeX The size of this rect on the X axis.
92  /// @param SizeY The size of this rect on the Y axis.
93  Rect(const Real& PosX, const Real& PosY, const Real& SizeX, const Real& SizeY, bool Relative)
94  {
95  this->Position.SetValues(PosX,PosY);
96  this->Size.SetValues(SizeX,SizeY);
97  this->Relative = Relative;
98  }
99  /// @brief Less Detailed Vector2 Constructor.
100  /// @details Sets all the data of the class.
101  /// @param Position The position of the Renderable's Rect.
102  /// @param Size The size of the Renderable's Rect.
103  Rect(const Vector2& Position, const Vector2& Size)
104  {
105  this->Position = Position;
106  this->Size = Size;
107  this->Relative = false;
108  }
109  /// @brief Vector2 Constructor.
110  /// @details Sets all the data of the class.
111  /// @param Position The position of the Renderable's Rect.
112  /// @param Size The size of the Renderable's Rect.
113  /// @param Relative Whether or not this Rect is using relative(0-1) or absolute units(Pixels).
114  Rect(const Vector2& Position, const Vector2& Size, bool Relative)
115  {
116  this->Position = Position;
117  this->Size = Size;
118  this->Relative = Relative;
119  }
120  /// @brief Copy Constructor.
121  /// @param Other The other Rect to copy.
122  Rect(const Rect& Other)
123  {
124  this->Position = Other.Position;
125  this->Size = Other.Size;
126  this->Relative = Other.Relative;
127  }
128  /// @brief No Initialization Constructor.
129  /// @details Sets all data members to zero's.
131  {
132  this->SetIdentity();
133  this->Relative = false;
134  }
135  /// @brief Class destructor.
136  ~Rect() {}
137 
138  ///////////////////////////////////////////////////////////////////////////////
139  // Utility Methods
140 
141  /// @brief Sets all the values of this rect to zero.
142  inline void SetIdentity()
143  {
144  this->Position.SetIdentity();
145  this->Size.SetIdentity();
146  }
147  /// @brief Gets the coordinates to the center of this rect.
148  /// @return Returns a vector2 containing the central point of this rect.
149  inline Vector2 GetRectCenter() const
150  {
151  return Vector2(Position.X + (Size.X * 0.5),Position.Y + (Size.Y * 0.5));
152  }
153  /// @brief Checks to see if another Rect is overlapping with this one.
154  /// @param OtherRect The other rect to compare against.
155  /// @return Returns true if these rects overlap with each other, false otherwise.
156  inline bool CheckOverlap(const Rect& OtherRect) const
157  {
158  bool XOverlap = ValueInRange(this->Position.X, OtherRect.Position.X, OtherRect.Position.X + OtherRect.Size.X) ||
159  ValueInRange(OtherRect.Position.X, this->Position.X, this->Position.X + this->Size.X);
160 
161  bool YOverlap = ValueInRange(this->Position.Y, OtherRect.Position.Y, OtherRect.Position.Y + OtherRect.Size.Y) ||
162  ValueInRange(OtherRect.Position.Y, this->Position.Y, this->Position.Y + this->Size.Y);
163 
164  return (XOverlap && YOverlap);
165  }
166  /// @brief Checks to see if a point in 2D space is inside this rect.
167  /// @param Point The point in 2D space to check.
168  /// @return Returns true if the provided point is within this rect, false otherwise.
169  inline bool IsInside(const Vector2& Point) const
170  {
171  return ( ValueInRange(Point.X,this->Position.X,this->Position.X + this->Size.X) &&
172  ValueInRange(Point.Y,this->Position.Y,this->Position.Y + this->Size.Y) );
173  }
174  /// @brief Gets whether or point on the X axis is within the limits of this rect or not.
175  /// @param Position The point on the X axis.
176  /// @return Returns true in the provided position is within this rect's limits, false otherwise.
177  inline bool IsWithinWidth(const Real& Position) const
178  {
179  return ValueInRange(Position,this->Position.X,this->Position.X + this->Size.X);
180  }
181  /// @brief Gets whether or point on the Y axis is within the limits of this rect or not.
182  /// @param Position The point on the Y axis.
183  /// @return Returns true in the provided position is within this rect's limits, false otherwise.
184  inline bool IsWithinHeight(const Real& Position) const
185  {
186  return ValueInRange(Position,this->Position.Y,this->Position.Y + this->Size.Y);
187  }
188 
189  ///////////////////////////////////////////////////////////////////////////////
190  // Transform Methods
191 
192  /// @brief Scales this rect.
193  /// @note This will scale the rect based on it's center, not it's top-left position. If you want to instead preserve the position of the Rect then apply the scaling manually.
194  /// @param Scaling A Vector2 representing the X and Y scaling to be applied to this rect.
195  /// @return Returns a reference to this.
196  inline Rect& ApplyScaling(const Vector2& Scaling)
197  {
198  Vector2 PrevCenter = this->GetRectCenter();
199  this->Size *= Scaling;
200 
201  this->Position.X = PrevCenter.X - ( this->Size.X * 0.5 );
202  this->Position.Y = PrevCenter.Y - ( this->Size.Y * 0.5 );
203 
204  return *this;
205  }
206 
207  ///////////////////////////////////////////////////////////////////////////////
208  // Overloaded Operators
209 
210  /// @brief Assignment Operator.
211  /// @details Copys the contents of a Rect to another.
212  /// @param Other The other Rect to copy from.
213  inline Rect& operator=(const Rect& Other)
214  {
215  this->Position = Other.Position;
216  this->Size = Other.Size;
217  this->Relative = Other.Relative;
218  return *this;
219  }
220  /// @brief Equality Comparison Operator.
221  /// @details Checks to see if the two Rects are equal.
222  /// @param Other The other Rect to compare against.
223  inline bool operator==(const Rect& Other)
224  {
225  return ( this->Position == Other.Position && this->Size == Other.Size && this->Relative == Other.Relative );
226  }
227  /// @brief Inequality Comparison Operator.
228  /// @details Checks to see if the two rects are different.
229  /// @param Other The other Rect to compare against.
230  inline bool operator!=(const Rect& Other)
231  {
232  return ( this->Position != Other.Position || this->Size != Other.Size || this->Relative != Other.Relative );
233  }
234 
235  ///////////////////////////////////////////////////////////////////////////////
236  // Serialization
237 
238  /// @brief Convert this class to an XML::Node ready for serialization.
239  /// @param ParentNode The point in the XML hierarchy that all this renderable should be appended to.
240  void ProtoSerialize(XML::Node& ParentNode) const
241  {
242  XML::Node RectNode = ParentNode.AppendChild( Rect::GetSerializableName() );
243 
244  if( RectNode.AppendAttribute("Version").SetValue("1") &&
245  RectNode.AppendAttribute("PositionX").SetValue(this->Position.X) &&
246  RectNode.AppendAttribute("PositionY").SetValue(this->Position.Y) &&
247  RectNode.AppendAttribute("SizeX").SetValue(this->Size.X) &&
248  RectNode.AppendAttribute("SizeY").SetValue(this->Size.Y) )
249  {
250  return;
251  }else{
252  SerializeError("Create XML Attribute Values",Rect::GetSerializableName(),true);
253  }
254  }
255  /// @brief Take the data stored in an XML Node and overwrite this object with it.
256  /// @param SelfRoot An XML::Node containing the data to populate this class with.
257  void ProtoDeSerialize(const XML::Node& SelfRoot)
258  {
259  XML::Attribute CurrAttrib;
260  XML::Node RectNode = SelfRoot.GetChild( Rect::GetSerializableName() );
261 
262  if( !RectNode.Empty() ) {
263  if(RectNode.GetAttribute("Version").AsInt() == 1) {
264  CurrAttrib = RectNode.GetAttribute("PositionX");
265  if( !CurrAttrib.Empty() )
266  this->Position.X = CurrAttrib.AsReal();
267 
268  CurrAttrib = RectNode.GetAttribute("PositionY");
269  if( !CurrAttrib.Empty() )
270  this->Position.Y = CurrAttrib.AsReal();
271 
272  CurrAttrib = RectNode.GetAttribute("SizeX");
273  if( !CurrAttrib.Empty() )
274  this->Size.X = CurrAttrib.AsReal();
275 
276  CurrAttrib = RectNode.GetAttribute("SizeY");
277  if( !CurrAttrib.Empty() )
278  this->Size.X = CurrAttrib.AsReal();
279  }else{
280  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + Rect::GetSerializableName() + ": Not Version 1.");
281  }
282  }else{
283  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,Rect::GetSerializableName() + " was not found in the provided XML node, which was expected.");
284  }
285  }
286  /// @brief Get the name of the the XML tag the Renderable class will leave behind as its instances are serialized.
287  /// @return A string containing the name of this class.
289  {
290  return "Rect";
291  }
292  };//Rect
293  }//UI
294 }//Mezzanine
295 
296 #endif