1 /***********************************************************************
2 	created:	14/3/2004
3 	author:		Paul D Turner
4 
5 	purpose:	Defines interface for Size class
6 *************************************************************************/
7 /***************************************************************************
8  *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
9  *
10  *   Permission is hereby granted, free of charge, to any person obtaining
11  *   a copy of this software and associated documentation files (the
12  *   "Software"), to deal in the Software without restriction, including
13  *   without limitation the rights to use, copy, modify, merge, publish,
14  *   distribute, sublicense, and/or sell copies of the Software, and to
15  *   permit persons to whom the Software is furnished to do so, subject to
16  *   the following conditions:
17  *
18  *   The above copyright notice and this permission notice shall be
19  *   included in all copies or substantial portions of the Software.
20  *
21  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  *   OTHER DEALINGS IN THE SOFTWARE.
28  ***************************************************************************/
29 #ifndef _CEGUISize_h_
30 #define _CEGUISize_h_
31 
32 #include "CEGUI/UDim.h"
33 #include "CEGUI/Vector.h"
34 #include <typeinfo>
35 #include <ostream>
36 
37 // Start of CEGUI namespace section
38 namespace CEGUI
39 {
40 
41 /*!
42 \brief
43     How aspect ratio should be maintained
44 */
45 enum AspectMode
46 {
47     //! Ignores the target aspect (default)
48     AM_IGNORE,
49     /*!
50     Satisfies the aspect ratio by shrinking the size as little
51     as possible to fit inside it
52     */
53     AM_SHRINK,
54     /*!
55     Satisfies the aspect ratio by expanding the widget as little
56     as possible outside it
57     */
58     AM_EXPAND
59 };
60 
61 /*!
62 \brief
63 	Class that holds the size (width & height) of something.
64 */
65 template<typename T>
66 class Size:
67     public AllocatedObject<Size<T> >
68 {
69 public:
70     typedef T value_type;
71 
Size()72     inline Size()
73     {}
74 
Size(const T width,const T height)75     inline Size(const T width, const T height):
76         d_width(width),
77         d_height(height)
78     {}
79 
Size(const Size & v)80     inline Size(const Size& v):
81         d_width(v.d_width),
82         d_height(v.d_height)
83     {}
84 
85     inline bool operator==(const Size& other) const
86     {
87         return d_width == other.d_width && d_height == other.d_height;
88     }
89 
90     inline bool operator!=(const Size& other) const
91     {
92         return !operator==(other);
93     }
94 
95     inline Size operator*(const T c) const
96     {
97         return Size(d_width * c, d_height * c);
98     }
99 
100     inline Size operator*(const Size& s) const
101     {
102         return Size(d_width * s.d_width, d_height * s.d_height);
103     }
104 
105     inline Size operator*(const Vector2f& vec) const
106     {
107         return Size(d_width * vec.d_x, d_height * vec.d_y);
108     }
109 
110     inline Size operator+(const Size& s) const
111     {
112         return Size(d_width + s.d_width, d_height + s.d_height);
113     }
114 
115     inline Size operator-(const Size& s) const
116     {
117         return Size(d_width - s.d_width, d_height - s.d_height);
118     }
119 
clamp(const Size & min,const Size & max)120     inline void clamp(const Size& min, const Size& max)
121     {
122         assert(min.d_width <= max.d_width);
123         assert(min.d_height <= max.d_height);
124 
125         if (d_width < min.d_width)
126             d_width = min.d_width;
127         else if (d_width > max.d_width)
128             d_width = max.d_width;
129 
130         if (d_height < min.d_height)
131             d_height = min.d_height;
132         else if (d_height > max.d_height)
133             d_height = max.d_height;
134     }
135 
scaleToAspect(AspectMode mode,T ratio)136     inline void scaleToAspect(AspectMode mode, T ratio)
137     {
138         if (mode == AM_IGNORE)
139             return;
140 
141         if(d_width <= 0 && d_height <= 0)
142             return;
143 
144         assert(ratio > 0);
145 
146         const T expectedWidth = d_height * ratio;
147         const bool keepHeight = (mode == AM_SHRINK) ?
148                 expectedWidth <= d_width : expectedWidth >= d_width;
149 
150         if (keepHeight)
151         {
152             d_width = expectedWidth;
153         }
154         else
155         {
156             d_height = d_width / ratio;
157         }
158     }
159 
160     /*!
161     \brief allows writing the size to std ostream
162     */
163     inline friend std::ostream& operator << (std::ostream& s, const Size& v)
164     {
165         s << "CEGUI::Size<" << typeid(T).name() << ">(" << v.d_width << ", " << v.d_height << ")";
166         return s;
167     }
168 
169     //! \brief finger saving alias for Size(side, side)
square(const T side)170     inline static Size square(const T side)
171     {
172         return Size(side, side);
173     }
174 
175     //! \brief finger saving alias for Size(0, 0)
zero()176     inline static Size zero()
177     {
178         return square(TypeSensitiveZero<T>());
179     }
180 
181     //! \brief finger saving alias for Size(1, 1)
one()182     inline static Size one()
183     {
184         return square(TypeSensitiveOne<T>());
185     }
186 
187     //! \brief finger saving alias for Size(1, 0)
one_width()188     inline static Size one_width()
189     {
190         return Size(TypeSensitiveOne<T>(), TypeSensitiveZero<T>());
191     }
192 
193     //! \brief finger saving alias for Size(0, 1)
one_height()194     inline static Size one_height()
195     {
196         return Size(TypeSensitiveOne<T>(), TypeSensitiveZero<T>());
197     }
198 
199     T d_width;
200     T d_height;
201 };
202 
203 // the main reason for this is to keep C++ API in sync with other languages
204 typedef Size<float> Sizef;
205 typedef Size<UDim> USize;
206 
207 inline USize operator*(const USize& i, float x)
208 {
209     return i * UDim(x,x);
210 }
211 
212 } // End of  CEGUI namespace section
213 
214 #endif	// end of guard _CEGUISize_h_
215