2
0

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