File: CInput.h

package info (click to toggle)
0ad 0.0.26-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 130,460 kB
  • sloc: cpp: 261,824; ansic: 198,392; javascript: 19,067; python: 14,557; sh: 7,629; perl: 4,072; xml: 849; makefile: 741; java: 533; ruby: 229; php: 190; pascal: 30; sql: 21; tcl: 4
file content (241 lines) | stat: -rw-r--r-- 7,197 bytes parent folder | download | duplicates (4)
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
/* Copyright (C) 2022 Wildfire Games.
 * This file is part of 0 A.D.
 *
 * 0 A.D. is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * 0 A.D. is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef INCLUDED_CINPUT
#define INCLUDED_CINPUT

#include "gui/CGUISprite.h"
#include "gui/ObjectBases/IGUIObject.h"
#include "gui/ObjectBases/IGUIScrollBarOwner.h"
#include "gui/SettingTypes/CGUIString.h"
#include "lib/external_libraries/libsdl.h"

#include <list>
#include <vector>

/**
 * Text field where you can input and edit the text.
 *
 * It doesn't use IGUITextOwner, because we don't need
 * any other features than word-wrapping, and we need to be
 * able to rapidly change the string.
 */
class CInput : public IGUIObject, public IGUIScrollBarOwner
{
	GUI_OBJECT(CInput)

protected: // forwards
	struct SRow;

public:
	CInput(CGUI& pGUI);
	virtual ~CInput();

	/**
	 * @see IGUIObject#ResetStates()
	 */
	virtual void ResetStates();

	// Check where the mouse is hovering, and get the appropriate text position.
	//  return is the text-position index.
	int GetMouseHoveringTextPosition() const;

	// Same as above, but only on one row in X, and a given value, not the mouse's.
	//  wanted is filled with x if the row didn't extend as far as the mouse pos.
	int GetXTextPosition(const std::list<SRow>::const_iterator& c, const float& x, float& wanted) const;

protected:

	void SetupGeneratedPlaceholderText();

	/**
	 * @see IGUIObject#HandleMessage()
	 */
	virtual void HandleMessage(SGUIMessage& Message);

	/**
	 * Handle events manually to catch keyboard inputting.
	 */
	virtual InReaction ManuallyHandleKeys(const SDL_Event_* ev);

	/**
	 * Handle events manually to catch keys which change the text.
	 */
	virtual void ManuallyMutableHandleKeyDownEvent(const SDL_Keycode keyCode);

	/**
	 * Handle events manually to catch keys which don't change the text.
	 */
	virtual void ManuallyImmutableHandleKeyDownEvent(const SDL_Keycode keyCode);

	/**
	 * Handle hotkey events (called by ManuallyHandleKeys)
	 */
	virtual InReaction ManuallyHandleHotkeyEvent(const SDL_Event_* ev);

	/**
	 * @see IGUIObject#UpdateCachedSize()
	 */
	virtual void UpdateCachedSize();

	/**
	 * Draws the Text
	 */
	virtual void Draw(CCanvas2D& canvas);

	void DrawContent(CCanvas2D& canvas);

	/**
	 * Calculate m_CharacterPosition
	 * the main task for this function is to perfom word-wrapping
	 * You input from which character it has been changed, because
	 * if we add a character to the very last end, we don't want
	 * process everything all over again! Also notice you can
	 * specify a 'to' also, it will only be used though if a '\n'
	 * appears, because then the word-wrapping won't change after
	 * that.
	 */
	void UpdateText(int from = 0, int to_before = -1, int to_after = -1);

	/**
	 * Draws the text generated for placeholder.
	 *
	 * @param canvas Canvas to draw on.
	 * @param clipping Clipping rectangle, don't even add a parameter
	 *        to get no clipping.
	 */
	virtual void DrawPlaceholderText(CCanvas2D& canvas, const CRect& clipping = CRect());

	/**
	 * Delete the current selection. Also places the pointer at the
	 * crack between the two segments kept.
	 */
	void DeleteCurSelection();

