123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
- // Copyright (C) 2015 Faust Logic, Inc.
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- #ifndef _GUICANVAS_H_
- #define _GUICANVAS_H_
- #ifndef _SIMBASE_H_
- #include "console/simBase.h"
- #endif
- #ifndef _GUICONTROL_H_
- #include "gui/core/guiControl.h"
- #endif
- #ifndef _PLATFORMINPUT_H_
- #include "platform/platformInput.h"
- #endif
- #ifndef _SIGNAL_H_
- #include "core/util/tSignal.h"
- #endif
- #include "platform/input/IProcessInput.h"
- #include "windowManager/platformWindowMgr.h"
- #include "gfx/gfxFence.h"
- /// A canvas on which rendering occurs.
- ///
- ///
- /// @section GuiCanvas_contents What a GUICanvas Can Contain...
- ///
- /// @subsection GuiCanvas_content_contentcontrol Content Control
- /// A content control is the top level GuiControl for a screen. This GuiControl
- /// will be the parent control for all other GuiControls on that particular
- /// screen.
- ///
- /// @subsection GuiCanvas_content_dialogs Dialogs
- ///
- /// A dialog is essentially another screen, only it gets overlaid on top of the
- /// current content control, and all input goes to the dialog. This is most akin
- /// to the "Open File" dialog box found in most operating systems. When you
- /// choose to open a file, and the "Open File" dialog pops up, you can no longer
- /// send input to the application, and must complete or cancel the open file
- /// request. Torque keeps track of layers of dialogs. The dialog with the highest
- /// layer is on top and will get all the input, unless the dialog is
- /// modeless, which is a profile option.
- ///
- /// @see GuiControlProfile
- ///
- /// @section GuiCanvas_dirty Dirty Rectangles
- ///
- /// The GuiCanvas is based on dirty regions.
- ///
- /// Every frame the canvas paints only the areas of the canvas that are 'dirty'
- /// or need updating. In most cases, this only is the area under the mouse cursor.
- /// This is why if you look in guiCanvas.cc the call to glClear is commented out.
- /// If you want a really good idea of what exactly dirty regions are and how they
- /// work, un-comment that glClear line in the renderFrame method of guiCanvas.cc
- ///
- /// What you will see is a black screen, except in the dirty regions, where the
- /// screen will be painted normally. If you are making an animated GuiControl
- /// you need to add your control to the dirty areas of the canvas.
- ///
- class guiCanvas;
- typedef Signal<void(GuiCanvas* canvas)> CanvasSizeChangeSignal;
- class GuiCanvas : public GuiControl, public IProcessInput
- {
- protected:
- typedef GuiControl Parent;
- /// @name Rendering
- /// @{
- RectI mOldUpdateRects[2];
- RectI mCurUpdateRect;
- U32 mLastRenderMs;
- /// @}
- /// @name Cursor Properties
- /// @{
- bool mCursorEnabled;
- bool mShowCursor;
- bool mRenderFront;
- Point2F mCursorPt; ///< Current cursor position in local coordinates.
- Point2I mLastCursorPt;
- GuiCursor *mDefaultCursor;
- GuiCursor *mLastCursor;
- bool mLastCursorEnabled;
- bool mForceMouseToGUI;
- bool mClampTorqueCursor;
- bool mAlwaysHandleMouseButtons;
- bool mDisplayWindow;
- /// @}
- /// @name Mouse Input
- /// @{
- SimObjectPtr<GuiControl> mMouseCapturedControl; ///< All mouse events will go to this ctrl only
- SimObjectPtr<GuiControl> mMouseControl; ///< the control the mouse was last seen in unless some other one captured it
- bool mMouseControlClicked; ///< whether the current ctrl has been clicked - used by helpctrl
- U32 mPrevMouseTime; ///< this determines how long the mouse has been in the same control
- bool mMouseButtonDown; ///< Flag to determine if the button is depressed
- bool mMouseRightButtonDown; ///< bool to determine if the right button is depressed
- bool mMouseMiddleButtonDown; ///< Middle button flag
- GuiEvent mLastEvent;
- U8 mLastMouseClickCount;
- S32 mLastMouseDownTime;
- bool mLeftMouseLast;
- bool mMiddleMouseLast;
- bool mRightMouseLast;
- Point2F mMouseDownPoint;
- /// Processes keyboard input events. Helper method for processInputEvent
- ///
- /// \param inputEvent Information on the input even to be processed.
- /// \return True if the event was handled or false if it was not.
- virtual bool processKeyboardEvent(InputEventInfo &inputEvent);
- /// Processes mouse input events. Helper method for processInputEvent
- ///
- /// \param inputEvent Information on the input even to be processed.
- /// \return True if the event was handled or false if it was not.
- virtual bool processMouseEvent(InputEventInfo &inputEvent);
- /// Processes gamepad input events. Helper method for processInputEvent
- ///
- /// \param inputEvent Information on the input even to be processed.
- /// \return True if the event was handled or false if it was not.
- virtual bool processGamepadEvent(InputEventInfo &inputEvent);
- virtual void findMouseControl(const GuiEvent &event);
- virtual void refreshMouseControl();
- /// @}
- /// @name Keyboard Input
- /// @{
- /// Accelerator key map
- struct AccKeyMap
- {
- GuiControl *ctrl;
- U32 index;
- U32 keyCode;
- U32 modifier;
- };
- Vector <AccKeyMap> mAcceleratorMap;
- //for tooltip rendering
- U32 mHoverControlStart;
- GuiControl* mHoverControl;
- Point2I mHoverPosition;
- bool mHoverPositionSet;
- U32 mHoverLeftControlTime;
- public:
- /// Setting for how to handle 'enableKeyboardTranslation' and 'setNativeAcceleratorsEnabled' requests.
- enum KeyTranslationMode
- {
- TranslationMode_Platform,
- TranslationMode_Callback,
- TranslationMode_Ignore,
- };
- protected:
- KeyTranslationMode mKeyTranslationMode;
- KeyTranslationMode mNativeAcceleratorMode;
- /// @}
- // Internal event handling callbacks for use with PlatformWindow.
- void handleResize (WindowId did, S32 width, S32 height);
- void handleAppEvent (WindowId did, S32 event);
- void handlePaintEvent (WindowId did);
- PlatformWindow *mPlatformWindow;
- GFXFence **mFences;
- S32 mNextFenceIdx;
- S32 mNumFences;
- static bool setProtectedNumFences( void *object, const char *index, const char *data );
- virtual void setupFences();
-
- void checkLockMouseMove( const GuiEvent& event );
- //Signal used to let others know this canvas has changed size.
- static CanvasSizeChangeSignal smCanvasSizeChangeSignal;
- GuiControl *mMenuBarCtrl;
- GuiControl* mMenuBackground;
- public:
- DECLARE_CONOBJECT(GuiCanvas);
- DECLARE_CATEGORY( "Gui Core" );
-
- GuiCanvas();
- virtual ~GuiCanvas();
- virtual bool onAdd();
- virtual void onRemove();
- #ifdef TORQUE_TOOLS
- void setMenuBar(SimObject *obj);
- SimObject* getMenuBar() { return mMenuBarCtrl; }
- #endif
- static void initPersistFields();
- static CanvasSizeChangeSignal& getCanvasSizeChangeSignal() { return smCanvasSizeChangeSignal; }
- /// @name Rendering methods
- ///
- /// @{
- /// Repaints the dirty regions of the canvas
- /// @param preRenderOnly If set to true, only the onPreRender methods of all the GuiControls will be called
- /// @param bufferSwap If set to true, it will swap buffers at the end. This is to support canvas-subclassing.
- virtual void renderFrame(bool preRenderOnly, bool bufferSwap = true);
- /// Repaints the canvas by calling the platform window display event.
- virtual void paint();
- /// Repaints the canvas skipping rendering if the target time
- /// has not yet elapsed.
- /// @param elapsedMS The time since the last frame.
- virtual void repaint(U32 elapsedMS);
- /// This signal is triggered at the beginning and end of each render frame
- ///
- /// @param beginFrame true at the beginning of the frame, false at the end
- ///
- typedef Signal <void ( bool beginFrame )> GuiCanvasFrameSignal;
- static GuiCanvasFrameSignal& getGuiCanvasFrameSignal();
- /// Adds a dirty area to the canvas so it will be updated on the next frame
- /// @param pos Screen-coordinates of the upper-left hand corner of the dirty area
- /// @param ext Width/height of the dirty area
- virtual void addUpdateRegion(Point2I pos, Point2I ext);
- /// Resets the update regions so that the next call to renderFrame will
- /// repaint the whole canvas
- virtual void resetUpdateRegions();
- /// Resizes the content control to match the canvas size.
- void maintainSizing();
- /// This builds a rectangle which encompasses all of the dirty regions to be
- /// repainted
- /// @param updateUnion (out) Rectangle which surrounds all dirty areas
- virtual void buildUpdateUnion(RectI *updateUnion);
- /// This will swap the buffers at the end of renderFrame. It was added for canvas
- /// sub-classes in case they wanted to do some custom code before the buffer
- /// flip occured.
- virtual void swapBuffers();
- /// @}
- /// @name Canvas Content Management
- /// @{
- /// This returns the PlatformWindow owned by this Canvas
- virtual PlatformWindow *getPlatformWindow()
- {
- return mPlatformWindow;
- }
- /// This sets the content control to something different
- /// @param gui New content control
- virtual void setContentControl(GuiControl *gui);
- /// Returns the content control
- virtual GuiControl *getContentControl();
- /// Adds a dialog control onto the stack of dialogs
- /// @param gui Dialog to add
- /// @param layer Layer to put dialog on
- /// @param center Center dialog on canvas.
- virtual void pushDialogControl(GuiControl *gui, S32 layer = 0, bool center = false);
- /// Removes a specific layer of dialogs
- /// @param layer Layer to pop off from
- virtual void popDialogControl(S32 layer = 0);
- /// Removes a specific dialog control
- /// @param gui Dialog to remove from the dialog stack
- virtual void popDialogControl(GuiControl *gui);
- ///@}
- /// This turns on/off front-buffer rendering
- /// @param front True if all rendering should be done to the front buffer
- virtual void setRenderFront(bool front) { mRenderFront = front; }
- /// @name Cursor commands
- /// A cursor can be on, but not be shown. If a cursor is not on, than it does not
- /// process input.
- /// @{
- /// Sets the cursor for the canvas.
- /// @param cursor New cursor to use.
- virtual void setCursor(GuiCursor *cursor);
- S32 mCursorChanged;
- /// Returns true if the cursor is on.
- virtual bool isCursorON() { return mCursorEnabled; }
- /// Sets if mouse events should be passed to the GUI even if the cursor is off.
- /// @param onOff True if events should be passed to the GUI if the cursor is off
- virtual void setForceMouseToGUI(bool onOff);
- /// Sets if the Torque cursor should be clamped to the window.
- /// @param onOff True if the Torque cursor should be clamped against the window
- virtual void setClampTorqueCursor(bool onOff);
- /// Returns if the Torque cursor is clamped to the window
- virtual bool getClampTorqueCursor() { return mClampTorqueCursor; }
- /// Turns the cursor on or off.
- /// @param onOff True if the cursor should be on.
- virtual void setCursorON(bool onOff);
- /// Sets the position of the cursor
- /// @param pt Point, in screenspace for the cursor
- virtual void setCursorPos(const Point2I &pt);
- /// Returns the point, in screenspace, at which the cursor is located.
- virtual Point2I getCursorPos();
- /// Returns the point, in local coordinates, at which the cursor is located
- virtual Point2I getCursorPosLocal() { return Point2I(S32(mCursorPt.x), S32(mCursorPt.y)); }
- /// Enable/disable rendering of the cursor.
- /// @param state True if we should render cursor
- virtual void showCursor(bool state);
- /// Returns true if the cursor is being rendered.
- virtual bool isCursorShown();
- void cursorClick(S32 buttonId, bool isDown);
- void cursorNudge(F32 x, F32 y);
- /// @}
- ///used by the tooltip resource
- Point2I getCursorExtent() { return mDefaultCursor->getExtent(); }
-
- /// @name Input Processing
- /// @{
- /// Processes an input event
- /// @see InputEvent
- /// @param event Input event to process
- virtual bool processInputEvent(InputEventInfo &inputEvent);
- /// @}
- /// @name Mouse Methods
- /// @{
- /// When a control gets the mouse lock this means that that control gets
- /// ALL mouse input and no other control receives any input.
- /// @param lockingControl Control to lock mouse to
- virtual void mouseLock(GuiControl *lockingControl);
- /// Unlocks the mouse from a control
- /// @param lockingControl Control to unlock from
- virtual void mouseUnlock(GuiControl *lockingControl);
- /// Returns the control which the mouse is over
- virtual GuiControl* getMouseControl() { return mMouseControl; }
- /// Returns the control which the mouse is locked to if any
- virtual GuiControl* getMouseLockedControl() { return mMouseCapturedControl; }
- /// Returns true if the left mouse button is down
- virtual bool mouseButtonDown(void) { return mMouseButtonDown; }
- /// Returns true if the right mouse button is down
- virtual bool mouseRightButtonDown(void) { return mMouseRightButtonDown; }
- /// @}
- /// @name Mouse input methods
- /// These events process the events before passing them down to the
- /// controls they effect. This allows for things such as the input
- /// locking and such.
- ///
- /// Each of these methods corresponds to the action in it's method name
- /// and processes the GuiEvent passed as a parameter
- /// @{
- virtual void rootMouseUp(const GuiEvent &event);
- virtual void rootMouseDown(const GuiEvent &event);
- virtual void rootMouseMove(const GuiEvent &event);
- virtual void rootMouseDragged(const GuiEvent &event);
- virtual void rootRightMouseDown(const GuiEvent &event);
- virtual void rootRightMouseUp(const GuiEvent &event);
- virtual void rootRightMouseDragged(const GuiEvent &event);
- virtual void rootMiddleMouseDown(const GuiEvent &event);
- virtual void rootMiddleMouseUp(const GuiEvent &event);
- virtual void rootMiddleMouseDragged(const GuiEvent &event);
- virtual bool rootMouseWheelUp(const GuiEvent &event);
- virtual bool rootMouseWheelDown(const GuiEvent &event);
- /// @}
- /// @name Keyboard input methods
- /// First responders
- ///
- /// A first responder is a the GuiControl which responds first to input events
- /// before passing them off for further processing.
- /// @{
- /// Moves the first responder to the next tabable controle
- virtual bool tabNext(void);
- /// Moves the first responder to the previous tabable control
- virtual bool tabPrev(void);
- /// Setups a keyboard accelerator which maps to a GuiControl.
- ///
- /// @param ctrl GuiControl to map to.
- /// @param index
- /// @param keyCode Key code.
- /// @param modifier Shift, ctrl, etc.
- virtual void addAcceleratorKey(GuiControl *ctrl, U32 index, U32 keyCode, U32 modifier);
- /// Sets the first responder.
- /// @param firstResponder Control to designate as first responder
- virtual void setFirstResponder(GuiControl *firstResponder);
- /// This is used to toggle processing of native OS accelerators, not
- /// to be confused with the Torque accelerator key system, to keep them
- /// from swallowing up keystrokes. Both GuiTextEditCtrl and GuiTextPadCtrl
- /// use this method.
- virtual void setNativeAcceleratorsEnabled( bool enabled );
- /// @}
- ///
- virtual Point2I getWindowSize();
- virtual void enableKeyboardTranslation();
- virtual void disableKeyboardTranslation();
- virtual void setWindowTitle(const char *newTitle);
- DECLARE_CALLBACK(bool, onSetKeyboardTranslationEnabled, (bool enable));
- DECLARE_CALLBACK(bool, onSetNativeAcceleratorsEnabled, (bool enable));
- private:
- static const U32 MAX_GAMEPADS = 4; ///< The maximum number of supported gamepads
- protected:
- bool mConsumeLastInputEvent;
- public:
- void clearMouseRightButtonDown(void) { mMouseRightButtonDown = false; }
- void clearMouseButtonDown(void) { mMouseButtonDown = false; }
- void setConsumeLastInputEvent(bool flag) { mConsumeLastInputEvent = flag; }
- bool getLastCursorPoint(Point2I& pt) const { pt = mLastCursorPt; return mLastCursorEnabled; }
- };
- typedef GuiCanvas::KeyTranslationMode KeyboardTranslationMode;
- DefineEnumType(KeyboardTranslationMode);
- #endif
|