guiControl.h 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _GUICONTROL_H_
  23. #define _GUICONTROL_H_
  24. #ifndef _PLATFORM_H_
  25. #include "platform/platform.h"
  26. #endif
  27. #ifndef _MPOINT_H_
  28. #include "math/mPoint.h"
  29. #endif
  30. #ifndef _MRECT_H_
  31. #include "math/mRect.h"
  32. #endif
  33. #ifndef _COLOR_H_
  34. #include "graphics/gColor.h"
  35. #endif
  36. #ifndef _SIMBASE_H_
  37. #include "sim/simBase.h"
  38. #endif
  39. #ifndef _GUITYPES_H_
  40. #include "gui/guiTypes.h"
  41. #endif
  42. #ifndef _EVENT_H_
  43. #include "platform/event.h"
  44. #endif
  45. #ifndef _STRINGBUFFER_H_
  46. #include "string/stringBuffer.h"
  47. #endif
  48. #ifndef _LANG_H_
  49. #include "gui/language/lang.h"
  50. #endif
  51. #ifndef _TICKABLE_H_
  52. #include "platform/Tickable.h"
  53. #endif
  54. #ifndef _MFLUID_H_
  55. #include "math/mFluid.h"
  56. #endif
  57. class GuiCanvas;
  58. class GuiEditCtrl;
  59. //-----------------------------------------------------------------------------
  60. /// @defgroup gui_group Gui System
  61. /// The GUI system in Torque provides a powerful way of creating
  62. /// WYSIWYG User Interfaces for your Game or Application written
  63. /// in Torque.
  64. ///
  65. /// The GUI Provides a range of different controls that you may use
  66. /// to arrange and layout your GUI's, including Buttons, Lists, Bitmaps
  67. /// Windows, Containers, and HUD elements.
  68. ///
  69. /// The Base Control Class GuiControl provides a basis upon which to
  70. /// write GuiControl's that may be specific to your particular type
  71. /// of game.
  72. /// @addtogroup gui_core_group Core
  73. /// @section GuiControl_Intro Introduction
  74. ///
  75. /// GuiControl is the base class for GUI controls in Torque. It provides these
  76. /// basic areas of functionality:
  77. /// - Inherits from SimGroup, so that controls can have children.
  78. /// - Interfacing with a GuiControlProfile.
  79. /// - An abstraction from the details of handling user input
  80. /// and so forth, providing friendly hooks like onMouseEnter(), onMouseMove(),
  81. /// and onMouseLeave(), onKeyDown(), and so forth.
  82. /// - An abstraction from the details of rendering and resizing.
  83. /// - Helper functions to manipulate the mouse (mouseLock and
  84. /// mouseUnlock), and convert coordinates (localToGlobalCoord() and
  85. /// globalToLocalCoord()).
  86. ///
  87. /// @ref GUI has an overview of the GUI system.
  88. ///
  89. /// Tickable Information - taken from guiTickCtrl now retired.
  90. /// This Gui Control is designed to recieve update ticks at a constant interval.
  91. /// It was created to be the Parent class of a control which used a DynamicTexture
  92. /// along with a VectorField to create warping effects much like the ones found
  93. /// in visualization displays for iTunes or Winamp. Those displays are updated
  94. /// at the framerate frequency. This works fine for those effects, however for
  95. /// an application of the same type of effects for things like Gui transitions
  96. /// the framerate-driven update frequency is not desireable because it does not
  97. /// allow the developer to be able to have any idea of a consistant user-experience.
  98. ///
  99. /// Enter the Tickable interface. This lets the Gui control, in this case, update
  100. /// the dynamic texture at a constant rate of once per tick, even though it gets
  101. /// rendered every frame, thus creating a framerate-independant update frequency
  102. /// so that the effects are at a consistant speed regardless of the specifics
  103. /// of the system the user is on. This means that the screen-transitions will
  104. /// occur in the same time on a machine getting 300fps in the Gui shell as a
  105. /// machine which gets 150fps in the Gui shell.
  106. /// @see Tickable
  107. ///
  108. /// @ingroup gui_group Gui System
  109. /// @{
  110. class GuiControl : public SimGroup, public virtual Tickable
  111. {
  112. private:
  113. typedef SimGroup Parent;
  114. typedef GuiControl Children;
  115. public:
  116. /// @name Control State
  117. /// @{
  118. GuiControlProfile *mProfile;
  119. static const S32 DEFAULT_TOOLTIP_WIDTH = 250;
  120. static const S32 DEFAULT_TOOLTIP_HOVERTIME = 1000;
  121. GuiControlProfile *mTooltipProfile;
  122. S32 mTipHoverTime;
  123. S32 mTooltipWidth;
  124. static bool writeToolTipWidthFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return ctrl->mTooltipWidth != DEFAULT_TOOLTIP_WIDTH; }
  125. static bool writeToolTipHoverTimeFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return ctrl->mTipHoverTime != DEFAULT_TOOLTIP_HOVERTIME; }
  126. bool mVisible;
  127. bool mActive;
  128. bool mAwake;
  129. bool mSetFirstResponder;
  130. bool mCanSave;
  131. bool mIsContainer; ///< True if the GuiEditor can drag other controls into this one.
  132. bool mRendersChildren; ///< True if the control renders children. If false, then the control cannot be a container. This is set by the class and cannot be changed by the user.
  133. bool mUseInput; ///< True if input events like a click can be passed to this gui. False will pass events to the parent and this object and its children will not process input (touch and keyboard).
  134. S32 mLayer;
  135. static S32 smCursorChanged; ///< Has this control modified the cursor? -1 or type
  136. RectI mBounds;
  137. Point2I mMinExtent;
  138. Point2I mRenderInsetLT; ///Add this to the mBounds and parent offset to get the true render location of the control
  139. Point2I mRenderInsetRB; ///The actual rendered inset for the right and bottom sides.
  140. StringTableEntry mLangTableName;
  141. LangTable *mLangTable;
  142. static bool smDesignTime; ///< static GuiControl boolean that specifies if the GUI Editor is active
  143. /// @}
  144. /// @name Design Time Editor Access
  145. /// @{
  146. static GuiEditCtrl *smEditorHandle; ///< static GuiEditCtrl pointer that gives controls access to editor-NULL if editor is closed
  147. /// @}
  148. virtual bool isEditMode();
  149. virtual bool isEditSelected();
  150. /// @name Keyboard Input
  151. /// @{
  152. GuiControl* mFirstResponder;
  153. static GuiControl *smPrevResponder;
  154. static GuiControl *smCurResponder;
  155. /// @}
  156. enum horizSizingOptions
  157. {
  158. horizResizeRight = 0, ///< fixed on the left and width
  159. horizResizeWidth, ///< fixed on the left and right
  160. horizResizeLeft, ///< fixed on the right and width
  161. horizResizeCenter,
  162. horizResizeRelative, ///< resize relative
  163. horizResizeFill ///< fill the entire content area of the parent
  164. };
  165. enum vertSizingOptions
  166. {
  167. vertResizeBottom = 0, ///< fixed on the top and in height
  168. vertResizeHeight, ///< fixed on the top and bottom
  169. vertResizeTop, ///< fixed in height and on the bottom
  170. vertResizeCenter,
  171. vertResizeRelative, ///< resize relative
  172. vertResizeFill ///< fill the entire content area of the parent
  173. };
  174. enum TextRotationOptions
  175. {
  176. tRotateNone = 0,
  177. tRotateLeft,
  178. tRotateRight
  179. };
  180. bool mPassEventThru = false;
  181. protected:
  182. /// @name Control State
  183. /// @{
  184. S32 mHorizSizing; ///< Set from horizSizingOptions.
  185. S32 mVertSizing; ///< Set from vertSizingOptions.
  186. Point2I mStoredExtent; //Used in conjunction with the min extent.
  187. Point2F mStoredRelativePosH; //Used to prevent rounding drift when using relative positioning.
  188. Point2F mStoredRelativePosV; //Used to prevent rounding drift when using relative positioning.
  189. bool mUseRelPosH;
  190. bool mUseRelPosV;
  191. StringTableEntry mConsoleVariable;
  192. StringTableEntry mConsoleCommand;
  193. StringTableEntry mAltConsoleCommand;
  194. StringTableEntry mAcceleratorKey;
  195. StringTableEntry mTooltip;
  196. StringTableEntry mText;
  197. StringTableEntry mTextID;
  198. bool mTextWrap;
  199. bool mTextExtend;
  200. AlignmentType mAlignment;
  201. VertAlignmentType mVAlignment;
  202. F32 mFontSizeAdjust;
  203. ColorI mFontColor;
  204. bool mOverrideFontColor;
  205. static bool writeFontSizeAdjustFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return ctrl->mFontSizeAdjust != 1; }
  206. static bool writeFontColorFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return ctrl->mOverrideFontColor && ctrl->mFontColor != ColorI(0,0,0,255); }
  207. static bool writeOverrideFontColorFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return ctrl->mOverrideFontColor; }
  208. /// @}
  209. /// @name Console
  210. /// The console variable collection of functions allows a console variable to be bound to the GUI control.
  211. ///
  212. /// This allows, say, an edit field to be bound to '$foo'. The value of the console
  213. /// variable '$foo' would then be equal to the text inside the text field. Changing
  214. /// either changes the other.
  215. /// @{
  216. /// Sets the value of the console variable bound to this control
  217. /// @param value String value to assign to control's console variable
  218. void setVariable(const char *value);
  219. /// Sets the value of the console variable bound to this control
  220. /// @param value Integer value to assign to control's console variable
  221. void setIntVariable(S32 value);
  222. /// Sets the value of the console variable bound to this control
  223. /// @param value Float value to assign to control's console variable
  224. void setFloatVariable(F32 value);
  225. const char* getVariable(); ///< Returns value of control's bound variable as a string
  226. S32 getIntVariable(); ///< Returns value of control's bound variable as a integer
  227. F32 getFloatVariable(); ///< Returns value of control's bound variable as a float
  228. public:
  229. /// Set the name of the console variable which this GuiObject is bound to
  230. /// @param variable Variable name
  231. void setConsoleVariable(const char *variable);
  232. /// Set the name of the console function bound to, such as a script function
  233. /// a button calls when clicked.
  234. /// @param newCmd Console function to attach to this GuiControl
  235. void setConsoleCommand(const char *newCmd);
  236. const char * getConsoleCommand(); ///< Returns the name of the function bound to this GuiControl
  237. LangTable *getGUILangTable(void);
  238. const UTF8 *getGUIString(S32 id);
  239. /// @}
  240. protected:
  241. /// @name Callbacks
  242. /// @{
  243. /// Executes a console command, and returns the result.
  244. ///
  245. /// The global console variable $ThisControl is set to the id of the calling
  246. /// control. WARNING: because multiple controls may set $ThisControl, at any time,
  247. /// the value of $ThisControl should be stored in a local variable by the
  248. /// callback code. The use of the $ThisControl variable is not thread safe.
  249. /// Executes mConsoleCommand, and returns the result.
  250. const char* execConsoleCallback();
  251. /// Executes mAltConsoleCommand, and returns the result.
  252. const char* execAltConsoleCallback();
  253. /// @}
  254. public:
  255. /// @name Editor
  256. /// These functions are used by the GUI Editor
  257. /// @{
  258. /// Sets the size of the GuiControl
  259. /// @param horz Width of the control
  260. /// @param vert Height of the control
  261. void setSizing(S32 horz, S32 vert);
  262. /// Overrides Parent Serialization to allow specific controls to not be saved (Dynamic Controls, etc)
  263. void write(Stream &stream, U32 tabStop, U32 flags);
  264. /// Returns boolean specifying if a control can be serialized
  265. bool getCanSave();
  266. /// Set serialization flag
  267. void setCanSave(bool bCanSave);
  268. /// Returns boolean as to whether any parent of this control has the 'no serialization' flag set.
  269. bool getCanSaveParent();
  270. /// @}
  271. public:
  272. /// @name Initialization
  273. /// @{
  274. DECLARE_CONOBJECT(GuiControl);
  275. GuiControl();
  276. virtual ~GuiControl();
  277. static void initPersistFields();
  278. /// @}
  279. /// @name Accessors
  280. /// @{
  281. const Point2I& getPosition() { return mBounds.point; } ///< Returns position of the control
  282. const Point2I& getExtent() { return mBounds.extent; } ///< Returns extents of the control
  283. const RectI& getBounds() { return mBounds; } ///< Returns the bounds of the control
  284. const Point2I& getMinExtent() { return mMinExtent; } ///< Returns minimum size the control can be
  285. const S32 getLeft() { return mBounds.point.x; } ///< Returns the X position of the control
  286. const S32 getTop() { return mBounds.point.y; } ///< Returns the Y position of the control
  287. const S32 getWidth() { return mBounds.extent.x; } ///< Returns the width of the control
  288. const S32 getHeight() { return mBounds.extent.y; } ///< Returns the height of the control
  289. virtual void setText(const char *text);
  290. virtual void setTextID(S32 id);
  291. virtual void setTextID(const char *id);
  292. virtual const char* getText();
  293. inline void setTextWrap(const bool wrap) { mTextWrap = wrap; }
  294. inline bool getTextWrap() { return mTextWrap; }
  295. inline void setTextExtend(const bool extend) { mTextExtend = extend; }
  296. inline bool getTextExtend() { return mTextExtend; }
  297. const horizSizingOptions getHorizSizing() { return static_cast<horizSizingOptions>(mHorizSizing); }
  298. const vertSizingOptions getVertSizing() { return static_cast<vertSizingOptions>(mVertSizing); }
  299. void setHorizSizing(const horizSizingOptions sizing) { mHorizSizing = sizing; }
  300. void setVertSizing(const vertSizingOptions sizing) { mVertSizing = sizing; }
  301. // Text Property Accessors
  302. static bool setTextProperty(void* obj, const char* data) { static_cast<GuiControl*>(obj)->setText(data); return false; }
  303. static const char* getTextProperty(void* obj, const char* data) { return static_cast<GuiControl*>(obj)->getText(); }
  304. static bool writeTextWrapFn(void* obj, const char* data) { return static_cast<GuiControl*>(obj)->getTextWrap(); }
  305. static bool writeTextExtendFn(void* obj, const char* data) { return static_cast<GuiControl*>(obj)->getTextExtend(); }
  306. static bool setExtentFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); Vector2 v = Vector2(data); ctrl->setExtent(Point2I(v.x, v.y)); ctrl->resetStoredExtent(); ctrl->resetStoredRelPos(); return false; }
  307. static bool setMinExtentFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); Vector2 v = Vector2(data); ctrl->mMinExtent.set(v.x, v.y); ctrl->resetStoredExtent(); ctrl->resetStoredRelPos(); return false; }
  308. static bool writeMinExtentFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return ctrl->mMinExtent.x != 0 || ctrl->mMinExtent.y != 0; }
  309. static bool setPositionFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); Vector2 v = Vector2(data); ctrl->setPosition(Point2I(v.x, v.y)); ctrl->resetStoredRelPos(); return false; }
  310. /// @}
  311. /// @name Flags
  312. /// @{
  313. /// Sets the visibility of the control
  314. /// @param value True if object should be visible
  315. virtual void setVisible(bool value);
  316. inline bool isVisible() { return mVisible; } ///< Returns true if the object is visible
  317. static bool writeVisibleFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return !ctrl->isVisible(); }
  318. static bool writeUseInputFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return !ctrl->mUseInput; }
  319. static bool writeIsContainerFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); return ctrl->mRendersChildren && !ctrl->mIsContainer; }
  320. static bool setIsContainerFn(void* obj, const char* data) { GuiControl* ctrl = static_cast<GuiControl*>(obj); ctrl->mIsContainer = ctrl->mRendersChildren ? dAtob(data) : false; return false; }
  321. /// Sets the status of this control as active and responding or inactive
  322. /// @param value True if this is active
  323. virtual void setActive(bool value);
  324. bool isActive() { return mActive; } ///< Returns true if this control is active
  325. bool isAwake() { return mAwake; } ///< Returns true if this control is awake
  326. /// @}
  327. /// Get information about the size of a scroll line.
  328. ///
  329. /// @param rowHeight The height, in pixels, of a row
  330. /// @param columnWidth The width, in pixels, of a column
  331. virtual void getScrollLineSizes(U32 *rowHeight, U32 *columnWidth);
  332. /// Get information about the cursor.
  333. /// @param cursor Cursor information will be stored here
  334. /// @param showCursor Will be set to true if the cursor is visible
  335. /// @param lastGuiEvent GuiEvent containing cursor position and modifyer keys (ie ctrl, shift, alt etc)
  336. virtual void getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent);
  337. /// @name Children
  338. /// @{
  339. /// Adds an object as a child of this object.
  340. /// @param obj New child object of this control
  341. virtual void addObject(SimObject *obj);
  342. /// Removes a child object from this control.
  343. /// @param obj Object to remove from this control
  344. void removeObject(SimObject *obj);
  345. GuiControl *getParent(); ///< Returns the control which owns this one.
  346. GuiCanvas *getRoot(); ///< Returns the root canvas of this control.
  347. /// @}
  348. /// @name Coordinates
  349. /// @{
  350. /// Translates local coordinates (wrt this object) into global coordinates
  351. ///
  352. /// @param src Local coordinates to translate
  353. virtual Point2I localToGlobalCoord(const Point2I &src);
  354. /// Returns global coordinates translated into local space
  355. ///
  356. /// @param src Global coordinates to translate
  357. virtual Point2I globalToLocalCoord(const Point2I &src);
  358. /// @}
  359. /// @name Resizing
  360. /// @{
  361. /// Changes the size and/or position of this control
  362. /// @param newPosition New position of this control
  363. /// @param newExtent New size of this control
  364. virtual void resize(const Point2I &newPosition, const Point2I &newExtent);
  365. /// Changes the position of this control
  366. /// @param newPosition New position of this control
  367. virtual void setPosition( const Point2I &newPosition );
  368. /// Changes the size of this control
  369. /// @param newExtent New size of this control
  370. virtual void setExtent( const Point2I &newExtent );
  371. /// Changes the bounds of this control
  372. /// @param newBounds New bounds of this control
  373. virtual void setBounds( const RectI &newBounds );
  374. /// Changes the X position of this control
  375. /// @param newXPosition New X Position of this control
  376. virtual void setLeft( S32 newLeft );
  377. /// Changes the Y position of this control
  378. /// @param newYPosition New Y Position of this control
  379. virtual void setTop( S32 newTop );
  380. /// Changes the width of this control
  381. /// @param newWidth New width of this control
  382. virtual void setWidth( S32 newWidth );
  383. /// Changes the height of this control
  384. /// @param newHeight New Height of this control
  385. virtual void setHeight( S32 newHeight );
  386. /// Called when a child control of the object is resized
  387. /// @param child Child object
  388. virtual void childResized(GuiControl *child);
  389. /// Called when a child control of the object is moved
  390. /// @param child Child object
  391. virtual void childMoved(GuiControl* child);
  392. /// Called when the children of this control may have been reordered
  393. virtual void childrenReordered();
  394. /// Called when this objects parent is resized
  395. /// @param oldParentExtent The old size of the parent object
  396. /// @param newParentExtent The new size of the parent object
  397. virtual void parentResized(const Point2I &oldParentExtent, const Point2I &newParentExtent);
  398. /// Removes the resize mode of fill and changes it to right or bottom
  399. void preventResizeModeFill();
  400. /// Removes the resize mode of center and changes it to right or bottom
  401. void preventResizeModeCenter();
  402. /// @}
  403. /// @name Rendering
  404. /// @{
  405. /// Called when this control is to render itself
  406. /// @param offset The location this control is to begin rendering
  407. /// @param updateRect The screen area this control has drawing access to
  408. virtual void onRender(Point2I offset, const RectI &updateRect);
  409. /// Render a tooltip at the specified cursor position for this control
  410. /// @param cursorPos position of cursor to display the tip near
  411. /// @param tipText optional alternate tip to be rendered
  412. virtual bool renderTooltip(Point2I &cursorPos, const char* tipText = NULL );
  413. /// Called when this control should render its children
  414. /// @param offset The top left of the parent control
  415. /// @param contentOffset The top left of the parent's content
  416. /// @param updateRect The screen area this control has drawing access to
  417. virtual void renderChildControls(const Point2I& offset, const RectI& content, const RectI& updateRect);
  418. /// Renders a single child control
  419. virtual void renderChild(GuiControl* ctrl, const Point2I& offset, const RectI& content, const RectI& clipRect);
  420. /// Sets the area (local coordinates) this control wants refreshed each frame
  421. /// @param pos UpperLeft point on rectangle of refresh area
  422. /// @param ext Extent of update rect
  423. void setUpdateRegion(Point2I pos, Point2I ext);
  424. /// Sets the update area of the control to encompass the whole control
  425. virtual void setUpdate();
  426. /// @}
  427. //child hierarchy calls
  428. void awaken(); ///< Called when this control and its children have been wired up.
  429. void sleep(); ///< Called when this control is no more.
  430. void preRender(); ///< Prerender this control and all its children.
  431. /// @name Events
  432. ///
  433. /// If you subclass these, make sure to call the Parent::'s versions.
  434. ///
  435. /// @{
  436. /// Called when this object is asked to wake up returns true if it's actually awake at the end
  437. virtual bool onWake();
  438. /// Called when this object is asked to sleep
  439. virtual void onSleep();
  440. /// Do special pre-render proecessing
  441. virtual void onPreRender();
  442. /// Called when this object is removed using delete.
  443. virtual void onRemove();
  444. /// Called when this object is removed using delete or parent.remove().
  445. virtual void onGroupRemove();
  446. /// Called when this object is added to the scene
  447. virtual bool onAdd();
  448. /// Called when this object has a new child. Congratulations!
  449. virtual void onChildAdded( GuiControl *child );
  450. /// Called when a child is removed.
  451. virtual void onChildRemoved(GuiControl* child);
  452. /// @}
  453. /// @name Console
  454. /// @{
  455. /// Returns the value of the variable bound to this object
  456. virtual const char *getScriptValue();
  457. /// Sets the value of the variable bound to this object
  458. virtual void setScriptValue(const char *value);
  459. /// @}
  460. /// @name Input (Keyboard/Mouse)
  461. /// @{
  462. /// This function will return true if the provided coordinates (wrt parent object) are
  463. /// within the bounds of this control
  464. /// @param parentCoordPoint Coordinates to test
  465. virtual bool pointInControl(const Point2I& parentCoordPoint);
  466. /// Returns true if the global cursor is inside this control
  467. bool cursorInControl();
  468. /// Returns the control which the provided point is under, with layering
  469. /// @param pt Point to test
  470. /// @param initialLayer Layer of gui objects to begin the search
  471. virtual GuiControl* findHitControl(const Point2I &pt, S32 initialLayer = -1, const bool ignoreUseInput = false, const bool ignoreEditSelected = true);
  472. /// Lock the mouse within the provided control
  473. /// @param lockingControl Control to lock the mouse within
  474. virtual void mouseLock(GuiControl *lockingControl);
  475. /// Turn on mouse locking with last used lock control
  476. virtual void mouseLock();
  477. /// Unlock the mouse
  478. virtual void mouseUnlock();
  479. /// Returns true if the mouse is locked
  480. virtual bool isMouseLocked();
  481. /// @}
  482. bool mAllowEventPassThru;
  483. bool handleTouchDown(const GuiEvent& event, const Point2I& pt, S32 initialLayer = -1);
  484. bool handleTouchUp(const GuiEvent& event, const Point2I& pt, S32 initialLayer = -1);
  485. bool handleTouchMove(const GuiEvent& event, const Point2I& pt, S32 initialLayer = -1);
  486. //Sends a script event with modifier and mouse position if the script method exists. Returns true if the event is consumed.
  487. bool sendScriptMouseEvent(const char* name, const GuiEvent& event);
  488. bool sendScriptKeyEvent(const char* name, const InputEvent& event);
  489. /// General input handler.
  490. virtual bool onInputEvent(const InputEvent &event);
  491. /// @name Touch/Mouse Events
  492. /// These functions are called when the input event which is
  493. /// in the name of the function occurs.
  494. /// @{
  495. virtual void onTouchUp(const GuiEvent &event);
  496. virtual void onTouchDown(const GuiEvent &event);
  497. virtual void onTouchMove(const GuiEvent &event);
  498. virtual void onTouchDragged(const GuiEvent &event);
  499. virtual void onTouchEnter(const GuiEvent &event);
  500. virtual void onTouchLeave(const GuiEvent &event);
  501. virtual void onMouseWheelUp(const GuiEvent &event);
  502. virtual void onMouseWheelDown(const GuiEvent &event);
  503. virtual void onRightMouseDown(const GuiEvent &event);
  504. virtual void onRightMouseUp(const GuiEvent &event);
  505. virtual void onRightMouseDragged(const GuiEvent &event);
  506. virtual void onMiddleMouseDown(const GuiEvent &event);
  507. virtual void onMiddleMouseUp(const GuiEvent &event);
  508. virtual void onMiddleMouseDragged(const GuiEvent &event);
  509. /// @}
  510. //Called just before onTouch down for the hit control. The focus should then bubble up through the
  511. //controls allowing windows to move to the front. If the focus arrives at the canvas and the first responder
  512. //wasn't found, then the first responder loses the focus.
  513. virtual void onFocus(bool foundFirstResponder);
  514. /// @name Editor Mouse Events
  515. ///
  516. /// These functions are called when the input event which is
  517. /// in the name of the function occurs. Conversly from normal
  518. /// mouse events, these have a boolean return value that, if
  519. /// they return true, the editor will NOT act on them or be able
  520. /// to respond to this particular event.
  521. ///
  522. /// This is particularly useful for when writing controls so that
  523. /// they may become aware of the editor and allow customization
  524. /// of their data or appearance as if they were actually in use.
  525. /// For example, the GuiTabBookCtrl catches on mouse down to select
  526. /// a tab and NOT let the editor do any instant group manipulation.
  527. ///
  528. /// @{
  529. /// Called when a mouseDown event occurs on a control and the GUI editor is active
  530. /// @param event the GuiEvent which caused the call to this function
  531. /// @param offset the offset which is representative of the units x and y that the editor takes up on screen
  532. virtual bool onMouseDownEditor(const GuiEvent &event, const Point2I& offset);
  533. /// Called when a mouseUp event occurs on a control and the GUI editor is active
  534. /// @param event the GuiEvent which caused the call to this function
  535. /// @param offset the offset which is representative of the units x and y that the editor takes up on screen
  536. virtual bool onMouseUpEditor(const GuiEvent &event, const Point2I& offset) { return false; };
  537. /// Called when a rightMouseDown event occurs on a control and the GUI editor is active
  538. /// @param event the GuiEvent which caused the call to this function
  539. /// @param offset the offset which is representative of the units x and y that the editor takes up on screen
  540. virtual bool onRightMouseDownEditor(const GuiEvent &event, const Point2I& offset) { return false; };
  541. /// Called when a mouseDragged event occurs on a control and the GUI editor is active
  542. /// @param event the GuiEvent which caused the call to this function
  543. /// @param offset the offset which is representative of the units x and y that the editor takes up on screen
  544. virtual bool onMouseDraggedEditor(const GuiEvent &event, const Point2I& offset) { return false; };
  545. /// @}
  546. /// @name Tabs
  547. /// @{
  548. /// Find the first tab-accessable child of this control
  549. virtual GuiControl* findFirstTabable();
  550. /// Find the last tab-accessable child of this control
  551. /// @param firstCall Set to true to clear the global previous responder
  552. virtual GuiControl* findLastTabable(bool firstCall = true);
  553. /// Find previous tab-accessable control with respect to the provided one
  554. /// @param curResponder Current control
  555. /// @param firstCall Set to true to clear the global previous responder
  556. virtual GuiControl* findPrevTabable(GuiControl *curResponder, bool firstCall = true);
  557. /// Find next tab-accessable control with regards to the provided control.
  558. ///
  559. /// @param curResponder Current control
  560. /// @param firstCall Set to true to clear the global current responder
  561. virtual GuiControl* findNextTabable(GuiControl *curResponder, bool firstCall = true);
  562. /// @}
  563. /// Returns true if the provided control is a child (grandchild, or greatgrandchild) of this one.
  564. ///
  565. /// @param child Control to test
  566. virtual bool ControlIsChild(GuiControl *child);
  567. /// @name First Responder
  568. /// A first responder is the control which reacts first, in it's responder chain, to keyboard events
  569. /// The responder chain is set for each parent and so there is only one first responder amongst it's
  570. /// children.
  571. /// @{
  572. /// Sets the first responder for child controls
  573. /// @param firstResponder First responder for this chain
  574. virtual void setFirstResponder(GuiControl *firstResponder);
  575. /// Sets up this control to be the first in it's group to respond to an input event
  576. /// @param value True if this should be a first responder
  577. virtual void makeFirstResponder(bool value);
  578. /// Returns true if this control is a first responder
  579. bool isFirstResponder();
  580. /// Sets this object to be a first responder
  581. virtual void setFirstResponder();
  582. /// Clears the first responder for this chain
  583. void clearFirstResponder();
  584. void clearFirstResponder(GuiControl* target);
  585. /// Returns the first responder for this chain
  586. GuiControl *getFirstResponder() { return mFirstResponder; }
  587. /// Occurs when the first responder for this chain is lost
  588. virtual void onLoseFirstResponder();
  589. /// @}
  590. /// @name Keyboard Events
  591. /// @{
  592. /// Adds the accelerator key for this object to the canvas
  593. void addAcceleratorKey();
  594. /// Adds this control's accelerator key to the accelerator map, and
  595. /// recursively tells all children to do the same.
  596. virtual void buildAcceleratorMap();
  597. /// Occurs when the accelerator key for this control is pressed
  598. ///
  599. /// @param index Index in the acclerator map of the key
  600. virtual void acceleratorKeyPress(U32 index);
  601. /// Occurs when the accelerator key for this control is released
  602. ///
  603. /// @param index Index in the acclerator map of the key
  604. virtual void acceleratorKeyRelease(U32 index);
  605. /// Happens when a key is depressed
  606. /// @param event Event descriptor (which contains the key)
  607. virtual bool onKeyDown(const GuiEvent &event);
  608. /// Happens when a key is released
  609. /// @param event Event descriptor (which contains the key)
  610. virtual bool onKeyUp(const GuiEvent &event);
  611. /// Happens when a key is held down, resulting in repeated keystrokes.
  612. /// @param event Event descriptor (which contains the key)
  613. virtual bool onKeyRepeat(const GuiEvent &event);
  614. /// @}
  615. /// Sets the control profile for this control.
  616. ///
  617. /// @see GuiControlProfile
  618. /// @param prof Control profile to apply
  619. virtual void setControlProfile(GuiControlProfile *prof);
  620. /// Occurs when this control performs its "action"
  621. virtual void onAction();
  622. /// @name Peer Messaging
  623. /// Used to send a message to other GUIControls which are children of the same parent.
  624. ///
  625. /// This is mostly used by radio controls.
  626. /// @{
  627. void messageSiblings(S32 message); ///< Send a message to all siblings
  628. virtual void onMessage(GuiControl *sender, S32 msg); ///< Receive a message from another control
  629. /// @}
  630. /// @name Canvas Events
  631. /// Functions called by the canvas
  632. /// @{
  633. /// Called if this object is a dialog, when it is added to the visible layers
  634. virtual void onDialogPush();
  635. /// Called if this object is a dialog, when it is removed from the visible layers
  636. virtual void onDialogPop();
  637. /// @}
  638. /// Renders justified text using the profile.
  639. ///
  640. /// @note This should move into the graphics library at some point
  641. void renderText(const Point2I &offset, const Point2I &extent, const char *text, GuiControlProfile *profile, TextRotationOptions rot = tRotateNone);
  642. virtual void renderLineList(const Point2I& offset, const Point2I& extent, const S32 startOffsetY, const vector<string> lineList, GuiControlProfile* profile, const TextRotationOptions rot = tRotateNone);
  643. virtual vector<string> getLineList(const char* text, GuiControlProfile* profile, S32 totalWidth);
  644. virtual void renderTextLine(const Point2I& startPoint, const string line, GuiControlProfile* profile, F32 rotationInDegrees, U32 ibeamPosAtLineStart, U32 lineNumber);
  645. /// Returns a new rect based on the margins.
  646. RectI applyMargins(Point2I &offset, Point2I &extent, GuiControlState currentState, GuiControlProfile *profile);
  647. /// Returns the bounds of the rect after considering the borders.
  648. RectI applyBorders(Point2I &offset, Point2I &extent, GuiControlState currentState, GuiControlProfile *profile);
  649. /// Returns the bounds of the rect this time with padding.
  650. RectI applyPadding(Point2I &offset, Point2I &extent, GuiControlState currentState, GuiControlProfile *profile);
  651. /// Returns the bounds of the rect with margin, borders, and padding applied.
  652. RectI getInnerRect(GuiControlState currentState = GuiControlState::NormalState);
  653. RectI getInnerRect(Point2I& offset, GuiControlState currentState = GuiControlState::NormalState);
  654. virtual RectI getInnerRect(Point2I &offset, Point2I &extent, GuiControlState currentState, GuiControlProfile *profile);
  655. /// Returns the extent of the outer rect given the extent of the inner rect.
  656. Point2I getOuterExtent(Point2I &innerExtent, GuiControlState currentState, GuiControlProfile *profile);
  657. S32 getOuterWidth(S32 innerExtent, GuiControlState currentState, GuiControlProfile* profile);
  658. S32 getOuterHeight(S32 innerExtent, GuiControlState currentState, GuiControlProfile* profile);
  659. virtual void inspectPostApply();
  660. virtual void inspectPreApply();
  661. //Stores or spends stored extent
  662. Point2I extentBattery(Point2I &newExtent);
  663. //Expells all stored extent
  664. inline void resetStoredExtent() { mStoredExtent.set(0,0); }
  665. //Stores the position when using relative positioning
  666. Point2F relPosBatteryH(S32 pos, S32 ext, S32 parentExt);
  667. Point2F relPosBatteryV(S32 pos, S32 ext, S32 parentExt);
  668. void relPosBattery(Point2F& battery, S32 pos, S32 ext, S32 parentExt);
  669. void resetStoredRelPos() { mUseRelPosH = false; mUseRelPosV = false; }
  670. virtual void setDataField(StringTableEntry slotName, const char* array, const char* value);
  671. protected:
  672. bool mPreviouslyAwake;
  673. virtual void interpolateTick(F32 delta) {};
  674. virtual void processTick() {};
  675. virtual void advanceTime(F32 timeDelta) {};
  676. S32 getTextHorizontalOffset(S32 textWidth, S32 totalWidth, AlignmentType align);
  677. S32 getTextVerticalOffset(S32 textHeight, S32 totalHeight, VertAlignmentType align);
  678. AlignmentType getAlignmentType();
  679. VertAlignmentType getVertAlignmentType();
  680. AlignmentType getAlignmentType(GuiControlProfile* profile);
  681. VertAlignmentType getVertAlignmentType(GuiControlProfile* profile);
  682. const ColorI& getFontColor(GuiControlProfile* profile, const GuiControlState state = GuiControlState::NormalState);
  683. };
  684. /// @}
  685. /// <summary>
  686. /// Can be inherited from to add the members and methods needed to easily add smooth
  687. /// transitions between fill colors in default rendering. To use this:
  688. /// 1. First, inherit from this class instead of GuiControl.
  689. /// 2. In the render function, when it calls renderUniversalRect(), pass in getFillColor() and true to
  690. /// override the existing fill color. It should look like:
  691. /// renderUniversalRect(ctrlRect, mProfile, currentState, getFillColor(currentState), true);
  692. ///
  693. /// Note that this will only change the fill color used during default rendering.
  694. /// </summary>
  695. class GuiEasingSupport : public GuiControl
  696. {
  697. private:
  698. typedef GuiControl Parent;
  699. protected:
  700. FluidColorI mFluidFillColor; //The actual fill color as it moves fluidly from one color to another.
  701. GuiControlState mPreviousState;
  702. GuiControlState mCurrentState;
  703. public:
  704. GuiEasingSupport();
  705. static void initPersistFields();
  706. EasingFunction mEaseFillColorHL; //Transitioning to or from HL (if SL is not involved)
  707. EasingFunction mEaseFillColorSL; //Transitioning to or from SL (over HL)
  708. S32 mEaseTimeFillColorHL;
  709. S32 mEaseTimeFillColorSL;
  710. virtual void setControlProfile(GuiControlProfile* prof);
  711. const ColorI& getFillColor(const GuiControlState state); //Returns the fill color based on the state.
  712. virtual void processTick();
  713. inline const char* getEasingFunctionDescription(const EasingFunction ease) { return mFluidFillColor.getEasingFunctionDescription(ease); };
  714. };
  715. #endif