	/**
	 * Is text selected? It can be denote two ways, m_iBufferPos_Tail
	 * being -1 or the same as m_iBufferPos. This makes for clearer
	 * code.
	 */
	bool SelectingText() const;

	/// Get area of where text can be drawn.
	float GetTextAreaWidth();

	/// Called every time the auto-scrolling should be checked.
	void UpdateAutoScroll();

	/// Clear composed IME input when supported (SDL2 only).
	void ClearComposedText();

	/// Updates the buffer (cursor) position exposed to JS.
	void UpdateBufferPositionSetting();
protected:
	/// Cursor position
	int m_iBufferPos;
	/// Cursor position we started to select from. (-1 if not selecting)
	/// (NB: Can be larger than m_iBufferPos if selecting from back to front.)
	int m_iBufferPos_Tail;

	/// If we're composing text with an IME
	bool m_ComposingText;
	/// The length and position of the current IME composition
	int m_iComposedLength, m_iComposedPos;
	/// The position to insert committed text
	int m_iInsertPos;

	// the outer vector is lines, and the inner is X positions
	//  in a row. So that we can determine where characters are
	//  placed. It's important because we need to know where the
	//  pointer should be placed when the input control is pressed.
	struct SRow
	{
		// Where the Row starts
		int m_ListStart;

		// List of X values for each character.
		std::vector<float> m_ListOfX;
	};

	/**
	 * List of rows to ease changing its size, so iterators stay valid.
	 * For one-liners only one row is used.
	 */
	std::list<SRow> m_CharacterPositions;

	// *** Things for a multi-lined input control *** //

	/**
	 * When you change row with up/down, and the row you jump to does
	 * not have anything at that X position, then it will keep the
	 * m_WantedX position in mind when switching to the next row.
	 * It will keep on being used until it reach a row which meets the
	 * requirements.
	 * 0.0f means not in use.
	 */
	float m_WantedX;

	/**
	 * If we are in the process of selecting a larger selection of text
	 * using the mouse click (hold) and drag, this is true.
	 */
	bool m_SelectingText;

	/**
	 * Whether the cached text is currently valid (if not then SetupText will be called by Draw)
	 */
	bool m_GeneratedPlaceholderTextValid;

	CGUIText m_GeneratedPlaceholderText;

	// *** Things for one-line input control *** //
	float m_HorizontalScroll;

	/// Used to store the previous time for flashing the cursor.
	double m_PrevTime;

	/// Cursor blink rate in seconds, if greater than 0.0.
	double m_CursorBlinkRate;

	/// If the cursor should be drawn or not.
	bool m_CursorVisState;

	static const CStr EventNameTextEdit;
	static const CStr EventNamePress;
	static const CStr EventNameTab;

	CGUISimpleSetting<i32> m_BufferPosition;
	CGUISimpleSetting<float> m_BufferZone;
	CGUISimpleSetting<CStrW> m_Caption;
	CGUISimpleSetting<CGUIString> m_PlaceholderText;
	CGUISimpleSetting<CStrW> m_Font;
	CGUISimpleSetting<CStrW> m_MaskChar;
	CGUISimpleSetting<bool> m_Mask;
	CGUISimpleSetting<i32> m_MaxLength;
	CGUISimpleSetting<bool> m_MultiLine;
	CGUISimpleSetting<bool> m_Readonly;
	CGUISimpleSetting<bool> m_ScrollBar;
	CGUISimpleSetting<CStr> m_ScrollBarStyle;
	CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
	CGUISimpleSetting<CGUISpriteInstance> m_SpriteOverlay;
	CGUISimpleSetting<CGUISpriteInstance> m_SpriteSelectArea;
	CGUISimpleSetting<CGUIColor> m_TextColor;
	CGUISimpleSetting<CGUIColor> m_TextColorSelected;
	CGUISimpleSetting<CGUIColor> m_PlaceholderColor;
};

#endif // INCLUDED_CINPUT