aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/vgui_controls/RichText.h
blob: 704ef08b7ab23c7387be5c5eeb16c8f4db61ad51 (plain) (blame)
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
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================//

#ifndef RICHTEXT_H
#define RICHTEXT_H

#ifdef _WIN32
#pragma once
#endif

#include <vgui_controls/Panel.h>
#include <utlvector.h>

namespace vgui
{

class ClickPanel;

//-----------------------------------------------------------------------------
// Purpose: Non-editable display of a rich text control
//-----------------------------------------------------------------------------
class RichText : public Panel
{
	DECLARE_CLASS_SIMPLE( RichText, Panel );

public:
	RichText(Panel *parent, const char *panelName);
	~RichText();

	// text manipulation
	virtual void SetText(const char *text);
	virtual void SetText(const wchar_t *text);
	void GetText(int offset, OUT_Z_BYTECAP(bufLenInBytes) wchar_t *buf, int bufLenInBytes);
	void GetText(int offset, OUT_Z_BYTECAP(bufLenInBytes) char *pch, int bufLenInBytes);

	// configuration
	void SetFont(HFont font);

	// inserts characters at the end of the stream
	void InsertChar(wchar_t ch);
	void InsertString(const char *text);
	void InsertString(const wchar_t *wszText);
	
	// selection
	void SelectNone();
	void SelectAllText();
	void SelectNoText();
	MESSAGE_FUNC( CutSelected, "DoCutSelected" );
	MESSAGE_FUNC( CopySelected, "DoCopySelected" );

	// sets the RichText control interactive or not (meaning you can select/copy text in the window)
	void SetPanelInteractive( bool bInteractive ){ m_bInteractive = bInteractive; }

	// sets the RichText scrollbar invisible if it's not going to be used
	void SetUnusedScrollbarInvisible( bool bInvis ){ m_bUnusedScrollbarInvis = bInvis; }

	// cursor movement
	void GotoTextStart();	// go to start of text buffer
	void GotoTextEnd();	// go to end of text buffer

	// configuration
	// sets visibility of scrollbar
	void SetVerticalScrollbar(bool state);
	// sets limit of number of characters insertable into field; set to -1 to remove maximum
	// only works with if rich-edit is NOT enabled
	void SetMaximumCharCount(int maxChars);

	// rich edit commands
	void InsertColorChange(Color col);
	// IndentChange doesn't take effect until the next newline character
	void InsertIndentChange(int pixelsIndent);
	// clickable text
	// notification that text was clicked is through "TextClicked" message
	void InsertClickableTextStart( const char *pchClickAction = NULL );
	void InsertClickableTextEnd();
	// inserts a string that needs to be scanned for urls/mailto commands to be made clickable
	void InsertPossibleURLString(const char *text, Color URLTextColor, Color normalTextColor);

	void InsertFade( float flSustain, float flLength );

	void ResetAllFades( bool bHold, bool bOnlyExpired = false, float flNewSustain = -1.0f );

	// sets the height of the window so all text is visible.
	// used by tooltips
	void SetToFullHeight();
	int GetNumLines();

	/* CUSTOM MESSAGE HANDLING
		"SetText"
			input:	"text"	- text is set to be this string
	*/

	/* MESSAGE SENDING (to action signal targets)
		"TextChanged"	- sent when the text is edited by the user
			
		
		"TextClicked"	- sent when clickable text has been clicked on
			"text"	- the text that was clicked on
	*/

	virtual bool RequestInfo(KeyValues *outputData);
	/* INFO HANDLING
		"GetText"
			returns:
				"text" - text contained in the text box
	*/
	virtual void SetFgColor( Color color );
	virtual void SetDrawOffsets( int ofsx, int ofsy );
	bool IsScrollbarVisible();

	// sets how URL's are handled
	// if set, a "URLClicked" "url" "<data>" message will be sent to that panel
	void SetURLClickedHandler( Panel *pPanelToHandleClickMsg );

	void SetUnderlineFont( HFont font );

	bool IsAllTextAlphaZero() const;
	bool HasText() const;

	void SetDrawTextOnly();

protected:
	virtual void OnThink();
	virtual void PerformLayout();  // layout the text in the window
	virtual void ApplySchemeSettings(IScheme *pScheme);
	virtual void Paint();

	virtual void ApplySettings( KeyValues *inResourceData );
	virtual void GetSettings( KeyValues *outResourceData );
	virtual const char *GetDescription( void );
	MESSAGE_FUNC_WCHARPTR( OnSetText, "SetText", text );
	MESSAGE_FUNC( OnSliderMoved, "ScrollBarSliderMoved" ); // respond to scroll bar events
	virtual void OnKillFocus();
	virtual void OnMouseWheeled(int delta);	// respond to mouse wheel events
	virtual void OnKeyCodeTyped(KeyCode code);	//respond to keyboard events
	
	MESSAGE_FUNC_INT( OnClickPanel, "ClickPanel", index);

	virtual void OnCursorMoved(int x, int y);  // respond to moving the cursor with mouse button down
	virtual void OnMousePressed(MouseCode code); // respond to mouse down events
	virtual void OnMouseDoublePressed(MouseCode code);
	virtual void OnMouseReleased(MouseCode code);	// respond to mouse up events

	virtual void OnMouseFocusTicked(); // do while window has mouse focus
	virtual void OnCursorEntered();	 // handle cursor entering window
	virtual void OnCursorExited();	 // handle cursor exiting window

