MyGUI 3.4.3
MyGUI_EditBox.cpp
Go to the documentation of this file.
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#include "MyGUI_Precompiled.h"
8#include "MyGUI_EditBox.h"
9#include "MyGUI_Gui.h"
10#include "MyGUI_ResourceSkin.h"
11#include "MyGUI_SkinManager.h"
12#include "MyGUI_InputManager.h"
16#include "MyGUI_ScrollBar.h"
17
18#include <algorithm>
19#include <cctype>
20
21namespace MyGUI
22{
23
51
52 const float EDIT_CURSOR_TIMER = 0.7f;
53 const float EDIT_ACTION_MOUSE_TIMER = 0.05f;
54 const int EDIT_CURSOR_MAX_POSITION = 100000;
55 const int EDIT_CURSOR_MIN_POSITION = -100000;
56 const size_t EDIT_MAX_UNDO = 128;
57 const size_t EDIT_DEFAULT_MAX_TEXT_LENGTH = 2048;
58 const float EDIT_OFFSET_HORZ_CURSOR = 10.0f; // дополнительное смещение для курсора
59 const int EDIT_ACTION_MOUSE_ZONE = 1500; // область для восприятия мыши за пределом эдита
60 const std::string_view EDIT_CLIPBOARD_TYPE_TEXT = "Text";
61 const int EDIT_MOUSE_WHEEL = 50; // область для восприятия мыши за пределом эдита
62
64 mMaxTextLength(EDIT_DEFAULT_MAX_TEXT_LENGTH)
65 {
67 }
68
70 {
72
74
75 // FIXME нам нужен фокус клавы
76 setNeedKeyFocus(true);
77
79 if (getClientWidget() != nullptr)
80 {
88 }
89
91 assignWidget(mVScroll, "VScroll");
92 if (mVScroll != nullptr)
93 {
95 }
96
98 assignWidget(mHScroll, "HScroll");
99 if (mHScroll != nullptr)
100 {
102 }
103
105 if (getClientWidget() != nullptr)
106 {
108 if (text)
109 mClientText = text;
110 }
111
113
114 // первоначальная инициализация курсора
115 if (mClientText != nullptr)
117
118 updateSelectText();
119 }
120
122 {
123 mScrollViewClient = nullptr;
124 mClientText = nullptr;
125 mVScroll = nullptr;
126 mHScroll = nullptr;
127
129 }
130
132 {
133 if ((_old == getClientWidget()) || (mIsFocus))
134 return;
135
136 mIsFocus = true;
137 updateEditState();
138 }
139
141 {
142 if ((_new == getClientWidget()) || (!mIsFocus))
143 return;
144
145 mIsFocus = false;
146 updateEditState();
147 }
148
149 void EditBox::notifyMousePressed(Widget* _sender, int _left, int _top, MouseButton _id)
150 {
151 if (mClientText == nullptr)
152 return;
153
154 // в статике все недоступно
155 if (mModeStatic)
156 return;
157
162 mCursorTimer = 0;
163 updateSelectText();
164
165 if (_id == MouseButton::Left)
166 mMouseLeftPressed = true;
167 }
168
169 void EditBox::notifyMouseReleased(Widget* _sender, int _left, int _top, MouseButton _id)
170 {
171 // сбрасываем всегда
172 mMouseLeftPressed = false;
173 }
174
175 void EditBox::notifyMouseDrag(Widget* _sender, int _left, int _top, MouseButton _id)
176 {
177 if (_id != MouseButton::Left)
178 return;
179
180 if (mClientText == nullptr)
181 return;
182
183 // в статике все недоступно
184 if (mModeStatic)
185 return;
186
187 // останавливаем курсор
189
190 // сбрасываем все таймеры
191 mCursorTimer = 0;
193
194 size_t old = mCursorPosition;
195 IntPoint point(_left, _top);
197
198 if (old != mCursorPosition)
199 {
201
202 if (mStartSelect == ITEM_NONE)
203 mStartSelect = old;
204
205 mEndSelect = (size_t)mCursorPosition;
208 else
210
212 }
213 }
214
216 {
217 if (mClientText == nullptr)
218 return;
219
220 // в статике все недоступно
221 if (mModeStatic)
222 return;
223
225
226 size_t cursorPosition = mClientText->getCursorPosition(lastPressed);
227 mStartSelect = cursorPosition;
228 mEndSelect = cursorPosition;
229
231 UString::utf32string::reverse_iterator iterBack = text.rend() - cursorPosition;
232 UString::utf32string::iterator iterForw = text.begin() + cursorPosition;
233
234 while (iterBack != text.rend())
235 {
236 if (((*iterBack) < 256) && (ispunct(*iterBack) || isspace(*iterBack)))
237 break;
238 ++iterBack;
239 mStartSelect--;
240 }
241 while (iterForw != text.end())
242 {
243 if (((*iterForw) < 256) && (ispunct(*iterForw) || isspace(*iterForw)))
244 break;
245 ++iterForw;
246 mEndSelect++;
247 }
248
251 }
252
253 void EditBox::onMouseDrag(int _left, int _top, MouseButton _id)
254 {
255 notifyMouseDrag(nullptr, _left, _top, _id);
256
257 Base::onMouseDrag(_left, _top, _id);
258 }
259
261 {
262 if (!mIsPressed)
263 {
264 mIsPressed = true;
265 updateEditState();
266
267 if (!mModeStatic)
268 {
269 if (mClientText != nullptr)
270 {
271 mCursorActive = true;
272 Gui::getInstance().eventFrameStart += newDelegate(this, &EditBox::frameEntered);
275 mCursorTimer = 0;
276 }
277 }
278 }
279
281 }
282
284 {
285 if (mIsPressed)
286 {
287 mIsPressed = false;
288 updateEditState();
289
290 if (mClientText != nullptr)
291 {
292 mCursorActive = false;
293 Gui::getInstance().eventFrameStart -= newDelegate(this, &EditBox::frameEntered);
296 }
297 }
298
300 }
301
302 static bool isWhitespace(const UString::code_point& c)
303 {
304 return c == ' ' || c == '\t';
305 }
306
308 {
309#if MYGUI_PLATFORM == MYGUI_PLATFORM_LINUX || MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32
310 switch (key.getValue())
311 {
315 case KeyCode::Insert:
316 return input.isShiftPressed() ? EditCommand::Paste
318 case KeyCode::Return:
324 case KeyCode::Home:
329 }
330 if (input.isControlPressed())
331 {
332 switch (key.getValue())
333 {
334 case KeyCode::C: return EditCommand::Copy;
335 case KeyCode::V: return EditCommand::Paste;
336 case KeyCode::X: return EditCommand::Cut;
337 case KeyCode::Z: return EditCommand::Undo;
338 case KeyCode::Y: return EditCommand::Redo;
340 }
341 }
342#elif MYGUI_PLATFORM == MYGUI_PLATFORM_APPLE
343 switch (key.getValue())
344 {
348 case KeyCode::Return:
351 {
352 if (input.isAltPressed())
354 if (input.isMetaPressed() || input.isControlPressed())
357 }
359 {
360 if (input.isAltPressed())
362 if (input.isMetaPressed() || input.isControlPressed())
365 }
368 case KeyCode::Home:
373 }
374 if (input.isMetaPressed())
375 {
376 switch (key.getValue())
377 {
378 case KeyCode::C: return EditCommand::Copy;
379 case KeyCode::V: return EditCommand::Paste;
380 case KeyCode::X: return EditCommand::Cut;
383 }
384 }
385#endif
387 }
388
390 {
391 if (mClientText == nullptr || getClientWidget() == nullptr)
392 {
393 Base::onKeyButtonPressed(_key, _char);
394 return;
395 }
396
397 // в статическом режиме ничего не доступно
398 if (mModeStatic)
399 {
400 Base::onKeyButtonPressed(_key, _char);
401 return;
402 }
403
405
407 mCursorTimer = 0.0f;
408
409 auto editCmd = ToEditCommand(_key, input);
410
411 if (editCmd == EditCommand::LoseFocus)
412 {
414 }
415 else if (editCmd == EditCommand::ErasePrevious)
416 {
417 // если нуно то удаляем выделенный текст
418 if (!mModeReadOnly)
419 {
420 // сбрасываем повтор
421 commandResetRedo();
422
423 if (!deleteTextSelect(true))
424 {
425 // прыгаем на одну назад и удаляем
426 if (mCursorPosition != 0)
427 {
429 eraseText(mCursorPosition, 1, true);
430 }
431 }
432 // отсылаем событие о изменении
434 }
435 }
436 else if (editCmd == EditCommand::EraseNext)
437 {
438 if (!mModeReadOnly)
439 {
440 // сбрасываем повтор
441 commandResetRedo();
442
443 // если нуно то удаляем выделенный текст
444 if (!deleteTextSelect(true))
445 {
447 {
448 eraseText(mCursorPosition, 1, true);
449 }
450 }
451 // отсылаем событие о изменении
453 }
454 }
455 else if (editCmd == EditCommand::Paste)
456 {
457 // сбрасываем повтор
458 commandResetRedo();
459
460 commandPaste();
461 }
462 else if (editCmd == EditCommand::Copy)
463 {
464 commandCopy();
465 }
466 else if (editCmd == EditCommand::Cut)
467 {
468 commandResetRedo();
469
470 commandCut();
471 }
472 else if (editCmd == EditCommand::Undo)
473 {
474 commandUndo();
475 }
476 else if (editCmd == EditCommand::Redo)
477 {
478 commandRedo();
479 }
480 else if (editCmd == EditCommand::SelectAll)
481 {
483 }
484 else if (editCmd == EditCommand::NewLine)
485 {
486 // работаем только в режиме редактирования
487 if (!mModeReadOnly)
488 {
489 if (mModeMultiline)
490 {
491 // сбрасываем повтор
492 commandResetRedo();
493
494 // попытка объединения двух комманд
495 size_t size = mVectorUndoChangeInfo.size();
496 // непосредственно операции
497 deleteTextSelect(true);
499 // проверяем на возможность объединения
500 if ((size + 2) == mVectorUndoChangeInfo.size())
501 commandMerge();
502 // отсылаем событие о изменении
504 }
505 // при сингл лайн и и мульти+сонтрол шлем эвент
506 else
507 {
509 }
510 }
511 }
512 else if (editCmd == EditCommand::AcceptEntry)
513 {
515 }
516 else if (editCmd == EditCommand::MoveRight || editCmd == EditCommand::MoveRightWord)
517 {
519 {
520 if (editCmd == EditCommand::MoveRightWord)
521 {
522 if (mModePassword)
523 {
525 }
526 else
527 {
528 const UString& text = getRealString();
530 {
532 }
534 {
536 }
537 }
538 }
539 else
540 {
542 }
544 updateSelectText();
545 }
546 // сбрасываем выделение
547 else if (isTextSelection() && !input.isShiftPressed())
548 {
549 resetSelect();
550 }
551 }
552 else if (editCmd == EditCommand::MoveLeft || editCmd == EditCommand::MoveLeftWord)
553 {
554 if (mCursorPosition != 0)
555 {
556 if (editCmd == EditCommand::MoveLeftWord)
557 {
558 if (mModePassword)
559 {
560 mCursorPosition = 0;
561 }
562 else
563 {
564 const UString& text = getRealString();
565 while (mCursorPosition > 0 && isWhitespace(text[mCursorPosition - 1]))
566 {
568 }
569 while (mCursorPosition > 0 && !isWhitespace(text[mCursorPosition - 1]))
570 {
572 }
573 }
574 }
575 else
576 {
578 }
580 updateSelectText();
581 }
582 // сбрасываем выделение
583 else if (isTextSelection() && !input.isShiftPressed())
584 {
585 resetSelect();
586 }
587 }
588 else if (editCmd == EditCommand::MoveUp)
589 {
591 point.top -= mClientText->getFontHeight();
592 size_t old = mCursorPosition;
594 // самая верхняя строчка
595 if (old == mCursorPosition)
596 {
597 if (mCursorPosition != 0)
598 {
599 mCursorPosition = 0;
601 updateSelectText();
602 }
603 // сбрасываем выделение
604 else if (isTextSelection() && !input.isShiftPressed())
605 {
606 resetSelect();
607 }
608 }
609 else
610 {
612 updateSelectText();
613 }
614 }
615 else if (editCmd == EditCommand::MoveDown)
616 {
618 point.top += mClientText->getFontHeight();
619 size_t old = mCursorPosition;
621 // самая нижняя строчка
622 if (old == mCursorPosition)
623 {
625 {
628 updateSelectText();
629 }
630 // сбрасываем выделение
631 else if (isTextSelection() && !input.isShiftPressed())
632 {
633 resetSelect();
634 }
635 }
636 else
637 {
639 updateSelectText();
640 }
641 }
642 else if (editCmd == EditCommand::MoveLineBeginning)
643 {
646 size_t old = mCursorPosition;
648 if (old != mCursorPosition)
649 {
651 updateSelectText();
652 }
653 else if (isTextSelection() && !input.isShiftPressed())
654 {
655 resetSelect();
656 }
657 }
658 else if (editCmd == EditCommand::MoveTextBeginning)
659 {
660 if (0 != mCursorPosition)
661 {
662 mCursorPosition = 0;
664 updateSelectText();
665 }
666 else if (isTextSelection() && !input.isShiftPressed())
667 {
668 resetSelect();
669 }
670 }
671 else if (editCmd == EditCommand::MoveLineEnd)
672 {
675 size_t old = mCursorPosition;
677 if (old != mCursorPosition)
678 {
680 updateSelectText();
681 }
682 else if (isTextSelection() && !input.isShiftPressed())
683 {
684 resetSelect();
685 }
686 }
687 else if (editCmd == EditCommand::MoveTextEnd)
688 {
690 {
693 updateSelectText();
694 }
695 else if (isTextSelection() && !input.isShiftPressed())
696 {
697 resetSelect();
698 }
699 }
700 else if (editCmd == EditCommand::MovePageUp)
701 {
702 // на размер окна, но не меньше одной строки
707 size_t old = mCursorPosition;
709 // самая верхняя строчка
710 if (old == mCursorPosition)
711 {
712 if (mCursorPosition != 0)
713 {
714 mCursorPosition = 0;
716 updateSelectText();
717 }
718 // сбрасываем выделение
719 else if (isTextSelection() && !input.isShiftPressed())
720 {
721 resetSelect();
722 }
723 }
724 else
725 {
727 updateSelectText();
728 }
729 }
730 else if (editCmd == EditCommand::MovePageDown)
731 {
732 // на размер окна, но не меньше одной строки
737 size_t old = mCursorPosition;
739 // самая нижняя строчка
740 if (old == mCursorPosition)
741 {
743 {
746 updateSelectText();
747 }
748 // сбрасываем выделение
749 else if (isTextSelection() && !input.isShiftPressed())
750 {
751 resetSelect();
752 }
753 }
754 else
755 {
757 updateSelectText();
758 }
759 }
760 else if ((_key == KeyCode::LeftShift) || (_key == KeyCode::RightShift))
761 {
762 // для правильно выделения
763 if (mStartSelect == ITEM_NONE)
764 {
766 }
767 }
768 else
769 {
770 // если не нажат контрл, то обрабатываем как текст
771 if (!mModeReadOnly && _char != 0)
772 {
773 // сбрасываем повтор
774 commandResetRedo();
775
776 // таб только если нужно
777 if (_char != '\t' || mTabPrinting)
778 {
779 // попытка объединения двух комманд
780 size_t size = mVectorUndoChangeInfo.size();
781 // непосредственно операции
782 deleteTextSelect(true);
784 // проверяем на возможность объединения
785 if ((size + 2) == mVectorUndoChangeInfo.size())
786 commandMerge();
787 // отсылаем событие о изменении
789 }
790 }
791 }
792
793 Base::onKeyButtonPressed(_key, _char);
794 }
795
796 void EditBox::frameEntered(float _frame)
797 {
798 if (mClientText == nullptr)
799 return;
800
801 // в статике все недоступно
802 if (mModeStatic)
803 return;
804
805 if (mCursorActive)
806 {
807 mCursorTimer += _frame;
808
810 {
814 }
815 }
816
817 // сдвигаем курсор по положению мыши
819 {
820 mActionMouseTimer += _frame;
821
823 {
825 const IntRect& view = getClientWidget()->getAbsoluteRect();
826 mouse.left -= view.left;
827 mouse.top -= view.top;
828 IntPoint point;
829
830 bool action = false;
831
832 // вверх на одну строчку
833 if ((mouse.top < 0) && (mouse.top > -EDIT_ACTION_MOUSE_ZONE))
834 {
835 if ((mouse.left > 0) && (mouse.left <= getClientWidget()->getWidth()))
836 {
838 point.top -= mClientText->getFontHeight();
839 action = true;
840 }
841 }
842 // вниз на одну строчку
843 else if (
844 (mouse.top > getClientWidget()->getHeight()) &&
845 (mouse.top < (getClientWidget()->getHeight() + EDIT_ACTION_MOUSE_ZONE)))
846 {
847 if ((mouse.left > 0) && (mouse.left <= getClientWidget()->getWidth()))
848 {
850 point.top += mClientText->getFontHeight();
851 action = true;
852 }
853 }
854
855 // влево на небольшое расстояние
856 if ((mouse.left < 0) && (mouse.left > -EDIT_ACTION_MOUSE_ZONE))
857 {
859 point.left -= (int)EDIT_OFFSET_HORZ_CURSOR;
860 action = true;
861 }
862 // вправо на небольшое расстояние
863 else if (
864 (mouse.left > getClientWidget()->getWidth()) &&
865 (mouse.left < (getClientWidget()->getWidth() + EDIT_ACTION_MOUSE_ZONE)))
866 {
868 point.left += (int)EDIT_OFFSET_HORZ_CURSOR;
869 action = true;
870 }
871
872 if (action)
873 {
874 size_t old = mCursorPosition;
876
877 if (old != mCursorPosition)
878 {
880
881 if (mStartSelect == ITEM_NONE)
882 mStartSelect = old;
883
884 mEndSelect = (size_t)mCursorPosition;
887 else
889
890 // пытаемся показать курсор
892 }
893 }
894 // если в зону не попадает то сбрасываем
895 else
896 {
898 }
899
902 }
903
904 } // if (mMouseLeftPressed)
905 }
906
907 void EditBox::setTextCursor(size_t _index)
908 {
909 // сбрасываем выделение
910 resetSelect();
911
912 // новая позиция
913 if (_index > mTextLength)
914 _index = mTextLength;
915
916 if (mCursorPosition == _index)
917 return;
918
919 mCursorPosition = _index;
920
921 // обновляем по позиции
922 if (mClientText != nullptr)
924
925 updateSelectText();
926 }
927
928 void EditBox::setTextSelection(size_t _start, size_t _end)
929 {
930 if (_start > mTextLength)
931 _start = mTextLength;
932 if (_end > mTextLength)
933 _end = mTextLength;
934
935 mStartSelect = _start;
936 mEndSelect = _end;
937
938 if (mClientText != nullptr)
939 {
942 else
944 }
945
947 return;
948 // курсор на конец выделения
950
951 // обновляем по позиции
952 if (mClientText != nullptr)
954 }
955
956 bool EditBox::deleteTextSelect(bool _history)
957 {
958 if (!isTextSelection())
959 return false;
960
961 // начало и конец выделения
962 size_t start = getTextSelectionStart();
963 size_t end = getTextSelectionEnd();
964
965 eraseText(start, end - start, _history);
966
967 return true;
968 }
969
970 void EditBox::resetSelect()
971 {
972 if (mStartSelect != ITEM_NONE)
973 {
975 if (mClientText != nullptr)
977 }
978 }
979
980 void EditBox::commandPosition(size_t _undo, size_t _redo, size_t _length, VectorChangeInfo* _info)
981 {
982 if (_info != nullptr)
983 _info->push_back(TextCommandInfo(_undo, _redo, _length));
984 }
985
986 void EditBox::commandMerge()
987 {
988 if (mVectorUndoChangeInfo.size() < 2)
989 return; // на всякий
990 // сохраняем последние набор отмен
992 mVectorUndoChangeInfo.pop_back();
993
994 // объединяем последовательности
995 for (const auto& iter : info)
996 {
997 mVectorUndoChangeInfo.back().push_back(iter);
998 }
999 }
1000
1001 bool EditBox::commandUndo()
1002 {
1003 if (mVectorUndoChangeInfo.empty())
1004 return false;
1005
1006 resetSelect();
1007
1008 // save last undo info
1010 // move undo info to redo
1011 mVectorUndoChangeInfo.pop_back();
1012 mVectorRedoChangeInfo.push_back(info);
1013
1014 UString::utf32string text = getRealString().asUTF32();
1015
1016 // apply undo
1017 for (VectorChangeInfo::const_reverse_iterator iter = info.rbegin(); iter != info.rend(); ++iter)
1018 {
1019 const auto& change = *iter;
1020 switch (change.type)
1021 {
1022 case TextCommandInfo::COMMAND_INSERT: text.erase(change.start, change.text.size()); break;
1023 case TextCommandInfo::COMMAND_ERASE: text.insert(change.start, change.text); break;
1025 mCursorPosition = change.undo;
1026 mTextLength = change.length;
1027 break;
1028 }
1029 }
1030
1031 setRealString(UString(text));
1032
1033 // restore cursor position
1034 if (mClientText != nullptr)
1036 updateSelectText();
1037
1038 eventEditTextChange(this);
1039
1040 return true;
1041 }
1042
1043 bool EditBox::commandRedo()
1044 {
1045 if (mVectorRedoChangeInfo.empty())
1046 return false;
1047
1048 // сбрасываем выделение
1049 resetSelect();
1050
1051 // save last undo info
1053 // move redo info to undo
1054 mVectorRedoChangeInfo.pop_back();
1055 mVectorUndoChangeInfo.push_back(info);
1056
1057 UString::utf32string text = getRealString().asUTF32();
1058
1059 // apply redo
1060 for (const auto& change : info)
1061 {
1062 switch (change.type)
1063 {
1064 case TextCommandInfo::COMMAND_INSERT: text.insert(change.start, change.text); break;
1065 case TextCommandInfo::COMMAND_ERASE: text.erase(change.start, change.text.size()); break;
1067 mCursorPosition = change.redo;
1068 mTextLength = change.length;
1069 break;
1070 }
1071 }
1072
1073 setRealString(UString(text));
1074
1075 // restore cursor position
1076 if (mClientText != nullptr)
1078 updateSelectText();
1079
1080 eventEditTextChange(this);
1081
1082 return true;
1083 }
1084
1085 void EditBox::saveInHistory(VectorChangeInfo* _info)
1086 {
1087 if (_info == nullptr)
1088 return;
1089 // если нет информации об изменении
1090 if (_info->empty())
1091 return;
1092 if ((_info->size() == 1) && (_info->back().type == TextCommandInfo::COMMAND_POSITION))
1093 return;
1094
1095 mVectorUndoChangeInfo.push_back(*_info);
1096 // проверяем на максимальный размер
1098 mVectorUndoChangeInfo.pop_front();
1099 }
1100
1101 // возвращает текст
1102 UString EditBox::getTextInterval(size_t _start, size_t _count) const
1103 {
1104 // подстраховка
1105 if (_start > mTextLength)
1106 _start = mTextLength;
1107 // конец диапазона
1108 size_t end = _start + _count;
1109
1110 // итератор нашей строки
1111 TextIterator iterator(getRealString());
1112
1113 // дефолтный цвет
1114 UString colour;
1115 if (mClientText != nullptr)
1117
1118 // нужно ли вставлять цвет
1119 bool need_colour = true;
1120
1121 // цикл прохода по строке
1122 while (iterator.moveNext())
1123 {
1124 // текущаяя позиция
1125 size_t pos = iterator.getPosition();
1126
1127 // еще рано
1128 if (pos < _start)
1129 {
1130 // берем цвет из позиции и запоминаем
1131 iterator.getTagColour(colour);
1132
1133 continue;
1134 }
1135
1136 // проверяем на надобность начального тега
1137 if (pos == _start)
1138 {
1139 need_colour = !iterator.getTagColour(colour);
1140 // сохраняем место откуда начинается
1141 iterator.saveStartPoint();
1142 }
1143
1144 // а теперь просто до конца диапазона
1145 else if (pos == end)
1146 break;
1147 }
1148
1149 // возвращаем строку
1150 if (need_colour)
1151 return colour + iterator.getFromStart();
1152 return iterator.getFromStart();
1153 }
1154
1155 // выделяет цветом диапазон
1156 void EditBox::_setTextColour(size_t _start, size_t _count, const Colour& _colour, bool _history)
1157 {
1158 // история изменений
1159 VectorChangeInfo* history = nullptr;
1160 if (_history)
1161 history = new VectorChangeInfo();
1162
1163 // конец диапазона
1164 size_t end = _start + _count;
1165
1166 // итератор нашей строки
1167 TextIterator iterator(getRealString(), history);
1168
1169 // дефолтный цвет
1170 UString colour;
1171 if (mClientText != nullptr)
1173
1174 // цикл прохода по строке
1175 while (iterator.moveNext())
1176 {
1177 // текущаяя позиция
1178 size_t pos = iterator.getPosition();
1179
1180 // берем цвет из позиции и запоминаем
1181 iterator.getTagColour(colour);
1182
1183 // еще рано
1184 if (pos < _start)
1185 continue;
1186
1187 // ставим начальный тег
1188 if (pos == _start)
1189 iterator.setTagColour(_colour);
1190
1191 // внутри диапазона очищаем все
1192 else if (pos < end)
1193 iterator.clearTagColour();
1194
1195 // на конец ставим последний найденный или дефолтный
1196 else if (pos == end)
1197 {
1198 iterator.setTagColour(colour);
1199 // и выходим из цикла
1200 break;
1201 }
1202 }
1203
1204 // сохраняем позицию для восстановления курсора
1205 commandPosition(_start, _start + _count, mTextLength, history);
1206
1207 // запоминаем в историю
1208 if (_history)
1209 {
1210 saveInHistory(history);
1211 delete history;
1212 }
1213 // сбрасываем историю
1214 else
1215 commandResetHistory();
1216
1217 // и возвращаем строку на место
1218 setRealString(iterator.getText());
1219 }
1220
1221 void EditBox::setTextSelectColour(const Colour& _colour, bool _history)
1222 {
1223 // нужно выделение
1224 if (!isTextSelection())
1225 return;
1226 // начало и конец выделения
1227 size_t start = getTextSelectionStart();
1228 size_t end = getTextSelectionEnd();
1229 _setTextColour(start, end - start, _colour, _history);
1230 }
1231
1233 {
1234 if (!isTextSelection())
1235 return {};
1236 size_t start = getTextSelectionStart();
1237 size_t end = getTextSelectionEnd();
1238 return getTextInterval(start, end - start);
1239 }
1240
1241 void EditBox::setEditPassword(bool _password)
1242 {
1243 if (mModePassword == _password)
1244 return;
1245 mModePassword = _password;
1246
1247 if (mModePassword)
1248 {
1249 if (mClientText != nullptr)
1250 {
1253 }
1254 }
1255 else
1256 {
1257 if (mClientText != nullptr)
1258 {
1261 }
1262 }
1263 // обновляем по размерам
1264 updateView();
1265 // сбрасываем историю
1266 commandResetHistory();
1267 }
1268
1269 void EditBox::setText(const UString& _caption, bool _history)
1270 {
1271 // сбрасываем выделение
1272 resetSelect();
1273
1274 // история изменений
1275 VectorChangeInfo* history = nullptr;
1276 if (_history)
1277 history = new VectorChangeInfo();
1278
1279 // итератор нашей строки
1280 TextIterator iterator(getRealString(), history);
1281
1282 // вставляем текст
1283 iterator.setText(_caption, mModeMultiline || mModeWordWrap);
1284
1286 {
1287 iterator.cutMaxLengthFromBeginning(mMaxTextLength);
1288 }
1289 else
1290 {
1291 // обрезаем по максимальной длинне
1292 iterator.cutMaxLength(mMaxTextLength);
1293 }
1294
1295 // запоминаем размер строки
1296 size_t old = mTextLength;
1297 // новая позиция и положение на конец вставки
1298 mCursorPosition = mTextLength = iterator.getSize();
1299
1300 // сохраняем позицию для восстановления курсора
1301 commandPosition(0, mTextLength, old, history);
1302
1303 // запоминаем в историю
1304 if (_history)
1305 {
1306 saveInHistory(history);
1307 delete history;
1308 }
1309 // сбрасываем историю
1310 else
1311 commandResetHistory();
1312
1313 // и возвращаем строку на место
1314 setRealString(iterator.getText());
1315
1316 // обновляем по позиции
1317 if (mClientText != nullptr)
1319 updateSelectText();
1320 }
1321
1322 void EditBox::insertText(const UString& _text, size_t _start, bool _history)
1323 {
1324 // сбрасываем выделение
1325 resetSelect();
1326
1327 // если строка пустая, или размер максимален
1328 if (_text.empty())
1329 return;
1330
1332 return;
1333
1334 // история изменений
1335 VectorChangeInfo* history = nullptr;
1336 if (_history)
1337 history = new VectorChangeInfo();
1338
1339 // итератор нашей строки
1340 TextIterator iterator(getRealString(), history);
1341
1342 // дефолтный цвет
1343 UString colour;
1344 if (mClientText != nullptr)
1346 // нужен ли тег текста
1347 // потом переделать через TextIterator чтобы отвязать понятие тег от эдита
1348 bool need_colour = ((_text.size() > 6) && (_text[0] == L'#') && (_text[1] != L'#'));
1349
1350 // цикл прохода по строке
1351 while (iterator.moveNext())
1352 {
1353 // текущаяя позиция
1354 size_t pos = iterator.getPosition();
1355
1356 // текущий цвет
1357 if (need_colour)
1358 iterator.getTagColour(colour);
1359
1360 // если дошли то выходим
1361 if (pos == _start)
1362 break;
1363 }
1364
1365 // если нужен цвет то вставляем
1366 if (need_colour)
1367 iterator.setTagColour(colour);
1368
1369 // а теперь вставляем строку
1370 iterator.insertText(_text, mModeMultiline || mModeWordWrap);
1371
1373 {
1374 iterator.cutMaxLengthFromBeginning(mMaxTextLength);
1375 }
1376 else
1377 {
1378 // обрезаем по максимальной длинне
1379 iterator.cutMaxLength(mMaxTextLength);
1380 }
1381
1382 // запоминаем размер строки
1383 size_t old = mTextLength;
1384 // новая позиция и положение на конец вставки
1385 mTextLength = iterator.getSize();
1387
1388 // сохраняем позицию для восстановления курсора
1389 commandPosition(_start, _start + mTextLength - old, old, history);
1390
1391 // запоминаем в историю
1392 if (_history)
1393 {
1394 saveInHistory(history);
1395 delete history;
1396 }
1397 // сбрасываем историю
1398 else
1399 commandResetHistory();
1400
1401 // и возвращаем строку на место
1402 setRealString(iterator.getText());
1403
1404 // обновляем по позиции
1405 if (mClientText != nullptr)
1407 updateSelectText();
1408 }
1409
1410 void EditBox::eraseText(size_t _start, size_t _count, bool _history)
1411 {
1412 // чета маловато
1413 if (_count == 0)
1414 return;
1415
1416 // сбрасываем выделение
1417 resetSelect();
1418
1419 // история изменений
1420 VectorChangeInfo* history = nullptr;
1421 if (_history)
1422 history = new VectorChangeInfo();
1423
1424 // итератор нашей строки
1425 TextIterator iterator(getRealString(), history);
1426
1427 // дефолтный цвет
1428 UString colour;
1429 // конец диапазона
1430 size_t end = _start + _count;
1431 bool need_colour = false;
1432
1433 // цикл прохода по строке
1434 while (iterator.moveNext())
1435 {
1436 // текущаяя позиция
1437 size_t pos = iterator.getPosition();
1438
1439 // еще рано
1440 if (pos < _start)
1441 {
1442 // берем цвет из позиции и запоминаем
1443 iterator.getTagColour(colour);
1444 continue;
1445 }
1446
1447 // сохраняем место откуда начинается
1448 if (pos == _start)
1449 {
1450 // если до диапазона был цвет, то нужно закрыть тег
1451 if (!colour.empty())
1452 {
1453 need_colour = true;
1454 colour.clear();
1455 }
1456 // берем цвет из позиции и запоминаем
1457 iterator.getTagColour(colour);
1458 iterator.saveStartPoint();
1459 }
1460
1461 // внутри диапазона
1462 else if (pos < end)
1463 {
1464 // берем цвет из позиции и запоминаем
1465 iterator.getTagColour(colour);
1466 }
1467
1468 // окончание диапазона
1469 else if (pos == end)
1470 {
1471 // нужно ставить тег или нет
1472 if (!colour.empty())
1473 need_colour = true;
1474 if (iterator.getTagColour(colour))
1475 need_colour = false;
1476
1477 break;
1478 }
1479 }
1480
1481 // удаляем диапазон
1482 iterator.eraseFromStart();
1483 // и вставляем последний цвет
1484 if (need_colour)
1485 iterator.setTagColour(colour);
1486
1487 // сохраняем позицию для восстановления курсора
1488 commandPosition(_start + _count, _start, mTextLength, history);
1489
1490 // на месте удаленного
1491 mCursorPosition = _start;
1492 mTextLength -= _count;
1493
1494 // запоминаем в историю
1495 if (_history)
1496 {
1497 saveInHistory(history);
1498 delete history;
1499 }
1500 // сбрасываем историю
1501 else
1502 commandResetHistory();
1503
1504 // и возвращаем строку на место
1505 setRealString(iterator.getText());
1506
1507 // обновляем по позиции
1508 if (mClientText != nullptr)
1510 updateSelectText();
1511 }
1512
1513 void EditBox::commandCut()
1514 {
1515 commandCopy();
1517 {
1518 deleteTextSelect(true);
1519 eventEditTextChange(this);
1520 }
1521 }
1522
1523 void EditBox::commandCopy() const
1524 {
1525 if (isTextSelection() && (!mModePassword))
1527 else
1529 }
1530
1531 void EditBox::commandPaste()
1532 {
1534 if ((!mModeReadOnly) && (!clipboard.empty()))
1535 {
1536 // попытка объединения двух комманд
1537 size_t size = mVectorUndoChangeInfo.size();
1538 // непосредственно операции
1539 deleteTextSelect(true);
1540 insertText(clipboard, mCursorPosition, true);
1541 // проверяем на возможность объединения
1542 if ((size + 2) == mVectorUndoChangeInfo.size())
1543 commandMerge();
1544 // отсылаем событие о изменении
1545 eventEditTextChange(this);
1546 }
1547 }
1548
1549 const UString& EditBox::getRealString() const
1550 {
1551 if (mModePassword)
1552 return mPasswordText;
1553 if (mClientText == nullptr)
1554 return mPasswordText;
1555
1556 return mClientText->getCaption();
1557 }
1558
1559 void EditBox::setRealString(const UString& _caption)
1560 {
1561 if (mModePassword)
1562 {
1563 mPasswordText = _caption;
1564 if (mClientText != nullptr)
1566 }
1567 else
1568 {
1569 if (mClientText != nullptr)
1570 mClientText->setCaption(_caption);
1571 }
1572 }
1573
1575 {
1576 mCharPassword = _char;
1577 if (mModePassword)
1578 {
1579 if (mClientText != nullptr)
1581 }
1582 }
1583
1584 void EditBox::updateEditState()
1585 {
1586 if (!getInheritedEnabled())
1587 {
1588 _setWidgetState("disabled");
1589 }
1590 else if (mIsPressed)
1591 {
1592 if (mIsFocus)
1593 _setWidgetState("pushed");
1594 else
1595 _setWidgetState("normal_checked");
1596 }
1597 else if (mIsFocus)
1598 {
1599 _setWidgetState("highlighted");
1600 }
1601 else
1602 {
1603 _setWidgetState("normal");
1604 }
1605 }
1606
1607 void EditBox::setPosition(const IntPoint& _point)
1608 {
1609 Base::setPosition(_point);
1610 }
1611
1613 {
1614 // если перенос, то сбрасываем размер текста
1615 if (mModeWordWrap)
1616 {
1617 if (mClientText != nullptr)
1618 mClientText->setWordWrap(true);
1619 }
1620
1621 updateView();
1622 }
1623
1624 void EditBox::setSize(const IntSize& _size)
1625 {
1626 Base::setSize(_size);
1627
1628 eraseView();
1629 }
1630
1631 void EditBox::setCoord(const IntCoord& _coord)
1632 {
1633 Base::setCoord(_coord);
1634
1635 eraseView();
1636 }
1637
1638 void EditBox::setCaption(const UString& _value)
1639 {
1640 setText(_value, false);
1641 }
1642
1644 {
1645 return getRealString();
1646 }
1647
1648 void EditBox::updateSelectText()
1649 {
1650 if (!mModeStatic)
1651 {
1653 if ((input.isShiftPressed()) && (mStartSelect != ITEM_NONE))
1654 {
1655 // меняем выделение
1656 mEndSelect = (size_t)mCursorPosition;
1657 if (mClientText != nullptr)
1658 {
1661 else
1663 }
1664 }
1665 else if (mStartSelect != ITEM_NONE)
1666 {
1667 // сбрасываем шифт
1669 if (mClientText != nullptr)
1671 }
1672 }
1673
1674 // пытаемся показать курсор
1676 }
1677
1679 {
1680 Base::setTextAlign(_value);
1681
1682 if (mClientText != nullptr)
1683 mClientText->setTextAlign(_value);
1684
1685 // так как мы сами рулим смещениями
1686 updateView();
1687 }
1688
1689 void EditBox::setTextColour(const Colour& _value)
1690 {
1691 Base::setTextColour(_value);
1692
1693 if (mClientText != nullptr)
1694 mClientText->setTextColour(_value);
1695 }
1696
1698 {
1699 if (mClientText != nullptr)
1700 return mClientText->getCoord();
1701 return Base::getTextRegion();
1702 }
1703
1705 {
1706 if (mClientText != nullptr)
1707 return mClientText->getTextSize();
1708 return Base::getTextSize();
1709 }
1710
1711 void EditBox::notifyScrollChangePosition(ScrollBar* _sender, size_t _position)
1712 {
1713 if (mClientText == nullptr)
1714 return;
1715
1716 if (_sender == mVScroll)
1717 {
1719 point.top = _position;
1720 mClientText->setViewOffset(point);
1721 }
1722 else if (_sender == mHScroll)
1723 {
1725 point.left = _position;
1726 mClientText->setViewOffset(point);
1727 }
1728 }
1729
1730 void EditBox::notifyMouseWheel(Widget* _sender, int _rel)
1731 {
1732 if (mClientText == nullptr)
1733 return;
1734
1735 if (mVRange != 0)
1736 {
1738 int offset = point.top;
1739 if (_rel < 0)
1740 offset += EDIT_MOUSE_WHEEL;
1741 else
1742 offset -= EDIT_MOUSE_WHEEL;
1743
1744 offset = std::clamp(offset, 0, int(mVRange));
1745
1746 if (offset != point.top)
1747 {
1748 point.top = offset;
1749 if (mVScroll != nullptr)
1750 mVScroll->setScrollPosition(offset);
1751 mClientText->setViewOffset(point);
1752 }
1753 }
1754 else if (mHRange != 0)
1755 {
1757 int offset = point.left;
1758 if (_rel < 0)
1759 offset += EDIT_MOUSE_WHEEL;
1760 else
1761 offset -= EDIT_MOUSE_WHEEL;
1762
1763 offset = std::clamp(offset, 0, int(mHRange));
1764
1765 if (offset != point.left)
1766 {
1767 point.left = offset;
1768 if (mHScroll != nullptr)
1769 mHScroll->setScrollPosition(offset);
1770 mClientText->setViewOffset(point);
1771 }
1772 }
1773 }
1774
1776 {
1777 mModeWordWrap = _value;
1778 if (mClientText != nullptr)
1780
1781 eraseView();
1782 }
1783
1784 void EditBox::setFontName(std::string_view _value)
1785 {
1786 Base::setFontName(_value);
1787
1788 if (mClientText != nullptr)
1789 mClientText->setFontName(_value);
1790
1791 eraseView();
1792 }
1793
1794 void EditBox::setFontHeight(int _value)
1795 {
1796 Base::setFontHeight(_value);
1797
1798 if (mClientText != nullptr)
1799 mClientText->setFontHeight(_value);
1800
1801 eraseView();
1802 }
1803
1805 {
1806 return (nullptr == mClientText) ? 0 : mClientText->getFontHeight();
1807 }
1808
1810 {
1813 }
1814
1816 {
1818 updateCursorPosition();
1820 }
1821
1822 void EditBox::updateCursorPosition()
1823 {
1824 if (mClientText == nullptr || getClientWidget() == nullptr)
1825 return;
1826
1827 // размер контекста текста
1828 IntSize textSize = mClientText->getTextSize();
1829
1830 // текущее смещение контекста текста
1832 // расчетное смещение
1833 IntPoint offset = point;
1834
1835 // абсолютные координаты курсора
1837 cursor.right++;
1838
1839 // абсолютные координаты вью
1840 const IntRect& view = getClientWidget()->getAbsoluteRect();
1841
1842 // проверяем и показываем курсор
1843 if (!view.inside(cursor))
1844 {
1845 // горизонтальное смещение
1846 if (textSize.width > view.width())
1847 {
1848 if (cursor.left < view.left)
1849 {
1850 offset.left = point.left - (view.left - cursor.left);
1851 // добавляем смещение, только если курсор не перепрыгнет
1853 offset.left -= int(EDIT_OFFSET_HORZ_CURSOR);
1854 }
1855 else if (cursor.right > view.right)
1856 {
1857 offset.left = point.left + (cursor.right - view.right);
1858 // добавляем смещение, только если курсор не перепрыгнет
1860 offset.left += int(EDIT_OFFSET_HORZ_CURSOR);
1861 }
1862 }
1863
1864 // вертикальное смещение
1865 if (textSize.height > view.height())
1866 {
1867 int delta = 0;
1868 if (cursor.height() > view.height())
1869 {
1870 // if text is bigger than edit height then place it in center
1871 delta = ((cursor.bottom - view.bottom) - (view.top - cursor.top)) / 2;
1872 }
1873 else if (cursor.top < view.top)
1874 {
1875 delta = -(view.top - cursor.top);
1876 }
1877 else if (cursor.bottom > view.bottom)
1878 {
1879 delta = (cursor.bottom - view.bottom);
1880 }
1881 offset.top = point.top + delta;
1882 }
1883 }
1884
1885 if (offset != point)
1886 {
1887 mClientText->setViewOffset(offset);
1888 // обновить скролы
1889 if (mVScroll != nullptr)
1891 if (mHScroll != nullptr)
1893 }
1894 }
1895
1896 void EditBox::setContentPosition(const IntPoint& _point)
1897 {
1898 if (mClientText != nullptr)
1899 mClientText->setViewOffset(_point);
1900 }
1901
1902 IntSize EditBox::getViewSize() const
1903 {
1904 if (mClientText != nullptr)
1905 return mClientText->getSize();
1907 }
1908
1909 IntSize EditBox::getContentSize() const
1910 {
1911 if (mClientText != nullptr)
1912 return mClientText->getTextSize();
1914 }
1915
1916 size_t EditBox::getVScrollPage() const
1917 {
1918 if (mClientText != nullptr)
1919 return (size_t)mClientText->getFontHeight();
1921 }
1922
1923 size_t EditBox::getHScrollPage() const
1924 {
1925 if (mClientText != nullptr)
1926 return (size_t)mClientText->getFontHeight();
1928 }
1929
1930 IntPoint EditBox::getContentPosition() const
1931 {
1932 if (mClientText != nullptr)
1933 return mClientText->getViewOffset();
1935 }
1936
1937 Align EditBox::getContentAlign() const
1938 {
1939 if (mClientText != nullptr)
1940 return mClientText->getTextAlign();
1942 }
1943
1944 void EditBox::setTextIntervalColour(size_t _start, size_t _count, const Colour& _colour)
1945 {
1946 _setTextColour(_start, _count, _colour, false);
1947 }
1948
1953
1958
1960 {
1961 return (mStartSelect != ITEM_NONE) && (mStartSelect != mEndSelect);
1962 }
1963
1965 {
1966 deleteTextSelect(false);
1967 }
1968
1970 {
1971 setTextSelectColour(_colour, false);
1972 }
1973
1975 {
1976 return mEndSelect - mStartSelect;
1977 }
1978
1980 {
1981 setText(TextIterator::toTagsString(_text), false);
1982 }
1983
1985 {
1986 return TextIterator::getOnlyText(getRealString());
1987 }
1988
1989 void EditBox::insertText(const UString& _text, size_t _index)
1990 {
1991 insertText(_text, _index, false);
1992 }
1993
1994 void EditBox::addText(const UString& _text)
1995 {
1996 insertText(_text, ITEM_NONE, false);
1997 }
1998
1999 void EditBox::eraseText(size_t _start, size_t _count)
2000 {
2001 eraseText(_start, _count, false);
2002 }
2003
2005 {
2006 mModeReadOnly = _value;
2007 // сбрасываем историю
2008 commandResetHistory();
2009 }
2010
2012 {
2013 mModeMultiline = _value;
2014 // на всякий, для убирания переносов
2015 if (!mModeMultiline)
2016 {
2017 setText(getRealString(), false);
2018 }
2019 // обновляем по размерам
2020 else
2021 {
2022 updateView();
2023 }
2024 // сбрасываем историю
2025 commandResetHistory();
2026 }
2027
2028 void EditBox::setEditStatic(bool _value)
2029 {
2030 mModeStatic = _value;
2031 resetSelect();
2032
2033 if (getClientWidget() != nullptr)
2034 {
2035 if (mModeStatic)
2036 getClientWidget()->setPointer(std::string_view{});
2037 else
2039 }
2040 }
2041
2043 {
2044 if (!_value.empty())
2045 setPasswordChar(_value[0]);
2046 }
2047
2049 {
2050 mVisibleVScroll = _value;
2051 updateView();
2052 }
2053
2055 {
2056 mVisibleHScroll = _value;
2057 updateView();
2058 }
2059
2061 {
2062 return mVRange + 1;
2063 }
2064
2066 {
2067 return mClientText == nullptr ? 0 : mClientText->getViewOffset().top;
2068 }
2069
2071 {
2072 if (mClientText == nullptr)
2073 return;
2074
2075 if (_index > mVRange)
2076 _index = mVRange;
2077
2079 point.top = _index;
2080
2081 mClientText->setViewOffset(point);
2082 // обновить скролы
2083 if (mVScroll != nullptr)
2085 }
2086
2088 {
2089 return mHRange + 1;
2090 }
2091
2093 {
2094 return mClientText == nullptr ? 0 : mClientText->getViewOffset().left;
2095 }
2096
2098 {
2099 if (mClientText == nullptr)
2100 return;
2101
2102 if (_index > mHRange)
2103 _index = mHRange;
2104
2106 point.left = _index;
2107
2108 mClientText->setViewOffset(point);
2109 // обновить скролы
2110 if (mHScroll != nullptr)
2112 }
2113
2115 {
2116 return mClientText == nullptr ? false : mClientText->getInvertSelected();
2117 }
2118
2120 {
2121 if (mClientText != nullptr)
2123 }
2124
2125 void EditBox::setPropertyOverride(std::string_view _key, std::string_view _value)
2126 {
2128 if (_key == "CursorPosition")
2130
2132 else if (_key == "TextSelect")
2136
2138 else if (_key == "ReadOnly")
2140
2142 else if (_key == "Password")
2144
2146 else if (_key == "MultiLine")
2148
2150 else if (_key == "PasswordChar")
2151 setPasswordChar(UString(_value));
2152
2154 else if (_key == "MaxTextLength")
2156
2158 else if (_key == "OverflowToTheLeft")
2160
2162 else if (_key == "Static")
2164
2166 else if (_key == "VisibleVScroll")
2168
2170 else if (_key == "VisibleHScroll")
2172
2174 else if (_key == "WordWrap")
2176
2178 else if (_key == "TabPrinting")
2180
2182 else if (_key == "InvertSelected")
2184
2185 else
2186 {
2187 Base::setPropertyOverride(_key, _value);
2188 return;
2189 }
2190
2191 eventChangeProperty(this, _key, _value);
2192 }
2193
2195 {
2196 return mCursorPosition;
2197 }
2198
2200 {
2201 return mTextLength;
2202 }
2203
2205 {
2206 mOverflowToTheLeft = _value;
2207 }
2208
2210 {
2211 return mOverflowToTheLeft;
2212 }
2213
2214 void EditBox::setMaxTextLength(size_t _value)
2215 {
2216 mMaxTextLength = _value;
2217 }
2218
2220 {
2221 return mMaxTextLength;
2222 }
2223
2225 {
2226 return mModeReadOnly;
2227 }
2228
2230 {
2231 return mModePassword;
2232 }
2233
2235 {
2236 return mModeMultiline;
2237 }
2238
2240 {
2241 return mModeStatic;
2242 }
2243
2245 {
2246 return mCharPassword;
2247 }
2248
2250 {
2251 return mModeWordWrap;
2252 }
2253
2254 void EditBox::setTabPrinting(bool _value)
2255 {
2256 mTabPrinting = _value;
2257 }
2258
2260 {
2261 return mTabPrinting;
2262 }
2263
2265 {
2266 return mVisibleVScroll;
2267 }
2268
2270 {
2271 return mVisibleHScroll;
2272 }
2273
2274 void EditBox::commandResetRedo()
2275 {
2276 mVectorRedoChangeInfo.clear();
2277 }
2278
2279 void EditBox::commandResetHistory()
2280 {
2281 mVectorRedoChangeInfo.clear();
2282 mVectorUndoChangeInfo.clear();
2283 }
2284
2286 {
2288
2289 if (mClientText != nullptr)
2291 }
2292
2293 void EditBox::setTextShadow(bool _value)
2294 {
2295 Base::setTextShadow(_value);
2296
2297 if (mClientText != nullptr)
2298 mClientText->setShadow(_value);
2299 }
2300
2301} // namespace MyGUI
std::string getClipboardData(std::string_view _type) const
void setClipboardData(std::string_view _type, std::string_view _data)
static ClipboardManager & getInstance()
void clearClipboardData(std::string_view _type)
DequeUndoRedoInfo mVectorUndoChangeInfo
void setFontHeight(int _value) override
void insertText(const UString &_text, size_t _index=ITEM_NONE)
size_t getTextLength() const
void setMaxTextLength(size_t _value)
Sets the max amount of text allowed in the edit field.
size_t getVScrollRange() const
size_t getVScrollPosition() const
IntCoord getTextRegion() const override
void setSize(const IntSize &_size) override
void setTextShadow(bool _value) override
ISubWidgetText * mClientText
void notifyMouseSetFocus(Widget *_sender, Widget *_old)
const UString & getCaption() const override
bool isVisibleVScroll() const
int getFontHeight() const override
void setTextSelection(size_t _start, size_t _end)
bool getEditStatic() const
void eraseText(size_t _start, size_t _count=1)
void notifyMouseDrag(Widget *_sender, int _left, int _top, MouseButton _id)
void setEditStatic(bool _value)
UString mPasswordText
size_t getTextSelectionStart() const
void setEditMultiLine(bool _value)
void shutdownOverride() override
EventPair< EventHandle_WidgetVoid, EventHandle_EditPtr > eventEditTextChange
void setPropertyOverride(std::string_view _key, std::string_view _value) override
void notifyMouseReleased(Widget *_sender, int _left, int _top, MouseButton _id)
size_t getTextCursor() const
bool getEditPassword() const
void setTabPrinting(bool _value)
Char getPasswordChar() const
bool getEditMultiLine() const
void onMouseDrag(int _left, int _top, MouseButton _id) override
IntSize getTextSize() const override
void setPasswordChar(Char _char)
bool isVisibleHScroll() const
void setEditWordWrap(bool _value)
DequeUndoRedoInfo mVectorRedoChangeInfo
size_t getHScrollRange() const
void onKeyButtonPressed(KeyCode _key, Char _char) override
void setTextColour(const Colour &_value) override
void setVisibleVScroll(bool _value)
void setHScrollPosition(size_t _index)
void setTextShadowColour(const Colour &_value) override
std::string mOriginalPointer
void notifyMouseLostFocus(Widget *_sender, Widget *_new)
void setTextSelectionColour(const Colour &_colour)
void onKeyLostFocus(Widget *_new) override
void setCaption(const UString &_value) override
void notifyMouseButtonDoubleClick(Widget *_sender)
void setVisibleHScroll(bool _value)
bool getEditReadOnly() const
void notifyScrollChangePosition(ScrollBar *_sender, size_t _position)
void setPosition(const IntPoint &_point) override
size_t getTextSelectionLength() const
UString getTextInterval(size_t _start, size_t _count) const
UString getTextSelection() const
bool isTextSelection() const
void setOverflowToTheLeft(bool _value)
Sets if surplus characters should push characters off the left side rather than ignored.
bool getEditWordWrap() const
void setCoord(const IntCoord &_coord) override
size_t getHScrollPosition() const
void addText(const UString &_text)
void setOnlyText(const UString &_text)
size_t getTextSelectionEnd() const
void setInvertSelected(bool _value)
void setVScrollPosition(size_t _index)
bool getTabPrinting() const
UString getOnlyText() const
void notifyMouseWheel(Widget *_sender, int _rel)
bool getInvertSelected() const
EventPair< EventHandle_WidgetVoid, EventHandle_EditPtr > eventEditSelectAccept
void setTextAlign(Align _value) override
bool getOverflowToTheLeft() const
Returns true if surplus characters will be pushed off the left rather than ignored.
void setTextIntervalColour(size_t _start, size_t _count, const Colour &_colour)
size_t getMaxTextLength() const
Gets the max amount of text allowed in the edit field.
void setEditReadOnly(bool _value)
void setFontName(std::string_view _value) override
void onKeySetFocus(Widget *_old) override
void setEditPassword(bool _password)
void notifyMousePressed(Widget *_sender, int _left, int _top, MouseButton _id)
void initialiseOverride() override
void setTextCursor(size_t _index)
static Gui & getInstance()
Definition MyGUI_Gui.cpp:34
EventHandle_FrameEventDelegate eventFrameStart
Definition MyGUI_Gui.h:215
const IntCoord & getCoord() const
virtual bool getInvertSelected() const
virtual void setTextColour(const Colour &)
virtual IntPoint getViewOffset() const
virtual const Colour & getTextColour() const
virtual const UString & getCaption() const
virtual void setTextAlign(Align)
IntRect getCursorRect(size_t _position) const
IntPoint getCursorPoint(size_t _position) const
virtual void setCaption(const UString &)
virtual IntSize getTextSize() const
virtual void setShadowColour(const Colour &)
virtual void setWordWrap(bool)
virtual void setCursorPosition(size_t)
virtual void setFontHeight(int)
virtual size_t getCursorPosition() const
virtual int getFontHeight() const
virtual void setInvertSelected(bool)
virtual void setFontName(std::string_view)
virtual void setVisibleCursor(bool)
virtual void setTextSelection(size_t, size_t)
virtual Align getTextAlign() const
virtual void setSelectBackground(bool)
virtual void setViewOffset(const IntPoint &)
virtual void setShadow(bool)
virtual bool isVisibleCursor() const
const IntPoint & getLastPressedPosition(MouseButton _id) const
void setKeyFocusWidget(Widget *_widget)
static InputManager & getInstance()
IntPoint getMousePositionByLayer() const
widget description should be here.
EventHandle_ScrollBarPtrSizeT eventScrollChangePosition
void setScrollPosition(size_t _position)
virtual IntSize getViewSize() const
virtual size_t getHScrollPage() const
virtual IntPoint getContentPosition() const
virtual Align getContentAlign() const
virtual IntSize getContentSize() const
virtual size_t getVScrollPage() const
ISubWidgetText * getSubWidgetText() const
static UString getOnlyText(const UString &_text)
static UString getTextNewLine()
static UString getTextCharInfo(Char _char)
static UString convertTagColour(const Colour &_colour)
static UString toTagsString(const UString &_text)
bool getTagColour(UString &_colour) const
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
const utf32string & asUTF32() const
returns the current string in UTF-32 form within a utf32string
void clear()
deletes all of the elements in the string
std::basic_string< unicode_char > utf32string
string type used for returning UTF-32 formatted data
uint16 code_point
a single UTF-16 code point
bool empty() const
returns true if the string has no elements, false otherwise
widget description should be here.
bool getInheritedEnabled() const
EventHandle_WidgetStringString eventChangeProperty
bool _setWidgetState(std::string_view _state)
Widget * getClientWidget()
void assignWidget(T *&_widget, std::string_view _name)
EventHandle_WidgetVoid eventMouseButtonDoubleClick
EventHandle_WidgetIntIntButton eventMouseButtonReleased
const std::string & getPointer() const
void setNeedKeyFocus(bool _value)
EventHandle_WidgetIntIntButton eventMouseButtonPressed
EventHandle_WidgetWidget eventMouseSetFocus
void setPointer(std::string_view _value)
EventHandle_WidgetWidget eventMouseLostFocus
EventPairAddParameter< EventHandle_WidgetIntInt, EventHandle_WidgetIntIntButton > eventMouseDrag
EventHandle_WidgetInt eventMouseWheel
T parseValue(std::string_view _value)
const int EDIT_MOUSE_WHEEL
types::TRect< int > IntRect
Definition MyGUI_Types.h:33
const int EDIT_CURSOR_MIN_POSITION
types::TPoint< int > IntPoint
Definition MyGUI_Types.h:27
std::vector< TextCommandInfo > VectorChangeInfo
const size_t EDIT_MAX_UNDO
const int EDIT_CURSOR_MAX_POSITION
unsigned int Char
Definition MyGUI_Types.h:50
constexpr size_t ITEM_NONE
const float EDIT_CURSOR_TIMER
static EditCommand ToEditCommand(KeyCode key, const InputManager &input)
types::TSize< int > IntSize
Definition MyGUI_Types.h:30
const float EDIT_OFFSET_HORZ_CURSOR
static bool isWhitespace(const UString::code_point &c)
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
const std::string_view EDIT_CLIPBOARD_TYPE_TEXT
const float EDIT_ACTION_MOUSE_TIMER
const int EDIT_ACTION_MOUSE_ZONE
const size_t EDIT_DEFAULT_MAX_TEXT_LENGTH
int getValue() const
bool inside(const TRect< T > &_value) const