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