Added different textures for each ptolemaic camel rank
[0ad.git] / source / gui / IGUIObject.h
blob298326baed9a18b447424fdcfe8d9e881434219e
1 /* Copyright (C) 2012 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/>.
19 The base class of an object
21 --Overview--
23 All objects are derived from this class, it's an ADT
24 so it can't be used per se
26 Also contains a Dummy object which is used for
27 completely blank objects.
29 --Usage--
31 Write about how to use it here
33 --Examples--
35 Provide examples of how to use this code, if necessary
37 --More info--
39 Check GUI.h
43 #ifndef INCLUDED_IGUIOBJECT
44 #define INCLUDED_IGUIOBJECT
46 //--------------------------------------------------------
47 // Includes / Compiler directives
48 //--------------------------------------------------------
49 #include "GUIbase.h"
50 #include "GUItext.h"
51 #include <string>
52 #include <vector>
53 #include "lib/input.h" // just for IN_PASS
55 #include "ps/XML/Xeromyces.h"
57 #include "gui/scripting/JSInterface_IGUIObject.h"
59 struct SGUISetting;
60 struct SGUIStyle;
61 class CGUI;
62 class CScriptValRooted;
64 //--------------------------------------------------------
65 // Macros
66 //--------------------------------------------------------
68 //--------------------------------------------------------
69 // Types
70 //--------------------------------------------------------
72 // Map with pointers
73 typedef std::map<CStr, SGUISetting> map_Settings;
75 struct JSObject;
77 //--------------------------------------------------------
78 // Error declarations
79 //--------------------------------------------------------
81 ERROR_TYPE(GUI, UnableToParse);
83 //--------------------------------------------------------
84 // Declarations
85 //--------------------------------------------------------
87 /**
88 * Setting Type
89 * @see SGUISetting
91 * For use of later macros, all names should be GUIST_ followed
92 * by the code name (case sensitive!).
94 #define TYPE(T) GUIST_##T,
95 enum EGUISettingType
97 #include "GUItypes.h"
99 #undef TYPE
102 * A GUI Setting is anything that can be inputted from XML as
103 * \<object\>-attributes (with exceptions). For instance:
104 * \<object style="null"\>
106 * "style" will be a SGUISetting.
108 struct SGUISetting
110 SGUISetting() : m_pSetting(NULL) {}
112 void *m_pSetting;
113 EGUISettingType m_Type;
117 * Base settings, all objects possess these settings
118 * in their m_BaseSettings
119 * Instructions can be found in the documentations.
121 /*struct SGUIBaseSettings
123 //int banan;
124 bool m_Absolute;
125 CStr m_Caption; // Is usually set within an XML element and not in the attributes
126 bool m_Enabled;
127 bool m_Ghost;
128 bool m_Hidden;
129 CClientArea m_Size;
130 CStr m_Style;
131 float m_Z;
132 };*/
134 //////////////////////////////////////////////////////////
137 * GUI object such as a button or an input-box.
138 * Abstract data type !
140 class IGUIObject
142 friend class CGUI;
143 friend class CInternalCGUIAccessorBase;
144 friend class IGUIScrollBar;
145 friend class GUITooltip;
147 // Allow getProperty to access things like GetParent()
148 friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
149 friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp);
150 friend JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uintN argc, jsval* vp);
152 public:
153 IGUIObject();
154 virtual ~IGUIObject();
157 * Checks if mouse is hovering this object.
158 * The mouse position is cached in CGUI.
160 * This function checks if the mouse is hovering the
161 * rectangle that the base setting "size" makes.
162 * Although it is virtual, so one could derive
163 * an object from CButton, which changes only this
164 * to checking the circle that "size" makes.
166 * @return true if mouse is hovering
168 virtual bool MouseOver();
171 * Test if mouse position is over an icon
173 virtual bool MouseOverIcon();
175 //--------------------------------------------------------
176 /** @name Leaf Functions */
177 //--------------------------------------------------------
178 //@{
180 /// Get object name, name is unique
181 const CStr& GetName() const { return m_Name; }
183 /// Get object name
184 void SetName(const CStr& Name) { m_Name = Name; }
186 // Get Presentable name.
187 // Will change all internally set names to something like "<unnamed object>"
188 CStr GetPresentableName() const;
191 * Adds object and its children to the map, it's name being the
192 * first part, and the second being itself.
194 * @param ObjectMap Adds this to the map_pObjects.
196 * @throws PSERROR_GUI_ObjectNeedsName Name is missing
197 * @throws PSERROR_GUI_NameAmbiguity Name is already taken
199 void AddToPointersMap(map_pObjects &ObjectMap);
202 * Notice nothing will be returned or thrown if the child hasn't
203 * been inputted into the GUI yet. This is because that's were
204 * all is checked. Now we're just linking two objects, but
205 * it's when we're inputting them into the GUI we'll check
206 * validity! Notice also when adding it to the GUI this function
207 * will inevitably have been called by CGUI::AddObject which
208 * will catch the throw and return the error code.
209 * i.e. The user will never put in the situation wherein a throw
210 * must be caught, the GUI's internal error handling will be
211 * completely transparent to the interfacially sequential model.
213 * @param pChild Child to add
215 * @throws PSERROR_GUI from CGUI::UpdateObjects().
217 void AddChild(IGUIObject *pChild);
219 //@}
220 //--------------------------------------------------------
221 /** @name Iterate */
222 //--------------------------------------------------------
223 //@{
225 vector_pObjects::iterator ChildrenItBegin() { return m_Children.begin(); }
226 vector_pObjects::iterator ChildrenItEnd() { return m_Children.end(); }
228 //@}
229 //--------------------------------------------------------
230 /** @name Settings Management */
231 //--------------------------------------------------------
232 //@{
235 * Checks if settings exists, only available for derived
236 * classes that has this set up, that's why the base
237 * class just returns false
239 * @param Setting setting name
240 * @return True if settings exist.
242 bool SettingExists(const CStr& Setting) const;
245 * All sizes are relative to resolution, and the calculation
246 * is not wanted in real time, therefore it is cached, update
247 * the cached size with this function.
249 virtual void UpdateCachedSize();
252 * Set a setting by string, regardless of what type it is.
254 * example a CRect(10,10,20,20) would be "10 10 20 20"
256 * @param Setting Setting by name
257 * @param Value Value to set to
258 * @param SkipMessage Does not send a GUIM_SETTINGS_UPDATED if true
260 * @return PSRETURN (PSRETURN_OK if successful)
262 PSRETURN SetSetting(const CStr& Setting, const CStrW& Value, const bool& SkipMessage=false);
265 * Retrieves the type of a named setting.
267 * @param Setting Setting by name
268 * @param Type Stores an EGUISettingType
269 * @return PSRETURN (PSRETURN_OK if successful)
271 PSRETURN GetSettingType(const CStr& Setting, EGUISettingType &Type) const;
274 * Set the script handler for a particular object-specific action
276 * @param Action Name of action
277 * @param Code Javascript code to execute when the action occurs
278 * @param pGUI GUI instance to associate the script with
280 void RegisterScriptHandler(const CStr& Action, const CStr& Code, CGUI* pGUI);
283 * Retrieves the JSObject representing this GUI object.
285 JSObject* GetJSObject();
287 //@}
288 protected:
289 //--------------------------------------------------------
290 /** @name Called by CGUI and friends
292 * Methods that the CGUI will call using
293 * its friendship, these should not
294 * be called by user.
295 * These functions' security are a lot
296 * what constitutes the GUI's
298 //--------------------------------------------------------
299 //@{
302 * Add a setting to m_Settings
304 * @param Type Setting type
305 * @param Name Setting reference name
307 void AddSetting(const EGUISettingType &Type, const CStr& Name);
310 * Calls Destroy on all children, and deallocates all memory.
311 * MEGA TODO Should it destroy it's children?
313 virtual void Destroy();
315 public:
317 * This function is called with different messages
318 * for instance when the mouse enters the object.
320 * @param Message GUI Message
322 virtual void HandleMessage(SGUIMessage& UNUSED(Message)) {}
324 protected:
326 * Draws the object.
328 * @throws PSERROR if any. But this will mostlikely be
329 * very rare since if an object is drawn unsuccessfully
330 * it'll probably only output in the Error log, and not
331 * disrupt the whole GUI drawing.
333 virtual void Draw()=0;
336 * Some objects need to handle the SDL_Event_ manually.
337 * For instance the input box.
339 * Only the object with focus will have this function called.
341 * Returns either IN_PASS or IN_HANDLED. If IN_HANDLED, then
342 * the key won't be passed on and processed by other handlers.
343 * This is used for keys that the GUI uses.
345 virtual InReaction ManuallyHandleEvent(const SDL_Event_* UNUSED(ev)) { return IN_PASS; }
348 * Loads a style.
350 * @param GUIinstance Reference to the GUI
351 * @param StyleName Style by name
353 void LoadStyle(CGUI &GUIinstance, const CStr& StyleName);
356 * Loads a style.
358 * @param Style The style object.
360 void LoadStyle(const SGUIStyle &Style);
363 * Returns not the Z value, but the actual buffered Z value, i.e. if it's
364 * defined relative, then it will check its parent's Z value and add
365 * the relativity.
367 * @return Actual Z value on the screen.
369 virtual float GetBufferedZ() const;
371 void SetGUI(CGUI * const &pGUI) { m_pGUI = pGUI; }
374 * Set parent of this object
376 void SetParent(IGUIObject *pParent) { m_pParent = pParent; }
379 * Reset internal state of this object
381 virtual void ResetStates()
383 // Notify the gui that we aren't hovered anymore
384 UpdateMouseOver(NULL);
387 public:
388 CGUI *GetGUI() { return m_pGUI; }
389 const CGUI *GetGUI() const { return m_pGUI; }
392 * Take focus!
394 void SetFocus();
396 protected:
398 * Check if object is focused.
400 bool IsFocused() const;
403 * <b>NOTE!</b> This will not just return m_pParent, when that is
404 * need use it! There is one exception to it, when the parent is
405 * the top-node (the object that isn't a real object), this
406 * will return NULL, so that the top-node's children are
407 * seemingly parentless.
409 * @return Pointer to parent
411 IGUIObject *GetParent() const;
414 * Get Mouse from CGUI.
416 CPos GetMousePos() const;
419 * Handle additional children to the \<object\>-tag. In IGUIObject, this function does
420 * nothing. In CList and CDropDown, it handles the \<item\>, used to build the data.
422 * Returning false means the object doesn't recognize the child. Should be reported.
423 * Notice 'false' is default, because an object not using this function, should not
424 * have any additional children (and this function should never be called).
426 virtual bool HandleAdditionalChildren(const XMBElement& UNUSED(child),
427 CXeromyces* UNUSED(pFile)) { return false; }
430 * Cached size, real size m_Size is actually dependent on resolution
431 * and can have different *real* outcomes, this is the real outcome
432 * cached to avoid slow calculations in real time.
434 CRect m_CachedActualSize;
437 * Send event to this GUI object (HandleMessage and ScriptEvent)
439 * @param type Type of GUI message to be handled
440 * @param EventName String representation of event name
441 * @return IN_HANDLED if event was handled, or IN_PASS if skipped
443 InReaction SendEvent(EGUIMessageType type, const CStr& EventName);
446 * Execute the script for a particular action.
447 * Does nothing if no script has been registered for that action.
448 * The mouse coordinates will be passed as the first argument.
450 * @param Action Name of action
452 void ScriptEvent(const CStr& Action);
455 * Execute the script for a particular action.
456 * Does nothing if no script has been registered for that action.
458 * @param Action Name of action
459 * @param Argument Argument to pass to action
461 void ScriptEvent(const CStr& Action, const CScriptValRooted& Argument);
463 void SetScriptHandler(const CStr& Action, JSObject* Function);
466 * Inputes the object that is currently hovered, this function
467 * updates this object accordingly (i.e. if it's the object
468 * being inputted one thing happens, and not, another).
470 * @param pMouseOver Object that is currently hovered,
471 * can OF COURSE be NULL too!
473 void UpdateMouseOver(IGUIObject * const &pMouseOver);
475 //@}
476 private:
477 //--------------------------------------------------------
478 /** @name Internal functions */
479 //--------------------------------------------------------
480 //@{
483 * Inputs a reference pointer, checks if the new inputted object
484 * if hovered, if so, then check if this's Z value is greater
485 * than the inputted object... If so then the object is closer
486 * and we'll replace the pointer with this.
487 * Also Notice input can be NULL, which means the Z value demand
488 * is out. NOTICE you can't input NULL as const so you'll have
489 * to set an object to NULL.
491 * @param pObject Object pointer, can be either the old one, or
492 * the new one.
494 void ChooseMouseOverAndClosest(IGUIObject* &pObject);
496 // Is the object a Root object, in philosophy, this means it
497 // has got no parent, and technically, it's got the m_BaseObject
498 // as parent.
499 bool IsRootObject() const;
502 * Logs an invalid setting search and returns the correct return result
504 * @return the error result
506 PSRETURN LogInvalidSettings(const CStr8& Setting) const;
508 // Variables
510 protected:
511 // Name of object
512 CStr m_Name;
514 // Constructed on the heap, will be destroyed along with the the object
515 // TODO Gee: really the above?
516 vector_pObjects m_Children;
518 // Pointer to parent
519 IGUIObject *m_pParent;
521 //This represents the last click time for each mouse button
522 double m_LastClickTime[6];
525 * This is an array of true or false, each element is associated with
526 * a string representing a setting. Number of elements is equal to
527 * number of settings.
529 * A true means the setting has been manually set in the file when
530 * read. This is important to know because I don't want to force
531 * the user to include its \<styles\>-XML-files first, so somehow
532 * the GUI needs to know which settings were set, and which is meant
533 * to
536 // More variables
538 // Is mouse hovering the object? used with the function MouseOver()
539 bool m_MouseHovering;
542 * Settings pool, all an object's settings are located here
543 * If a derived object has got more settings that the base
544 * settings, it's because they have a new version of the
545 * function SetupSettings().
547 * @see SetupSettings()
549 public:
550 std::map<CStr, SGUISetting> m_Settings;
552 private:
553 // An object can't function stand alone
554 CGUI *m_pGUI;
556 // Internal storage for registered script handlers.
557 std::map<CStr, JSObject**> m_ScriptHandlers;
559 // Cached JSObject representing this GUI object
560 JSObject *m_JSObject;
565 * Dummy object used primarily for the root object
566 * or objects of type 'empty'
568 class CGUIDummyObject : public IGUIObject
570 GUI_OBJECT(CGUIDummyObject)
572 public:
574 virtual void Draw() {}
575 // Empty can never be hovered. It is only a category.
576 virtual bool MouseOver() { return false; }
579 #endif