Added different textures for each ptolemaic camel rank
[0ad.git] / source / gui / CGUI.h
bloba6abab3d7f9e2fad9cc311e06cb8b0a58fc0cdce
1 /* Copyright (C) 2013 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 CGUI
21 --Overview--
23 This is the top class of the whole GUI, all objects
24 and settings are stored within this class.
26 --More info--
28 Check GUI.h
32 #ifndef INCLUDED_CGUI
33 #define INCLUDED_CGUI
35 //--------------------------------------------------------
36 // Includes / Compiler directives
37 //--------------------------------------------------------
38 // NOTE: GUI.h included at the bottom of this file (has to be after CGUI class
39 // definition)
41 #include "GUITooltip.h"
42 #include "GUIbase.h"
44 #include "ps/Overlay.h" // CPos and CRect
46 #include "lib/input.h"
48 #include "ps/XML/Xeromyces.h"
50 #include <boost/unordered_set.hpp>
52 //--------------------------------------------------------
53 // Macros
54 //--------------------------------------------------------
56 //--------------------------------------------------------
57 // Types
58 //--------------------------------------------------------
60 //--------------------------------------------------------
61 // Error declarations
62 //--------------------------------------------------------
64 ERROR_TYPE(GUI, JSOpenFailed);
66 //--------------------------------------------------------
67 // Declarations
68 //--------------------------------------------------------
70 /**
71 * Contains a list of values for new defaults to objects.
73 struct SGUIStyle
75 // A list of defaults for
76 std::map<CStr, CStrW> m_SettingsDefaults;
79 struct JSObject; // The GUI stores a JSObject*, so needs to know that JSObject exists
80 class IGUIObject;
81 class CGUISpriteInstance;
82 struct SGUIText;
83 struct CColor;
84 struct SGUIText;
85 struct SGUIIcon;
86 class CGUIString;
87 class CGUISprite;
88 struct SGUIImageEffects;
89 struct SGUIScrollBarStyle;
90 class GUITooltip;
92 /**
93 * The main object that represents a whole GUI page.
95 * No interfacial functions throws.
97 class CGUI
99 NONCOPYABLE(CGUI);
101 friend class IGUIObject;
102 friend class IGUIScrollBarOwner;
103 friend class CInternalCGUIAccessorBase;
105 private:
106 // Private typedefs
107 typedef IGUIObject *(*ConstructObjectFunction)();
109 public:
110 CGUI();
111 ~CGUI();
114 * Initializes GUI script classes
116 static void ScriptingInit();
119 * Initializes the GUI, needs to be called before the GUI is used
121 void Initialize();
124 * Performs processing that should happen every frame
125 * (including sending the "Tick" event to scripts)
127 void TickObjects();
130 * Sends a specified script event to every object
132 * @param EventName String representation of event name
134 void SendEventToAll(const CStr& EventName);
137 * Displays the whole GUI
139 void Draw();
142 * Draw GUI Sprite
144 * @param Sprite Object referring to the sprite (which also caches
145 * calculations for faster rendering)
146 * @param CellID Number of the icon cell to use. (Ignored if this sprite doesn't
147 * have any images with "cell-size")
148 * @param Z Drawing order, depth value
149 * @param Rect Position and Size
150 * @param Clipping The sprite shouldn't be drawn outside this rectangle
152 void DrawSprite(const CGUISpriteInstance& Sprite, int CellID, const float &Z,
153 const CRect &Rect, const CRect &Clipping=CRect());
156 * Draw a SGUIText object
158 * @param Text Text object.
159 * @param DefaultColor Color used if no tag applied.
160 * @param pos position
161 * @param z z value.
162 * @param clipping
164 void DrawText(SGUIText &Text, const CColor &DefaultColor,
165 const CPos &pos, const float &z, const CRect &clipping);
168 * Clean up, call this to clean up all memory allocated
169 * within the GUI.
171 void Destroy();
174 * The replacement of Process(), handles an SDL_Event_
176 * @param ev SDL Event, like mouse/keyboard input
178 InReaction HandleEvent(const SDL_Event_* ev);
181 * Load a GUI XML file into the GUI.
183 * <b>VERY IMPORTANT!</b> All \<styles\>-files must be read before
184 * everything else!
186 * @param Filename Name of file
187 * @param Paths Set of paths; all XML and JS files loaded will be added to this
189 void LoadXmlFile(const VfsPath& Filename, boost::unordered_set<VfsPath>& Paths);
192 * Checks if object exists and return true or false accordingly
194 * @param Name String name of object
195 * @return true if object exists
197 bool ObjectExists(const CStr& Name) const;
201 * Returns the GUI object with the desired name, or NULL
202 * if no match is found,
204 * @param Name String name of object
205 * @return Matching object, or NULL
207 IGUIObject* FindObjectByName(const CStr& Name) const;
210 * Returns the GUI object under the mouse, or NULL if none.
212 IGUIObject* FindObjectUnderMouse() const;
215 * The GUI needs to have all object types inputted and
216 * their constructors. Also it needs to associate a type
217 * by a string name of the type.
219 * To add a type:
220 * @code
221 * AddObjectType("button", &CButton::ConstructObject);
222 * @endcode
224 * @param str Reference name of object type
225 * @param pFunc Pointer of function ConstuctObject() in the object
227 * @see CGUI#ConstructObject()
229 void AddObjectType(const CStr& str, ConstructObjectFunction pFunc) { m_ObjectTypes[str] = pFunc; }
232 * Update Resolution, should be called every time the resolution
233 * of the OpenGL screen has been changed, this is because it needs
234 * to re-cache all its actual sizes
236 * Needs no input since screen resolution is global.
238 * @see IGUIObject#UpdateCachedSize()
240 void UpdateResolution();
243 * Generate a SGUIText object from the inputted string.
244 * The function will break down the string and its
245 * tags to calculate exactly which rendering queries
246 * will be sent to the Renderer. Also, horizontal alignment
247 * is taken into acount in this method but NOT vertical alignment.
249 * Done through the CGUI since it can communicate with
251 * @param Text Text to generate SGUIText object from
252 * @param Font Default font, notice both Default color and default font
253 * can be changed by tags.
254 * @param Width Width, 0 if no word-wrapping.
255 * @param BufferZone space between text and edge, and space between text and images.
256 * @param pObject Optional parameter for error output. Used *only* if error parsing fails,
257 * and we need to be able to output which object the error occured in to aid the user.
259 SGUIText GenerateText(const CGUIString &Text, const CStrW& Font,
260 const float &Width, const float &BufferZone,
261 const IGUIObject *pObject=NULL);
264 * Returns the JSObject* associated with the GUI
266 * @return The relevant JS object
268 JSObject* GetScriptObject() { return m_ScriptObject; }
271 * Check if an icon exists
273 bool IconExists(const CStr& str) const { return (m_Icons.count(str) != 0); }
276 * Get Icon (a copy, can never be changed)
278 SGUIIcon GetIcon(const CStr& str) const { return m_Icons.find(str)->second; }
281 * Get pre-defined color (if it exists)
282 * Returns false if it fails.
284 bool GetPreDefinedColor(const CStr& name, CColor &Output);
286 private:
289 * Updates the object pointers, needs to be called each
290 * time an object has been added or removed.
292 * This function is atomic, meaning if it throws anything, it will
293 * have seen it through that nothing was ultimately changed.
295 * @throws PSERROR_GUI that is thrown from IGUIObject::AddToPointersMap().
297 void UpdateObjects();
300 * Adds an object to the GUI's object database
301 * Private, since you can only add objects through
302 * XML files. Why? Because it enables the GUI to
303 * be much more encapsulated and safe.
305 * @throws Rethrows PSERROR_GUI from IGUIObject::AddChild().
307 void AddObject(IGUIObject* pObject);
310 * You input the name of the object type, and let's
311 * say you input "button", then it will construct a
312 * CGUIObjet* as a CButton.
314 * @param str Name of object type
315 * @return Newly constructed IGUIObject (but constructed as a subclass)
317 IGUIObject *ConstructObject(const CStr& str);
320 * Get Focused Object.
322 IGUIObject *GetFocusedObject() { return m_FocusedObject; }
324 public:
326 * Change focus to new object.
327 * Will send LOST_FOCUS/GOT_FOCUS messages as appropriate.
328 * pObject can be NULL to remove all focus.
330 void SetFocusedObject(IGUIObject* pObject);
332 private:
333 //--------------------------------------------------------
334 /** @name XML Reading Xeromyces specific subroutines
336 * These does not throw!
337 * Because when reading in XML files, it won't be fatal
338 * if an error occurs, perhaps one particular object
339 * fails, but it'll still continue reading in the next.
340 * All Error are reported with ReportParseError
342 //--------------------------------------------------------
345 Xeromyces_* functions tree
346 <objects> (ReadRootObjects)
348 +-<script> (ReadScript)
350 +-<object> (ReadObject)
352 +-<action>
354 +-Optional Type Extensions (IGUIObject::ReadExtendedElement) TODO
356 +-<<object>> *recursive*
359 <styles> (ReadRootStyles)
361 +-<style> (ReadStyle)
364 <sprites> (ReadRootSprites)
366 +-<sprite> (ReadSprite)
368 +-<image> (ReadImage)
371 <setup> (ReadRootSetup)
373 +-<tooltip> (ReadToolTip)
375 +-<scrollbar> (ReadScrollBar)
377 +-<icon> (ReadIcon)
379 +-<color> (ReadColor)
381 //@{
383 // Read Roots
386 * Reads in the root element \<objects\> (the DOMElement).
388 * @param Element The Xeromyces object that represents
389 * the objects-tag.
390 * @param pFile The Xeromyces object for the file being read
391 * @param Paths Collects the set of all XML/JS files that are loaded
393 * @see LoadXmlFile()
395 void Xeromyces_ReadRootObjects(XMBElement Element, CXeromyces* pFile, boost::unordered_set<VfsPath>& Paths);
398 * Reads in the root element \<sprites\> (the DOMElement).
400 * @param Element The Xeromyces object that represents
401 * the sprites-tag.
402 * @param pFile The Xeromyces object for the file being read
404 * @see LoadXmlFile()
406 void Xeromyces_ReadRootSprites(XMBElement Element, CXeromyces* pFile);
409 * Reads in the root element \<styles\> (the DOMElement).
411 * @param Element The Xeromyces object that represents
412 * the styles-tag.
413 * @param pFile The Xeromyces object for the file being read
415 * @see LoadXmlFile()
417 void Xeromyces_ReadRootStyles(XMBElement Element, CXeromyces* pFile);
420 * Reads in the root element \<setup\> (the DOMElement).
422 * @param Element The Xeromyces object that represents
423 * the setup-tag.
424 * @param pFile The Xeromyces object for the file being read
426 * @see LoadXmlFile()
428 void Xeromyces_ReadRootSetup(XMBElement Element, CXeromyces* pFile);
430 // Read Subs
433 * Notice! Recursive function!
435 * Read in an \<object\> (the XMBElement) and stores it
436 * as a child in the pParent.
438 * It will also check the object's children and call this function
439 * on them too. Also it will call all other functions that reads
440 * in other stuff that can be found within an object. Check the
441 * tree in the beginning of this class' Xeromyces_* section.
443 * @param Element The Xeromyces object that represents
444 * the object-tag.
445 * @param pFile The Xeromyces object for the file being read
446 * @param pParent Parent to add this object as child in.
447 * @param NameSubst A set of substitution strings that will be
448 * applied to all object names within this object.
449 * @param Paths Output set of file paths that this GUI object
450 * relies on.
452 * @see LoadXmlFile()
454 void Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, const std::vector<std::pair<CStr, CStr> >& NameSubst, boost::unordered_set<VfsPath>& Paths);
457 * Reads in the element \<repeat\>, which repeats its child \<object\>s
458 * 'count' times, replacing the string "[n]" in its descendants' names
459 * with "[0]", "[1]", etc.
461 void Xeromyces_ReadRepeat(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, boost::unordered_set<VfsPath>& Paths);
464 * Reads in the element \<script\> (the XMBElement) and executes
465 * the script's code.
467 * @param Element The Xeromyces object that represents
468 * the script-tag.
469 * @param pFile The Xeromyces object for the file being read
470 * @param Paths Output set of file paths that this script is loaded from.
472 * @see LoadXmlFile()
474 void Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, boost::unordered_set<VfsPath>& Paths);
477 * Reads in the element \<sprite\> (the XMBElement) and stores the
478 * result in a new CGUISprite.
480 * @param Element The Xeromyces object that represents
481 * the sprite-tag.
482 * @param pFile The Xeromyces object for the file being read
484 * @see LoadXmlFile()
486 void Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile);
489 * Reads in the element \<image\> (the XMBElement) and stores the
490 * result within the CGUISprite.
492 * @param Element The Xeromyces object that represents
493 * the image-tag.
494 * @param pFile The Xeromyces object for the file being read
495 * @param parent Parent sprite.
497 * @see LoadXmlFile()
499 void Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite &parent);
502 * Reads in the element \<effect\> (the XMBElement) and stores the
503 * result within the SGUIImageEffects.
505 * @param Element The Xeromyces object that represents
506 * the image-tag.
507 * @param pFile The Xeromyces object for the file being read
508 * @param effects Effects object to add this effect to.
510 * @see LoadXmlFile()
512 void Xeromyces_ReadEffects(XMBElement Element, CXeromyces* pFile, SGUIImageEffects &effects);
515 * Reads in the element \<style\> (the XMBElement) and stores the
516 * result in m_Styles.
518 * @param Element The Xeromyces object that represents
519 * the style-tag.
520 * @param pFile The Xeromyces object for the file being read
522 * @see LoadXmlFile()
524 void Xeromyces_ReadStyle(XMBElement Element, CXeromyces* pFile);
527 * Reads in the element \<scrollbar\> (the XMBElement) and stores the
528 * result in m_ScrollBarStyles.
530 * @param Element The Xeromyces object that represents
531 * the scrollbar-tag.
532 * @param pFile The Xeromyces object for the file being read
534 * @see LoadXmlFile()
536 void Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile);
539 * Reads in the element \<icon\> (the XMBElement) and stores the
540 * result in m_Icons.
542 * @param Element The Xeromyces object that represents
543 * the scrollbar-tag.
544 * @param pFile The Xeromyces object for the file being read
546 * @see LoadXmlFile()
548 void Xeromyces_ReadIcon(XMBElement Element, CXeromyces* pFile);
551 * Reads in the element \<tooltip\> (the XMBElement) and stores the
552 * result as an object with the name __tooltip_#.
554 * @param Element The Xeromyces object that represents
555 * the scrollbar-tag.
556 * @param pFile The Xeromyces object for the file being read
558 * @see LoadXmlFile()
560 void Xeromyces_ReadTooltip(XMBElement Element, CXeromyces* pFile);
563 * Reads in the element \<color\> (the XMBElement) and stores the
564 * result in m_PreDefinedColors
566 * @param Element The Xeromyces object that represents
567 * the scrollbar-tag.
568 * @param pFile The Xeromyces object for the file being read
570 * @see LoadXmlFile()
572 void Xeromyces_ReadColor(XMBElement Element, CXeromyces* pFile);
574 //@}
576 private:
578 // Variables
580 //--------------------------------------------------------
581 /** @name Miscellaneous */
582 //--------------------------------------------------------
583 //@{
586 * An JSObject* under which all GUI JavaScript things will
587 * be created, so that they can be garbage-collected
588 * when the GUI shuts down.
590 JSObject* m_ScriptObject;
593 * don't want to pass this around with the
594 * ChooseMouseOverAndClosest broadcast -
595 * we'd need to pack this and pNearest in a struct
597 CPos m_MousePos;
600 * Indicates which buttons are pressed (bit 0 = LMB,
601 * bit 1 = RMB, bit 2 = MMB)
603 unsigned int m_MouseButtons;
605 // Tooltip
606 GUITooltip m_Tooltip;
609 * This is a bank of custom colors, it is simply a look up table that
610 * will return a color object when someone inputs the name of that
611 * color. Of course the colors have to be declared in XML, there are
612 * no hard-coded values.
614 std::map<CStr, CColor> m_PreDefinedColors;
616 //@}
617 //--------------------------------------------------------
618 /** @name Objects */
619 //--------------------------------------------------------
620 //@{
623 * Base Object, all its children are considered parentless
624 * because this is not a real object per se.
626 IGUIObject* m_BaseObject;
629 * Focused object!
630 * Say an input box that is selected. That one is focused.
631 * There can only be one focused object.
633 IGUIObject* m_FocusedObject;
635 /**
636 * Just pointers for fast name access, each object
637 * is really constructed within its parent for easy
638 * recursive management.
639 * Notice m_BaseObject won't belong here since it's
640 * not considered a real object.
642 map_pObjects m_pAllObjects;
645 * Number of object that has been given name automatically.
646 * the name given will be '__internal(#)', the number (#)
647 * being this variable. When an object's name has been set
648 * as followed, the value will increment.
650 int m_InternalNameNumber;
653 * Function pointers to functions that constructs
654 * IGUIObjects by name... For instance m_ObjectTypes["button"]
655 * is filled with a function that will "return new CButton();"
657 std::map<CStr, ConstructObjectFunction> m_ObjectTypes;
660 * Map from hotkey names to objects that listen to the hotkey.
661 * (This is an optimisation to avoid recursing over the whole GUI
662 * tree every time a hotkey is pressed).
663 * Currently this is only set at load time - dynamic changes to an
664 * object's hotkey property will be ignored.
666 std::map<CStr, std::vector<IGUIObject*> > m_HotkeyObjects;
668 //--------------------------------------------------------
669 // Databases
670 //--------------------------------------------------------
672 // Sprites
673 std::map<CStr, CGUISprite> m_Sprites;
675 // Styles
676 std::map<CStr, SGUIStyle> m_Styles;
678 // Scroll-bar styles
679 std::map<CStr, SGUIScrollBarStyle> m_ScrollBarStyles;
681 // Icons
682 std::map<CStr, SGUIIcon> m_Icons;
685 #endif