1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
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
|