Team Fortress 2 Source Code as on 22/4/2020
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.

543 lines
18 KiB

  1. //=========== Copyright Valve Corporation, All rights reserved. ===============//
  2. //
  3. // Purpose:
  4. //=============================================================================//
  5. #ifndef IUIINPUT_H
  6. #define IUIINPUT_H
  7. #ifdef _WIN32
  8. #pragma once
  9. #endif
  10. #include "keycodes.h"
  11. #include "mousecodes.h"
  12. #include "gamepadcodes.h"
  13. #include "tier0/platform.h"
  14. #include "tier1/utldelegate.h"
  15. #include "../controls/panelhandle.h"
  16. #include "../uieventcodes.h"
  17. #include "../iuiengine.h"
  18. #ifdef SOURCE2_PANORAMA
  19. #include "inputsystem/buttoncode.h"
  20. #endif
  21. namespace panorama
  22. {
  23. class CPanel2D;
  24. class IImageSource;
  25. class IUISettings;
  26. // the classes of input we understand
  27. enum EInputType
  28. {
  29. k_eInputNone = 0,
  30. k_eKeyDown = 1, // raw down press
  31. k_eKeyUp = 2, // raw release
  32. k_eKeyChar = 3, // composited text entry from the OS
  33. k_eMouseDown = 4,
  34. k_eMouseUp = 5,
  35. k_eMouseMove = 6,
  36. k_eMouseDoubleClick = 7,
  37. k_eMouseTripleClick = 8,
  38. k_eMouseWheel = 9,
  39. k_eMouseEnter = 10,
  40. k_eMouseLeave = 11,
  41. k_eGamePadDown = 12,
  42. k_eGamePadUp = 13,
  43. k_eGamePadAnalog = 14,
  44. k_eOverlayCommand = 5000,
  45. k_eInputTypeMaxRange = 0xFFFFFFFF // force size to 32 bits
  46. };
  47. enum EActiveControllerType
  48. {
  49. k_EActiveControllerType_None, // we aren't using a controller or we don't know to do
  50. k_EActiveControllerType_XInput,
  51. k_EActiveControllerType_Steam,
  52. };
  53. //
  54. // structs container input type specific data
  55. //
  56. struct KeyData_t
  57. {
  58. EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
  59. KeyCode m_KeyCode;
  60. uint8 m_RepeatCount;
  61. bool m_bFirstDown; // is this the first time this key was pressed
  62. wchar_t m_UniChar; // unicode equivalent of this key
  63. uint32 m_Modifiers; // alt, ctrl, etc held down?
  64. };
  65. struct MouseData_t
  66. {
  67. EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
  68. MouseCode m_MouseCode;
  69. uint32 m_Modifiers;
  70. uint8 m_RepeatCount;
  71. int m_Delta;
  72. };
  73. struct GamePadData_t
  74. {
  75. EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
  76. GamePadCode m_GamePadCode;
  77. uint8 m_RepeatCount; // home many times in a row we have had this button down
  78. float m_fValue; // the analog value of the deflection if an axis
  79. // if an analog event then these two are set for each axis value
  80. float m_fValueX; // the analog value of the deflection along horizontal
  81. float m_fValueY; // the analog value of the deflection along vertical
  82. // For Steam controller analog events this value will indicate the time the users finger went down
  83. float m_flFingerDown;
  84. // For Steam controller analog events these values indicate the starting finger position (so you can do some basic swipe stuff)
  85. float m_fValueXFirst;
  86. float m_fValueYFirst;
  87. // For Steam controller analog events this is the raw sampled coordinate without deadzoning
  88. float m_fValueXRaw;
  89. float m_fValueYRaw;
  90. };
  91. struct InputMessage_t
  92. {
  93. EInputType m_eInputType;
  94. float m_flInputTime;
  95. union
  96. {
  97. EPanelEventSource_t m_eSource; // where did this event originate? this is the first field of the other *Data_t structs below.
  98. KeyData_t m_KeyData;
  99. MouseData_t m_MouseData;
  100. GamePadData_t m_GamePadData;
  101. };
  102. };
  103. //
  104. // A combination of event type and specific code data to mean an input event, like on key down of the A key
  105. //
  106. struct ActionInput_t
  107. {
  108. ActionInput_t()
  109. {
  110. m_InputType = k_eInputNone;
  111. m_Data.m_KeyCode = KEY_NONE;
  112. m_unModifiers = MODIFIER_NONE;
  113. }
  114. explicit ActionInput_t( EInputType type, KeyCode code, uint32 unModifiers, const char *pchNamespace )
  115. {
  116. m_InputType = type;
  117. m_Data.m_KeyCode = code;
  118. m_unModifiers = unModifiers;
  119. if ( pchNamespace && pchNamespace[0] )
  120. m_symNameSpace = pchNamespace;
  121. }
  122. explicit ActionInput_t( EInputType type, GamePadCode code, const char *pchNamespace )
  123. {
  124. m_InputType = type;
  125. m_Data.m_GamePadCode = code;
  126. m_unModifiers = MODIFIER_NONE;
  127. if ( pchNamespace && pchNamespace[0] )
  128. m_symNameSpace = pchNamespace;
  129. }
  130. explicit ActionInput_t( EInputType type, MouseCode code, const char *pchNamespace )
  131. {
  132. m_InputType = type;
  133. m_Data.m_MouseCode = code;
  134. m_unModifiers = MODIFIER_NONE;
  135. if ( pchNamespace && pchNamespace[0] )
  136. m_symNameSpace = pchNamespace;
  137. }
  138. ActionInput_t( InputMessage_t &msg, const char *pchNamespace )
  139. {
  140. m_InputType = msg.m_eInputType;
  141. if ( pchNamespace && pchNamespace[0] )
  142. m_symNameSpace = pchNamespace;
  143. m_unModifiers = MODIFIER_NONE;
  144. switch ( msg.m_eInputType )
  145. {
  146. default:
  147. AssertMsg( false, "Unknown input type to ActionInput_t( InputMessage_t )" );
  148. break;
  149. case k_eKeyDown:
  150. case k_eKeyUp:
  151. case k_eKeyChar:
  152. m_Data.m_KeyCode = msg.m_KeyData.m_KeyCode;
  153. m_unModifiers = msg.m_KeyData.m_Modifiers;
  154. break;
  155. case k_eMouseDown:
  156. case k_eMouseDoubleClick:
  157. case k_eMouseTripleClick:
  158. case k_eMouseUp:
  159. case k_eMouseMove:
  160. case k_eMouseWheel:
  161. m_Data.m_MouseCode = msg.m_MouseData.m_MouseCode;
  162. m_unModifiers = msg.m_MouseData.m_Modifiers;
  163. break;
  164. case k_eMouseEnter:
  165. case k_eMouseLeave:
  166. break;
  167. case k_eGamePadDown:
  168. case k_eGamePadUp:
  169. case k_eGamePadAnalog:
  170. m_Data.m_GamePadCode = msg.m_GamePadData.m_GamePadCode;
  171. break;
  172. }
  173. }
  174. // Can't ever make this not 32bits in size, see crazy comparison operators below. Also, each
  175. // member must be exactly 32bits, not less with uninitialized data.
  176. EInputType m_InputType;
  177. union
  178. {
  179. KeyCode m_KeyCode;
  180. GamePadCode m_GamePadCode;
  181. MouseCode m_MouseCode;
  182. } m_Data;
  183. uint32 m_unModifiers;
  184. CPanoramaSymbol m_symNameSpace;
  185. bool operator<( const ActionInput_t &that ) const
  186. {
  187. if ( m_InputType != that.m_InputType )
  188. return m_InputType < that.m_InputType;
  189. if ( m_unModifiers != that.m_unModifiers )
  190. return m_unModifiers < that.m_unModifiers;
  191. // I have a namespace and you don't
  192. if ( m_symNameSpace.IsValid() && !that.m_symNameSpace.IsValid() )
  193. return true;
  194. // You have a namespace and I don't
  195. if ( that.m_symNameSpace.IsValid() && !m_symNameSpace.IsValid() )
  196. return false;
  197. // compare namespace if both are valid but not equal
  198. if ( m_symNameSpace.IsValid() && that.m_symNameSpace.IsValid() && m_symNameSpace != that.m_symNameSpace )
  199. return m_symNameSpace < that.m_symNameSpace;
  200. // lets compare the raw code now
  201. switch( m_InputType )
  202. {
  203. default:
  204. case k_eKeyDown:
  205. case k_eKeyUp:
  206. case k_eKeyChar:
  207. return m_Data.m_KeyCode < that.m_Data.m_KeyCode;
  208. case k_eMouseDown:
  209. case k_eMouseUp:
  210. case k_eMouseMove:
  211. case k_eMouseWheel:
  212. case k_eMouseDoubleClick:
  213. case k_eMouseTripleClick:
  214. return m_Data.m_MouseCode < that.m_Data.m_MouseCode;
  215. case k_eGamePadDown:
  216. case k_eGamePadUp:
  217. case k_eGamePadAnalog:
  218. return m_Data.m_GamePadCode < that.m_Data.m_GamePadCode;
  219. }
  220. }
  221. bool operator==( const ActionInput_t &that ) const
  222. {
  223. if ( m_InputType == that.m_InputType && m_unModifiers == that.m_unModifiers &&
  224. // also if both namespace are valid and equal OR either namespace is unset (i.e "global")
  225. ( ( m_symNameSpace.IsValid() && that.m_symNameSpace.IsValid() && m_symNameSpace == that.m_symNameSpace ) || ( !m_symNameSpace.IsValid() && !that.m_symNameSpace.IsValid() ) ) )
  226. {
  227. switch( m_InputType )
  228. {
  229. default:
  230. case k_eKeyDown:
  231. case k_eKeyUp:
  232. case k_eKeyChar:
  233. return m_Data.m_KeyCode == that.m_Data.m_KeyCode;
  234. case k_eMouseDoubleClick:
  235. case k_eMouseTripleClick:
  236. case k_eMouseDown:
  237. case k_eMouseUp:
  238. case k_eMouseMove:
  239. case k_eMouseWheel:
  240. return m_Data.m_MouseCode == that.m_Data.m_MouseCode;
  241. case k_eGamePadDown:
  242. case k_eGamePadUp:
  243. case k_eGamePadAnalog:
  244. return m_Data.m_GamePadCode == that.m_Data.m_GamePadCode;
  245. }
  246. }
  247. return false;
  248. }
  249. };
  250. // Helpers for checking modifier state
  251. inline bool IsControlPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LCONTROL || unModifiers & MODIFIER_RCONTROL; }
  252. inline bool IsAltPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LALT || unModifiers & MODIFIER_RALT; }
  253. inline bool IsShiftPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LSHIFT || unModifiers & MODIFIER_RSHIFT; }
  254. inline bool IsWinPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LWIN || unModifiers & MODIFIER_RWIN; }
  255. //
  256. // struct to wrap mouse move events for mouse tracked panels
  257. //
  258. struct MouseTrackingResults_t
  259. {
  260. MouseTrackingResults_t()
  261. {
  262. m_hPanel = k_ulInvalidPanelHandle64;
  263. m_flX = 0.0f;
  264. m_flY = 0.0f;
  265. }
  266. MouseTrackingResults_t( uint64 handle, float x, float y )
  267. {
  268. m_hPanel = handle;
  269. m_flX = x;
  270. m_flY = y;
  271. }
  272. uint64 m_hPanel;
  273. float m_flX;
  274. float m_flY;
  275. };
  276. //
  277. // An interface to receive captured input
  278. //
  279. class IInputCapture
  280. {
  281. public:
  282. // keyboard
  283. virtual bool OnCapturedKeyDown( IUIPanel *pPanel, const KeyData_t &code ) = 0;
  284. virtual bool OnCapturedKeyUp( IUIPanel *pPanel, const KeyData_t &code ) = 0;
  285. virtual bool OnCapturedKeyTyped( IUIPanel *pPanel, const KeyData_t &unichar ) = 0;
  286. // mouse
  287. virtual bool OnCapturedMouseMove( IUIPanel *pPanel ) = 0;
  288. virtual bool OnCapturedMouseButtonDown( IUIPanel *pPanel, const MouseData_t &code ) = 0;
  289. virtual bool OnCapturedMouseButtonUp( IUIPanel *pPanel, const MouseData_t &code ) = 0;
  290. virtual bool OnCapturedMouseButtonDoubleClick( IUIPanel *pPanel, const MouseData_t &code ) = 0;
  291. virtual bool OnCapturedMouseButtonTripleClick( IUIPanel *pPanel, const MouseData_t &code ) = 0;
  292. virtual bool OnCapturedMouseWheel( IUIPanel *pPanel, const MouseData_t &code ) = 0;
  293. // gamepad
  294. virtual bool OnCapturedGamePadDown( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
  295. virtual bool OnCapturedGamePadUp( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
  296. virtual bool OnCapturedGamePadAnalog( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
  297. };
  298. class CDefaultInputCapture : public IInputCapture
  299. {
  300. public:
  301. // keyboard
  302. virtual bool OnCapturedKeyDown( panorama::IUIPanel *pPanel, const panorama::KeyData_t &code ) OVERRIDE { return false; }
  303. virtual bool OnCapturedKeyUp( panorama::IUIPanel *pPanel, const panorama::KeyData_t &code ) OVERRIDE { return false; }
  304. virtual bool OnCapturedKeyTyped( panorama::IUIPanel *pPanel, const panorama::KeyData_t &unichar ) OVERRIDE { return false; }
  305. // mouse
  306. virtual bool OnCapturedMouseMove( panorama::IUIPanel *pPanel ) OVERRIDE { return false; }
  307. virtual bool OnCapturedMouseButtonDown( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
  308. virtual bool OnCapturedMouseButtonUp( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
  309. virtual bool OnCapturedMouseButtonDoubleClick( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
  310. virtual bool OnCapturedMouseButtonTripleClick( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
  311. virtual bool OnCapturedMouseWheel( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
  312. // gamepad
  313. virtual bool OnCapturedGamePadDown( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
  314. virtual bool OnCapturedGamePadUp( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
  315. virtual bool OnCapturedGamePadAnalog( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
  316. };
  317. //
  318. // Handles per top level window focus
  319. //
  320. class IUIWindowInput
  321. {
  322. public:
  323. virtual bool InputEvent( InputMessage_t &msg, bool bNewEvent = true ) = 0;
  324. // Receive mouse move events, in window coordinate space
  325. virtual void OnMouseMove( float flMouseX, float flMouseY, bool bSynthesized = false ) = 0;
  326. // current mouse coordinates and visibility
  327. virtual void GetSurfaceMousePosition( float &x, float &y ) = 0;
  328. virtual bool BCursorVisible() = 0;
  329. virtual void WakeupMouseCursor() = 0;
  330. virtual void FadeOutCursorNow() = 0;
  331. // gamepad state
  332. virtual int GetNumGamepadsConnected() = 0;
  333. virtual bool BWasGamepadConnectedThisSession() = 0;
  334. virtual bool BWasGamepadUsedThisSession() = 0;
  335. virtual bool BWasSteamControllerConnectedThisSession() = 0;
  336. virtual bool BWasSteamControllerUsedThisSession() = 0;
  337. // tracking of last input type
  338. virtual bool BWasGamepadLastInputSource() = 0;
  339. virtual bool BWasMouseLastInputSource() = 0;
  340. virtual bool BWasKeyboardOrMouseLastInputSource() = 0;
  341. // Get the last input source
  342. virtual EPanelEventSource_t GetLastPanelEventSource() = 0;
  343. // Keyboard / mouse info
  344. virtual bool BWasKeyboardOrMouseUsedThisSession() = 0;
  345. virtual bool BWasMouseMovedThisSession() = 0;
  346. // top level OS window support
  347. virtual void GotWindowFocus() = 0;
  348. virtual void LostWindowFocus() = 0;
  349. virtual bool BHasWindowFocus() = 0;
  350. // Window can temporarily disable all input, used for overlay when the game is focused, but overlay inactive
  351. virtual bool BAllowInput( InputMessage_t &msg ) = 0;
  352. // panel management
  353. virtual void SetInputFocus( IUIPanel *pPanel, bool bScrollParentToFit, bool bChangeContextIfNeeded ) = 0;
  354. virtual bool SetInputFocusContext( IUIPanel *pPanelInContext ) = 0;
  355. virtual void PopInputContext() = 0;
  356. virtual IUIPanel *GetInputFocusContext() = 0;
  357. virtual IUIPanel *GetInputFocus() = 0;
  358. virtual IUIPanel *GetMouseHover() = 0;
  359. virtual void PanelDeleted( IUIPanel *pPanel, IUIPanel *pParent ) = 0;
  360. // input hooks
  361. virtual void HookPanelInput( IUIPanel *pPanel, IInputCapture *pInputCapture ) = 0;
  362. virtual void RemovePanelInputHook( IUIPanel *pPanel, IInputCapture *pInputCapture ) = 0;
  363. // set this panel to always (or stop) getting MouseMove events
  364. virtual void AddMouseTrackingPanel( IUIPanel *pPanel ) = 0;
  365. virtual void RemoveMouseTrackingPanel( IUIPanel *pPanel ) = 0;
  366. // Are we currently inside a set input focus call
  367. virtual bool BInSetInputFocusTraverse() = 0;
  368. // Queue a panel focus event to occur once we finish with setting input focus
  369. virtual void QueuePanelFocusEvent( IUIPanel *pPanel, CPanoramaSymbol symPanelEvent ) = 0;
  370. // reset any mouse movement count as we just hid the cursor
  371. virtual void ResetMouseMoveCount() = 0;
  372. // Get focus panel at time of last mouse down
  373. virtual IUIPanel *GetFocusOnLastMouseDown() = 0;
  374. };
  375. //
  376. // Handles key/mouse/gamepad input and dispatches to appropriate panels
  377. //
  378. class IUIInput
  379. {
  380. public:
  381. virtual void Initialize( IUISettings *pSettings ) = 0;
  382. // Not ifdef'd or specific to windows. v_key ended up as a common
  383. // denominator in lots of code (overlay as an example)
  384. // 0x00 for error in mapping. There is no 0x00 VKEY
  385. virtual uint16 KeyCodeToWindowsVKey( const KeyCode inKey ) = 0;
  386. // KEY_NONE will come back on error.
  387. virtual KeyCode WindowsVKeyToKeyCode( uint16 inKey ) = 0;
  388. #ifdef SOURCE2_PANORAMA
  389. virtual ButtonCode_t KeyCodeToButtonCode( const KeyCode inKey ) = 0;
  390. virtual ButtonCode_t MouseCodeToButtonCode( const MouseCode inKey ) = 0;
  391. #endif
  392. // kb/mouse input
  393. virtual bool InputEvent( InputMessage_t &msg ) = 0;
  394. // used to capture all input
  395. virtual void SetInputCapture( IInputCapture *pCapture ) = 0;
  396. virtual void ReleaseInputCapture( IInputCapture *pCapture ) = 0;
  397. virtual CUtlVector< IInputCapture * > &GetInputCapture() = 0;
  398. // Checks whether gamepads are connected
  399. virtual int GetNumGamepadsConnected() const = 0;
  400. // did any gamepad have input since we last asked
  401. virtual bool BWasGamepadOrSteamControllerActive() = 0;
  402. // flags to tell steam controller layer which buttons to treat as mouse and not disable cursor on seeing
  403. virtual void SetSteamPadButtonsToTreatAsMouse( uint64 ulButtonMask ) = 0;
  404. // if a gamepad is connected then its friendly name
  405. virtual const char *PchGamePadName() = 0;
  406. // return true if we are emulating a gamepad using a simple joystick, so we have less input functionality available
  407. virtual bool BEmulatingGamePadWithJoystick() = 0;
  408. // helper for gamepad codes, returns values that are inside the deadzone for this joystick
  409. virtual float GetDeadZoneValue( GamePadCode code ) = 0;
  410. // translate an event into the gamepad key bound to it, XK_NULL if not bound
  411. virtual const GamePadCode GetGamePadBindForEvent( const char *pchEvent, const IUIPanel *pFromPanel ) = 0;
  412. // is capslock on
  413. virtual bool BIsCapsLockOn() = 0;
  414. // If we're trying to show help text for a controller, which type of controller is most relevant (ie., most recently
  415. // used, exists, etc.)? You probably don't want to call this directly but instead listen for ActiveControllerTypeChanged.
  416. virtual EActiveControllerType GetActiveControllerType() const = 0;
  417. // Get count of actively connected Steam controllers
  418. virtual uint32 GetSteamControllerCount() const = 0;
  419. // Get the time a steam controller was last assigned/used
  420. virtual float GetLastSteamControllerActiveTime() const = 0;
  421. // Get the time a non-steam controller was last assigned/used
  422. virtual float GetLastGamePadControllerActiveTime() const = 0;
  423. // Get the ID of the steam controller currently sending events to the window
  424. virtual int GetLastSteamControllerActiveIndex() const = 0;
  425. // Pulse haptic feedback on active gamepad/steam controller if supported
  426. virtual void PulseActiveControllerHaptic( IUIEngine::EHapticFeedbackPosition ePosition, IUIEngine::EHapticFeedbackStrength eStrength ) = 0;
  427. // Is finger actively down on steam controller right pad? Probably means mouse emulation in use.
  428. virtual bool BIsFingerDownOnSteamControllerRightPad() const = 0;
  429. // Register a file path to look for keybindings
  430. virtual void RegisterKeyBindingsFile( const char *pszFilePath ) = 0;
  431. // Force a reload of the keybindings
  432. virtual void ReloadKeyBindings() = 0;
  433. // Private APIs for remote gamepad input, called on a separate network thread
  434. virtual void RemoteGamepadAttached( int nGamepadID ) = 0;
  435. virtual void RemoteGamepadDetached( int nGamepadID ) = 0;
  436. virtual void SetRemoteGamepadAxis( int nGamepadID, int nAxis, int nValue ) = 0;
  437. virtual void SetRemoteGamepadButton( int nGamepadID, int nButton, int nValue ) = 0;
  438. // Turn off whatever (wireless) controller was last active
  439. virtual void TurnOffActiveController() = 0;
  440. // Get gamepad code value from textual name for config files, event code, etc
  441. virtual panorama::GamePadCode GamePadCodeFromName( const char * pchGamePadCode ) = 0;
  442. // Check if two gamepad codes are the 'same' button but on different vendor devices
  443. virtual bool BIsGamePadCodeEquivalentIgnoringVendor( GamePadCode a, GamePadCode b ) = 0;
  444. };
  445. } // namespace panorama
  446. #endif // IUIINPUT_H