guiCanvas.h
Engine/source/gui/core/guiCanvas.h
Classes:
class
class
Accelerator key map.
Detailed Description
Public Typedefs
typedef Signal< void(GuiCanvas *canvas)> CanvasSizeChangeSignal
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _GUICANVAS_H_ 25#define _GUICANVAS_H_ 26 27#ifndef _SIMBASE_H_ 28#include "console/simBase.h" 29#endif 30#ifndef _GUICONTROL_H_ 31#include "gui/core/guiControl.h" 32#endif 33#ifndef _PLATFORMINPUT_H_ 34#include "platform/platformInput.h" 35#endif 36 37#ifndef _SIGNAL_H_ 38#include "core/util/tSignal.h" 39#endif 40 41#include "platform/input/IProcessInput.h" 42#include "windowManager/platformWindowMgr.h" 43#include "gfx/gfxFence.h" 44 45/// A canvas on which rendering occurs. 46/// 47/// 48/// @section GuiCanvas_contents What a GUICanvas Can Contain... 49/// 50/// @subsection GuiCanvas_content_contentcontrol Content Control 51/// A content control is the top level GuiControl for a screen. This GuiControl 52/// will be the parent control for all other GuiControls on that particular 53/// screen. 54/// 55/// @subsection GuiCanvas_content_dialogs Dialogs 56/// 57/// A dialog is essentially another screen, only it gets overlaid on top of the 58/// current content control, and all input goes to the dialog. This is most akin 59/// to the "Open File" dialog box found in most operating systems. When you 60/// choose to open a file, and the "Open File" dialog pops up, you can no longer 61/// send input to the application, and must complete or cancel the open file 62/// request. Torque keeps track of layers of dialogs. The dialog with the highest 63/// layer is on top and will get all the input, unless the dialog is 64/// modeless, which is a profile option. 65/// 66/// @see GuiControlProfile 67/// 68/// @section GuiCanvas_dirty Dirty Rectangles 69/// 70/// The GuiCanvas is based on dirty regions. 71/// 72/// Every frame the canvas paints only the areas of the canvas that are 'dirty' 73/// or need updating. In most cases, this only is the area under the mouse cursor. 74/// This is why if you look in guiCanvas.cc the call to glClear is commented out. 75/// If you want a really good idea of what exactly dirty regions are and how they 76/// work, un-comment that glClear line in the renderFrame method of guiCanvas.cc 77/// 78/// What you will see is a black screen, except in the dirty regions, where the 79/// screen will be painted normally. If you are making an animated GuiControl 80/// you need to add your control to the dirty areas of the canvas. 81/// 82class guiCanvas; 83typedef Signal<void(GuiCanvas* canvas)> CanvasSizeChangeSignal; 84class GuiCanvas : public GuiControl, public IProcessInput 85{ 86 87protected: 88 typedef GuiControl Parent; 89 90 /// @name Rendering 91 /// @{ 92 RectI mOldUpdateRects[2]; 93 RectI mCurUpdateRect; 94 U32 mLastRenderMs; 95 /// @} 96 97 /// @name Cursor Properties 98 /// @{ 99 100 bool mCursorEnabled; 101 bool mShowCursor; 102 bool mRenderFront; 103 Point2F mCursorPt; ///< Current cursor position in local coordinates. 104 Point2I mLastCursorPt; 105 GuiCursor *mDefaultCursor; 106 GuiCursor *mLastCursor; 107 bool mLastCursorEnabled; 108 bool mForceMouseToGUI; 109 bool mClampTorqueCursor; 110 bool mAlwaysHandleMouseButtons; 111 112 bool mDisplayWindow; 113 114 /// @} 115 116 /// @name Mouse Input 117 /// @{ 118 119 SimObjectPtr<GuiControl> mMouseCapturedControl; ///< All mouse events will go to this ctrl only 120 SimObjectPtr<GuiControl> mMouseControl; ///< the control the mouse was last seen in unless some other one captured it 121 bool mMouseControlClicked; ///< whether the current ctrl has been clicked - used by helpctrl 122 U32 mPrevMouseTime; ///< this determines how long the mouse has been in the same control 123 bool mMouseButtonDown; ///< Flag to determine if the button is depressed 124 bool mMouseRightButtonDown; ///< bool to determine if the right button is depressed 125 bool mMouseMiddleButtonDown; ///< Middle button flag 126 GuiEvent mLastEvent; 127 128 U8 mLastMouseClickCount; 129 S32 mLastMouseDownTime; 130 bool mLeftMouseLast; 131 bool mMiddleMouseLast; 132 bool mRightMouseLast; 133 Point2F mMouseDownPoint; 134 135 /// Processes keyboard input events. Helper method for processInputEvent 136 /// 137 /// \param inputEvent Information on the input even to be processed. 138 /// \return True if the event was handled or false if it was not. 139 virtual bool processKeyboardEvent(InputEventInfo &inputEvent); 140 141 /// Processes mouse input events. Helper method for processInputEvent 142 /// 143 /// \param inputEvent Information on the input even to be processed. 144 /// \return True if the event was handled or false if it was not. 145 virtual bool processMouseEvent(InputEventInfo &inputEvent); 146 147 /// Processes gamepad input events. Helper method for processInputEvent 148 /// 149 /// \param inputEvent Information on the input even to be processed. 150 /// \return True if the event was handled or false if it was not. 151 virtual bool processGamepadEvent(InputEventInfo &inputEvent); 152 153 virtual void findMouseControl(const GuiEvent &event); 154 virtual void refreshMouseControl(); 155 /// @} 156 157 /// @name Keyboard Input 158 /// @{ 159 160 /// Accelerator key map 161 struct AccKeyMap 162 { 163 GuiControl *ctrl; 164 U32 index; 165 U32 keyCode; 166 U32 modifier; 167 }; 168 Vector <AccKeyMap> mAcceleratorMap; 169 170 //for tooltip rendering 171 U32 mHoverControlStart; 172 GuiControl* mHoverControl; 173 Point2I mHoverPosition; 174 bool mHoverPositionSet; 175 U32 mHoverLeftControlTime; 176 177 /// @} 178 179 // Internal event handling callbacks for use with PlatformWindow. 180 void handleResize (WindowId did, S32 width, S32 height); 181 void handleAppEvent (WindowId did, S32 event); 182 void handlePaintEvent (WindowId did); 183 184 PlatformWindow *mPlatformWindow; 185 GFXFence **mFences; 186 S32 mNextFenceIdx; 187 S32 mNumFences; 188 189 static bool setProtectedNumFences( void *object, const char *index, const char *data ); 190 virtual void setupFences(); 191 192 void checkLockMouseMove( const GuiEvent& event ); 193 //Signal used to let others know this canvas has changed size. 194 static CanvasSizeChangeSignal smCanvasSizeChangeSignal; 195 196 GuiControl *mMenuBarCtrl; 197 198public: 199 DECLARE_CONOBJECT(GuiCanvas); 200 DECLARE_CATEGORY( "Gui Core" ); 201 202 GuiCanvas(); 203 virtual ~GuiCanvas(); 204 205 virtual bool onAdd(); 206 virtual void onRemove(); 207 208 void setMenuBar(SimObject *obj); 209 210 static void initPersistFields(); 211 212 static CanvasSizeChangeSignal& getCanvasSizeChangeSignal() { return smCanvasSizeChangeSignal; } 213 214 /// @name Rendering methods 215 /// 216 /// @{ 217 218 /// Repaints the dirty regions of the canvas 219 /// @param preRenderOnly If set to true, only the onPreRender methods of all the GuiControls will be called 220 /// @param bufferSwap If set to true, it will swap buffers at the end. This is to support canvas-subclassing. 221 virtual void renderFrame(bool preRenderOnly, bool bufferSwap = true); 222 223 /// Repaints the canvas by calling the platform window display event. 224 virtual void paint(); 225 226 /// Repaints the canvas skipping rendering if the target time 227 /// has not yet elapsed. 228 /// @param elapsedMS The time since the last frame. 229 virtual void repaint(U32 elapsedMS); 230 231 /// This signal is triggered at the beginning and end of each render frame 232 /// 233 /// @param beginFrame true at the beginning of the frame, false at the end 234 /// 235 typedef Signal <void ( bool beginFrame )> GuiCanvasFrameSignal; 236 237 static GuiCanvasFrameSignal& getGuiCanvasFrameSignal(); 238 239 /// Adds a dirty area to the canvas so it will be updated on the next frame 240 /// @param pos Screen-coordinates of the upper-left hand corner of the dirty area 241 /// @param ext Width/height of the dirty area 242 virtual void addUpdateRegion(Point2I pos, Point2I ext); 243 244 /// Resets the update regions so that the next call to renderFrame will 245 /// repaint the whole canvas 246 virtual void resetUpdateRegions(); 247 248 /// Resizes the content control to match the canvas size. 249 void maintainSizing(); 250 251 /// This builds a rectangle which encompasses all of the dirty regions to be 252 /// repainted 253 /// @param updateUnion (out) Rectangle which surrounds all dirty areas 254 virtual void buildUpdateUnion(RectI *updateUnion); 255 256 /// This will swap the buffers at the end of renderFrame. It was added for canvas 257 /// sub-classes in case they wanted to do some custom code before the buffer 258 /// flip occured. 259 virtual void swapBuffers(); 260 261 /// @} 262 263 /// @name Canvas Content Management 264 /// @{ 265 266 /// This returns the PlatformWindow owned by this Canvas 267 virtual PlatformWindow *getPlatformWindow() 268 { 269 return mPlatformWindow; 270 } 271 272 /// This sets the content control to something different 273 /// @param gui New content control 274 virtual void setContentControl(GuiControl *gui); 275 276 /// Returns the content control 277 virtual GuiControl *getContentControl(); 278 279 /// Adds a dialog control onto the stack of dialogs 280 /// @param gui Dialog to add 281 /// @param layer Layer to put dialog on 282 /// @param center Center dialog on canvas. 283 virtual void pushDialogControl(GuiControl *gui, S32 layer = 0, bool center = false); 284 285 /// Removes a specific layer of dialogs 286 /// @param layer Layer to pop off from 287 virtual void popDialogControl(S32 layer = 0); 288 289 /// Removes a specific dialog control 290 /// @param gui Dialog to remove from the dialog stack 291 virtual void popDialogControl(GuiControl *gui); 292 ///@} 293 294 /// This turns on/off front-buffer rendering 295 /// @param front True if all rendering should be done to the front buffer 296 virtual void setRenderFront(bool front) { mRenderFront = front; } 297 298 /// @name Cursor commands 299 /// A cursor can be on, but not be shown. If a cursor is not on, than it does not 300 /// process input. 301 /// @{ 302 303 /// Sets the cursor for the canvas. 304 /// @param cursor New cursor to use. 305 virtual void setCursor(GuiCursor *cursor); 306 S32 mCursorChanged; 307 308 /// Returns true if the cursor is on. 309 virtual bool isCursorON() { return mCursorEnabled; } 310 311 /// Sets if mouse events should be passed to the GUI even if the cursor is off. 312 /// @param onOff True if events should be passed to the GUI if the cursor is off 313 virtual void setForceMouseToGUI(bool onOff); 314 315 /// Sets if the Torque cursor should be clamped to the window. 316 /// @param onOff True if the Torque cursor should be clamped against the window 317 virtual void setClampTorqueCursor(bool onOff); 318 319 /// Returns if the Torque cursor is clamped to the window 320 virtual bool getClampTorqueCursor() { return mClampTorqueCursor; } 321 322 /// Turns the cursor on or off. 323 /// @param onOff True if the cursor should be on. 324 virtual void setCursorON(bool onOff); 325 326 /// Sets the position of the cursor 327 /// @param pt Point, in screenspace for the cursor 328 virtual void setCursorPos(const Point2I &pt); 329 330 /// Returns the point, in screenspace, at which the cursor is located. 331 virtual Point2I getCursorPos(); 332 333 /// Enable/disable rendering of the cursor. 334 /// @param state True if we should render cursor 335 virtual void showCursor(bool state); 336 337 /// Returns true if the cursor is being rendered. 338 virtual bool isCursorShown(); 339 340 void cursorClick(S32 buttonId, bool isDown); 341 342 void cursorNudge(F32 x, F32 y); 343 /// @} 344 345 ///used by the tooltip resource 346 Point2I getCursorExtent() { return mDefaultCursor->getExtent(); } 347 348 /// @name Input Processing 349 /// @{ 350 351 /// Processes an input event 352 /// @see InputEvent 353 /// @param event Input event to process 354 virtual bool processInputEvent(InputEventInfo &inputEvent); 355 /// @} 356 357 /// @name Mouse Methods 358 /// @{ 359 360 /// When a control gets the mouse lock this means that that control gets 361 /// ALL mouse input and no other control receives any input. 362 /// @param lockingControl Control to lock mouse to 363 virtual void mouseLock(GuiControl *lockingControl); 364 365 /// Unlocks the mouse from a control 366 /// @param lockingControl Control to unlock from 367 virtual void mouseUnlock(GuiControl *lockingControl); 368 369 /// Returns the control which the mouse is over 370 virtual GuiControl* getMouseControl() { return mMouseControl; } 371 372 /// Returns the control which the mouse is locked to if any 373 virtual GuiControl* getMouseLockedControl() { return mMouseCapturedControl; } 374 375 /// Returns true if the left mouse button is down 376 virtual bool mouseButtonDown(void) { return mMouseButtonDown; } 377 378 /// Returns true if the right mouse button is down 379 virtual bool mouseRightButtonDown(void) { return mMouseRightButtonDown; } 380 381 /// @} 382 383 /// @name Mouse input methods 384 /// These events process the events before passing them down to the 385 /// controls they effect. This allows for things such as the input 386 /// locking and such. 387 /// 388 /// Each of these methods corresponds to the action in it's method name 389 /// and processes the GuiEvent passed as a parameter 390 /// @{ 391 virtual void rootMouseUp(const GuiEvent &event); 392 virtual void rootMouseDown(const GuiEvent &event); 393 virtual void rootMouseMove(const GuiEvent &event); 394 virtual void rootMouseDragged(const GuiEvent &event); 395 396 virtual void rootRightMouseDown(const GuiEvent &event); 397 virtual void rootRightMouseUp(const GuiEvent &event); 398 virtual void rootRightMouseDragged(const GuiEvent &event); 399 400 virtual void rootMiddleMouseDown(const GuiEvent &event); 401 virtual void rootMiddleMouseUp(const GuiEvent &event); 402 virtual void rootMiddleMouseDragged(const GuiEvent &event); 403 404 virtual bool rootMouseWheelUp(const GuiEvent &event); 405 virtual bool rootMouseWheelDown(const GuiEvent &event); 406 /// @} 407 408 /// @name Keyboard input methods 409 /// First responders 410 /// 411 /// A first responder is a the GuiControl which responds first to input events 412 /// before passing them off for further processing. 413 /// @{ 414 415 /// Moves the first responder to the next tabable controle 416 virtual bool tabNext(void); 417 418 /// Moves the first responder to the previous tabable control 419 virtual bool tabPrev(void); 420 421 /// Setups a keyboard accelerator which maps to a GuiControl. 422 /// 423 /// @param ctrl GuiControl to map to. 424 /// @param index 425 /// @param keyCode Key code. 426 /// @param modifier Shift, ctrl, etc. 427 virtual void addAcceleratorKey(GuiControl *ctrl, U32 index, U32 keyCode, U32 modifier); 428 429 /// Sets the first responder. 430 /// @param firstResponder Control to designate as first responder 431 virtual void setFirstResponder(GuiControl *firstResponder); 432 433 /// This is used to toggle processing of native OS accelerators, not 434 /// to be confused with the Torque accelerator key system, to keep them 435 /// from swallowing up keystrokes. Both GuiTextEditCtrl and GuiTextPadCtrl 436 /// use this method. 437 virtual void setNativeAcceleratorsEnabled( bool enabled ); 438 /// @} 439 440 /// 441 virtual Point2I getWindowSize(); 442 443 virtual void enableKeyboardTranslation(); 444 virtual void disableKeyboardTranslation(); 445 446 virtual void setWindowTitle(const char *newTitle); 447 448private: 449 static const U32 MAX_GAMEPADS = 4; ///< The maximum number of supported gamepads 450}; 451 452#endif 453
