1 /* Copyright (C) 2009 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. 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 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. 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.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
23 Contains help class GUI<>, which gives us templated
24 parameter to all functions within GUI.
32 #ifndef INCLUDED_GUIUTIL
33 #define INCLUDED_GUIUTIL
36 //--------------------------------------------------------
37 // Includes / Compiler directives
38 //--------------------------------------------------------
40 #include "ps/Parser.h"
42 #include "ps/Overlay.h"
44 #include "CGUISprite.h"
45 #include "IGUIObject.h"
47 //--------------------------------------------------------
48 // Help Classes/Structs for the GUI
49 //--------------------------------------------------------
56 bool __ParseString(const CStrW
& Value
, T
&tOutput
);
58 // Model-view-projection matrix with (0,0) in top-left of screen
59 CMatrix3D
GetDefaultGuiMatrix();
61 //--------------------------------------------------------
62 // Forward declarations
63 //--------------------------------------------------------
67 * Base class to only the class GUI. This superclass is
68 * kind of a templateless extention of the class GUI.
69 * Used for other functions to friend with, because it
70 * can't friend with GUI since it's templated (at least
71 * not on all compilers we're using).
73 class CInternalCGUIAccessorBase
76 /// Get object pointer
77 static IGUIObject
* GetObjectPointer(CGUI
&GUIinstance
, const CStr
& Object
);
80 static const IGUIObject
* GetObjectPointer(const CGUI
&GUIinstance
, const CStr
& Object
);
82 /// Wrapper for ResetStates
83 static void QueryResetting(IGUIObject
*pObject
);
85 static void HandleMessage(IGUIObject
*pObject
, SGUIMessage
&message
);
90 // Used to ensure type-safety, sort of
91 template<typename T
> void CheckType(const IGUIObject
* obj
, const CStr
& setting
);
96 * Includes static functions that needs one template
99 * int is only to please functions that doesn't even use T
100 * and are only within this class because it's convenient
102 template <typename T
=int>
103 class GUI
: public CInternalCGUIAccessorBase
105 // Private functions further ahead
107 friend class IGUIObject
;
108 friend class CInternalCGUIAccessorBase
;
112 // Like GetSetting (below), but doesn't make a copy of the value
113 // (so it can be modified later)
114 static PSRETURN
GetSettingPointer(const IGUIObject
*pObject
, const CStr
& Setting
, T
* &Value
);
117 * Retrieves a setting by name from object pointer
119 * @param pObject Object pointer
120 * @param Setting Setting by name
121 * @param Value Stores value here, note type T!
123 static PSRETURN
GetSetting(const IGUIObject
*pObject
, const CStr
& Setting
, T
&Value
);
126 * Sets a value by name using a real datatype as input.
128 * This is the official way of setting a setting, no other
129 * way should only cautiously be used!
131 * @param pObject Object pointer
132 * @param Setting Setting by name
133 * @param Value Sets value to this, note type T!
134 * @param SkipMessage Does not send a GUIM_SETTINGS_UPDATED if true
136 static PSRETURN
SetSetting(IGUIObject
*pObject
, const CStr
& Setting
,
137 const T
&Value
, const bool &SkipMessage
=false);
140 * Retrieves a setting by settings name and object name
142 * @param GUIinstance GUI Object const ref
143 * @param Object Object name
144 * @param Setting Setting by name
145 * @param Value Stores value here, note type T!
147 static PSRETURN
GetSetting(
148 const CGUI
&GUIinstance
, const CStr
& Object
,
149 const CStr
& Setting
, T
&Value
)
151 if (!GUIinstance
.ObjectExists(Object
))
152 return PSRETURN_GUI_NullObjectProvided
;
154 // Retrieve pointer and call sibling function
155 const IGUIObject
*pObject
= GetObjectPointer(GUIinstance
, Object
);
157 return GetSetting(pObject
, Setting
, Value
);
161 * Sets a value by setting and object name using a real
164 * This is just a wrapper so that we can type the object name
165 * and not input the actual pointer.
167 * @param GUIinstance GUI Object, reference since we'll be changing values
168 * @param Object Object name
169 * @param Setting Setting by name
170 * @param Value Sets value to this, note type T!
171 * @param SkipMessage Does not send a GUIM_SETTINGS_UPDATED if true
173 static PSRETURN
SetSetting(
174 CGUI
&GUIinstance
, const CStr
& Object
,
175 const CStr
& Setting
, const T
&Value
,
176 const bool& SkipMessage
=false)
178 if (!GUIinstance
.ObjectExists(Object
))
179 return PSRETURN_GUI_NullObjectProvided
;
181 // Retrieve pointer and call sibling function
183 // Important, we don't want to use this T, we want
184 // to use the standard T, since that will be the
185 // one with the friend relationship
186 IGUIObject
*pObject
= GetObjectPointer(GUIinstance
, Object
);
188 return SetSetting(pObject
, Setting
, Value
, SkipMessage
);
192 * This will return the value of the first sprite if it's not null,
193 * if it is null, it will return the value of the second sprite, if
194 * that one is null, then null it is.
196 * @param prim Primary sprite that should be used
197 * @param sec Secondary sprite if Primary should fail
198 * @return Resulting string
200 static const CGUISpriteInstance
& FallBackSprite(
201 const CGUISpriteInstance
& prim
,
202 const CGUISpriteInstance
& sec
)
204 return (prim
.IsEmpty() ? sec
: prim
);
208 * Same principle as FallBackSprite
210 * @param prim Primary color that should be used
211 * @param sec Secondary color if Primary should fail
212 * @return Resulting color
213 * @see FallBackSprite
215 static CColor
FallBackColor(const CColor
&prim
, const CColor
&sec
)
218 return ((prim
!=CColor())?(prim
):(sec
));
222 * Sets a value by setting and object name using a real
225 * This is just a wrapper for __ParseString() which really
228 * @param Value The value in string form, like "0 0 100% 100%"
229 * @param tOutput Parsed value of type T
230 * @return True at success.
232 * @see __ParseString()
234 static bool ParseString(const CStrW
& Value
, T
&tOutput
)
236 return __ParseString
<T
>(Value
, tOutput
);
239 static bool ParseColor(const CStrW
& Value
, CColor
&tOutput
, float DefaultAlpha
);
243 // templated typedef of function pointer
244 typedef void (IGUIObject::*void_Object_pFunction_argT
)(const T
&arg
);
245 typedef void (IGUIObject::*void_Object_pFunction_argRefT
)(T
&arg
);
246 typedef void (IGUIObject::*void_Object_pFunction
)();
249 * If you want to call a IGUIObject-function
250 * on not just an object, but also on ALL of their children
251 * you want to use this recursion system.
252 * It recurses an object calling a function on itself
253 * and all children (and so forth).
255 * <b>Restrictions:</b>\n
256 * You can also set restrictions, so that if the recursion
257 * reaches an objects with certain setup, it just doesn't
258 * call the function on the object, nor it's children for
259 * that matter. i.e. it cuts that object off from the
260 * recursion tree. What setups that can cause restrictions
261 * are hardcoded and specific. Check out the defines
262 * GUIRR_* for all different setups.
264 * Error reports are either logged or thrown out of RecurseObject.
265 * Always use it with try/catch!
267 * @param RR Recurse Restrictions, set to 0 if no restrictions
268 * @param pObject Top object, this is where the iteration starts
269 * @param pFunc Function to recurse
270 * @param Argument Argument for pFunc of type T
271 * @throws PSERROR Depends on what pFunc might throw. PSERROR is standard.
272 * Itself doesn't throw anything.
274 static void RecurseObject(int RR
, IGUIObject
*pObject
, void_Object_pFunction_argT pFunc
, const T
&Argument
)
276 // TODO Gee: Don't run this for the base object.
277 if (CheckIfRestricted(RR
, pObject
))
280 (pObject
->*pFunc
)(Argument
);
283 vector_pObjects::iterator it
;
284 for (it
= pObject
->ChildrenItBegin(); it
!= pObject
->ChildrenItEnd(); ++it
)
286 RecurseObject(RR
, *it
, pFunc
, Argument
);
291 * Argument is reference.
293 * @see RecurseObject()
295 static void RecurseObject(int RR
, IGUIObject
*pObject
, void_Object_pFunction_argRefT pFunc
, T
&Argument
)
297 if (CheckIfRestricted(RR
, pObject
))
300 (pObject
->*pFunc
)(Argument
);
303 vector_pObjects::iterator it
;
304 for (it
= pObject
->ChildrenItBegin(); it
!= pObject
->ChildrenItEnd(); ++it
)
306 RecurseObject(RR
, *it
, pFunc
, Argument
);
313 * @see RecurseObject()
315 static void RecurseObject(int RR
, IGUIObject
*pObject
, void_Object_pFunction pFunc
)
317 if (CheckIfRestricted(RR
, pObject
))
323 vector_pObjects::iterator it
;
324 for (it
= pObject
->ChildrenItBegin(); it
!= pObject
->ChildrenItEnd(); ++it
)
326 RecurseObject(RR
, *it
, pFunc
);
332 * Checks restrictions for the iteration, for instance if
333 * you tell the recursor to avoid all hidden objects, it
334 * will, and this function checks a certain object's
335 * restriction values.
337 * @param RR What kind of restriction, for instance hidden or disabled
338 * @param pObject Object
339 * @return true if restricted
341 static bool CheckIfRestricted(int RR
, IGUIObject
*pObject
)
343 // Statically initialise some strings, so we don't have to do
344 // lots of allocation every time this function is called
345 static CStr
strHidden("hidden");
346 static CStr
strEnabled("enabled");
347 static CStr
strGhost("ghost");
349 if (RR
& GUIRR_HIDDEN
)
352 GUI
<bool>::GetSetting(pObject
, strHidden
, hidden
);
357 if (RR
& GUIRR_DISABLED
)
359 bool enabled
= false;
360 GUI
<bool>::GetSetting(pObject
, strEnabled
, enabled
);
365 if (RR
& GUIRR_GHOST
)
368 GUI
<bool>::GetSetting(pObject
, strGhost
, ghost
);
374 // false means not restricted