diff options
Diffstat (limited to 'public/panorama/textinput/textinput_daisywheel.h')
| -rw-r--r-- | public/panorama/textinput/textinput_daisywheel.h | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/public/panorama/textinput/textinput_daisywheel.h b/public/panorama/textinput/textinput_daisywheel.h new file mode 100644 index 0000000..a523fc9 --- /dev/null +++ b/public/panorama/textinput/textinput_daisywheel.h @@ -0,0 +1,377 @@ +//=========== Copyright Valve Corporation, All rights reserved. ===============// +// +// Purpose: +//=============================================================================// + +#ifndef PANORAMA_TEXTINPUT_DAISYWHEEL_H +#define PANORAMA_TEXTINPUT_DAISYWHEEL_H + +#include "panorama/textinput/textinput.h" +#include "panorama/controls/panel2d.h" +#include "panorama/controls/label.h" +#include "panorama/input/iuiinput.h" +#include "mathlib/beziercurve.h" +#include "tier1/utlptr.h" +#include "panorama/uischeduleddel.h" + +namespace panorama +{ + +// Forward declaration +class CTextInputDaisyWheel; +class CTextEntry; +class ITextInputSuggest; +class CLabel; + +//----------------------------------------------------------------------------- +// Purpose: Implementation of daisy wheel text input handler +//----------------------------------------------------------------------------- +class CTextInputDaisyWheel : public panorama::CTextInputHandler +{ + DECLARE_PANEL2D( CTextInputDaisyWheel, panorama::CPanel2D ); + +public: + // Constructor + CTextInputDaisyWheel( panorama::IUIWindow *pParent, const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl ); + CTextInputDaisyWheel( panorama::CPanel2D *parent, const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl ); + + // Destructor + ~CTextInputDaisyWheel(); + + // CTextInputHandler overrides + virtual void OpenHandler() OVERRIDE; + virtual void CloseHandlerImpl( bool bCommitText ) OVERRIDE; + virtual ETextInputHandlerType_t GetType() OVERRIDE; + virtual ITextInputControl *GetControlInterface() OVERRIDE; + virtual void SuggestWord( const wchar_t *pwch, int ich ) OVERRIDE; + virtual void SetYButtonAction( const char *pchLabel, IUIEvent *pEvent ) OVERRIDE; + + static void GetSupportedLanguages( CUtlVector<ELanguage> &vecLangs ); +private: + void Initialize( const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl ); + + // This isn't part of CTextInputHandler because currently there is no need to set this dynamically + void SetMode( ETextInputMode_t mode ); + + // CPanel2D overrides + virtual bool OnGamePadUp( const panorama::GamePadData_t &code ) OVERRIDE; + virtual bool OnGamePadDown( const panorama::GamePadData_t &code ) OVERRIDE; + virtual bool OnGamePadAnalog( const panorama::GamePadData_t &code ) OVERRIDE; + virtual bool OnKeyTyped( const KeyData_t &unichar ) OVERRIDE; + virtual bool OnKeyDown( const KeyData_t &code ) OVERRIDE; + virtual bool OnKeyUp( const KeyData_t &code ) OVERRIDE; + + // + // Daisy wheel input type + // + enum EDaisyInputType_t + { + k_EDaisyInputTypeABXY, // ABXY layout has color buttons printing keys + k_EDaisyInputTypeRS, // RS layout requires Right Stick usage to print keys + k_EDaisyInputTypePIN, // Button map to numbers for secret PIN entry + }; + + // Set daisy wheel type + void SetDaisyInputType( EDaisyInputType_t eType ); + + // Add an emoticon to the list of emoji this daisywheel will show + // TODO: Currently not part of CTextInputHandler because emoticons need work + void AddEmoticon( const char *szInsert, const char *szImageURL ); + void CommitEmoticons(); + +#ifdef DBGFLAG_VALIDATE + void ValidateClientPanel( CValidator &validator, const tchar *pchName ); +#endif + + // User wants to move focus to the next field on the page + bool NextFocus(); + + static const int k_cPetals = 8; // # petals in flower (hardcoded for now) + static const int k_cItemsPerPetal = 4; // # letters visible on each petal, max + static const int k_cItemsPerLayoutMax = k_cPetals * k_cItemsPerPetal; // # letters total per layout, max + + struct Emoticon_t + { + CUtlString sType; + CUtlString sImageURL; + }; + + // + // A single wheel layout configuration: name and UTF-8 sequences of characters + // Structure is allocated with more memory at the end of the structure, name and + // UTF-8 sequences follow this structure object + // + class CDaisyConfig + { + public: + CDaisyConfig( const char *pchName ) : m_sName( pchName ) + { + } + + // Get the name of wheel layout + char const * GetName() const { return m_sName.String(); } + + // Get number of items in this wheel layout + int GetNumItems() const { return m_cItems; } + + // Get a given item in this wheel layout, must be >= zero and < number of items + // double the index, because each item is NUL terminated + const char * GetItem( int idx ) const + { + if ( idx >= k_cItemsPerLayoutMax || idx < 0 ) + { + Assert( false ); + return ""; + } + + return m_vecText.Base() + m_rgich[ idx ]; + } + + #ifdef DBGFLAG_VALIDATE + void Validate( CValidator &validator, const tchar *pchName ) + { + VALIDATE_SCOPE(); + ValidateObj( m_sName ); + ValidateObj( m_vecText ); + } + #endif + + // name of this layout + CUtlString m_sName; + + // Number of items in this wheel layout + int m_cItems; + + // offsets into the text block for each item in this layout + int m_rgich[ k_cItemsPerLayoutMax ]; + + // block of text for this layout, UTF-8 + CUtlVector< char > m_vecText; + }; + + // After configuration has been loaded and assigned walk through all + // controls and set their values to represent the loaded config + void SetControlsFromConfiguration(); + + // map the trigger inputs to a config + enum EDaisyConfig_t + { + k_EDaisyConfigNone = -1, + k_EDaisyConfigCaps, + k_EDaisyConfigLetters, + k_EDaisyConfigNumbers, + k_EDaisyConfigSpecial, + k_EDaisyConfigNumbersOnly, + k_EDaisyConfigPhoneNumber, + k_EDaisyConfigSteamCodeChars, + k_EDaisyConfigEmoji, + }; + typedef CUtlMap< EDaisyConfig_t, CUtlPtr< CDaisyConfig >, int, CDefLess< EDaisyConfig_t > > MapConfigEntries_t; + + EDaisyConfig_t EDaisyConfigFromString( const char *pchValue ); + EDaisyConfig_t ConfigFromTriggerState( bool bLeftTrigger, bool bRightTrigger ); + + // update the trigger legends based on the current trigger state + void UpdateTriggerLegends(); + + // moves controls to existing config (caps -> lowercase) + void AdvanceControlsConfiguration( EDaisyConfig_t eConfig ); + + // Types a character from selected group's side of world: "E" | "W" | "N" | "S" + bool TypeCharacterFromSide( char chSide ); + + // Types a given wide character into text entry + bool TypeWchar( uchar16 wch ); + + // Simulates a key down event + bool TypeKeyDown( panorama::KeyCode eCode ); + + // Loads configuration file for specified language + bool LoadInputConfigurationFile( ELanguage language ); + + // Loads configuration file + bool LoadInputConfigurationFile( const char *szConfig, const char *szConfigRootDir ); + + // Builds configuration structure based on buffer loaded from config file + bool LoadConfigurationBuffer( char const *pszBase, MapConfigEntries_t *pmapConfigs ); + + // Switch between most recent languages + bool SwitchLanguage(); + bool ShowThisLanguage( ELanguage language ); + + // For a given config item determine which group and group side the item should be at + void GetItemLocation( CDaisyConfig *pCfg, int iItem, char const *&szGroup, char const *&szItem ); + + // Get name of the group square indexed by -1|0|1 pair of x,y coordinates; returns side or wolrd like: "E" | "NE" | "N" | "NW" | etc. + char const * GetGroupNameSq( int x, int y ); + + // Gets a sequential index of the group square indexed by -1|0|1 pair of x,y coordinates + int GetGroupIdxSq( int x, int y ); + + // Gets the side of world name of group by its sequential index + char const * GetGroup( int idxGroup ); + + // Gets the side of world name of item by its sequential index + char const * GetSide( int idxSide ); + + // Process scheduled key repeat + void ScheduleKeyRepeats( panorama::GamePadCode eCode ); + void CancelOutstandingRepeats() { ScheduleKeyRepeats( XK_NULL ); } + + void ScheduledKeyRepeatFunction(); + + bool HandlePropertyTransitionEnd( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, CStyleSymbol sym ); + + // Listen for focus lost + bool HandleInputFocusLost( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel ); + + // events bound in window_keybinds.cfg + bool ShowHideSettings(); + + // settings events + bool CancelSettings(); + + // auto-suggestion + void ShowSuggestion( const char *szPrefix, const char *szSuffix ); + void ClearSuggestionVisual() + { + ShowSuggestion( "", "" ); + } + void ClearSuggestionState() + { + m_sSuggestion.Clear(); + ClearSuggestionVisual(); + } + + bool BCursorAtStartOfSentence(); + bool BConvertNextSpaceToPeriod(); + + // Play sound for a give daisy wheel activity + enum EDaisyAction_t + { + k_EDaisySound_ButtonA, + k_EDaisySound_ButtonB, + k_EDaisySound_ButtonX, + k_EDaisySound_ButtonY, + k_EDaisySound_KeySpacebar, + k_EDaisySound_KeyBackspace, + k_EDaisySound_KeyLeft, + k_EDaisySound_KeyRight, + k_EDaisySound_KeyHome, + k_EDaisySound_KeyEnd, + k_EDaisySound_FocusAreaChanged, + k_EDaisySound_ConfigChanged, + k_EDaisySound_FocusAreaCold, + k_EDaisySound_PerformAutosuggest, + }; + void PlayDaisyActionSound( EDaisyAction_t eAction ); + + // Function to handle gamepad data depending on daisy wheel settings + typedef bool (CTextInputDaisyWheel::*PFNGamePadData)( const panorama::GamePadData_t &code ); + + MapConfigEntries_t m_mapConfigEntries; // Processed configuration entries + EDaisyConfig_t m_eConfigCurrent; // Current config, can be cycled with triggers + bool m_bRestrictConfig; // if true, stick to current config (no changing layouts) + + panorama::CPanel2D *m_pStickPri; // Primary stick control + float m_flStickPriSelectOct[2]; // Selection octant angles (std: lo=M_PI/6, hi=M_PI/3) + float m_flStickPriMoveScale[2]; // Scale for primary stick movement + float m_flStickPriSelectDist[2]; // Selection distances + float m_flStickPriSelectAngleSticky; // Selection angle to stick to area + float m_flStickPriColdTime; // How long we need primary stick to remain cold + int m_nSelectionGroup[2]; // Currently selected group + + panorama::CPanel2D *m_pStickSnd; // Secondary stick control + float m_flStickSndMoveScale[2]; // Scale for secondary stick movement + float m_flStickSndSelectDist[2]; // Selection distances for secondary stick + float m_flStickSndSelectAngleSticky; // Selection angle for secondary stick to stick to area + + panorama::CLabel *m_pLang; // Language legend label + + double m_flPickedItemTransitionTime; // Time for picked item to highlight + + PFNGamePadData m_pfnOnGamePadDown; // Current config for gamepad down + PFNGamePadData m_pfnOnGamePadAnalog; // Current config for gamepad analog + + // settings + bool m_bDoubleSpaceToDotSpace; + bool m_bAutoCaps; + + // Tracking doublespace = dot+space + bool m_bOnlySpacesEnteredSinceBackspace; + + // Tracking trigger state for typing + bool m_bTriggersDownState[2]; // Whether trigger is down + + // Tracking stick cold state + double m_flTimeStickCold; // When stick went into cold state (rolls when hot) + + // Tracking key repeats + CCubicBezierCurve< Vector2D > m_repeatCurve; // Curve for key repeats + double m_repeatStartTime; // Time when the key was initially pressed + double m_repeatNextTime; // Time when the key will repeat next + panorama::GamePadCode m_repeatGamePadCode; // Which key was pressed (low level, for key-up tracking) + uint32 m_repeatCounter; // How many key repeats have happened + panorama::CUIScheduledDel m_repeatFunction; // Scheduled function triggering key repeats + + // Stick processing routines + bool OnGamePadAnalog_ProcessLeftStickForGroup( const panorama::GamePadData_t &code ); + bool OnGamePadAnalog_ProcessRightStickForSide( const panorama::GamePadData_t &code ); + bool OnGamePadAnalog_Trigger( const panorama::GamePadData_t &code ); + bool HandleTextInputDaisyWheelOnGamePadAnalogTriggersChanged(); + + // ABXY handlers + bool DaisyABXY_OnGamePadDown( const panorama::GamePadData_t &code ); + bool DaisyABXY_OnGamePadAnalog( const panorama::GamePadData_t &code ); + + // RS handlers + bool DaisyRS_OnGamePadDown( const panorama::GamePadData_t &code ); + bool DaisyRS_OnGamePadAnalog( const panorama::GamePadData_t &code ); + + // PINpad handlers + bool DaisyPIN_OnGamePadDown( const panorama::GamePadData_t & code ); + bool DaisyPIN_OnGamePadAnalog( const panorama::GamePadData_t &code ); + + ELanguage m_language; // currently loaded language + + ITextInputSuggest *m_psuggest; // suggestion engine + CUtlString m_sSuggestion; // result of suggestion + + panorama::CLabel *m_plabelSuggestionPrefix; // label containing prefix of current suggestion + panorama::CLabel *m_plabelSuggestionSuffix; // label containing prefix of current suggestion + + double m_flInputStartTime; // when did the user first start typing + bool m_bUsedKeyboard; // true if the kb was used for ANY input + bool m_bUsedGamepad; // true if the gamepad was used for ANY input + + ITextInputControl *m_pTextInputControl; // control interface for moving text input between a control and daisy wheel + IUIEvent *m_pYbuttonAction; // the action to fire if the Y button is hit + panorama::CLabel *m_pYButtonText; // label for ybutton text + ETextInputMode_t m_mode; // text input mode + bool m_bDisplaySuggestions; // If true, allow suggestions to be displayed + + // mode can disable specific footer sections + bool m_bDisableRightTrigger; + bool m_bDisableRightBumper; + bool m_bDisableLeftTrigger; + bool m_bDisableLanguageSelect; + + enum ERightStickPos + { + k_RightStick_None, + k_RightStick_Up, + k_RightStick_Down, + k_RightStick_Left, + k_RightStick_Right, + }; + ERightStickPos m_eSteamRightStickPos; + Vector2D m_vecRightPadPos; + + CUtlVector< Emoticon_t > m_vecEmoji; + bool m_bLoadedEmoji; +}; + +} // namespace panorama + +#endif // PANORAMA_TEXTINPUT_DAISYWHEEL_H + |