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.

377 lines
13 KiB

  1. //=========== Copyright Valve Corporation, All rights reserved. ===============//
  2. //
  3. // Purpose:
  4. //=============================================================================//
  5. #ifndef PANORAMA_TEXTINPUT_DAISYWHEEL_H
  6. #define PANORAMA_TEXTINPUT_DAISYWHEEL_H
  7. #include "panorama/textinput/textinput.h"
  8. #include "panorama/controls/panel2d.h"
  9. #include "panorama/controls/label.h"
  10. #include "panorama/input/iuiinput.h"
  11. #include "mathlib/beziercurve.h"
  12. #include "tier1/utlptr.h"
  13. #include "panorama/uischeduleddel.h"
  14. namespace panorama
  15. {
  16. // Forward declaration
  17. class CTextInputDaisyWheel;
  18. class CTextEntry;
  19. class ITextInputSuggest;
  20. class CLabel;
  21. //-----------------------------------------------------------------------------
  22. // Purpose: Implementation of daisy wheel text input handler
  23. //-----------------------------------------------------------------------------
  24. class CTextInputDaisyWheel : public panorama::CTextInputHandler
  25. {
  26. DECLARE_PANEL2D( CTextInputDaisyWheel, panorama::CPanel2D );
  27. public:
  28. // Constructor
  29. CTextInputDaisyWheel( panorama::IUIWindow *pParent, const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
  30. CTextInputDaisyWheel( panorama::CPanel2D *parent, const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
  31. // Destructor
  32. ~CTextInputDaisyWheel();
  33. // CTextInputHandler overrides
  34. virtual void OpenHandler() OVERRIDE;
  35. virtual void CloseHandlerImpl( bool bCommitText ) OVERRIDE;
  36. virtual ETextInputHandlerType_t GetType() OVERRIDE;
  37. virtual ITextInputControl *GetControlInterface() OVERRIDE;
  38. virtual void SuggestWord( const wchar_t *pwch, int ich ) OVERRIDE;
  39. virtual void SetYButtonAction( const char *pchLabel, IUIEvent *pEvent ) OVERRIDE;
  40. static void GetSupportedLanguages( CUtlVector<ELanguage> &vecLangs );
  41. private:
  42. void Initialize( const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
  43. // This isn't part of CTextInputHandler because currently there is no need to set this dynamically
  44. void SetMode( ETextInputMode_t mode );
  45. // CPanel2D overrides
  46. virtual bool OnGamePadUp( const panorama::GamePadData_t &code ) OVERRIDE;
  47. virtual bool OnGamePadDown( const panorama::GamePadData_t &code ) OVERRIDE;
  48. virtual bool OnGamePadAnalog( const panorama::GamePadData_t &code ) OVERRIDE;
  49. virtual bool OnKeyTyped( const KeyData_t &unichar ) OVERRIDE;
  50. virtual bool OnKeyDown( const KeyData_t &code ) OVERRIDE;
  51. virtual bool OnKeyUp( const KeyData_t &code ) OVERRIDE;
  52. //
  53. // Daisy wheel input type
  54. //
  55. enum EDaisyInputType_t
  56. {
  57. k_EDaisyInputTypeABXY, // ABXY layout has color buttons printing keys
  58. k_EDaisyInputTypeRS, // RS layout requires Right Stick usage to print keys
  59. k_EDaisyInputTypePIN, // Button map to numbers for secret PIN entry
  60. };
  61. // Set daisy wheel type
  62. void SetDaisyInputType( EDaisyInputType_t eType );
  63. // Add an emoticon to the list of emoji this daisywheel will show
  64. // TODO: Currently not part of CTextInputHandler because emoticons need work
  65. void AddEmoticon( const char *szInsert, const char *szImageURL );
  66. void CommitEmoticons();
  67. #ifdef DBGFLAG_VALIDATE
  68. void ValidateClientPanel( CValidator &validator, const tchar *pchName );
  69. #endif
  70. // User wants to move focus to the next field on the page
  71. bool NextFocus();
  72. static const int k_cPetals = 8; // # petals in flower (hardcoded for now)
  73. static const int k_cItemsPerPetal = 4; // # letters visible on each petal, max
  74. static const int k_cItemsPerLayoutMax = k_cPetals * k_cItemsPerPetal; // # letters total per layout, max
  75. struct Emoticon_t
  76. {
  77. CUtlString sType;
  78. CUtlString sImageURL;
  79. };
  80. //
  81. // A single wheel layout configuration: name and UTF-8 sequences of characters
  82. // Structure is allocated with more memory at the end of the structure, name and
  83. // UTF-8 sequences follow this structure object
  84. //
  85. class CDaisyConfig
  86. {
  87. public:
  88. CDaisyConfig( const char *pchName ) : m_sName( pchName )
  89. {
  90. }
  91. // Get the name of wheel layout
  92. char const * GetName() const { return m_sName.String(); }
  93. // Get number of items in this wheel layout
  94. int GetNumItems() const { return m_cItems; }
  95. // Get a given item in this wheel layout, must be >= zero and < number of items
  96. // double the index, because each item is NUL terminated
  97. const char * GetItem( int idx ) const
  98. {
  99. if ( idx >= k_cItemsPerLayoutMax || idx < 0 )
  100. {
  101. Assert( false );
  102. return "";
  103. }
  104. return m_vecText.Base() + m_rgich[ idx ];
  105. }
  106. #ifdef DBGFLAG_VALIDATE
  107. void Validate( CValidator &validator, const tchar *pchName )
  108. {
  109. VALIDATE_SCOPE();
  110. ValidateObj( m_sName );
  111. ValidateObj( m_vecText );
  112. }
  113. #endif
  114. // name of this layout
  115. CUtlString m_sName;
  116. // Number of items in this wheel layout
  117. int m_cItems;
  118. // offsets into the text block for each item in this layout
  119. int m_rgich[ k_cItemsPerLayoutMax ];
  120. // block of text for this layout, UTF-8
  121. CUtlVector< char > m_vecText;
  122. };
  123. // After configuration has been loaded and assigned walk through all
  124. // controls and set their values to represent the loaded config
  125. void SetControlsFromConfiguration();
  126. // map the trigger inputs to a config
  127. enum EDaisyConfig_t
  128. {
  129. k_EDaisyConfigNone = -1,
  130. k_EDaisyConfigCaps,
  131. k_EDaisyConfigLetters,
  132. k_EDaisyConfigNumbers,
  133. k_EDaisyConfigSpecial,
  134. k_EDaisyConfigNumbersOnly,
  135. k_EDaisyConfigPhoneNumber,
  136. k_EDaisyConfigSteamCodeChars,
  137. k_EDaisyConfigEmoji,
  138. };
  139. typedef CUtlMap< EDaisyConfig_t, CUtlPtr< CDaisyConfig >, int, CDefLess< EDaisyConfig_t > > MapConfigEntries_t;
  140. EDaisyConfig_t EDaisyConfigFromString( const char *pchValue );
  141. EDaisyConfig_t ConfigFromTriggerState( bool bLeftTrigger, bool bRightTrigger );
  142. // update the trigger legends based on the current trigger state
  143. void UpdateTriggerLegends();
  144. // moves controls to existing config (caps -> lowercase)
  145. void AdvanceControlsConfiguration( EDaisyConfig_t eConfig );
  146. // Types a character from selected group's side of world: "E" | "W" | "N" | "S"
  147. bool TypeCharacterFromSide( char chSide );
  148. // Types a given wide character into text entry
  149. bool TypeWchar( uchar16 wch );
  150. // Simulates a key down event
  151. bool TypeKeyDown( panorama::KeyCode eCode );
  152. // Loads configuration file for specified language
  153. bool LoadInputConfigurationFile( ELanguage language );
  154. // Loads configuration file
  155. bool LoadInputConfigurationFile( const char *szConfig, const char *szConfigRootDir );
  156. // Builds configuration structure based on buffer loaded from config file
  157. bool LoadConfigurationBuffer( char const *pszBase, MapConfigEntries_t *pmapConfigs );
  158. // Switch between most recent languages
  159. bool SwitchLanguage();
  160. bool ShowThisLanguage( ELanguage language );
  161. // For a given config item determine which group and group side the item should be at
  162. void GetItemLocation( CDaisyConfig *pCfg, int iItem, char const *&szGroup, char const *&szItem );
  163. // 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.
  164. char const * GetGroupNameSq( int x, int y );
  165. // Gets a sequential index of the group square indexed by -1|0|1 pair of x,y coordinates
  166. int GetGroupIdxSq( int x, int y );
  167. // Gets the side of world name of group by its sequential index
  168. char const * GetGroup( int idxGroup );
  169. // Gets the side of world name of item by its sequential index
  170. char const * GetSide( int idxSide );
  171. // Process scheduled key repeat
  172. void ScheduleKeyRepeats( panorama::GamePadCode eCode );
  173. void CancelOutstandingRepeats() { ScheduleKeyRepeats( XK_NULL ); }
  174. void ScheduledKeyRepeatFunction();
  175. bool HandlePropertyTransitionEnd( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, CStyleSymbol sym );
  176. // Listen for focus lost
  177. bool HandleInputFocusLost( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
  178. // events bound in window_keybinds.cfg
  179. bool ShowHideSettings();
  180. // settings events
  181. bool CancelSettings();
  182. // auto-suggestion
  183. void ShowSuggestion( const char *szPrefix, const char *szSuffix );
  184. void ClearSuggestionVisual()
  185. {
  186. ShowSuggestion( "", "" );
  187. }
  188. void ClearSuggestionState()
  189. {
  190. m_sSuggestion.Clear();
  191. ClearSuggestionVisual();
  192. }
  193. bool BCursorAtStartOfSentence();
  194. bool BConvertNextSpaceToPeriod();
  195. // Play sound for a give daisy wheel activity
  196. enum EDaisyAction_t
  197. {
  198. k_EDaisySound_ButtonA,
  199. k_EDaisySound_ButtonB,
  200. k_EDaisySound_ButtonX,
  201. k_EDaisySound_ButtonY,
  202. k_EDaisySound_KeySpacebar,
  203. k_EDaisySound_KeyBackspace,
  204. k_EDaisySound_KeyLeft,
  205. k_EDaisySound_KeyRight,
  206. k_EDaisySound_KeyHome,
  207. k_EDaisySound_KeyEnd,
  208. k_EDaisySound_FocusAreaChanged,
  209. k_EDaisySound_ConfigChanged,
  210. k_EDaisySound_FocusAreaCold,
  211. k_EDaisySound_PerformAutosuggest,
  212. };
  213. void PlayDaisyActionSound( EDaisyAction_t eAction );
  214. // Function to handle gamepad data depending on daisy wheel settings
  215. typedef bool (CTextInputDaisyWheel::*PFNGamePadData)( const panorama::GamePadData_t &code );
  216. MapConfigEntries_t m_mapConfigEntries; // Processed configuration entries
  217. EDaisyConfig_t m_eConfigCurrent; // Current config, can be cycled with triggers
  218. bool m_bRestrictConfig; // if true, stick to current config (no changing layouts)
  219. panorama::CPanel2D *m_pStickPri; // Primary stick control
  220. float m_flStickPriSelectOct[2]; // Selection octant angles (std: lo=M_PI/6, hi=M_PI/3)
  221. float m_flStickPriMoveScale[2]; // Scale for primary stick movement
  222. float m_flStickPriSelectDist[2]; // Selection distances
  223. float m_flStickPriSelectAngleSticky; // Selection angle to stick to area
  224. float m_flStickPriColdTime; // How long we need primary stick to remain cold
  225. int m_nSelectionGroup[2]; // Currently selected group
  226. panorama::CPanel2D *m_pStickSnd; // Secondary stick control
  227. float m_flStickSndMoveScale[2]; // Scale for secondary stick movement
  228. float m_flStickSndSelectDist[2]; // Selection distances for secondary stick
  229. float m_flStickSndSelectAngleSticky; // Selection angle for secondary stick to stick to area
  230. panorama::CLabel *m_pLang; // Language legend label
  231. double m_flPickedItemTransitionTime; // Time for picked item to highlight
  232. PFNGamePadData m_pfnOnGamePadDown; // Current config for gamepad down
  233. PFNGamePadData m_pfnOnGamePadAnalog; // Current config for gamepad analog
  234. // settings
  235. bool m_bDoubleSpaceToDotSpace;
  236. bool m_bAutoCaps;
  237. // Tracking doublespace = dot+space
  238. bool m_bOnlySpacesEnteredSinceBackspace;
  239. // Tracking trigger state for typing
  240. bool m_bTriggersDownState[2]; // Whether trigger is down
  241. // Tracking stick cold state
  242. double m_flTimeStickCold; // When stick went into cold state (rolls when hot)
  243. // Tracking key repeats
  244. CCubicBezierCurve< Vector2D > m_repeatCurve; // Curve for key repeats
  245. double m_repeatStartTime; // Time when the key was initially pressed
  246. double m_repeatNextTime; // Time when the key will repeat next
  247. panorama::GamePadCode m_repeatGamePadCode; // Which key was pressed (low level, for key-up tracking)
  248. uint32 m_repeatCounter; // How many key repeats have happened
  249. panorama::CUIScheduledDel m_repeatFunction; // Scheduled function triggering key repeats
  250. // Stick processing routines
  251. bool OnGamePadAnalog_ProcessLeftStickForGroup( const panorama::GamePadData_t &code );
  252. bool OnGamePadAnalog_ProcessRightStickForSide( const panorama::GamePadData_t &code );
  253. bool OnGamePadAnalog_Trigger( const panorama::GamePadData_t &code );
  254. bool HandleTextInputDaisyWheelOnGamePadAnalogTriggersChanged();
  255. // ABXY handlers
  256. bool DaisyABXY_OnGamePadDown( const panorama::GamePadData_t &code );
  257. bool DaisyABXY_OnGamePadAnalog( const panorama::GamePadData_t &code );
  258. // RS handlers
  259. bool DaisyRS_OnGamePadDown( const panorama::GamePadData_t &code );
  260. bool DaisyRS_OnGamePadAnalog( const panorama::GamePadData_t &code );
  261. // PINpad handlers
  262. bool DaisyPIN_OnGamePadDown( const panorama::GamePadData_t & code );
  263. bool DaisyPIN_OnGamePadAnalog( const panorama::GamePadData_t &code );
  264. ELanguage m_language; // currently loaded language
  265. ITextInputSuggest *m_psuggest; // suggestion engine
  266. CUtlString m_sSuggestion; // result of suggestion
  267. panorama::CLabel *m_plabelSuggestionPrefix; // label containing prefix of current suggestion
  268. panorama::CLabel *m_plabelSuggestionSuffix; // label containing prefix of current suggestion
  269. double m_flInputStartTime; // when did the user first start typing
  270. bool m_bUsedKeyboard; // true if the kb was used for ANY input
  271. bool m_bUsedGamepad; // true if the gamepad was used for ANY input
  272. ITextInputControl *m_pTextInputControl; // control interface for moving text input between a control and daisy wheel
  273. IUIEvent *m_pYbuttonAction; // the action to fire if the Y button is hit
  274. panorama::CLabel *m_pYButtonText; // label for ybutton text
  275. ETextInputMode_t m_mode; // text input mode
  276. bool m_bDisplaySuggestions; // If true, allow suggestions to be displayed
  277. // mode can disable specific footer sections
  278. bool m_bDisableRightTrigger;
  279. bool m_bDisableRightBumper;
  280. bool m_bDisableLeftTrigger;
  281. bool m_bDisableLanguageSelect;
  282. enum ERightStickPos
  283. {
  284. k_RightStick_None,
  285. k_RightStick_Up,
  286. k_RightStick_Down,
  287. k_RightStick_Left,
  288. k_RightStick_Right,
  289. };
  290. ERightStickPos m_eSteamRightStickPos;
  291. Vector2D m_vecRightPadPos;
  292. CUtlVector< Emoticon_t > m_vecEmoji;
  293. bool m_bLoadedEmoji;
  294. };
  295. } // namespace panorama
  296. #endif // PANORAMA_TEXTINPUT_DAISYWHEEL_H