platformWindow.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 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 _WINDOWMANAGER_PLATFORMWINDOW_H_
  23. #define _WINDOWMANAGER_PLATFORMWINDOW_H_
  24. #include "math/mRect.h"
  25. #include "core/util/journal/journaledSignal.h"
  26. #include "core/util/safeDelete.h"
  27. #include "windowManager/platformCursorController.h"
  28. #include "windowManager/windowInputGenerator.h"
  29. #ifndef _SIGNAL_H_ //Volumetric Fog
  30. #include "core/util/tSignal.h"
  31. #endif
  32. //forward decl's
  33. class PlatformWindowManager;
  34. class GFXDevice;
  35. struct GFXVideoMode;
  36. class GFXWindowTarget;
  37. class IProcessInput;
  38. typedef Signal<void(PlatformWindow *PlatformWindow, bool resize)> ScreenResChangeSignal;
  39. /// Abstract representation of a native OS window.
  40. ///
  41. /// Every windowing system has its own representations and conventions as
  42. /// regards the windows on-screen. In order to provide Torque with means for
  43. /// interfacing with multiple windows, tracking their state, etc. we provide
  44. /// this interface.
  45. ///
  46. /// This interface also allows the app to access the render target for the
  47. /// window it represents, as well as control mode switches, get mode info,
  48. /// and so on.
  49. ///
  50. /// @see PlatformWindowManager
  51. class PlatformWindow
  52. {
  53. friend class PlatformWindowManager;
  54. protected:
  55. /// Are we enabling IME or other keyboard input translation services,
  56. /// or concerned about raw input?
  57. bool mEnableKeyboardTranslation;
  58. /// When Torque GuiText input controls have focus they need to
  59. /// disable native OS keyboard accelerator translation.
  60. bool mEnableAccelerators;
  61. /// Minimum allowed size for this window. When possible, we will communicate
  62. /// this to the OS.
  63. Point2I mMinimumSize;
  64. /// When the resize is locked, this will be used as both minimum and maximum window size
  65. Point2I mLockedSize;
  66. /// When this is true, resizing is locked
  67. bool mResizeLocked;
  68. /// Is Idle?
  69. bool mIsBackground;
  70. /// Cursor Controller for this Window
  71. PlatformCursorController *mCursorController;
  72. /// An opaque ID used to resolve references to this Window
  73. WindowId mWindowId;
  74. /// Window Mouse/Key input Controller for this Window
  75. WindowInputGenerator *mWindowInputGenerator;
  76. /// Suppress device resets
  77. bool mSuppressReset;
  78. /// Offscreen Render
  79. bool mOffscreenRender;
  80. /// This is set as part of the canvas being shown, and flags that the windows should render as normal from now on.
  81. // Basically a flag that lets the window manager know that we've handled the splash screen, and to operate as normal.
  82. bool mDisplayWindow;
  83. /// Protected constructor so that the win
  84. PlatformWindow()
  85. {
  86. mIsBackground = false; // This could be toggled to true to prefer performance.
  87. mMinimumSize.set(0,0);
  88. mLockedSize.set(0,0);
  89. mResizeLocked = false;
  90. mEnableKeyboardTranslation = false;
  91. mEnableAccelerators = true;
  92. mCursorController = NULL;
  93. mSuppressReset = false;
  94. mOffscreenRender = false;
  95. mDisplayWindow = false;
  96. // This controller maps window input (Mouse/Keyboard) to a generic input consumer
  97. mWindowInputGenerator = new WindowInputGenerator( this );
  98. }
  99. static ScreenResChangeSignal smScreenResChangeSignal;
  100. public:
  101. /// To get rid of a window, just delete it. Make sure the GFXDevice is
  102. /// done with it first!
  103. virtual ~PlatformWindow()
  104. {
  105. SAFE_DELETE( mCursorController );
  106. SAFE_DELETE( mWindowInputGenerator );
  107. }
  108. /// Get the WindowController associated with this window
  109. virtual void setInputController( IProcessInput *controller ) { if( mWindowInputGenerator ) mWindowInputGenerator->setInputController( controller ); };
  110. WindowInputGenerator* getInputGenerator() const { return mWindowInputGenerator; }
  111. /// Get the ID that uniquely identifies this window in the context of its
  112. /// window manager.
  113. virtual WindowId getWindowId() { return 0; };
  114. enum WindowSystem
  115. {
  116. WindowSystem_Unknown = 0,
  117. WindowSystem_Windows,
  118. WindowSystem_X11,
  119. };
  120. virtual void* getSystemWindow(const WindowSystem system) { return NULL; }
  121. /// Set the flag that determines whether to suppress a GFXDevice reset
  122. inline void setSuppressReset(bool suppress) { mSuppressReset = suppress; };
  123. /// @name GFX State Management
  124. ///
  125. /// @{
  126. /// Return a pointer to the GFX device this window is bound to. A GFX
  127. /// device may use many windows, but a window can only be used by a
  128. /// single GFX device.
  129. virtual GFXDevice *getGFXDevice()=0;
  130. /// Return a pointer to this window's render target.
  131. ///
  132. /// By setting window targets from different windows, we can effect
  133. /// rendering to multiple windows from a single device.
  134. virtual GFXWindowTarget *getGFXTarget()=0;
  135. /// Set the video mode for this window.
  136. virtual void setVideoMode(const GFXVideoMode &mode);
  137. /// Get our current video mode - if the window has been resized, it will
  138. /// reflect this.
  139. virtual const GFXVideoMode &getVideoMode()=0;
  140. /// If we're fullscreen, this function returns us to desktop mode.
  141. ///
  142. /// This will be either the last mode that we had that was not
  143. /// fullscreen, or the equivalent mode, windowed.
  144. virtual bool clearFullscreen()=0;
  145. /// @return true if this window is fullscreen, false otherwise.
  146. virtual bool isFullscreen()=0;
  147. /// Acquire the entire screen
  148. void setFullscreen(const bool fullscreen);
  149. /// Set Idle State (Background)
  150. ///
  151. /// This is called to put a window into idle state, which causes it's
  152. /// rendering priority to be toned down to prefer performance
  153. virtual void setBackground( bool val ) { mIsBackground = val; };
  154. /// Get Idle State (Background)
  155. ///
  156. /// This is called to poll the window as to it's idle state.
  157. virtual bool getBackground() { return mIsBackground; };
  158. /// Set whether this window is intended for offscreen rendering
  159. /// An offscreen window will never be shown or lose focus
  160. virtual void setOffscreenRender(bool val ) { mOffscreenRender = val; };
  161. /// Set whether this window is intended for offscreen rendering
  162. ///
  163. /// This is called to poll the window as to it's idle state.
  164. virtual bool getOffscreenRender() { return mOffscreenRender; };
  165. /// Set whether this window is should display as normal
  166. virtual void setDisplayWindow(bool val ) { mDisplayWindow = val; };
  167. /// Set Focused State (Foreground)
  168. ///
  169. /// Claim OS input focus for this window
  170. virtual void setFocus() { }
  171. /// @}
  172. /// @name Caption
  173. ///
  174. /// @{
  175. /// Set the window's caption.
  176. virtual bool setCaption(const char *cap)=0;
  177. /// Get the window's caption.
  178. virtual const char *getCaption()=0;
  179. /// @}
  180. /// @name Visibility
  181. ///
  182. /// Control how the window is displayed
  183. /// @{
  184. /// Minimize the window on screen
  185. virtual void minimize()=0;
  186. /// Maximize the window on screen
  187. virtual void maximize()=0;
  188. /// Hide the window on screen
  189. virtual void hide()=0;
  190. /// Show the window on screen
  191. virtual void show()=0;
  192. /// Destroy the window on screen
  193. virtual void close()=0;
  194. /// Restore the window from a Maximized or Minimized state
  195. virtual void restore()=0;
  196. /// @}
  197. /// @name Window Bounds
  198. ///
  199. /// @{
  200. /// The Client Rectangle or "Render Area" of a window is the area that
  201. /// is occupied by a given client that is rendering to that window.
  202. /// This does not include the area occupied by a title-bar, menu,
  203. /// borders or other non-client elements.
  204. /// @{
  205. /// Set the Client Area Extent (Resolution) of this window
  206. virtual void setClientExtent( const Point2I newExtent ) = 0;
  207. /// Get the Client Area Extent (Resolution) of this window
  208. virtual const Point2I getClientExtent() = 0;
  209. /// @}
  210. /// The bounds of a Window are defined as the entire area occupied by
  211. /// that Window. This includes the area needed for a title-bar, menu,
  212. /// borders, and other non-client elements.
  213. ///
  214. /// @{
  215. /// Resize the window to have some new bounds.
  216. virtual void setBounds( const RectI &newBounds ) = 0;
  217. /// Get the position and size (fullscreen windows are always at (0,0)).
  218. virtual const RectI getBounds() const = 0;
  219. /// @}
  220. /// The Position of a window is always in relation to the very upper left
  221. /// of the window. This means that saying setPosition at 0,0 will put the
  222. /// position of the window title-bar (if one exists) at 0,0 and the Client
  223. /// area will be offset from that point by the space needed for the Non-Client
  224. /// area.
  225. /// @{
  226. /// Set the position of this window
  227. virtual void setPosition( const Point2I newPosition ) = 0;
  228. /// Get the position of this window
  229. virtual const Point2I getPosition() = 0;
  230. virtual void centerWindow() {};
  231. /// Resize the window to have a new size (but be in the same position).
  232. virtual bool setSize(const Point2I &newSize)=0;
  233. /// @}
  234. /// @name Coordinate Space Conversion
  235. /// @{
  236. /// Convert the coordinate given in this window space to screen coordinates.
  237. virtual Point2I clientToScreen( const Point2I& point ) = 0;
  238. /// Convert the given screen coordinates to coordinates in this window space.
  239. virtual Point2I screenToClient( const Point2I& point ) = 0;
  240. /// @}
  241. /// @name Windowed state
  242. ///
  243. /// This is only really meaningful if the window is not fullscreen.
  244. ///
  245. /// @{
  246. /// Returns true if the window is instantiated in the OS.
  247. virtual bool isOpen() = 0;
  248. /// Returns true if the window is visible.
  249. virtual bool isVisible() = 0;
  250. /// Returns true if the window has input focus
  251. virtual bool isFocused() = 0;
  252. /// Returns true if the window is minimized
  253. virtual bool isMinimized() = 0;
  254. /// Returns true if the window is maximized
  255. virtual bool isMaximized() = 0;
  256. /// @name Keyboard Translation
  257. ///
  258. /// When keyboard translation is on, keypress events that correspond to character input
  259. /// should be send as character input events rather than as raw key events *except* if
  260. /// shouldNotTranslate() returns true for a specific keypress event. This enables the
  261. /// platform layer to perform platform-specific character input mapping.
  262. ///
  263. /// @{
  264. /// Set if relevant keypress events should be translated into character input events.
  265. virtual void setKeyboardTranslation(const bool enabled)
  266. {
  267. mEnableKeyboardTranslation = enabled;
  268. }
  269. /// Returns true if keyboard translation is enabled.
  270. virtual bool getKeyboardTranslation() const
  271. {
  272. return mEnableKeyboardTranslation;
  273. }
  274. /// Returns true if the given keypress event should not be translated.
  275. virtual bool shouldNotTranslate( U32 modifiers, U32 keyCode ) const;
  276. /// @}
  277. /// Used to disable native OS keyboard accelerators.
  278. virtual void setAcceleratorsEnabled(const bool enabled)
  279. {
  280. mEnableAccelerators = enabled;
  281. }
  282. /// Returns true if native OS keyboard accelerators are enabled.
  283. virtual bool getAcceleratorsEnabled() const
  284. {
  285. return mEnableAccelerators;
  286. }
  287. /// Sets a minimum window size. We'll work with the OS to prevent user
  288. /// from sizing the window to less than this. Setting to (0,0) means
  289. /// user has complete freedom of resize.
  290. virtual void setMinimumWindowSize(Point2I minSize)
  291. {
  292. mMinimumSize = minSize;
  293. }
  294. /// Returns the current minimum window size for this window.
  295. virtual Point2I getMinimumWindowSize()
  296. {
  297. return mMinimumSize;
  298. }
  299. /// Locks/unlocks window resizing
  300. virtual void lockSize(bool locked)
  301. {
  302. mResizeLocked = locked;
  303. if (mResizeLocked)
  304. mLockedSize = getBounds().extent;
  305. }
  306. /// Returns true if the window size is locked
  307. virtual bool isSizeLocked()
  308. {
  309. return mResizeLocked;
  310. }
  311. /// Returns the locked window size
  312. virtual Point2I getLockedSize()
  313. {
  314. return mLockedSize;
  315. }
  316. /// @}
  317. /// @name Window Cursor
  318. ///
  319. /// Accessors to control a windows cursor shape and visibility
  320. ///
  321. /// @{
  322. /// Get the CursorController that this window owns.
  323. virtual PlatformCursorController *getCursorController() { return mCursorController; };
  324. /// Set the cursor position based on logical coordinates from the upper-right corner
  325. ///
  326. /// @param x The X position of the cursor
  327. /// @param y The Y position of the cursor
  328. virtual void setCursorPosition(S32 x, S32 y)
  329. {
  330. if( mCursorController != NULL )
  331. mCursorController->setCursorPosition(x,y);
  332. }
  333. /// Get the cursor position based on logical coordinates from the upper-right corner
  334. ///
  335. /// @param point A reference to a Point2I to store the coordinates
  336. virtual void getCursorPosition( Point2I &point )
  337. {
  338. if( mCursorController != NULL )
  339. mCursorController->getCursorPosition(point);
  340. }
  341. /// Set the cursor visibility on this window
  342. ///
  343. /// @param visible Whether the cursor should be visible or not
  344. virtual void setCursorVisible(bool visible)
  345. {
  346. if( mCursorController != NULL )
  347. mCursorController->setCursorVisible(visible);
  348. }
  349. /// Get the cursor visibility on this window
  350. ///
  351. /// @return true if the cursor is visible or false if it's hidden
  352. virtual bool isCursorVisible()
  353. {
  354. if( mCursorController != NULL )
  355. return mCursorController->isCursorVisible();
  356. return false;
  357. }
  358. /// Lock the mouse to this window.
  359. ///
  360. /// When this is set, the mouse will always be returned to the center
  361. /// of the client area after every mouse event. The mouse will also be
  362. /// hidden while it is locked.
  363. ///
  364. /// The mouse cannot be moved out of the bounds of the window, but the
  365. /// window may lose focus (for instance by an alt-tab or other event).
  366. /// While the window lacks focus, no mouse events will be reported.
  367. virtual void setMouseLocked( bool enable )=0;
  368. /// Is the mouse locked ?
  369. virtual bool isMouseLocked() const = 0;
  370. /// Should the mouse be locked at the next opportunity ?
  371. ///
  372. /// This flag is set to the current state of the mouse lock
  373. /// on a window, to specify the preferred lock status of the
  374. /// mouse in a platform window.
  375. ///
  376. /// This is important for situations where a call is made
  377. /// to setMouseLocked, and the window is not in a state that
  378. /// it can be cleanly locked. Take for example if it was called
  379. /// while the window is in the background, then it is not appropriate
  380. /// to lock the window, but rather the window should query this
  381. /// state at it's next opportunity and lock the mouse if requested.
  382. virtual bool shouldLockMouse() const = 0;
  383. /// @}
  384. virtual PlatformWindow * getNextWindow() const = 0;
  385. /// @name Event Handlers
  386. ///
  387. /// Various events that this window receives. These are all subclasses of
  388. /// JournaledSignal, so you can subscribe to them and receive notifications
  389. /// per the documentation for that class.
  390. ///
  391. /// @{
  392. ///
  393. AppEvent appEvent;
  394. MouseEvent mouseEvent;
  395. MouseWheelEvent wheelEvent;
  396. ButtonEvent buttonEvent;
  397. LinearEvent linearEvent;
  398. KeyEvent keyEvent;
  399. CharEvent charEvent;
  400. DisplayEvent displayEvent;
  401. ResizeEvent resizeEvent;
  402. IdleEvent idleEvent;
  403. /// @}
  404. static ScreenResChangeSignal& getScreenResChangeSignal() { return smScreenResChangeSignal; }
  405. /// Get the platform specific object needed to create or attach an accelerated
  406. /// graohics drawing context on or to the window
  407. /// Win32 D3D and OpenGL typically needs an HWND
  408. /// Mac Cocoa OpenGL typically needs an NSOpenGLView
  409. /// Mac Carbon OpenGL typically needs a WindowRef
  410. ///
  411. virtual void* getPlatformDrawable() const = 0;
  412. protected:
  413. virtual void _setFullscreen(const bool fullScreen) {};
  414. virtual void _setVideoMode(const GFXVideoMode &mode) = 0;
  415. };
  416. #endif