1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #ifndef MYGUI_ALIGN_H_
8 #define MYGUI_ALIGN_H_
9 
10 #include "MyGUI_Prerequest.h"
11 #include "MyGUI_Macros.h"
12 #include "MyGUI_Diagnostic.h"
13 #include "MyGUI_StringUtility.h"
14 #include <map>
15 
16 namespace MyGUI
17 {
18 
19 	struct MYGUI_EXPORT Align
20 	{
21 		enum Enum
22 		{
23 			HCenter = MYGUI_FLAG_NONE, /**< center horizontally */
24 			VCenter = MYGUI_FLAG_NONE, /**< center vertically */
25 			Center = HCenter | VCenter, /**< center in the dead center */
26 
27 			Left = MYGUI_FLAG(1), /**< value from the left (and center vertically) */
28 			Right = MYGUI_FLAG(2), /**< value from the right (and center vertically) */
29 			HStretch = Left | Right, /**< stretch horizontally proportionate to parent window (and center vertically) */
30 
31 			Top = MYGUI_FLAG(3), /**< value from the top (and center horizontally) */
32 			Bottom = MYGUI_FLAG(4), /**< value from the bottom (and center horizontally) */
33 			VStretch = Top | Bottom, /**< stretch vertically proportionate to parent window (and center horizontally) */
34 
35 			Stretch = HStretch | VStretch, /**< stretch proportionate to parent window */
36 			Default = Left | Top /**< default value (value from left and top) */
37 		};
38 
39 		Align(Enum _value = Default) :
mValueAlign40 			mValue(_value)
41 		{
42 		}
43 
isHCenterAlign44 		bool isHCenter() const
45 		{
46 			return HCenter == (mValue & ((int)HStretch));
47 		}
48 
isVCenterAlign49 		bool isVCenter() const
50 		{
51 			return VCenter == (mValue & ((int)VStretch));
52 		}
53 
isCenterAlign54 		bool isCenter() const
55 		{
56 			return Center == (mValue & ((int)Stretch));
57 		}
58 
isLeftAlign59 		bool isLeft() const
60 		{
61 			return Left == (mValue & ((int)HStretch));
62 		}
63 
isRightAlign64 		bool isRight() const
65 		{
66 			return Right == (mValue & ((int)HStretch));
67 		}
68 
isHStretchAlign69 		bool isHStretch() const
70 		{
71 			return HStretch == (mValue & ((int)HStretch));
72 		}
73 
isTopAlign74 		bool isTop() const
75 		{
76 			return Top == (mValue & ((int)VStretch));
77 		}
78 
isBottomAlign79 		bool isBottom() const
80 		{
81 			return (Bottom == (mValue & ((int)VStretch)));
82 		}
83 
isVStretchAlign84 		bool isVStretch() const
85 		{
86 			return (VStretch == (mValue & ((int)VStretch)));
87 		}
88 
isStretchAlign89 		bool isStretch() const
90 		{
91 			return (Stretch == (mValue & ((int)Stretch)));
92 		}
93 
isDefaultAlign94 		bool isDefault() const
95 		{
96 			return (Default == (mValue & ((int)Stretch)));
97 		}
98 
99 		Align& operator |= (Align const& _other)
100 		{
101 			mValue = Enum(int(mValue) | int(_other.mValue));
102 			return *this;
103 		}
104 
105 		friend Align operator | (Enum const& a, Enum const& b)
106 		{
107 			return Align(Enum(int(a) | int(b)));
108 		}
109 
110 		friend Align operator | (Align const& a, Align const& b)
111 		{
112 			return Align(Enum(int(a.mValue) | int(b.mValue)));
113 		}
114 
115 		friend bool operator == (Align const& a, Align const& b)
116 		{
117 			return a.mValue == b.mValue;
118 		}
119 
120 		friend bool operator != (Align const& a, Align const& b)
121 		{
122 			return a.mValue != b.mValue;
123 		}
124 
125 		typedef std::map<std::string, int> MapAlign;
126 
parseAlign127 		static Align parse(const std::string& _value)
128 		{
129 			Align result(Enum(0));
130 			const MapAlign& map_names = result.getValueNames();
131 			const std::vector<std::string>& vec = utility::split(_value);
132 			for (const auto& pos : vec)
133 			{
134 				auto iter = map_names.find(pos);
135 				if (iter != map_names.end())
136 				{
137 					result.mValue = Enum(int(result.mValue) | int(iter->second));
138 				}
139 			}
140 			return result;
141 		}
142 
printAlign143 		std::string print() const
144 		{
145 			std::string result;
146 
147 			if (mValue & Left)
148 			{
149 				if (mValue & Right)
150 					result = "HStretch";
151 				else
152 					result = "Left";
153 			}
154 			else if (mValue & Right)
155 				result = "Right";
156 			else
157 				result = "HCenter";
158 
159 			if (mValue & Top)
160 			{
161 				if (mValue & Bottom)
162 					result += " VStretch";
163 				else
164 					result += " Top";
165 			}
166 			else if (mValue & Bottom)
167 				result += " Bottom";
168 			else
169 				result += " VCenter";
170 
171 			return result;
172 		}
173 
174 		friend std::ostream& operator << ( std::ostream& _stream, const Align&  _value )
175 		{
176 			_stream << _value.print();
177 			return _stream;
178 		}
179 
180 		friend std::istream& operator >> ( std::istream& _stream, Align&  _value )
181 		{
182 			_value.mValue = Enum(0);
183 			std::string value;
184 			_stream >> value;
185 
186 			const MapAlign& map_names = _value.getValueNames();
187 			auto iter = map_names.find(value);
188 			if (iter != map_names.end())
189 				_value.mValue = Enum(int(_value.mValue) | int(iter->second));
190 
191 			if (!_stream.eof())
192 			{
193 				std::string value2;
194 				_stream >> value2;
195 				iter = map_names.find(value2);
196 				if (iter != map_names.end())
197 					_value.mValue = Enum(int(_value.mValue) | int(iter->second));
198 			}
199 
200 			return _stream;
201 		}
202 
getValueAlign203 		int getValue() const
204 		{
205 			return mValue;
206 		}
207 
208 	private:
getValueNamesAlign209 		const MapAlign& getValueNames() const
210 		{
211 			static MapAlign map_names;
212 
213 			if (map_names.empty())
214 			{
215 				// OBSOLETE
216 				map_names["ALIGN_HCENTER"] = HCenter;
217 				map_names["ALIGN_VCENTER"] = VCenter;
218 				map_names["ALIGN_CENTER"] = Center;
219 				map_names["ALIGN_LEFT"] = Left;
220 				map_names["ALIGN_RIGHT"] = Right;
221 				map_names["ALIGN_HSTRETCH"] = HStretch;
222 				map_names["ALIGN_TOP"] = Top;
223 				map_names["ALIGN_BOTTOM"] = Bottom;
224 				map_names["ALIGN_VSTRETCH"] = VStretch;
225 				map_names["ALIGN_STRETCH"] = Stretch;
226 				map_names["ALIGN_DEFAULT"] = Default;
227 
228 				MYGUI_REGISTER_VALUE(map_names, HCenter);
229 				MYGUI_REGISTER_VALUE(map_names, VCenter);
230 				MYGUI_REGISTER_VALUE(map_names, Center);
231 				MYGUI_REGISTER_VALUE(map_names, Left);
232 				MYGUI_REGISTER_VALUE(map_names, Right);
233 				MYGUI_REGISTER_VALUE(map_names, HStretch);
234 				MYGUI_REGISTER_VALUE(map_names, Top);
235 				MYGUI_REGISTER_VALUE(map_names, Bottom);
236 				MYGUI_REGISTER_VALUE(map_names, VStretch);
237 				MYGUI_REGISTER_VALUE(map_names, Stretch);
238 				MYGUI_REGISTER_VALUE(map_names, Default);
239 			}
240 
241 			return map_names;
242 		}
243 
244 	private:
245 		Enum mValue;
246 	};
247 
248 } // namespace MyGUI
249 
250 #endif // MYGUI_ALIGN_H_
251