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
377 lines
13 KiB
//=========== 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 |
|
|
|
|