summaryrefslogtreecommitdiff
path: root/public/panorama/input/iuiinput.h
diff options
context:
space:
mode:
Diffstat (limited to 'public/panorama/input/iuiinput.h')
-rw-r--r--public/panorama/input/iuiinput.h543
1 files changed, 543 insertions, 0 deletions
diff --git a/public/panorama/input/iuiinput.h b/public/panorama/input/iuiinput.h
new file mode 100644
index 0000000..df362e1
--- /dev/null
+++ b/public/panorama/input/iuiinput.h
@@ -0,0 +1,543 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+#ifndef IUIINPUT_H
+#define IUIINPUT_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "keycodes.h"
+#include "mousecodes.h"
+#include "gamepadcodes.h"
+#include "tier0/platform.h"
+#include "tier1/utldelegate.h"
+#include "../controls/panelhandle.h"
+#include "../uieventcodes.h"
+#include "../iuiengine.h"
+
+#ifdef SOURCE2_PANORAMA
+#include "inputsystem/buttoncode.h"
+#endif
+
+namespace panorama
+{
+
+class CPanel2D;
+class IImageSource;
+class IUISettings;
+
+// the classes of input we understand
+enum EInputType
+{
+ k_eInputNone = 0,
+ k_eKeyDown = 1, // raw down press
+ k_eKeyUp = 2, // raw release
+ k_eKeyChar = 3, // composited text entry from the OS
+ k_eMouseDown = 4,
+ k_eMouseUp = 5,
+ k_eMouseMove = 6,
+ k_eMouseDoubleClick = 7,
+ k_eMouseTripleClick = 8,
+ k_eMouseWheel = 9,
+ k_eMouseEnter = 10,
+ k_eMouseLeave = 11,
+ k_eGamePadDown = 12,
+ k_eGamePadUp = 13,
+ k_eGamePadAnalog = 14,
+
+ k_eOverlayCommand = 5000,
+
+ k_eInputTypeMaxRange = 0xFFFFFFFF // force size to 32 bits
+};
+
+
+enum EActiveControllerType
+{
+ k_EActiveControllerType_None, // we aren't using a controller or we don't know to do
+ k_EActiveControllerType_XInput,
+ k_EActiveControllerType_Steam,
+};
+
+//
+// structs container input type specific data
+//
+struct KeyData_t
+{
+ EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
+
+ KeyCode m_KeyCode;
+ uint8 m_RepeatCount;
+ bool m_bFirstDown; // is this the first time this key was pressed
+ wchar_t m_UniChar; // unicode equivalent of this key
+ uint32 m_Modifiers; // alt, ctrl, etc held down?
+};
+
+
+struct MouseData_t
+{
+ EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
+
+ MouseCode m_MouseCode;
+ uint32 m_Modifiers;
+ uint8 m_RepeatCount;
+ int m_Delta;
+};
+
+struct GamePadData_t
+{
+ EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
+
+ GamePadCode m_GamePadCode;
+ uint8 m_RepeatCount; // home many times in a row we have had this button down
+ float m_fValue; // the analog value of the deflection if an axis
+
+ // if an analog event then these two are set for each axis value
+ float m_fValueX; // the analog value of the deflection along horizontal
+ float m_fValueY; // the analog value of the deflection along vertical
+
+ // For Steam controller analog events this value will indicate the time the users finger went down
+ float m_flFingerDown;
+
+ // For Steam controller analog events these values indicate the starting finger position (so you can do some basic swipe stuff)
+ float m_fValueXFirst;
+ float m_fValueYFirst;
+
+ // For Steam controller analog events this is the raw sampled coordinate without deadzoning
+ float m_fValueXRaw;
+ float m_fValueYRaw;
+};
+
+
+struct InputMessage_t
+{
+ EInputType m_eInputType;
+ float m_flInputTime;
+ union
+ {
+ EPanelEventSource_t m_eSource; // where did this event originate? this is the first field of the other *Data_t structs below.
+ KeyData_t m_KeyData;
+ MouseData_t m_MouseData;
+ GamePadData_t m_GamePadData;
+ };
+};
+
+
+//
+// A combination of event type and specific code data to mean an input event, like on key down of the A key
+//
+struct ActionInput_t
+{
+ ActionInput_t()
+ {
+ m_InputType = k_eInputNone;
+ m_Data.m_KeyCode = KEY_NONE;
+ m_unModifiers = MODIFIER_NONE;
+ }
+
+ explicit ActionInput_t( EInputType type, KeyCode code, uint32 unModifiers, const char *pchNamespace )
+ {
+ m_InputType = type;
+ m_Data.m_KeyCode = code;
+ m_unModifiers = unModifiers;
+ if ( pchNamespace && pchNamespace[0] )
+ m_symNameSpace = pchNamespace;
+ }
+
+ explicit ActionInput_t( EInputType type, GamePadCode code, const char *pchNamespace )
+ {
+ m_InputType = type;
+ m_Data.m_GamePadCode = code;
+ m_unModifiers = MODIFIER_NONE;
+ if ( pchNamespace && pchNamespace[0] )
+ m_symNameSpace = pchNamespace;
+ }
+
+ explicit ActionInput_t( EInputType type, MouseCode code, const char *pchNamespace )
+ {
+ m_InputType = type;
+ m_Data.m_MouseCode = code;
+ m_unModifiers = MODIFIER_NONE;
+ if ( pchNamespace && pchNamespace[0] )
+ m_symNameSpace = pchNamespace;
+ }
+
+ ActionInput_t( InputMessage_t &msg, const char *pchNamespace )
+ {
+ m_InputType = msg.m_eInputType;
+ if ( pchNamespace && pchNamespace[0] )
+ m_symNameSpace = pchNamespace;
+ m_unModifiers = MODIFIER_NONE;
+ switch ( msg.m_eInputType )
+ {
+ default:
+ AssertMsg( false, "Unknown input type to ActionInput_t( InputMessage_t )" );
+ break;
+ case k_eKeyDown:
+ case k_eKeyUp:
+ case k_eKeyChar:
+ m_Data.m_KeyCode = msg.m_KeyData.m_KeyCode;
+ m_unModifiers = msg.m_KeyData.m_Modifiers;
+ break;
+ case k_eMouseDown:
+ case k_eMouseDoubleClick:
+ case k_eMouseTripleClick:
+ case k_eMouseUp:
+ case k_eMouseMove:
+ case k_eMouseWheel:
+ m_Data.m_MouseCode = msg.m_MouseData.m_MouseCode;
+ m_unModifiers = msg.m_MouseData.m_Modifiers;
+ break;
+ case k_eMouseEnter:
+ case k_eMouseLeave:
+ break;
+ case k_eGamePadDown:
+ case k_eGamePadUp:
+ case k_eGamePadAnalog:
+ m_Data.m_GamePadCode = msg.m_GamePadData.m_GamePadCode;
+ break;
+ }
+ }
+
+
+ // Can't ever make this not 32bits in size, see crazy comparison operators below. Also, each
+ // member must be exactly 32bits, not less with uninitialized data.
+ EInputType m_InputType;
+ union
+ {
+ KeyCode m_KeyCode;
+ GamePadCode m_GamePadCode;
+ MouseCode m_MouseCode;
+ } m_Data;
+
+ uint32 m_unModifiers;
+ CPanoramaSymbol m_symNameSpace;
+
+ bool operator<( const ActionInput_t &that ) const
+ {
+ if ( m_InputType != that.m_InputType )
+ return m_InputType < that.m_InputType;
+
+ if ( m_unModifiers != that.m_unModifiers )
+ return m_unModifiers < that.m_unModifiers;
+
+ // I have a namespace and you don't
+ if ( m_symNameSpace.IsValid() && !that.m_symNameSpace.IsValid() )
+ return true;
+
+ // You have a namespace and I don't
+ if ( that.m_symNameSpace.IsValid() && !m_symNameSpace.IsValid() )
+ return false;
+
+ // compare namespace if both are valid but not equal
+ if ( m_symNameSpace.IsValid() && that.m_symNameSpace.IsValid() && m_symNameSpace != that.m_symNameSpace )
+ return m_symNameSpace < that.m_symNameSpace;
+
+ // lets compare the raw code now
+ switch( m_InputType )
+ {
+ default:
+ case k_eKeyDown:
+ case k_eKeyUp:
+ case k_eKeyChar:
+ return m_Data.m_KeyCode < that.m_Data.m_KeyCode;
+ case k_eMouseDown:
+ case k_eMouseUp:
+ case k_eMouseMove:
+ case k_eMouseWheel:
+ case k_eMouseDoubleClick:
+ case k_eMouseTripleClick:
+ return m_Data.m_MouseCode < that.m_Data.m_MouseCode;
+ case k_eGamePadDown:
+ case k_eGamePadUp:
+ case k_eGamePadAnalog:
+ return m_Data.m_GamePadCode < that.m_Data.m_GamePadCode;
+ }
+ }
+
+ bool operator==( const ActionInput_t &that ) const
+ {
+ if ( m_InputType == that.m_InputType && m_unModifiers == that.m_unModifiers &&
+ // also if both namespace are valid and equal OR either namespace is unset (i.e "global")
+ ( ( m_symNameSpace.IsValid() && that.m_symNameSpace.IsValid() && m_symNameSpace == that.m_symNameSpace ) || ( !m_symNameSpace.IsValid() && !that.m_symNameSpace.IsValid() ) ) )
+ {
+ switch( m_InputType )
+ {
+ default:
+ case k_eKeyDown:
+ case k_eKeyUp:
+ case k_eKeyChar:
+ return m_Data.m_KeyCode == that.m_Data.m_KeyCode;
+ case k_eMouseDoubleClick:
+ case k_eMouseTripleClick:
+ case k_eMouseDown:
+ case k_eMouseUp:
+ case k_eMouseMove:
+ case k_eMouseWheel:
+ return m_Data.m_MouseCode == that.m_Data.m_MouseCode;
+ case k_eGamePadDown:
+ case k_eGamePadUp:
+ case k_eGamePadAnalog:
+ return m_Data.m_GamePadCode == that.m_Data.m_GamePadCode;
+ }
+ }
+ return false;
+ }
+
+};
+
+// Helpers for checking modifier state
+inline bool IsControlPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LCONTROL || unModifiers & MODIFIER_RCONTROL; }
+inline bool IsAltPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LALT || unModifiers & MODIFIER_RALT; }
+inline bool IsShiftPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LSHIFT || unModifiers & MODIFIER_RSHIFT; }
+inline bool IsWinPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LWIN || unModifiers & MODIFIER_RWIN; }
+
+
+//
+// struct to wrap mouse move events for mouse tracked panels
+//
+struct MouseTrackingResults_t
+{
+ MouseTrackingResults_t()
+ {
+ m_hPanel = k_ulInvalidPanelHandle64;
+ m_flX = 0.0f;
+ m_flY = 0.0f;
+
+ }
+ MouseTrackingResults_t( uint64 handle, float x, float y )
+ {
+ m_hPanel = handle;
+ m_flX = x;
+ m_flY = y;
+ }
+
+ uint64 m_hPanel;
+ float m_flX;
+ float m_flY;
+};
+
+//
+// An interface to receive captured input
+//
+class IInputCapture
+{
+public:
+ // keyboard
+ virtual bool OnCapturedKeyDown( IUIPanel *pPanel, const KeyData_t &code ) = 0;
+ virtual bool OnCapturedKeyUp( IUIPanel *pPanel, const KeyData_t &code ) = 0;
+ virtual bool OnCapturedKeyTyped( IUIPanel *pPanel, const KeyData_t &unichar ) = 0;
+
+ // mouse
+ virtual bool OnCapturedMouseMove( IUIPanel *pPanel ) = 0;
+ virtual bool OnCapturedMouseButtonDown( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+ virtual bool OnCapturedMouseButtonUp( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+ virtual bool OnCapturedMouseButtonDoubleClick( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+ virtual bool OnCapturedMouseButtonTripleClick( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+ virtual bool OnCapturedMouseWheel( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+
+ // gamepad
+ virtual bool OnCapturedGamePadDown( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
+ virtual bool OnCapturedGamePadUp( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
+ virtual bool OnCapturedGamePadAnalog( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
+};
+
+class CDefaultInputCapture : public IInputCapture
+{
+public:
+ // keyboard
+ virtual bool OnCapturedKeyDown( panorama::IUIPanel *pPanel, const panorama::KeyData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedKeyUp( panorama::IUIPanel *pPanel, const panorama::KeyData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedKeyTyped( panorama::IUIPanel *pPanel, const panorama::KeyData_t &unichar ) OVERRIDE { return false; }
+
+ // mouse
+ virtual bool OnCapturedMouseMove( panorama::IUIPanel *pPanel ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseButtonDown( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseButtonUp( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseButtonDoubleClick( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseButtonTripleClick( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseWheel( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+
+ // gamepad
+ virtual bool OnCapturedGamePadDown( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedGamePadUp( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedGamePadAnalog( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
+};
+
+//
+// Handles per top level window focus
+//
+class IUIWindowInput
+{
+public:
+ virtual bool InputEvent( InputMessage_t &msg, bool bNewEvent = true ) = 0;
+
+ // Receive mouse move events, in window coordinate space
+ virtual void OnMouseMove( float flMouseX, float flMouseY, bool bSynthesized = false ) = 0;
+
+ // current mouse coordinates and visibility
+ virtual void GetSurfaceMousePosition( float &x, float &y ) = 0;
+ virtual bool BCursorVisible() = 0;
+ virtual void WakeupMouseCursor() = 0;
+ virtual void FadeOutCursorNow() = 0;
+
+ // gamepad state
+ virtual int GetNumGamepadsConnected() = 0;
+ virtual bool BWasGamepadConnectedThisSession() = 0;
+ virtual bool BWasGamepadUsedThisSession() = 0;
+ virtual bool BWasSteamControllerConnectedThisSession() = 0;
+ virtual bool BWasSteamControllerUsedThisSession() = 0;
+
+ // tracking of last input type
+ virtual bool BWasGamepadLastInputSource() = 0;
+ virtual bool BWasMouseLastInputSource() = 0;
+ virtual bool BWasKeyboardOrMouseLastInputSource() = 0;
+
+ // Get the last input source
+ virtual EPanelEventSource_t GetLastPanelEventSource() = 0;
+
+ // Keyboard / mouse info
+ virtual bool BWasKeyboardOrMouseUsedThisSession() = 0;
+ virtual bool BWasMouseMovedThisSession() = 0;
+
+ // top level OS window support
+ virtual void GotWindowFocus() = 0;
+ virtual void LostWindowFocus() = 0;
+ virtual bool BHasWindowFocus() = 0;
+
+ // Window can temporarily disable all input, used for overlay when the game is focused, but overlay inactive
+ virtual bool BAllowInput( InputMessage_t &msg ) = 0;
+
+ // panel management
+ virtual void SetInputFocus( IUIPanel *pPanel, bool bScrollParentToFit, bool bChangeContextIfNeeded ) = 0;
+ virtual bool SetInputFocusContext( IUIPanel *pPanelInContext ) = 0;
+ virtual void PopInputContext() = 0;
+ virtual IUIPanel *GetInputFocusContext() = 0;
+ virtual IUIPanel *GetInputFocus() = 0;
+ virtual IUIPanel *GetMouseHover() = 0;
+ virtual void PanelDeleted( IUIPanel *pPanel, IUIPanel *pParent ) = 0;
+
+ // input hooks
+ virtual void HookPanelInput( IUIPanel *pPanel, IInputCapture *pInputCapture ) = 0;
+ virtual void RemovePanelInputHook( IUIPanel *pPanel, IInputCapture *pInputCapture ) = 0;
+
+ // set this panel to always (or stop) getting MouseMove events
+ virtual void AddMouseTrackingPanel( IUIPanel *pPanel ) = 0;
+ virtual void RemoveMouseTrackingPanel( IUIPanel *pPanel ) = 0;
+
+ // Are we currently inside a set input focus call
+ virtual bool BInSetInputFocusTraverse() = 0;
+
+ // Queue a panel focus event to occur once we finish with setting input focus
+ virtual void QueuePanelFocusEvent( IUIPanel *pPanel, CPanoramaSymbol symPanelEvent ) = 0;
+
+ // reset any mouse movement count as we just hid the cursor
+ virtual void ResetMouseMoveCount() = 0;
+
+ // Get focus panel at time of last mouse down
+ virtual IUIPanel *GetFocusOnLastMouseDown() = 0;
+};
+
+
+//
+// Handles key/mouse/gamepad input and dispatches to appropriate panels
+//
+class IUIInput
+{
+public:
+ virtual void Initialize( IUISettings *pSettings ) = 0;
+
+ // Not ifdef'd or specific to windows. v_key ended up as a common
+ // denominator in lots of code (overlay as an example)
+ // 0x00 for error in mapping. There is no 0x00 VKEY
+ virtual uint16 KeyCodeToWindowsVKey( const KeyCode inKey ) = 0;
+
+ // KEY_NONE will come back on error.
+ virtual KeyCode WindowsVKeyToKeyCode( uint16 inKey ) = 0;
+
+#ifdef SOURCE2_PANORAMA
+ virtual ButtonCode_t KeyCodeToButtonCode( const KeyCode inKey ) = 0;
+ virtual ButtonCode_t MouseCodeToButtonCode( const MouseCode inKey ) = 0;
+#endif
+
+ // kb/mouse input
+ virtual bool InputEvent( InputMessage_t &msg ) = 0;
+
+ // used to capture all input
+ virtual void SetInputCapture( IInputCapture *pCapture ) = 0;
+ virtual void ReleaseInputCapture( IInputCapture *pCapture ) = 0;
+ virtual CUtlVector< IInputCapture * > &GetInputCapture() = 0;
+
+ // Checks whether gamepads are connected
+ virtual int GetNumGamepadsConnected() const = 0;
+
+ // did any gamepad have input since we last asked
+ virtual bool BWasGamepadOrSteamControllerActive() = 0;
+
+ // flags to tell steam controller layer which buttons to treat as mouse and not disable cursor on seeing
+ virtual void SetSteamPadButtonsToTreatAsMouse( uint64 ulButtonMask ) = 0;
+
+ // if a gamepad is connected then its friendly name
+ virtual const char *PchGamePadName() = 0;
+
+ // return true if we are emulating a gamepad using a simple joystick, so we have less input functionality available
+ virtual bool BEmulatingGamePadWithJoystick() = 0;
+
+ // helper for gamepad codes, returns values that are inside the deadzone for this joystick
+ virtual float GetDeadZoneValue( GamePadCode code ) = 0;
+
+ // translate an event into the gamepad key bound to it, XK_NULL if not bound
+ virtual const GamePadCode GetGamePadBindForEvent( const char *pchEvent, const IUIPanel *pFromPanel ) = 0;
+
+ // is capslock on
+ virtual bool BIsCapsLockOn() = 0;
+
+ // If we're trying to show help text for a controller, which type of controller is most relevant (ie., most recently
+ // used, exists, etc.)? You probably don't want to call this directly but instead listen for ActiveControllerTypeChanged.
+ virtual EActiveControllerType GetActiveControllerType() const = 0;
+
+ // Get count of actively connected Steam controllers
+ virtual uint32 GetSteamControllerCount() const = 0;
+
+ // Get the time a steam controller was last assigned/used
+ virtual float GetLastSteamControllerActiveTime() const = 0;
+
+ // Get the time a non-steam controller was last assigned/used
+ virtual float GetLastGamePadControllerActiveTime() const = 0;
+
+ // Get the ID of the steam controller currently sending events to the window
+ virtual int GetLastSteamControllerActiveIndex() const = 0;
+
+ // Pulse haptic feedback on active gamepad/steam controller if supported
+ virtual void PulseActiveControllerHaptic( IUIEngine::EHapticFeedbackPosition ePosition, IUIEngine::EHapticFeedbackStrength eStrength ) = 0;
+
+ // Is finger actively down on steam controller right pad? Probably means mouse emulation in use.
+ virtual bool BIsFingerDownOnSteamControllerRightPad() const = 0;
+
+ // Register a file path to look for keybindings
+ virtual void RegisterKeyBindingsFile( const char *pszFilePath ) = 0;
+
+ // Force a reload of the keybindings
+ virtual void ReloadKeyBindings() = 0;
+
+ // Private APIs for remote gamepad input, called on a separate network thread
+ virtual void RemoteGamepadAttached( int nGamepadID ) = 0;
+ virtual void RemoteGamepadDetached( int nGamepadID ) = 0;
+ virtual void SetRemoteGamepadAxis( int nGamepadID, int nAxis, int nValue ) = 0;
+ virtual void SetRemoteGamepadButton( int nGamepadID, int nButton, int nValue ) = 0;
+
+ // Turn off whatever (wireless) controller was last active
+ virtual void TurnOffActiveController() = 0;
+
+ // Get gamepad code value from textual name for config files, event code, etc
+ virtual panorama::GamePadCode GamePadCodeFromName( const char * pchGamePadCode ) = 0;
+
+ // Check if two gamepad codes are the 'same' button but on different vendor devices
+ virtual bool BIsGamePadCodeEquivalentIgnoringVendor( GamePadCode a, GamePadCode b ) = 0;
+};
+
+} // namespace panorama
+
+#endif // IUIINPUT_H