|
|
//=========== 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
|