1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #ifndef MYGUI_EDIT_BOX_H_
8 #define MYGUI_EDIT_BOX_H_
9 
10 #include "MyGUI_Prerequest.h"
11 #include "MyGUI_TextBox.h"
12 #include "MyGUI_TextChangeHistory.h"
13 #include "MyGUI_TextIterator.h"
14 #include "MyGUI_EventPair.h"
15 #include "MyGUI_ScrollViewBase.h"
16 
17 namespace MyGUI
18 {
19 
20 	typedef delegates::CMultiDelegate1<EditBox*> EventHandle_EditPtr;
21 
22 	/** \brief @wpage{EditBox}
23 		EditBox widget description should be here.
24 	*/
25 	class MYGUI_EXPORT EditBox :
26 		public TextBox,
27 		public ScrollViewBase,
28 		public MemberObsolete<EditBox>
29 	{
30 		MYGUI_RTTI_DERIVED( EditBox )
31 
32 	public:
33 		EditBox();
34 
35 		/** Colour interval */
36 		void setTextIntervalColour(size_t _start, size_t _count, const Colour& _colour);
37 
38 		/** Get index of first selected character or ITEM_NONE if nothing selected */
39 		size_t getTextSelectionStart() const;
40 
41 		/** Get index of last selected character or ITEM_NONE if nothing selected */
42 		size_t getTextSelectionEnd() const;
43 
44 		/** Get length of selected text */
45 		size_t getTextSelectionLength() const;
46 
47 		// возвращает текст с тегами
48 		/** Get _count characters with tags from _start position */
49 		UString getTextInterval(size_t _start, size_t _count);
50 
51 		/** Set selected text interval
52 			@param _start of interval
53 			@param _end of interval
54 		*/
55 		void setTextSelection(size_t _start, size_t _end);
56 
57 		/** Delete selected text */
58 		void deleteTextSelection();
59 
60 		/** Get selected text */
61 		UString getTextSelection();
62 
63 		/** Is any text selected */
64 		bool isTextSelection() const;
65 
66 		/** Colour selected text */
67 		void setTextSelectionColour(const Colour& _value);
68 
69 		/** Set text cursor position */
70 		void setTextCursor(size_t _index);
71 		/** Get text cursor position */
72 		size_t getTextCursor() const;
73 
74 
75 		/** Set edit text applying tags */
76 		virtual void setCaption(const UString& _value);
77 		/** Get edit text with tags */
78 		const UString& getCaption() override;
79 
80 		/** Set edit text without tags */
81 		void setOnlyText(const UString& _value);
82 		/** Get edit text without tags */
83 		UString getOnlyText();
84 
85 		/** Get text length excluding tags
86 			For example "Hello" length is 5
87 			and "#00FF00Hello!" length is 6
88 		*/
89 		size_t getTextLength() const;
90 
91 		//! Sets if surplus characters should push characters off the left side rather than ignored
92 		void setOverflowToTheLeft(bool _value);
93 		//! Returns true if surplus characters will be pushed off the left rather than ignored
94 		bool getOverflowToTheLeft() const;
95 
96 		//! Sets the max amount of text allowed in the edit field.
97 		void setMaxTextLength(size_t _value);
98 		//! Gets the max amount of text allowed in the edit field.
99 		size_t getMaxTextLength() const;
100 
101 		/** Inser text at _index position (text end by default) */
102 		void insertText(const UString& _text, size_t _index = ITEM_NONE);
103 		/** Add text */
104 		void addText(const UString& _text);
105 		/** Erase _count characters from _start position */
106 		void eraseText(size_t _start, size_t _count = 1);
107 
108 		/** Enable or disable edit read only mode\n
109 			Read only mode: you can't edit text, but can select it.\n
110 			Disabled (false) by default.
111 		*/
112 		void setEditReadOnly(bool _value);
113 		/** Get edit read only mode flag */
114 		bool getEditReadOnly() const;
115 
116 		/** Enable or disable edit password mode\n
117 			Password mode: you see password chars (*** by default) instead text.\n
118 			Disabled (false) by default.
119 		*/
120 		void setEditPassword(bool _value);
121 		/** Get edit password mode flag */
122 		bool getEditPassword() const;
123 
124 		/** Enable or disable edit multiline mode\n
125 			Multile mode: new line character moves text to new line.\n
126 			Otherwise new lines replaced with space and all text is in single line.\n
127 			Disabled (false) by default.
128 		*/
129 		void setEditMultiLine(bool _value);
130 		/** Get edit multiline mode flag */
131 		bool getEditMultiLine() const;
132 
133 		/** Enable or disable edit static mode\n
134 			Static mode is same as read only, but you also can't select text.\n
135 			Disabled (false) by default.
136 		*/
137 		void setEditStatic(bool _value);
138 		/** Get edit static mode flag */
139 		bool getEditStatic() const;
140 
141 		/** Set edit password character ('*' by default) */
142 		void setPasswordChar(Char _value);
143 		/** Set edit password character ('*' by default). First character of string used. */
144 		void setPasswordChar(const UString& _char);
145 		/** Get edit password character */
146 		Char getPasswordChar() const;
147 
148 		/** Enable or disable edit word wrap mode\n
149 			Word Wrap mode: move words to new line if they goes out of width.
150 			Also in this mode you can't edit or select text.\n
151 			Disabled (false) by default.
152 		*/
153 		void setEditWordWrap(bool _value);
154 		/** Get edit word wrap mode flag */
155 		bool getEditWordWrap() const;
156 
157 		/** Enable or disable tab printing mode\n
158 			Tab printing mode: when editing text and pressing Tab key it displayed.
159 			If this mode disabled Tab key ignored.\n
160 			Disabled (false) by default.
161 		*/
162 		void setTabPrinting(bool _value);
163 		/** Get edit tab printing wrap mode flag */
164 		bool getTabPrinting() const;
165 
166 		/** Get invert selected text color property */
167 		bool getInvertSelected();
168 		/** Enable or disable inverting color of selected text\n
169 			Enabled (true) by default
170 		*/
171 		void setInvertSelected(bool _value);
172 
173 		//! @copydoc Widget::setPosition(const IntPoint& _value)
174 		void setPosition(const IntPoint& _value) override;
175 		//! @copydoc Widget::setSize(const IntSize& _value)
176 		void setSize(const IntSize& _value) override;
177 		//! @copydoc Widget::setCoord(const IntCoord& _value)
178 		void setCoord(const IntCoord& _value) override;
179 
180 		using Widget::setPosition;
181 		using Widget::setSize;
182 		using Widget::setCoord;
183 
184 		/** Show VScroll when text size larger than EditBox */
185 		void setVisibleVScroll(bool _value);
186 		/** Get Show VScroll flag */
187 		bool isVisibleVScroll() const;
188 		/** Get range of vertical scroll (or 0 if no scroll).
189 			Range measured in pixels (full text heiht minus EditBox height).
190 			For example if EditBox is 200 pixels height and 40 lines of text
191 			30 pixels height each (i.e. 600 pixels total), then return
192 			value is 400 ( = 600 - 200 ).
193 		*/
194 		size_t getVScrollRange() const;
195 		/** Get current position of vertical scroll (or 0 if no scroll) */
196 		size_t getVScrollPosition();
197 		/** Set current position of vertical scroll */
198 		void setVScrollPosition(size_t _index);
199 
200 		/** Show HScroll when text size larger than EditBox */
201 		void setVisibleHScroll(bool _value);
202 		/** Get Show HScroll flag */
203 		bool isVisibleHScroll() const;
204 		/** Get range of horizontal scroll (or 0 if no scroll).
205 			Range measured in pixels (full text width minus EditBox width).
206 			For example if EditBox is 200 pixels width and the longest line
207 			is 600 pixels width, then return value is 400 ( = 600 - 200 ).
208 		*/
209 		size_t getHScrollRange() const;
210 		/** Get current position of horizontal scroll (or 0 if no scroll) */
211 		size_t getHScrollPosition();
212 		/** Set current position of horizontal scroll */
213 		void setHScrollPosition(size_t _index);
214 
215 
216 		//! @copydoc TextBox::setFontName
217 		void setFontName(const std::string& _value) override;
218 		//! @copydoc TextBox::setFontHeight
219 		void setFontHeight(int _value) override;
220 
221 		//! @copydoc TextBox::setTextAlign
222 		void setTextAlign(Align _value) override;
223 		//! @copydoc TextBox::setTextColour
224 		void setTextColour(const Colour& _value) override;
225 
226 		//! @copydoc TextBox::getTextRegion
227 		IntCoord getTextRegion() override;
228 
229 		//! @copydoc TextBox::getTextSize
230 		IntSize getTextSize() override;
231 
232 		//! @copydoc TextBox::setTextShadowColour
233 		void setTextShadowColour(const Colour& _value) override;
234 
235 		//! @copydoc TextBox::setTextShadow
236 		void setTextShadow(bool _value) override;
237 
238 		/*events:*/
239 		/** Event : Enter pressed (Ctrl+enter in multiline mode).\n
240 			signature : void method(MyGUI::EditBox* _sender)
241 			@param _sender widget that called this event
242 		*/
243 		EventPair<EventHandle_WidgetVoid, EventHandle_EditPtr> eventEditSelectAccept;
244 
245 		/** Event : Text changed.\n
246 			signature : void method(MyGUI::EditBox* _sender)
247 			@param _sender widget that called this event
248 		*/
249 		EventPair<EventHandle_WidgetVoid, EventHandle_EditPtr> eventEditTextChange;
250 
251 	protected:
252 		void initialiseOverride() override;
253 		void shutdownOverride() override;
254 
255 		void onMouseDrag(int _left, int _top, MouseButton _id) override;
256 		void onKeyLostFocus(Widget* _new) override;
257 		void onKeySetFocus(Widget* _old) override;
258 		void onKeyButtonPressed(KeyCode _key, Char _char) override;
259 
260 		// потом убрать все нотифи в сраку
261 		void notifyMouseSetFocus(Widget* _sender, Widget* _old);
262 		void notifyMouseLostFocus(Widget* _sender, Widget* _new);
263 		void notifyMousePressed(Widget* _sender, int _left, int _top, MouseButton _id);
264 		void notifyMouseReleased(Widget* _sender, int _left, int _top, MouseButton _id);
265 		void notifyMouseDrag(Widget* _sender, int _left, int _top, MouseButton _id);
266 		void notifyMouseButtonDoubleClick(Widget* _sender);
267 
268 		void notifyScrollChangePosition(ScrollBar* _sender, size_t _position);
269 		void notifyMouseWheel(Widget* _sender, int _rel);
270 
271 		// обновление представления
272 		void updateView();
273 		void updateViewWithCursor();
274 
275 		void eraseView();
276 
277 		void setPropertyOverride(const std::string& _key, const std::string& _value) override;
278 
279 	private:
280 		// устанавливает текст
281 		void setText(const UString& _text, bool _history);
282 		// удаляет все что выделенно
283 		bool deleteTextSelect(bool _history);
284 		// вставляет текст в указанную позицию
285 		void insertText(const UString& _text, size_t _index, bool _history);
286 		// удаляет текст
287 		void eraseText(size_t _start, size_t _count, bool _history);
288 		// выделяет цветом выделение
289 		void setTextSelectColour(const Colour& _colour, bool _history);
290 		// выделяет цветом диапазон
291 		void _setTextColour(size_t _start, size_t _count, const Colour& _colour, bool _history);
292 
293 		void frameEntered(float _frame);
294 
295 		void updateEditState();
296 
297 		// обновляет курсор по координате
298 		void updateSelectText();
299 
300 		void resetSelect();
301 
302 		// запись в историю данных о позиции
303 		void commandPosition(size_t _undo, size_t _redo, size_t _length, VectorChangeInfo* _info = nullptr);
304 
305 		// команнды отмена и повтор
306 		bool commandRedo();
307 		bool commandUndo();
308 		// объединяет последние две комманды
309 		void commandMerge();
310 		// очистка
311 		void commandResetRedo();
312 		void commandResetHistory();
313 		void saveInHistory(VectorChangeInfo* _info = nullptr);
314 
315 		// работа с буфером обмена
316 		void commandCut();
317 		void commandCopy();
318 		void commandPast();
319 
320 		const UString& getRealString();
321 
322 		void setRealString(const UString& _caption);
323 
324 		void updateCursorPosition();
325 
326 		// размер данных
327 		IntSize getContentSize() override;
328 		// смещение данных
329 		IntPoint getContentPosition() override;
330 		void setContentPosition(const IntPoint& _point) override;
331 		// размер окна, через которые видно данные
332 		IntSize getViewSize() override;
333 		// размер на который прокручиваются данные при щелчке по скролу
334 		size_t getVScrollPage() override;
335 		size_t getHScrollPage() override;
336 
337 		Align getContentAlign() override;
338 
339 	protected:
340 		// нажата ли кнопка
341 		bool mIsPressed;
342 		// в фокусе ли кнопка
343 		bool mIsFocus;
344 
345 		bool mCursorActive;
346 		float mCursorTimer;
347 		float mActionMouseTimer;
348 
349 		// позиция курсора
350 		size_t mCursorPosition;
351 		// максимальное колличество
352 		size_t mTextLength;
353 
354 		// выделение
355 		size_t mStartSelect;
356 		size_t mEndSelect;
357 
358 		// списоки изменений для отмены и повтора
359 		DequeUndoRedoInfo mVectorUndoChangeInfo;
360 		DequeUndoRedoInfo mVectorRedoChangeInfo;
361 
362 		bool mMouseLeftPressed;
363 
364 		bool mModeReadOnly;
365 		bool mModePassword;
366 		bool mModeMultiline;
367 		bool mModeStatic;
368 		bool mModeWordWrap;
369 
370 		bool mTabPrinting;
371 
372 		// настоящий текст, закрытый за звездочками
373 		UString mPasswordText;
374 
375 		// для поддержки режима статик, где курсор не нужен
376 		std::string mOriginalPointer;
377 
378 		Char mCharPassword;
379 
380 		bool mOverflowToTheLeft;
381 		size_t mMaxTextLength;
382 
383 		ISubWidgetText* mClientText;
384 	};
385 
386 } // namespace MyGUI
387 
388 #endif // MYGUI_EDIT_BOX_H_
389