Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
8.6 KiB

  1. //===== Copyright � 1996-2010, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "inputsystem/iinputstacksystem.h"
  7. #include "tier2/tier2.h"
  8. #include "tier1/utlstack.h"
  9. // NOTE: This has to be the last file included!
  10. #include "tier0/memdbgon.h"
  11. //-----------------------------------------------------------------------------
  12. // An input context
  13. //-----------------------------------------------------------------------------
  14. struct InputContext_t
  15. {
  16. InputCursorHandle_t m_hCursorIcon;
  17. bool m_bEnabled;
  18. bool m_bCursorVisible;
  19. bool m_bMouseCaptureEnabled;
  20. };
  21. //-----------------------------------------------------------------------------
  22. // Stack system implementation
  23. //-----------------------------------------------------------------------------
  24. class CInputStackSystem : public CTier2AppSystem< IInputStackSystem >
  25. {
  26. typedef CTier2AppSystem< IInputStackSystem > BaseClass;
  27. // Methods of IAppSystem
  28. public:
  29. virtual const AppSystemInfo_t* GetDependencies();
  30. virtual void Shutdown();
  31. // Methods of IInputStackSystem
  32. public:
  33. virtual InputContextHandle_t PushInputContext();
  34. virtual void PopInputContext( );
  35. virtual void EnableInputContext( InputContextHandle_t hContext, bool bEnable );
  36. virtual void SetCursorVisible( InputContextHandle_t hContext, bool bVisible );
  37. virtual void SetCursorIcon( InputContextHandle_t hContext, InputCursorHandle_t hCursor );
  38. virtual void SetMouseCapture( InputContextHandle_t hContext, bool bEnable );
  39. virtual void SetCursorPosition( InputContextHandle_t hContext, int x, int y );
  40. virtual bool IsTopmostEnabledContext( InputContextHandle_t hContext ) const;
  41. private:
  42. // Updates the cursor based on the current state of the input stack
  43. void UpdateCursorState();
  44. CUtlStack< InputContext_t * > m_ContextStack;
  45. };
  46. //-----------------------------------------------------------------------------
  47. // Singleton instance
  48. //-----------------------------------------------------------------------------
  49. static CInputStackSystem s_InputStackSystem;
  50. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CInputStackSystem, IInputStackSystem,
  51. INPUTSTACKSYSTEM_INTERFACE_VERSION, s_InputStackSystem );
  52. //-----------------------------------------------------------------------------
  53. // Get dependencies
  54. //-----------------------------------------------------------------------------
  55. static AppSystemInfo_t s_Dependencies[] =
  56. {
  57. { "inputsystem" DLL_EXT_STRING, INPUTSYSTEM_INTERFACE_VERSION },
  58. { NULL, NULL }
  59. };
  60. const AppSystemInfo_t* CInputStackSystem::GetDependencies()
  61. {
  62. return s_Dependencies;
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Shutdown
  66. //-----------------------------------------------------------------------------
  67. void CInputStackSystem::Shutdown()
  68. {
  69. // Delete any leaked contexts
  70. while( m_ContextStack.Count() )
  71. {
  72. InputContext_t *pContext = NULL;
  73. m_ContextStack.Pop( pContext );
  74. delete pContext;
  75. }
  76. BaseClass::Shutdown();
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Allocates an input context, pushing it on top of the input stack,
  80. // thereby giving it top priority
  81. //-----------------------------------------------------------------------------
  82. InputContextHandle_t CInputStackSystem::PushInputContext()
  83. {
  84. InputContext_t *pContext = new InputContext_t;
  85. pContext->m_bEnabled = true;
  86. pContext->m_bCursorVisible = true;
  87. pContext->m_bMouseCaptureEnabled = false;
  88. pContext->m_hCursorIcon = g_pInputSystem->GetStandardCursor( INPUT_CURSOR_ARROW );
  89. m_ContextStack.Push( pContext );
  90. UpdateCursorState();
  91. return (InputContextHandle_t)pContext;
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Pops the top input context off the input stack, and destroys it.
  95. //-----------------------------------------------------------------------------
  96. void CInputStackSystem::PopInputContext( )
  97. {
  98. if ( m_ContextStack.Count() == 0 )
  99. return;
  100. InputContext_t *pContext = NULL;
  101. m_ContextStack.Pop( pContext );
  102. delete pContext;
  103. UpdateCursorState();
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Enables/disables an input context, allowing something lower on the
  107. // stack to have control of input. Disabling an input context which
  108. // owns mouse capture
  109. //-----------------------------------------------------------------------------
  110. void CInputStackSystem::EnableInputContext( InputContextHandle_t hContext, bool bEnable )
  111. {
  112. InputContext_t *pContext = ( InputContext_t* )hContext;
  113. if ( !pContext )
  114. return;
  115. if ( pContext->m_bEnabled == bEnable )
  116. return;
  117. // Disabling an input context will deactivate mouse capture, if it's active
  118. if ( !bEnable )
  119. {
  120. SetMouseCapture( hContext, false );
  121. }
  122. pContext->m_bEnabled = bEnable;
  123. // Updates the cursor state since the stack changed
  124. UpdateCursorState();
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Allows a context to make the cursor visible;
  128. // the topmost enabled context wins
  129. //-----------------------------------------------------------------------------
  130. void CInputStackSystem::SetCursorVisible( InputContextHandle_t hContext, bool bVisible )
  131. {
  132. InputContext_t *pContext = ( InputContext_t* )hContext;
  133. if ( !pContext )
  134. return;
  135. if ( pContext->m_bCursorVisible == bVisible )
  136. return;
  137. pContext->m_bCursorVisible = bVisible;
  138. // Updates the cursor state since the stack changed
  139. UpdateCursorState();
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Allows a context to set the cursor icon;
  143. // the topmost enabled context wins
  144. //-----------------------------------------------------------------------------
  145. void CInputStackSystem::SetCursorIcon( InputContextHandle_t hContext, InputCursorHandle_t hCursor )
  146. {
  147. InputContext_t *pContext = ( InputContext_t* )hContext;
  148. if ( !pContext )
  149. return;
  150. if ( pContext->m_hCursorIcon == hCursor )
  151. return;
  152. pContext->m_hCursorIcon = hCursor;
  153. // Updates the cursor state since the stack changed
  154. UpdateCursorState();
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Allows a context to enable mouse capture. Disabling an input context
  158. // deactivates mouse capture. Capture will occur if it happens on the
  159. // topmost enabled context
  160. //-----------------------------------------------------------------------------
  161. void CInputStackSystem::SetMouseCapture( InputContextHandle_t hContext, bool bEnable )
  162. {
  163. InputContext_t *pContext = ( InputContext_t* )hContext;
  164. if ( !pContext )
  165. return;
  166. if ( pContext->m_bMouseCaptureEnabled == bEnable )
  167. return;
  168. pContext->m_bMouseCaptureEnabled = bEnable;
  169. // Updates the cursor state since the stack changed
  170. UpdateCursorState();
  171. }
  172. //-----------------------------------------------------------------------------
  173. // Allows a context to set the mouse position. It only has any effect if the
  174. // specified context is the topmost enabled context
  175. //-----------------------------------------------------------------------------
  176. void CInputStackSystem::SetCursorPosition( InputContextHandle_t hContext, int x, int y )
  177. {
  178. if ( IsTopmostEnabledContext( hContext ) )
  179. {
  180. g_pInputSystem->SetCursorPosition( x, y );
  181. }
  182. }
  183. //-----------------------------------------------------------------------------
  184. // This this context the topmost enabled context?
  185. //-----------------------------------------------------------------------------
  186. bool CInputStackSystem::IsTopmostEnabledContext( InputContextHandle_t hContext ) const
  187. {
  188. InputContext_t *pContext = ( InputContext_t* )hContext;
  189. if ( !pContext )
  190. return false;
  191. int nCount = m_ContextStack.Count();
  192. for ( int i = nCount; --i >= 0; )
  193. {
  194. InputContext_t *pStackContext = m_ContextStack[i];
  195. if ( !pStackContext->m_bEnabled )
  196. continue;
  197. return ( pStackContext == pContext );
  198. }
  199. return false;
  200. }
  201. //-----------------------------------------------------------------------------
  202. // Updates the cursor based on the current state of the input stack
  203. //-----------------------------------------------------------------------------
  204. void CInputStackSystem::UpdateCursorState()
  205. {
  206. int nCount = m_ContextStack.Count();
  207. for ( int i = nCount; --i >= 0; )
  208. {
  209. InputContext_t *pContext = m_ContextStack[i];
  210. if ( !pContext->m_bEnabled )
  211. continue;
  212. if ( !pContext->m_bCursorVisible )
  213. {
  214. g_pInputSystem->SetCursorIcon( INPUT_CURSOR_HANDLE_INVALID );
  215. }
  216. else
  217. {
  218. g_pInputSystem->SetCursorIcon( pContext->m_hCursorIcon );
  219. }
  220. if ( pContext->m_bMouseCaptureEnabled )
  221. {
  222. g_pInputSystem->EnableMouseCapture( g_pInputSystem->GetAttachedWindow() );
  223. }
  224. else
  225. {
  226. g_pInputSystem->DisableMouseCapture( );
  227. }
  228. break;
  229. }
  230. }