Pyrogenesis  trunk
IGUIObject.h
Go to the documentation of this file.
1 /* Copyright (C) 2016 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 
18 /*
19 The base class of an object
20 
21 --Overview--
22 
23  All objects are derived from this class, it's an ADT
24  so it can't be used per se
25 
26  Also contains a Dummy object which is used for
27  completely blank objects.
28 
29 --Usage--
30 
31  Write about how to use it here
32 
33 --Examples--
34 
35  Provide examples of how to use this code, if necessary
36 
37 --More info--
38 
39  Check GUI.h
40 
41 */
42 
43 #ifndef INCLUDED_IGUIOBJECT
44 #define INCLUDED_IGUIOBJECT
45 
46 #include "GUIbase.h"
47 #include "GUItext.h"
48 
50 #include "lib/input.h" // just for IN_PASS
51 #include "ps/XML/Xeromyces.h"
52 
53 #include <string>
54 #include <vector>
55 
56 struct SGUISetting;
57 struct SGUIStyle;
58 class CGUI;
59 
60 class JSObject;
61 
62 ERROR_TYPE(GUI, UnableToParse);
63 
64 /**
65  * Setting Type
66  * @see SGUISetting
67  *
68  * For use of later macros, all names should be GUIST_ followed
69  * by the code name (case sensitive!).
70  */
71 #define TYPE(T) GUIST_##T,
73 {
74  #include "GUItypes.h"
75 };
76 #undef TYPE
77 
78 /**
79  * A GUI Setting is anything that can be inputted from XML as
80  * <object>-attributes (with exceptions). For instance:
81  * <object style="null">
82  *
83  * "style" will be a SGUISetting.
84  */
86 {
87  SGUISetting() : m_pSetting(NULL) {}
88 
89  void *m_pSetting;
91 };
92 
93 /**
94  * Base settings, all objects possess these settings
95  * in their m_BaseSettings
96  * Instructions can be found in the documentations.
97  */
98 /*struct SGUIBaseSettings
99 {
100  //int banan;
101  bool m_Absolute;
102  CStr m_Caption; // Is usually set within an XML element and not in the attributes
103  bool m_Enabled;
104  bool m_Ghost;
105  bool m_Hidden;
106  CClientArea m_Size;
107  CStr m_Style;
108  float m_Z;
109 };*/
110 
111 //////////////////////////////////////////////////////////
112 
113 /**
114  * GUI object such as a button or an input-box.
115  * Abstract data type !
116  */
118 {
119  friend class CGUI;
121  friend class IGUIScrollBar;
122  friend class GUITooltip;
123 
124  // Allow getProperty to access things like GetParent()
125  friend bool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp);
126  friend bool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool UNUSED(strict), JS::MutableHandleValue vp);
127  friend bool JSI_IGUIObject::getComputedSize(JSContext* cx, uint argc, jsval* vp);
128 
129 public:
130  IGUIObject();
131  virtual ~IGUIObject();
132 
133  /**
134  * Checks if mouse is hovering this object.
135  * The mouse position is cached in CGUI.
136  *
137  * This function checks if the mouse is hovering the
138  * rectangle that the base setting "size" makes.
139  * Although it is virtual, so one could derive
140  * an object from CButton, which changes only this
141  * to checking the circle that "size" makes.
142  *
143  * @return true if mouse is hovering
144  */
145  virtual bool MouseOver();
146 
147  /**
148  * Test if mouse position is over an icon
149  */
150  virtual bool MouseOverIcon();
151 
152  //--------------------------------------------------------
153  /** @name Leaf Functions */
154  //--------------------------------------------------------
155  //@{
156 
157  /// Get object name, name is unique
158  const CStr& GetName() const { return m_Name; }
159 
160  /// Get object name
161  void SetName(const CStr& Name) { m_Name = Name; }
162 
163  // Get Presentable name.
164  // Will change all internally set names to something like "<unnamed object>"
165  CStr GetPresentableName() const;
166 
167  /**
168  * Adds object and its children to the map, it's name being the
169  * first part, and the second being itself.
170  *
171  * @param ObjectMap Adds this to the map_pObjects.
172  *
173  * @throws PSERROR_GUI_ObjectNeedsName Name is missing
174  * @throws PSERROR_GUI_NameAmbiguity Name is already taken
175  */
176  void AddToPointersMap(map_pObjects& ObjectMap);
177 
178  /**
179  * Notice nothing will be returned or thrown if the child hasn't
180  * been inputted into the GUI yet. This is because that's were
181  * all is checked. Now we're just linking two objects, but
182  * it's when we're inputting them into the GUI we'll check
183  * validity! Notice also when adding it to the GUI this function
184  * will inevitably have been called by CGUI::AddObject which
185  * will catch the throw and return the error code.
186  * i.e. The user will never put in the situation wherein a throw
187  * must be caught, the GUI's internal error handling will be
188  * completely transparent to the interfacially sequential model.
189  *
190  * @param pChild Child to add
191  *
192  * @throws PSERROR_GUI from CGUI::UpdateObjects().
193  */
194  void AddChild(IGUIObject* pChild);
195 
196  //@}
197  //--------------------------------------------------------
198  /** @name Iterate
199  * Used to iterate over all children of this object.
200  */
201  //--------------------------------------------------------
202  //@{
203 
204  vector_pObjects::iterator begin() { return m_Children.begin(); }
205  vector_pObjects::iterator end() { return m_Children.end(); }
206 
207  //@}
208  //--------------------------------------------------------
209  /** @name Settings Management */
210  //--------------------------------------------------------
211  //@{
212 
213  /**
214  * Checks if settings exists, only available for derived
215  * classes that has this set up, that's why the base
216  * class just returns false
217  *
218  * @param Setting setting name
219  * @return True if settings exist.
220  */
221  bool SettingExists(const CStr& Setting) const;
222 
223  /**
224  * All sizes are relative to resolution, and the calculation
225  * is not wanted in real time, therefore it is cached, update
226  * the cached size with this function.
227  */
228  virtual void UpdateCachedSize();
229 
230  /**
231  * Set a setting by string, regardless of what type it is.
232  *
233  * example a CRect(10,10,20,20) would be "10 10 20 20"
234  *
235  * @param Setting Setting by name
236  * @param Value Value to set to
237  * @param SkipMessage Does not send a GUIM_SETTINGS_UPDATED if true
238  *
239  * @return PSRETURN (PSRETURN_OK if successful)
240  */
241  PSRETURN SetSetting(const CStr& Setting, const CStrW& Value, const bool& SkipMessage = false);
242 
243  /**
244  * Retrieves the type of a named setting.
245  *
246  * @param Setting Setting by name
247  * @param Type Stores an EGUISettingType
248  * @return PSRETURN (PSRETURN_OK if successful)
249  */
250  PSRETURN GetSettingType(const CStr& Setting, EGUISettingType& Type) const;
251 
252  /**
253  * Set the script handler for a particular object-specific action
254  *
255  * @param Action Name of action
256  * @param Code Javascript code to execute when the action occurs
257  * @param pGUI GUI instance to associate the script with
258  */
259  void RegisterScriptHandler(const CStr& Action, const CStr& Code, CGUI* pGUI);
260 
261  /**
262  * Retrieves the JSObject representing this GUI object.
263  */
264  JSObject* GetJSObject();
265 
266  //@}
267 protected:
268  //--------------------------------------------------------
269  /** @name Called by CGUI and friends
270  *
271  * Methods that the CGUI will call using
272  * its friendship, these should not
273  * be called by user.
274  * These functions' security are a lot
275  * what constitutes the GUI's
276  */
277  //--------------------------------------------------------
278  //@{
279 
280  /**
281  * Add a setting to m_Settings
282  *
283  * @param Type Setting type
284  * @param Name Setting reference name
285  */
286  void AddSetting(const EGUISettingType& Type, const CStr& Name);
287 
288  /**
289  * Calls Destroy on all children, and deallocates all memory.
290  * MEGA TODO Should it destroy it's children?
291  */
292  virtual void Destroy();
293 
294 public:
295  /**
296  * This function is called with different messages
297  * for instance when the mouse enters the object.
298  *
299  * @param Message GUI Message
300  */
301  virtual void HandleMessage(SGUIMessage& UNUSED(Message)) {}
302 
303 protected:
304  /**
305  * Draws the object.
306  *
307  * @throws PSERROR if any. But this will mostlikely be
308  * very rare since if an object is drawn unsuccessfully
309  * it'll probably only output in the Error log, and not
310  * disrupt the whole GUI drawing.
311  */
312  virtual void Draw() = 0;
313 
314  /**
315  * Some objects need to handle the SDL_Event_ manually.
316  * For instance the input box.
317  *
318  * Only the object with focus will have this function called.
319  *
320  * Returns either IN_PASS or IN_HANDLED. If IN_HANDLED, then
321  * the key won't be passed on and processed by other handlers.
322  * This is used for keys that the GUI uses.
323  */
324  virtual InReaction ManuallyHandleEvent(const SDL_Event_* UNUSED(ev)) { return IN_PASS; }
325 
326  /**
327  * Loads a style.
328  *
329  * @param GUIinstance Reference to the GUI
330  * @param StyleName Style by name
331  */
332  void LoadStyle(CGUI& GUIinstance, const CStr& StyleName);
333 
334  /**
335  * Loads a style.
336  *
337  * @param Style The style object.
338  */
339  void LoadStyle(const SGUIStyle& Style);
340 
341  /**
342  * Returns not the Z value, but the actual buffered Z value, i.e. if it's
343  * defined relative, then it will check its parent's Z value and add
344  * the relativity.
345  *
346  * @return Actual Z value on the screen.
347  */
348  virtual float GetBufferedZ() const;
349 
350  void SetGUI(CGUI* const& pGUI);
351 
352  /**
353  * Set parent of this object
354  */
355  void SetParent(IGUIObject* pParent) { m_pParent = pParent; }
356 
357  /**
358  * Reset internal state of this object
359  */
360  virtual void ResetStates()
361  {
362  // Notify the gui that we aren't hovered anymore
363  UpdateMouseOver(NULL);
364  }
365 
366 public:
367  CGUI* GetGUI() { return m_pGUI; }
368  const CGUI* GetGUI() const { return m_pGUI; }
369 
370  /**
371  * Take focus!
372  */
373  void SetFocus();
374 
375 protected:
376  /**
377  * Check if object is focused.
378  */
379  bool IsFocused() const;
380 
381  /**
382  * <b>NOTE!</b> This will not just return m_pParent, when that is
383  * need use it! There is one exception to it, when the parent is
384  * the top-node (the object that isn't a real object), this
385  * will return NULL, so that the top-node's children are
386  * seemingly parentless.
387  *
388  * @return Pointer to parent
389  */
390  IGUIObject* GetParent() const;
391 
392  /**
393  * Get Mouse from CGUI.
394  */
395  CPos GetMousePos() const;
396 
397  /**
398  * Handle additional children to the <object>-tag. In IGUIObject, this function does
399  * nothing. In CList and CDropDown, it handles the <item>, used to build the data.
400  *
401  * Returning false means the object doesn't recognize the child. Should be reported.
402  * Notice 'false' is default, because an object not using this function, should not
403  * have any additional children (and this function should never be called).
404  */
405  virtual bool HandleAdditionalChildren(const XMBElement& UNUSED(child), CXeromyces* UNUSED(pFile))
406  {
407  return false;
408  }
409 
410  /**
411  * Cached size, real size m_Size is actually dependent on resolution
412  * and can have different *real* outcomes, this is the real outcome
413  * cached to avoid slow calculations in real time.
414  */
416 
417  /**
418  * Send event to this GUI object (HandleMessage and ScriptEvent)
419  *
420  * @param type Type of GUI message to be handled
421  * @param EventName String representation of event name
422  * @return IN_HANDLED if event was handled, or IN_PASS if skipped
423  */
424  InReaction SendEvent(EGUIMessageType type, const CStr& EventName);
425 
426  /**
427  * Execute the script for a particular action.
428  * Does nothing if no script has been registered for that action.
429  * The mouse coordinates will be passed as the first argument.
430  *
431  * @param Action Name of action
432  */
433  void ScriptEvent(const CStr& Action);
434 
435  /**
436  * Execute the script for a particular action.
437  * Does nothing if no script has been registered for that action.
438  *
439  * @param Action Name of action
440  * @param Argument Argument to pass to action
441  */
442  void ScriptEvent(const CStr& Action, JS::HandleValue Argument);
443 
444  void SetScriptHandler(const CStr& Action, JS::HandleObject Function);
445 
446  /**
447  * Inputes the object that is currently hovered, this function
448  * updates this object accordingly (i.e. if it's the object
449  * being inputted one thing happens, and not, another).
450  *
451  * @param pMouseOver Object that is currently hovered,
452  * can OF COURSE be NULL too!
453  */
454  void UpdateMouseOver(IGUIObject* const& pMouseOver);
455 
456  //@}
457 private:
458  //--------------------------------------------------------
459  /** @name Internal functions */
460  //--------------------------------------------------------
461  //@{
462 
463  /**
464  * Inputs a reference pointer, checks if the new inputted object
465  * if hovered, if so, then check if this's Z value is greater
466  * than the inputted object... If so then the object is closer
467  * and we'll replace the pointer with this.
468  * Also Notice input can be NULL, which means the Z value demand
469  * is out. NOTICE you can't input NULL as const so you'll have
470  * to set an object to NULL.
471  *
472  * @param pObject Object pointer, can be either the old one, or
473  * the new one.
474  */
475  void ChooseMouseOverAndClosest(IGUIObject*& pObject);
476 
477  // Is the object a Root object, in philosophy, this means it
478  // has got no parent, and technically, it's got the m_BaseObject
479  // as parent.
480  bool IsRootObject() const;
481 
482  /**
483  * Logs an invalid setting search and returns the correct return result
484  *
485  * @return the error result
486  */
487  PSRETURN LogInvalidSettings(const CStr8& Setting) const;
488 
489  static void Trace(JSTracer* trc, void* data)
490  {
491  reinterpret_cast<IGUIObject*>(data)->TraceMember(trc);
492  }
493 
494  void TraceMember(JSTracer* trc);
495 
496  // Variables
497 
498 protected:
499  // Name of object
500  CStr m_Name;
501 
502  // Constructed on the heap, will be destroyed along with the the object
503  // TODO Gee: really the above?
505 
506  // Pointer to parent
508 
509  //This represents the last click time for each mouse button
510  double m_LastClickTime[6];
511 
512  /**
513  * This is an array of true or false, each element is associated with
514  * a string representing a setting. Number of elements is equal to
515  * number of settings.
516  *
517  * A true means the setting has been manually set in the file when
518  * read. This is important to know because I don't want to force
519  * the user to include its <styles>-XML-files first, so somehow
520  * the GUI needs to know which settings were set, and which is meant
521  * to.
522  */
523 
524  // More variables
525 
526  // Is mouse hovering the object? used with the function MouseOver()
528 
529  /**
530  * Settings pool, all an object's settings are located here
531  * If a derived object has got more settings that the base
532  * settings, it's because they have a new version of the
533  * function SetupSettings().
534  *
535  * @see SetupSettings()
536  */
537  public:
538  std::map<CStr, SGUISetting> m_Settings;
539 
540 private:
541  // An object can't function stand alone
543 
544  // Internal storage for registered script handlers.
545  std::map<CStr, JS::Heap<JSObject*> > m_ScriptHandlers;
546 
547  // Cached JSObject representing this GUI object
548  JS::PersistentRootedObject m_JSObject;
549 };
550 
551 
552 /**
553  * Dummy object used primarily for the root object
554  * or objects of type 'empty'
555  */
557 {
559 
560 public:
561 
562  virtual void Draw() {}
563  // Empty can never be hovered. It is only a category.
564  virtual bool MouseOver() { return false; }
565 };
566 
567 #endif // INCLUDED_IGUIOBJECT
virtual void ResetStates()
Reset internal state of this object.
Definition: IGUIObject.h:360
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
Definition: code_annotation.h:38
CGUI * m_pGUI
Definition: IGUIObject.h:542
Base class to only the class GUI.
Definition: GUIutil.h:59
Dummy object used primarily for the root object or objects of type &#39;empty&#39;.
Definition: IGUIObject.h:556
std::map< CStr, JS::Heap< JSObject * > > m_ScriptHandlers
Definition: IGUIObject.h:545
IGUIObject * m_pParent
Definition: IGUIObject.h:507
Definition: XeroXMB.h:160
const CStr & GetName() const
Get object name, name is unique.
Definition: IGUIObject.h:158
EGUISettingType
Definition: IGUIObject.h:72
Base settings, all objects possess these settings in their m_BaseSettings Instructions can be found i...
Definition: IGUIObject.h:117
bool setProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict, JS::MutableHandleValue vp)
Definition: JSInterface_IGUIObject.cpp:309
vector_pObjects::iterator end()
Definition: IGUIObject.h:205
static void Trace(JSTracer *trc, void *data)
Definition: IGUIObject.h:489
Definition: libsdl.h:51
The main object that represents a whole GUI page.
Definition: CGUI.h:75
void * m_pSetting
Definition: IGUIObject.h:89
virtual bool HandleAdditionalChildren(const XMBElement &child, CXeromyces *pFile)
Handle additional children to the <object>-tag.
Definition: IGUIObject.h:405
virtual InReaction ManuallyHandleEvent(const SDL_Event_ *ev)
Some objects need to handle the SDL_Event_ manually.
Definition: IGUIObject.h:324
Includes static functions that needs one template argument.
Definition: GUIutil.h:89
vector_pObjects m_Children
Definition: IGUIObject.h:504
Config::Value_type Value
Definition: json_spirit_value.h:181
u32 PSRETURN
Definition: Errors.h:75
SGUISetting()
Definition: IGUIObject.h:87
void SetParent(IGUIObject *pParent)
Set parent of this object.
Definition: IGUIObject.h:355
InReaction
Definition: input.h:34
Definition: input.h:40
std::map< CStr, SGUISetting > m_Settings
Settings pool, all an object&#39;s settings are located here If a derived object has got more settings th...
Definition: IGUIObject.h:538
bool getComputedSize(JSContext *cx, uint argc, jsval *vp)
Definition: JSInterface_IGUIObject.cpp:669
EGUIMessageType
Message types.
Definition: GUIbase.h:57
void SetName(const CStr &Name)
Get object name.
Definition: IGUIObject.h:161
CRect m_CachedActualSize
Cached size, real size m_Size is actually dependent on resolution and can have different real outcome...
Definition: IGUIObject.h:415
Made to represent screen positions and delta values.
Definition: Shapes.h:169
std::map< CStr, IGUIObject * > map_pObjects
Definition: GUIbase.h:139
const CGUI * GetGUI() const
Definition: IGUIObject.h:368
bool getProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp)
Definition: JSInterface_IGUIObject.cpp:56
virtual bool MouseOver()
Checks if mouse is hovering this object.
Definition: IGUIObject.h:564
Definition: Xeromyces.h:42
ERROR_TYPE(GUI, UnableToParse)
std::vector< IGUIObject * > vector_pObjects
Definition: GUIbase.h:140
CGUI * GetGUI()
Definition: IGUIObject.h:367
unsigned int uint
Definition: types.h:42
A GUI Setting is anything that can be inputted from XML as <object>-attributes (with exceptions)...
Definition: IGUIObject.h:85
void Draw(DrawCalls &Calls, float Z)
Definition: GUIRenderer.cpp:345
The GUI Scroll-bar, used everywhere there is a scroll-bar in the game.
Definition: IGUIScrollBar.h:155
bool m_MouseHovering
This is an array of true or false, each element is associated with a string representing a setting...
Definition: IGUIObject.h:527
CStr m_Name
Definition: IGUIObject.h:500
EGUISettingType m_Type
Definition: IGUIObject.h:90
Message send to IGUIObject::HandleMessage() in order to give life to Objects manually with a derived ...
Definition: GUIbase.h:91
vector_pObjects::iterator begin()
Definition: IGUIObject.h:204
virtual void HandleMessage(SGUIMessage &Message)
This function is called with different messages for instance when the mouse enters the object...
Definition: IGUIObject.h:301
Contains a list of values for new defaults to objects.
Definition: CGUI.h:52
Definition: GUITooltip.h:27
JS::PersistentRootedObject m_JSObject
Definition: IGUIObject.h:548
#define GUI_OBJECT(obj)
Definition: GUIbase.h:48
virtual void Draw()
Draws the object.
Definition: IGUIObject.h:562
Rectangle class used for screen rectangles.
Definition: Shapes.h:73