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.

361 lines
12 KiB

  1. //=========== Copyright Valve Corporation, All rights reserved. ===============//
  2. //
  3. // Purpose:
  4. //=============================================================================//
  5. #ifndef PANORAMA_TEXTENTRY_H
  6. #define PANORAMA_TEXTENTRY_H
  7. #ifdef _WIN32
  8. #pragma once
  9. #endif
  10. #include "panel2d.h"
  11. #include "panorama/text/iuitextlayout.h"
  12. #include "panorama/textinput/textinput.h"
  13. #include "panorama/textinput/textinput_settings.h"
  14. #if !defined(SOURCE2_PANORAMA)
  15. #include "../common/globals.h"
  16. #include "../common/reliabletimer.h"
  17. #include "../common/framefunction.h"
  18. #endif
  19. #include "panorama/uischeduleddel.h"
  20. #include "imesystem/imeuiinterface.h"
  21. namespace panorama
  22. {
  23. class CLabel;
  24. class CTextEntryAutocomplete;
  25. #if defined( SOURCE2_PANORAMA )
  26. class CTextEntryIMEControls;
  27. #endif // defined( SOURCE2_PANORAMA )
  28. DECLARE_PANEL_EVENT1( TextEntrySubmit, const char * ); // always raised when user is done submitting text
  29. DECLARE_PANEL_EVENT0( TextEntryChanged ); // call CTextEntry::RaiseChangeEvents() to enable
  30. DECLARE_PANEL_EVENT0( TextEntryShowTextInputHandler );
  31. DECLARE_PANEL_EVENT0( TextEntryHideTextInputHandler );
  32. DECLARE_PANEL_EVENT0( TextEntryInsertFromClipboard );
  33. DECLARE_PANEL_EVENT0( TextEntryCopyToClipboard );
  34. DECLARE_PANEL_EVENT0( TextEntryCutToClipboard );
  35. //-----------------------------------------------------------------------------
  36. // Purpose: text entry
  37. //-----------------------------------------------------------------------------
  38. class CTextEntry : public CPanel2D, public ITextInputControl
  39. #if defined( SOURCE2_PANORAMA )
  40. , public IIMEUITextField
  41. #endif // defined( SOURCE2_PANORAMA )
  42. {
  43. DECLARE_PANEL2D( CTextEntry, CPanel2D );
  44. public:
  45. CTextEntry( CPanel2D *parent, const char * pchPanelID );
  46. virtual ~CTextEntry();
  47. virtual void SetupJavascriptObjectTemplate() OVERRIDE;
  48. void SetUndoHistoryEnabled( bool bEnabled );
  49. void ClearUndoHistory();
  50. virtual bool OnKeyDown( const KeyData_t &code );
  51. virtual bool OnKeyTyped( const KeyData_t &unichar );
  52. virtual bool OnKeyUp( const KeyData_t & code ) { return BaseClass::OnKeyUp( code ); }
  53. virtual void Paint();
  54. virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
  55. virtual void OnInitializedFromLayout();
  56. virtual void OnStylesChanged();
  57. virtual void OnMouseMove( float flMouseX, float flMouseY );
  58. virtual bool OnMouseButtonDown( const MouseData_t &code );
  59. virtual bool OnMouseButtonUp( const MouseData_t &code );
  60. virtual bool OnMouseButtonDoubleClick( const MouseData_t &code );
  61. virtual bool OnMouseButtonTripleClick( const MouseData_t &code );
  62. virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
  63. virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties ) OVERRIDE;
  64. virtual bool BRequiresContentClipLayer() { return m_bMayDrawOutsideBounds; }
  65. void SetMode( ETextInputMode_t mode );
  66. ETextInputMode_t GetMode() { return m_modeInput; }
  67. void SetText( const char *pchValue );
  68. const char *PchGetText() const;
  69. const wchar_t *PwchGetText() const;
  70. void SetPlaceholderText( const char *pchValue );
  71. const char *PchGetPlaceholderText() const;
  72. void SetMaxChars( uint unMaxChars );
  73. uint GetCharCount() const { return m_vecWCharData.Count() - 1; } // m_vecWCharData is terminated, so remove extra char count
  74. uint GetMaxCharCount() const { return m_unMaxChars; }
  75. int32 GetCursorOffset() const { return m_nCursorOffset; }
  76. void SetCursorOffset( int32 nCursoroffset );
  77. bool BSupportsImmediateTextReturn() { return true; }
  78. void RequestControlString() { Assert( false ); } // no op, we already have the string
  79. // Insert clipboard contents into text entry
  80. void InsertFromClipboard();
  81. // Cut selected text to clipboard
  82. void CutToClipboard();
  83. // Copy selected text to clipboard
  84. void CopyToClipboard();
  85. bool OnInsertFromClipboard( const CPanelPtr< IUIPanel > &pPanel );
  86. bool OnCutToClipboard( const CPanelPtr< IUIPanel > &pPanel );
  87. bool OnCopyToClipboard( const CPanelPtr< IUIPanel > &pPanel );
  88. void SetAlwaysRenderCaret( bool bAlwaysRenderCaret );
  89. // Delete currently selected text
  90. void DeleteSelection( bool bDontPushUndoHistory );
  91. // Clear selection region, leaving nothing selected
  92. void ClearSelection();
  93. // select all the text in the control
  94. void SelectAll();
  95. // Lock the selection in place; it can only be unlocked or deleted
  96. void LockSelection( bool bLockSelection ) { m_bSelectionLocked = bLockSelection; }
  97. // Insert characters at cursor
  98. void InsertCharacterAtCursor( const wchar_t &unichar );
  99. void InsertCharactersAtCursor( const wchar_t *pwch, size_t cwch );
  100. bool BIsValidCharacter( const wchar_t wch );
  101. void RaiseChangeEvents( bool bEnable ) { m_bRaiseChangeEvents = bEnable; }
  102. virtual EMouseCursors GetMouseCursor();
  103. // ITextInputControl helpers
  104. virtual CPanel2D *GetAssociatedPanel() { return this; }
  105. panorama::CTextInputHandler *GetTextInputHandler() { return m_pTextInputHandler.Get(); }
  106. void SetTextInputHandler( panorama::CTextInputHandler *pTextInputHandler );
  107. virtual bool BRequiresFocus() OVERRIDE { return true; }
  108. // Autocomplete
  109. void ClearAutocomplete( void );
  110. void AddAutocomplete( const char *pszOption );
  111. #ifdef DBGFLAG_VALIDATE
  112. virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName );
  113. #endif
  114. int32 GetSelectionStart() { return m_nSelectionStartIndex; }
  115. int32 GetSelectionEnd() { return m_nSelectionEndIndex; }
  116. // Interface for IIMEUITextField
  117. #if defined( SOURCE2_PANORAMA )
  118. virtual void IME_SetLoggingChannel( LoggingChannelID_t loggingChannel ) OVERRIDE;
  119. virtual bool IME_IsEnabled() OVERRIDE;
  120. virtual IMEUIObjectType IME_GetObjectType() OVERRIDE;
  121. virtual wchar_t *IME_GetCompositionString() OVERRIDE;
  122. virtual void IME_CreateCompositionString() OVERRIDE;
  123. virtual void IME_ClearCompositionString() OVERRIDE;
  124. virtual void IME_CommitCompositionString( const wchar_t *pString ) OVERRIDE;
  125. virtual void IME_SetCompositionStringText( const wchar_t *pString ) OVERRIDE;
  126. virtual void IME_SetCompositionStringPosition( uint32 nPos ) OVERRIDE;
  127. virtual void IME_SetCursorInCompositionString( uint32 nPos ) OVERRIDE;
  128. virtual uint32 IME_GetCaretIndex() OVERRIDE;
  129. virtual uint32 IME_GetBeginIndex() OVERRIDE;
  130. virtual uint32 IME_GetEndIndex() OVERRIDE;
  131. virtual void IME_ReplaceCharacters( const wchar_t *pString, uint32 nStart, uint32 nEnd ) OVERRIDE;
  132. virtual void IME_SetSelection( uint32 nStart, uint32 nEnd ) OVERRIDE;
  133. virtual void IME_SetWideCursor( bool bWide ) OVERRIDE;
  134. virtual void IME_HighlightCompositionStringText( uint32 nPos, uint32 nLen, IMETextHighlightStyle highlightStyle ) OVERRIDE;
  135. virtual void IME_DeleteSelection() OVERRIDE;
  136. virtual void IME_RemoveInputWindow() OVERRIDE;
  137. virtual void IME_DisplayInputWindow( const wchar_t *pReadingString, const IMERectF *pPosition ) OVERRIDE;
  138. virtual void IME_RepositionInputWindow( const IMERectF *pPosition ) OVERRIDE;
  139. virtual void IME_CreateList( int nPageSize, int nListStartsAt1 ) OVERRIDE;
  140. virtual void IME_RemoveList() OVERRIDE;
  141. virtual void IME_ClearList() OVERRIDE;
  142. virtual void IME_ShowList( bool bShow ) OVERRIDE;
  143. virtual void IME_RepositionCandidateList( const IMERectF *pPosition ) OVERRIDE;
  144. virtual void IME_SelectItemInList( int32 nItemToSelect ) OVERRIDE;
  145. virtual void IME_AddToList( const wchar_t *pCandidateString ) OVERRIDE;
  146. #endif // defined( SOURCE2_PANORAMA )
  147. protected:
  148. virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions );
  149. virtual bool BIsClientPanelEvent( CPanoramaSymbol symProperty ) OVERRIDE;
  150. private:
  151. bool OnTextEntryShowTextInputHandler( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
  152. bool OnTextEntryHideTextInputHandler( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
  153. bool EventActivated ( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
  154. bool OnTextEntryScrollToCursor( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
  155. bool EventInputFocusTopLevelChanged( CPanelPtr< CPanel2D > ptrPanel );
  156. bool HandleTextInputFinished( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, bool bFinished, char const *pchText );
  157. bool EventInputFocusSet( const CPanelPtr< IUIPanel > &ptrPanel );
  158. bool EventInputFocusLost( const CPanelPtr< IUIPanel > &ptrPanel );
  159. IUITextLayout *CreateTextLayout( float flWidth, float flHeight );
  160. void RemoveCharacter( int32 offset );
  161. void RaiseTextChangedEvent();
  162. void UpdateSelectionToInclude( int32 unPreviousCursor, int32 unNewCursorPos );
  163. void Undo();
  164. void Redo();
  165. void PushUndoStack();
  166. void PushRedoStack();
  167. void UpdateCapsLockWarning();
  168. void OnScheduledCapsLockCheck();
  169. void MoveCaretToEnd( bool bIsShiftHeld );
  170. const wchar_t *PwchGetTextDisplay(); // honors password-entry mode
  171. bool m_bUndoHistoryEnabled;
  172. bool m_bContentSizeDirty; // content size is dirty - text has changed
  173. float m_flMaxWidthLastContentSize;
  174. float m_flMaxHeightLastContentSize;
  175. bool m_bCaretPositionDirty;
  176. bool m_bAlwaysRenderCaret;
  177. bool m_bMayDrawOutsideBounds;
  178. bool m_bShowTextInputHandlerOnLeftMouseUp;
  179. bool m_bSelectionLocked;
  180. bool m_bMultiline; // used to determine whether to swallow multiline-only characters (\n, etc.)
  181. Vector2D m_LastMousePos;
  182. CUtlVector<wchar_t> m_vecWCharData;
  183. CUtlVector<wchar_t> m_vecWCharDataPasswordDisplay;
  184. mutable CUtlString m_UTF8String;
  185. mutable bool m_bUTF8StringInvalid;
  186. uint32 m_unMaxChars;
  187. int32 m_nCursorOffset;
  188. Vector2D m_CaretCoords;
  189. float m_flCaretHeight;
  190. bool m_bLeftMouseIsDown;
  191. bool m_bSelectionRectDirty;
  192. int32 m_nSelectionStartIndex;
  193. int32 m_nSelectionEndIndex;
  194. bool m_bScrollableSizeDirty;
  195. float m_flLastFinalWidthToScrollable;
  196. float m_flLastFinalHeightToScrollable;
  197. // Translation of text in single line entries to scroll to show where the cursor is
  198. float m_flTextXTranslate;
  199. CPanelPtr< CTextInputHandler > m_pTextInputHandler;
  200. CUtlVector<IUITextLayout::HitTestRegionRect_t> m_vecSelectionRects;
  201. panorama::CTextInputHandlerSettings m_settingsTextInput;
  202. CUtlVector< wchar_t * > m_vecUndoStack;
  203. CUtlVector< wchar_t * > m_vecRedoStack;
  204. double m_flFocusTime;
  205. // only raise text changed events when requested, as we have to convert every character to UTF8 from unicode
  206. bool m_bRaiseChangeEvents;
  207. ETextInputMode_t m_modeInput;
  208. bool m_bDisplayInput;
  209. bool m_bWarnOnCapsLock;
  210. panorama::CUIScheduledDel m_scheduledCapsLockCheck;
  211. CLabel *m_pPlaceholderText;
  212. CPanelPtr< CTextEntryAutocomplete > m_pAutocompleteMenu;
  213. #if defined( SOURCE2_PANORAMA )
  214. // IME State
  215. bool m_bIMEWideCursor;
  216. CUtlVector< wchar_t > m_IMECompositionString;
  217. int32 m_nIMECompositionCursor;
  218. int32 m_nIMEStartingCursorInsertionOffset;
  219. int32 m_nIMEEndingCursorInsertionOffset;
  220. bool m_bIMERejectBackspace;
  221. CPanelPtr< CTextEntryIMEControls > m_pIMEControls;
  222. LoggingChannelID_t m_IMELoggingChannel;
  223. #endif // defined( SOURCE2_PANORAMA )
  224. };
  225. class CTextEntryAutocomplete : public CPanel2D
  226. {
  227. DECLARE_PANEL2D( CTextEntryAutocomplete, CPanel2D );
  228. public:
  229. CTextEntryAutocomplete( CTextEntry *pParent, const char *pchPanelID );
  230. virtual ~CTextEntryAutocomplete();
  231. void DeleteSelf( bool bSetFocusToTarget = true );
  232. void AddOption( const char *pszOption );
  233. private:
  234. // forward keys, arrows back to my parent
  235. virtual bool OnKeyDown( const KeyData_t &code );
  236. virtual bool OnKeyUp( const KeyData_t & code );
  237. virtual bool OnKeyTyped( const KeyData_t &unichar );
  238. void PositionNearParent();
  239. virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
  240. // events
  241. bool EventPanelActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
  242. bool EventInputFocusSet( const CPanelPtr< IUIPanel > &pPanel );
  243. void SuggestionSelected( CLabel *pLabel );
  244. CPanelPtr< CTextEntry > m_pTextEntryParent;
  245. bool m_bClosing;
  246. };
  247. #if defined( SOURCE2_PANORAMA )
  248. class CTextEntryIMEControls : public CPanel2D
  249. {
  250. DECLARE_PANEL2D( CTextEntryIMEControls, CPanel2D );
  251. public:
  252. CTextEntryIMEControls( CTextEntry *pParent, const char *pchPanelID );
  253. virtual ~CTextEntryIMEControls();
  254. void ClearCandidateList();
  255. void CreateCandidateList( int nPageSize, int nListStartsAt1 );
  256. void AddCandidate( const wchar_t *pszCandidateString );
  257. void SetSelectedCandidate( int nItemToSelect );
  258. void ShowCandidateList( bool bShow );
  259. void SetReadingString( const wchar_t *pReadingString );
  260. private:
  261. void PositionNearParent();
  262. virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
  263. CPanelPtr< CTextEntry > m_pTextEntryParent;
  264. CPanelPtr< CLabel > m_pReadingStringLabel;
  265. CPanelPtr< CPanel2D > m_pCandidateList;
  266. int m_nCandidateListPageSize;
  267. int m_nCandidateListSelectedIndex;
  268. bool m_bShowCandidateList;
  269. };
  270. #endif // defined( SOURCE2_PANORAMA )
  271. } // namespace panorama
  272. #endif // PANORAMA_TEXTENTRY_H