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