guiCanvas.h

Engine/source/gui/core/guiCanvas.h

More...

Classes:

class

Accelerator key map.

Public Typedefs

Signal< void(GuiCanvas *canvas)>
CanvasSizeChangeSignal 

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