	virtual void OnMouseCaptureLost(); 
	virtual void OnSizeChanged(int newWide, int newTall);
	virtual void OnSetFocus();

	// clickable url handling
	int ParseTextStringForUrls(const char *text, int startPos, char *pchURLText, int cchURLText, char *pchURL, int cchURL, bool &clickable);
	virtual void OnTextClicked(const wchar_t *text);

#ifdef DBGFLAG_VALIDATE
	virtual void Validate( CValidator &validator, char *pchName );
#endif // DBGFLAG_VALIDATE
	
protected:
	ScrollBar			*_vertScrollBar;	// the scroll bar used in the window

private:
	int GetLineHeight();
	HFont GetDefaultFont();

	const wchar_t *ResolveLocalizedTextAndVariables( char const *pchLookup, OUT_Z_BYTECAP(outbufsizeinbytes) wchar_t *outbuf, size_t outbufsizeinbytes );
	void CheckRecalcLineBreaks();

	void GotoWordRight();	// move cursor to start of next word
	void GotoWordLeft();	// move cursor to start of prev word

	void TruncateTextStream();
	bool GetSelectedRange(int& cx0,int& cx1);
	void CursorToPixelSpace(int cursorPos, int &cx, int &cy);
	int PixelToCursorSpace(int cx, int cy);
	void AddAnotherLine(int &cx, int &cy);
	void RecalculateDefaultState(int startIndex);

	void LayoutVerticalScrollBarSlider();
	void OpenEditMenu();
	void FinishingURL(int x, int y);
	// Returns the character index the drawing should Start at
	int GetStartDrawIndex(int &lineBreakIndexIndex);
	int GetCursorLine();
	int GetClickableTextIndexStart(int startIndex); 
	void CreateEditMenu(); // create copy/cut/paste menu

	MESSAGE_FUNC_INT( MoveScrollBar, "MoveScrollBar", delta );
	MESSAGE_FUNC_INT( MoveScrollBarDirect, "MoveScrollBarDirect", delta );

	// linebreak stream functions
	void InvalidateLineBreakStream();
	void RecalculateLineBreaks();

	struct TFade
	{
		float flFadeStartTime;
		float flFadeLength;
		float flFadeSustain;
		int  iOriginalAlpha;
	};

	// format stream - describes changes in formatting for the text stream
	struct TFormatStream
	{
		// render state
		Color color;
		int pixelsIndent;
		bool textClickable;
		CUtlSymbol m_sClickableTextAction;

		TFade fade;

		// position in TextStream that these changes take effect
		int textStreamIndex;
	};

	bool m_bResetFades;
	bool m_bInteractive;
	bool m_bUnusedScrollbarInvis;
	bool m_bAllTextAlphaIsZero;

	// data
	CUtlVector<wchar_t>   m_TextStream;		// the text in the text window is stored in this buffer
	CUtlVector<int>	   m_LineBreaks;		// an array that holds the index in the buffer to wrap lines at
	CUtlVector<TFormatStream> m_FormatStream;	// list of format changes

	bool m_bRecalcLineBreaks;

	int	_recalculateBreaksIndex;			// tells next linebreakindex index to Start recalculating line breaks	
	bool			   _invalidateVerticalScrollbarSlider;
	int                _cursorPos;			// the position in the text buffer of the blinking cursor
	bool			   _mouseSelection;		// whether we are highlighting text or not (selecting text)
	bool			   _mouseDragSelection;	// tells weather mouse is outside window and button is down so we select text
	int                _select[2];			// select[1] is the offset in the text to where the cursor is currently
											// select[0] is the offset to where the cursor was dragged to. or -1 if no drag.
	int				   _pixelsIndent;
	int				   _maxCharCount;		// max number of chars that can be in the text buffer
	HFont              _font;				// font of chars in the text buffer
	HFont			   m_hFontUnderline;
	Color			   _selectionColor;
	Color			   _selectionTextColor;	// color of the highlighted text
	bool			   _currentTextClickable;
	CUtlVector<ClickPanel *>  _clickableTextPanels;
	int				   _clickableTextIndex;
	Color				_defaultTextColor;
	int					_drawOffsetX;
	int					_drawOffsetY;

	Panel				*m_pInterior;
	PHandle				m_hPanelToHandleClickingURLs;


	// sub-controls
	Menu				*m_pEditMenu;		// cut/copy/paste popup

	char				*m_pszInitialText;	// initial text

	// saved state
	bool _recalcSavedRenderState;
	
	struct TRenderState
	{
		// rendering positions
		int x, y;
		
		// basic state
		Color textColor;
		int pixelsIndent;
		bool textClickable;

		// index into our current position in the formatting stream
		int formatStreamIndex;
	};
	TRenderState m_CachedRenderState;	// cached render state for the beginning of painting

	// updates a render state based on the formatting and color streams
	// returns true if any state changed
	bool UpdateRenderState(int textStreamPos, TRenderState &renderState);
	void CalculateFade( TRenderState &renderState );

	void GenerateRenderStateForTextStreamIndex(int textStreamIndex, TRenderState &renderState);
	int FindFormatStreamIndexForTextStreamPos(int textStreamIndex);

	// draws a string of characters with the same formatting using the current render state
	int DrawString(int iFirst, int iLast, TRenderState &renderState, HFont font);
};

} // namespace vgui


#endif // RICHTEXT_H