summaryrefslogtreecommitdiff
path: root/public/panorama/textinput/textinput_daisywheel.h
diff options
context:
space:
mode:
Diffstat (limited to 'public/panorama/textinput/textinput_daisywheel.h')
-rw-r--r--public/panorama/textinput/textinput_daisywheel.h377
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
+