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
|
//=========== Copyright Valve Corporation, All rights reserved. ===============//
//
// Purpose:
//=============================================================================//
#ifndef PANORAMA_TEXTENTRY_H
#define PANORAMA_TEXTENTRY_H
#ifdef _WIN32
#pragma once
#endif
#include "panel2d.h"
#include "panorama/text/iuitextlayout.h"
#include "panorama/textinput/textinput.h"
#include "panorama/textinput/textinput_settings.h"
#if !defined(SOURCE2_PANORAMA)
#include "../common/globals.h"
#include "../common/reliabletimer.h"
#include "../common/framefunction.h"
#endif
#include "panorama/uischeduleddel.h"
#include "imesystem/imeuiinterface.h"
namespace panorama
{
class CLabel;
class CTextEntryAutocomplete;
#if defined( SOURCE2_PANORAMA )
class CTextEntryIMEControls;
#endif // defined( SOURCE2_PANORAMA )
DECLARE_PANEL_EVENT1( TextEntrySubmit, const char * ); // always raised when user is done submitting text
DECLARE_PANEL_EVENT0( TextEntryChanged ); // call CTextEntry::RaiseChangeEvents() to enable
DECLARE_PANEL_EVENT0( TextEntryShowTextInputHandler );
DECLARE_PANEL_EVENT0( TextEntryHideTextInputHandler );
DECLARE_PANEL_EVENT0( TextEntryInsertFromClipboard );
DECLARE_PANEL_EVENT0( TextEntryCopyToClipboard );
DECLARE_PANEL_EVENT0( TextEntryCutToClipboard );
//-----------------------------------------------------------------------------
// Purpose: text entry
//-----------------------------------------------------------------------------
class CTextEntry : public CPanel2D, public ITextInputControl
#if defined( SOURCE2_PANORAMA )
, public IIMEUITextField
#endif // defined( SOURCE2_PANORAMA )
{
DECLARE_PANEL2D( CTextEntry, CPanel2D );
public:
CTextEntry( CPanel2D *parent, const char * pchPanelID );
virtual ~CTextEntry();
virtual void SetupJavascriptObjectTemplate() OVERRIDE;
void SetUndoHistoryEnabled( bool bEnabled );
void ClearUndoHistory();
virtual bool OnKeyDown( const KeyData_t &code );
virtual bool OnKeyTyped( const KeyData_t &unichar );
virtual bool OnKeyUp( const KeyData_t & code ) { return BaseClass::OnKeyUp( code ); }
virtual void Paint();
virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
virtual void OnInitializedFromLayout();
virtual void OnStylesChanged();
virtual void OnMouseMove( float flMouseX, float flMouseY );
virtual bool OnMouseButtonDown( const MouseData_t &code );
virtual bool OnMouseButtonUp( const MouseData_t &code );
virtual bool OnMouseButtonDoubleClick( const MouseData_t &code );
virtual bool OnMouseButtonTripleClick( const MouseData_t &code );
virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties ) OVERRIDE;
virtual bool BRequiresContentClipLayer() { return m_bMayDrawOutsideBounds; }
void SetMode( ETextInputMode_t mode );
ETextInputMode_t GetMode() { return m_modeInput; }
void SetText( const char *pchValue );
const char *PchGetText() const;
const wchar_t *PwchGetText() const;
void SetPlaceholderText( const char *pchValue );
const char *PchGetPlaceholderText() const;
void SetMaxChars( uint unMaxChars );
uint GetCharCount() const { return m_vecWCharData.Count() - 1; } // m_vecWCharData is terminated, so remove extra char count
uint GetMaxCharCount() const { return m_unMaxChars; }
int32 GetCursorOffset() const { return m_nCursorOffset; }
void SetCursorOffset( int32 nCursoroffset );
bool BSupportsImmediateTextReturn() { return true; }
void RequestControlString() { Assert( false ); } // no op, we already have the string
// Insert clipboard contents into text entry
void InsertFromClipboard();
// Cut selected text to clipboard
void CutToClipboard();
// Copy selected text to clipboard
void CopyToClipboard();
bool OnInsertFromClipboard( const CPanelPtr< IUIPanel > &pPanel );
bool OnCutToClipboard( const CPanelPtr< IUIPanel > &pPanel );
bool OnCopyToClipboard( const CPanelPtr< IUIPanel > &pPanel );
void SetAlwaysRenderCaret( bool bAlwaysRenderCaret );
// Delete currently selected text
void DeleteSelection( bool bDontPushUndoHistory );
// Clear selection region, leaving nothing selected
void ClearSelection();
// select all the text in the control
void SelectAll();
// Lock the selection in place; it can only be unlocked or deleted
void LockSelection( bool bLockSelection ) { m_bSelectionLocked = bLockSelection; }
// Insert characters at cursor
void InsertCharacterAtCursor( const wchar_t &unichar );
void InsertCharactersAtCursor( const wchar_t *pwch, size_t cwch );
bool BIsValidCharacter( const wchar_t wch );
void RaiseChangeEvents( bool bEnable ) { m_bRaiseChangeEvents = bEnable; }
virtual EMouseCursors GetMouseCursor();
// ITextInputControl helpers
virtual CPanel2D *GetAssociatedPanel() { return this; }
panorama::CTextInputHandler *GetTextInputHandler() { return m_pTextInputHandler.Get(); }
void SetTextInputHandler( panorama::CTextInputHandler *pTextInputHandler );
virtual bool BRequiresFocus() OVERRIDE { return true; }
// Autocomplete
void ClearAutocomplete( void );
void AddAutocomplete( const char *pszOption );
#ifdef DBGFLAG_VALIDATE
virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName );
#endif
int32 GetSelectionStart() { return m_nSelectionStartIndex; }
int32 GetSelectionEnd() { return m_nSelectionEndIndex; }
// Interface for IIMEUITextField
#if defined( SOURCE2_PANORAMA )
virtual void IME_SetLoggingChannel( LoggingChannelID_t loggingChannel ) OVERRIDE;
virtual bool IME_IsEnabled() OVERRIDE;
virtual IMEUIObjectType IME_GetObjectType() OVERRIDE;
virtual wchar_t *IME_GetCompositionString() OVERRIDE;
virtual void IME_CreateCompositionString() OVERRIDE;
virtual void IME_ClearCompositionString() OVERRIDE;
virtual void IME_CommitCompositionString( const wchar_t *pString ) OVERRIDE;
virtual void IME_SetCompositionStringText( const wchar_t *pString ) OVERRIDE;
virtual void IME_SetCompositionStringPosition( uint32 nPos ) OVERRIDE;
virtual void IME_SetCursorInCompositionString( uint32 nPos ) OVERRIDE;
virtual uint32 IME_GetCaretIndex() OVERRIDE;
virtual uint32 IME_GetBeginIndex() OVERRIDE;
virtual uint32 IME_GetEndIndex() OVERRIDE;
virtual void IME_ReplaceCharacters( const wchar_t *pString, uint32 nStart, uint32 nEnd ) OVERRIDE;
virtual void IME_SetSelection( uint32 nStart, uint32 nEnd ) OVERRIDE;
virtual void IME_SetWideCursor( bool bWide ) OVERRIDE;
virtual void IME_HighlightCompositionStringText( uint32 nPos, uint32 nLen, IMETextHighlightStyle highlightStyle ) OVERRIDE;
virtual void IME_DeleteSelection() OVERRIDE;
virtual void IME_RemoveInputWindow() OVERRIDE;
virtual void IME_DisplayInputWindow( const wchar_t *pReadingString, const IMERectF *pPosition ) OVERRIDE;
virtual void IME_RepositionInputWindow( const IMERectF *pPosition ) OVERRIDE;
virtual void IME_CreateList( int nPageSize, int nListStartsAt1 ) OVERRIDE;
virtual void IME_RemoveList() OVERRIDE;
virtual void IME_ClearList() OVERRIDE;
virtual void IME_ShowList( bool bShow ) OVERRIDE;
virtual void IME_RepositionCandidateList( const IMERectF *pPosition ) OVERRIDE;
virtual void IME_SelectItemInList( int32 nItemToSelect ) OVERRIDE;
virtual void IME_AddToList( const wchar_t *pCandidateString ) OVERRIDE;
#endif // defined( SOURCE2_PANORAMA )
protected:
virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions );
virtual bool BIsClientPanelEvent( CPanoramaSymbol symProperty ) OVERRIDE;
private:
bool OnTextEntryShowTextInputHandler( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
bool OnTextEntryHideTextInputHandler( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
bool EventActivated ( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
bool OnTextEntryScrollToCursor( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
bool EventInputFocusTopLevelChanged( CPanelPtr< CPanel2D > ptrPanel );
bool HandleTextInputFinished( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, bool bFinished, char const *pchText );
bool EventInputFocusSet( const CPanelPtr< IUIPanel > &ptrPanel );
bool EventInputFocusLost( const CPanelPtr< IUIPanel > &ptrPanel );
IUITextLayout *CreateTextLayout( float flWidth, float flHeight );
void RemoveCharacter( int32 offset );
void RaiseTextChangedEvent();
void UpdateSelectionToInclude( int32 unPreviousCursor, int32 unNewCursorPos );
void Undo();
void Redo();
void PushUndoStack();
void PushRedoStack();
void UpdateCapsLockWarning();
void OnScheduledCapsLockCheck();
void MoveCaretToEnd( bool bIsShiftHeld );
const wchar_t *PwchGetTextDisplay(); // honors password-entry mode
bool m_bUndoHistoryEnabled;
bool m_bContentSizeDirty; // content size is dirty - text has changed
float m_flMaxWidthLastContentSize;
float m_flMaxHeightLastContentSize;
bool m_bCaretPositionDirty;
bool m_bAlwaysRenderCaret;
bool m_bMayDrawOutsideBounds;
bool m_bShowTextInputHandlerOnLeftMouseUp;
bool m_bSelectionLocked;
bool m_bMultiline; // used to determine whether to swallow multiline-only characters (\n, etc.)
Vector2D m_LastMousePos;
CUtlVector<wchar_t> m_vecWCharData;
CUtlVector<wchar_t> m_vecWCharDataPasswordDisplay;
mutable CUtlString m_UTF8String;
mutable bool m_bUTF8StringInvalid;
uint32 m_unMaxChars;
int32 m_nCursorOffset;
Vector2D m_CaretCoords;
float m_flCaretHeight;
bool m_bLeftMouseIsDown;
bool m_bSelectionRectDirty;
int32 m_nSelectionStartIndex;
int32 m_nSelectionEndIndex;
bool m_bScrollableSizeDirty;
float m_flLastFinalWidthToScrollable;
float m_flLastFinalHeightToScrollable;
// Translation of text in single line entries to scroll to show where the cursor is
float m_flTextXTranslate;
CPanelPtr< CTextInputHandler > m_pTextInputHandler;
CUtlVector<IUITextLayout::HitTestRegionRect_t> m_vecSelectionRects;
panorama::CTextInputHandlerSettings m_settingsTextInput;
CUtlVector< wchar_t * > m_vecUndoStack;
CUtlVector< wchar_t * > m_vecRedoStack;
double m_flFocusTime;
// only raise text changed events when requested, as we have to convert every character to UTF8 from unicode
bool m_bRaiseChangeEvents;
ETextInputMode_t m_modeInput;
bool m_bDisplayInput;
bool m_bWarnOnCapsLock;
panorama::CUIScheduledDel m_scheduledCapsLockCheck;
CLabel *m_pPlaceholderText;
CPanelPtr< CTextEntryAutocomplete > m_pAutocompleteMenu;
#if defined( SOURCE2_PANORAMA )
// IME State
bool m_bIMEWideCursor;
CUtlVector< wchar_t > m_IMECompositionString;
int32 m_nIMECompositionCursor;
int32 m_nIMEStartingCursorInsertionOffset;
int32 m_nIMEEndingCursorInsertionOffset;
bool m_bIMERejectBackspace;
CPanelPtr< CTextEntryIMEControls > m_pIMEControls;
LoggingChannelID_t m_IMELoggingChannel;
#endif // defined( SOURCE2_PANORAMA )
};
class CTextEntryAutocomplete : public CPanel2D
{
DECLARE_PANEL2D( CTextEntryAutocomplete, CPanel2D );
public:
CTextEntryAutocomplete( CTextEntry *pParent, const char *pchPanelID );
virtual ~CTextEntryAutocomplete();
void DeleteSelf( bool bSetFocusToTarget = true );
void AddOption( const char *pszOption );
private:
// forward keys, arrows back to my parent
virtual bool OnKeyDown( const KeyData_t &code );
virtual bool OnKeyUp( const KeyData_t & code );
virtual bool OnKeyTyped( const KeyData_t &unichar );
void PositionNearParent();
virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
// events
bool EventPanelActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
bool EventInputFocusSet( const CPanelPtr< IUIPanel > &pPanel );
void SuggestionSelected( CLabel *pLabel );
CPanelPtr< CTextEntry > m_pTextEntryParent;
bool m_bClosing;
};
#if defined( SOURCE2_PANORAMA )
class CTextEntryIMEControls : public CPanel2D
{
DECLARE_PANEL2D( CTextEntryIMEControls, CPanel2D );
public:
CTextEntryIMEControls( CTextEntry *pParent, const char *pchPanelID );
virtual ~CTextEntryIMEControls();
void ClearCandidateList();
void CreateCandidateList( int nPageSize, int nListStartsAt1 );
void AddCandidate( const wchar_t *pszCandidateString );
void SetSelectedCandidate( int nItemToSelect );
void ShowCandidateList( bool bShow );
void SetReadingString( const wchar_t *pReadingString );
private:
void PositionNearParent();
virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
CPanelPtr< CTextEntry > m_pTextEntryParent;
CPanelPtr< CLabel > m_pReadingStringLabel;
CPanelPtr< CPanel2D > m_pCandidateList;
int m_nCandidateListPageSize;
int m_nCandidateListSelectedIndex;
bool m_bShowCandidateList;
};
#endif // defined( SOURCE2_PANORAMA )
} // namespace panorama
#endif // PANORAMA_TEXTENTRY_H
|