MyGUI  3.4.1
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"
13 #include "MyGUI_ClipboardManager.h"
14 #include "MyGUI_PointerManager.h"
15 #include "MyGUI_ISubWidgetText.h"
16 #include "MyGUI_ScrollBar.h"
17 
18 #include <cctype>
19 
20 namespace MyGUI
21 {
22 
23  const float EDIT_CURSOR_TIMER = 0.7f;
24  const float EDIT_ACTION_MOUSE_TIMER = 0.05f;
25  const int EDIT_CURSOR_MAX_POSITION = 100000;
26  const int EDIT_CURSOR_MIN_POSITION = -100000;
27  const size_t EDIT_MAX_UNDO = 128;
28  const size_t EDIT_DEFAULT_MAX_TEXT_LENGTH = 2048;
29  const float EDIT_OFFSET_HORZ_CURSOR = 10.0f; // дополнительное смещение для курсора
30  const int EDIT_ACTION_MOUSE_ZONE = 1500; // область для восприятия мыши за пределом эдита
31  const std::string EDIT_CLIPBOARD_TYPE_TEXT = "Text";
32  const int EDIT_MOUSE_WHEEL = 50; // область для восприятия мыши за пределом эдита
33 
35  mIsPressed(false),
36  mIsFocus(false),
37  mCursorActive(false),
38  mCursorTimer(0),
39  mActionMouseTimer(0),
40  mCursorPosition(0),
41  mTextLength(0),
42  mStartSelect(ITEM_NONE),
43  mEndSelect(0),
44  mMouseLeftPressed(false),
45  mModeReadOnly(false),
46  mModePassword(false),
47  mModeMultiline(false),
48  mModeStatic(false),
49  mModeWordWrap(false),
50  mTabPrinting(false),
51  mCharPassword('*'),
52  mOverflowToTheLeft(false),
53  mMaxTextLength(EDIT_DEFAULT_MAX_TEXT_LENGTH),
54  mClientText(nullptr)
55  {
57  }
58 
60  {
62 
64 
65  // FIXME нам нужен фокус клавы
66  setNeedKeyFocus(true);
67 
69  if (getClientWidget() != nullptr)
70  {
78  }
79 
81  assignWidget(mVScroll, "VScroll");
82  if (mVScroll != nullptr)
83  {
85  }
86 
88  assignWidget(mHScroll, "HScroll");
89  if (mHScroll != nullptr)
90  {
92  }
93 
95  if (getClientWidget() != nullptr)
96  {
98  if (text)
99  mClientText = text;
100  }
101 
103 
104  // первоначальная инициализация курсора
105  if (mClientText != nullptr)
107 
108  updateSelectText();
109  }
110 
112  {
113  mScrollViewClient = nullptr;
114  mClientText = nullptr;
115  mVScroll = nullptr;
116  mHScroll = nullptr;
117 
119  }
120 
122  {
123  if ((_old == getClientWidget()) || (mIsFocus))
124  return;
125 
126  mIsFocus = true;
127  updateEditState();
128  }
129 
131  {
132  if ((_new == getClientWidget()) || (!mIsFocus))
133  return;
134 
135  mIsFocus = false;
136  updateEditState();
137  }
138 
139  void EditBox::notifyMousePressed(Widget* _sender, int _left, int _top, MouseButton _id)
140  {
141  if (mClientText == nullptr)
142  return;
143 
144  // в статике все недоступно
145  if (mModeStatic)
146  return;
147 
152  mCursorTimer = 0;
153  updateSelectText();
154 
155  if (_id == MouseButton::Left)
156  mMouseLeftPressed = true;
157  }
158 
159  void EditBox::notifyMouseReleased(Widget* _sender, int _left, int _top, MouseButton _id)
160  {
161  // сбрасываем всегда
162  mMouseLeftPressed = false;
163  }
164 
165  void EditBox::notifyMouseDrag(Widget* _sender, int _left, int _top, MouseButton _id)
166  {
167  if (_id != MouseButton::Left)
168  return;
169 
170  if (mClientText == nullptr)
171  return;
172 
173  // в статике все недоступно
174  if (mModeStatic)
175  return;
176 
177  // останавливаем курсор
179 
180  // сбрасываем все таймеры
181  mCursorTimer = 0;
182  mActionMouseTimer = 0;
183 
184  size_t old = mCursorPosition;
185  IntPoint point(_left, _top);
187 
188  if (old != mCursorPosition)
189  {
191 
192  if (mStartSelect == ITEM_NONE)
193  mStartSelect = old;
194 
195  mEndSelect = (size_t)mCursorPosition;
196  if (mStartSelect > mEndSelect)
198  else
200 
202  }
203  }
204 
206  {
207  if (mClientText == nullptr)
208  return;
209 
210  // в статике все недоступно
211  if (mModeStatic)
212  return;
213 
215 
216  size_t cursorPosition = mClientText->getCursorPosition(lastPressed);
217  mStartSelect = cursorPosition;
218  mEndSelect = cursorPosition;
219 
220  UString::utf32string text = this->getOnlyText().asUTF32();
221  UString::utf32string::reverse_iterator iterBack = text.rend() - cursorPosition;
222  UString::utf32string::iterator iterForw = text.begin() + cursorPosition;
223 
224  while (iterBack != text.rend())
225  {
226  if (((*iterBack) < 256) && (ispunct(*iterBack) || isspace(*iterBack)))
227  break;
228  ++iterBack;
229  mStartSelect--;
230  }
231  while (iterForw != text.end())
232  {
233  if (((*iterForw) < 256) && (ispunct(*iterForw) || isspace(*iterForw)))
234  break;
235  ++iterForw;
236  mEndSelect++;
237  }
238 
241  }
242 
243  void EditBox::onMouseDrag(int _left, int _top, MouseButton _id)
244  {
245  notifyMouseDrag(nullptr, _left, _top, _id);
246 
247  Base::onMouseDrag(_left, _top, _id);
248  }
249 
251  {
252  if (!mIsPressed)
253  {
254  mIsPressed = true;
255  updateEditState();
256 
257  if (!mModeStatic)
258  {
259  if (mClientText != nullptr)
260  {
261  mCursorActive = true;
262  Gui::getInstance().eventFrameStart += newDelegate(this, &EditBox::frameEntered);
265  mCursorTimer = 0;
266  }
267  }
268  }
269 
270  Base::onKeySetFocus(_old);
271  }
272 
274  {
275  if (mIsPressed)
276  {
277  mIsPressed = false;
278  updateEditState();
279 
280  if (mClientText != nullptr)
281  {
282  mCursorActive = false;
283  Gui::getInstance().eventFrameStart -= newDelegate(this, &EditBox::frameEntered);
286  }
287  }
288 
289  Base::onKeyLostFocus(_new);
290  }
291 
293  return c == ' ' || c == '\t';
294  }
295 
297  {
298  if (mClientText == nullptr || getClientWidget() == nullptr)
299  {
300  Base::onKeyButtonPressed(_key, _char);
301  return;
302  }
303 
304  // в статическом режиме ничего не доступно
305  if (mModeStatic)
306  {
307  Base::onKeyButtonPressed(_key, _char);
308  return;
309  }
310 
312 
314  mCursorTimer = 0.0f;
315 
316  if (_key == KeyCode::Escape)
317  {
319  }
320  else if (_key == KeyCode::Backspace)
321  {
322  // если нуно то удаляем выделенный текст
323  if (!mModeReadOnly)
324  {
325  // сбрасываем повтор
326  commandResetRedo();
327 
328  if (!deleteTextSelect(true))
329  {
330  // прыгаем на одну назад и удаляем
331  if (mCursorPosition != 0)
332  {
333  mCursorPosition--;
334  eraseText(mCursorPosition, 1, true);
335  }
336  }
337  // отсылаем событие о изменении
338  eventEditTextChange(this);
339  }
340 
341  }
342  else if (_key == KeyCode::Delete)
343  {
344  if (input.isShiftPressed())
345  {
346  // сбрасываем повтор
347  commandResetRedo();
348 
349  commandCut();
350  }
351  else if (!mModeReadOnly)
352  {
353  // сбрасываем повтор
354  commandResetRedo();
355 
356  // если нуно то удаляем выделенный текст
357  if (!deleteTextSelect(true))
358  {
360  {
361  eraseText(mCursorPosition, 1, true);
362  }
363  }
364  // отсылаем событие о изменении
365  eventEditTextChange(this);
366  }
367 
368  }
369  else if (_key == KeyCode::Insert)
370  {
371  if (input.isShiftPressed())
372  {
373  // сбрасываем повтор
374  commandResetRedo();
375 
376  commandPast();
377  }
378  else if (input.isControlPressed())
379  {
380  commandCopy();
381  }
382 
383  }
384  else if ((_key == KeyCode::Return) || (_key == KeyCode::NumpadEnter))
385  {
386  // работаем только в режиме редактирования
387  if (!mModeReadOnly)
388  {
389  if ((mModeMultiline) && (!input.isControlPressed()))
390  {
391  // сбрасываем повтор
392  commandResetRedo();
393 
394  // попытка объединения двух комманд
395  size_t size = mVectorUndoChangeInfo.size();
396  // непосредственно операции
397  deleteTextSelect(true);
399  // проверяем на возможность объединения
400  if ((size + 2) == mVectorUndoChangeInfo.size())
401  commandMerge();
402  // отсылаем событие о изменении
403  eventEditTextChange(this);
404  }
405  // при сингл лайн и и мульти+сонтрол шлем эвент
406  else
407  {
408  eventEditSelectAccept(this);
409  }
410  }
411 
412  }
413  else if (_key == KeyCode::ArrowRight)
414  {
416  {
417  if (input.isControlPressed())
418  {
419  if (mModePassword)
420  {
422  }
423  else
424  {
425  const UString& text = getRealString();
427  {
428  mCursorPosition ++;
429  }
431  {
432  mCursorPosition ++;
433  }
434  }
435  }
436  else
437  {
438  mCursorPosition ++;
439  }
441  updateSelectText();
442  }
443  // сбрасываем выделение
444  else if (isTextSelection() && !input.isShiftPressed())
445  {
446  resetSelect();
447  }
448 
449  }
450  else if (_key == KeyCode::ArrowLeft)
451  {
452  if (mCursorPosition != 0)
453  {
454  if (input.isControlPressed())
455  {
456  if (mModePassword)
457  {
458  mCursorPosition = 0;
459  }
460  else
461  {
462  const UString& text = getRealString();
463  while (mCursorPosition > 0 && isWhitespace(text[mCursorPosition - 1]))
464  {
465  mCursorPosition --;
466  }
467  while (mCursorPosition > 0 && !isWhitespace(text[mCursorPosition - 1]))
468  {
469  mCursorPosition --;
470  }
471  }
472  }
473  else
474  {
475  mCursorPosition --;
476  }
478  updateSelectText();
479  }
480  // сбрасываем выделение
481  else if (isTextSelection() && !input.isShiftPressed())
482  {
483  resetSelect();
484  }
485 
486  }
487  else if (_key == KeyCode::ArrowUp)
488  {
490  point.top -= mClientText->getFontHeight();
491  size_t old = mCursorPosition;
493  // самая верхняя строчка
494  if (old == mCursorPosition)
495  {
496  if (mCursorPosition != 0)
497  {
498  mCursorPosition = 0;
500  updateSelectText();
501  }
502  // сбрасываем выделение
503  else if (isTextSelection() && !input.isShiftPressed())
504  {
505  resetSelect();
506  }
507  }
508  else
509  {
511  updateSelectText();
512  }
513 
514  }
515  else if (_key == KeyCode::ArrowDown)
516  {
518  point.top += mClientText->getFontHeight();
519  size_t old = mCursorPosition;
521  // самая нижняя строчка
522  if (old == mCursorPosition)
523  {
525  {
528  updateSelectText();
529  }
530  // сбрасываем выделение
531  else if (isTextSelection() && !input.isShiftPressed())
532  {
533  resetSelect();
534  }
535  }
536  else
537  {
539  updateSelectText();
540  }
541 
542  }
543  else if (_key == KeyCode::Home)
544  {
545  // в начало строки
546  if (!input.isControlPressed())
547  {
550  size_t old = mCursorPosition;
552  if (old != mCursorPosition)
553  {
555  updateSelectText();
556  }
557  else if (isTextSelection() && !input.isShiftPressed())
558  {
559  resetSelect();
560  }
561  }
562  // в начало всего текста
563  else
564  {
565  if (0 != mCursorPosition)
566  {
567  mCursorPosition = 0;
569  updateSelectText();
570  }
571  else if (isTextSelection() && !input.isShiftPressed())
572  {
573  resetSelect();
574  }
575  }
576 
577  }
578  else if (_key == KeyCode::End)
579  {
580  // в конец строки
581  if (!input.isControlPressed())
582  {
585  size_t old = mCursorPosition;
587  if (old != mCursorPosition)
588  {
590  updateSelectText();
591  }
592  else if (isTextSelection() && !input.isShiftPressed())
593  {
594  resetSelect();
595  }
596  }
597  // в самый конец
598  else
599  {
601  {
604  updateSelectText();
605  }
606  else if (isTextSelection() && !input.isShiftPressed())
607  {
608  resetSelect();
609  }
610  }
611 
612  }
613  else if (_key == KeyCode::PageUp)
614  {
615  // на размер окна, но не меньше одной строки
618  size_t old = mCursorPosition;
620  // самая верхняя строчка
621  if (old == mCursorPosition)
622  {
623  if (mCursorPosition != 0)
624  {
625  mCursorPosition = 0;
627  updateSelectText();
628  }
629  // сбрасываем выделение
630  else if (isTextSelection() && !input.isShiftPressed())
631  {
632  resetSelect();
633  }
634  }
635  else
636  {
638  updateSelectText();
639  }
640 
641  }
642  else if (_key == KeyCode::PageDown)
643  {
644  // на размер окна, но не меньше одной строки
647  size_t old = mCursorPosition;
649  // самая нижняя строчка
650  if (old == mCursorPosition)
651  {
653  {
656  updateSelectText();
657  }
658  // сбрасываем выделение
659  else if (isTextSelection() && !input.isShiftPressed())
660  {
661  resetSelect();
662  }
663  }
664  else
665  {
667  updateSelectText();
668  }
669 
670  }
671  else if ((_key == KeyCode::LeftShift) || (_key == KeyCode::RightShift))
672  {
673  // для правильно выделения
674  if (mStartSelect == ITEM_NONE)
675  {
677  }
678  }
679  else
680  {
681  // если не нажат контрл, то обрабатываем как текст
682  if (!input.isControlPressed())
683  {
684  if (!mModeReadOnly && _char != 0)
685  {
686  // сбрасываем повтор
687  commandResetRedo();
688 
689  // таб только если нужно
690  if (_char != '\t' || mTabPrinting)
691  {
692  // попытка объединения двух комманд
693  size_t size = mVectorUndoChangeInfo.size();
694  // непосредственно операции
695  deleteTextSelect(true);
697  // проверяем на возможность объединения
698  if ((size + 2) == mVectorUndoChangeInfo.size())
699  commandMerge();
700  // отсылаем событие о изменении
701  eventEditTextChange(this);
702  }
703  }
704  }
705  else if (_key == KeyCode::C)
706  {
707  commandCopy();
708 
709  }
710  else if (_key == KeyCode::X)
711  {
712  // сбрасываем повтор
713  commandResetRedo();
714 
715  commandCut();
716 
717  }
718  else if (_key == KeyCode::V)
719  {
720  // сбрасываем повтор
721  commandResetRedo();
722 
723  commandPast();
724 
725  }
726  else if (_key == KeyCode::A)
727  {
728  // выделяем весь текст
730 
731  }
732  else if (_key == KeyCode::Z)
733  {
734  // отмена
735  commandUndo();
736 
737  }
738  else if (_key == KeyCode::Y)
739  {
740  // повтор
741  commandRedo();
742 
743  }
744  }
745 
746  Base::onKeyButtonPressed(_key, _char);
747  }
748 
749  void EditBox::frameEntered(float _frame)
750  {
751  if (mClientText == nullptr)
752  return;
753 
754  // в статике все недоступно
755  if (mModeStatic)
756  return;
757 
758  if (mCursorActive)
759  {
760  mCursorTimer += _frame;
761 
763  {
767  }
768  }
769 
770  // сдвигаем курсор по положению мыши
771  if (mMouseLeftPressed)
772  {
773  mActionMouseTimer += _frame;
774 
776  {
778  const IntRect& view = getClientWidget()->getAbsoluteRect();
779  mouse.left -= view.left;
780  mouse.top -= view.top;
781  IntPoint point;
782 
783  bool action = false;
784 
785  // вверх на одну строчку
786  if ((mouse.top < 0) && (mouse.top > -EDIT_ACTION_MOUSE_ZONE))
787  {
788  if ((mouse.left > 0) && (mouse.left <= getClientWidget()->getWidth()))
789  {
791  point.top -= mClientText->getFontHeight();
792  action = true;
793  }
794  }
795  // вниз на одну строчку
796  else if ((mouse.top > getClientWidget()->getHeight()) && (mouse.top < (getClientWidget()->getHeight() + EDIT_ACTION_MOUSE_ZONE)))
797  {
798  if ((mouse.left > 0) && (mouse.left <= getClientWidget()->getWidth()))
799  {
801  point.top += mClientText->getFontHeight();
802  action = true;
803  }
804  }
805 
806  // влево на небольшое расстояние
807  if ((mouse.left < 0) && (mouse.left > -EDIT_ACTION_MOUSE_ZONE))
808  {
810  point.left -= (int)EDIT_OFFSET_HORZ_CURSOR;
811  action = true;
812  }
813  // вправо на небольшое расстояние
814  else if ((mouse.left > getClientWidget()->getWidth()) && (mouse.left < (getClientWidget()->getWidth() + EDIT_ACTION_MOUSE_ZONE)))
815  {
817  point.left += (int)EDIT_OFFSET_HORZ_CURSOR;
818  action = true;
819  }
820 
821  if (action)
822  {
823  size_t old = mCursorPosition;
825 
826  if (old != mCursorPosition)
827  {
829 
830  if (mStartSelect == ITEM_NONE)
831  mStartSelect = old;
832 
833  mEndSelect = (size_t)mCursorPosition;
834  if (mStartSelect > mEndSelect)
836  else
838 
839  // пытаемся показать курсор
841  }
842  }
843  // если в зону не попадает то сбрасываем
844  else
845  {
846  mActionMouseTimer = 0;
847  }
848 
851  }
852 
853  } // if (mMouseLeftPressed)
854  }
855 
856  void EditBox::setTextCursor(size_t _index)
857  {
858  // сбрасываем выделение
859  resetSelect();
860 
861  // новая позиция
862  if (_index > mTextLength)
863  _index = mTextLength;
864 
865  if (mCursorPosition == _index)
866  return;
867 
868  mCursorPosition = _index;
869 
870  // обновляем по позиции
871  if (mClientText != nullptr)
873 
874  updateSelectText();
875  }
876 
877  void EditBox::setTextSelection(size_t _start, size_t _end)
878  {
879  if (_start > mTextLength)
880  _start = mTextLength;
881  if (_end > mTextLength)
882  _end = mTextLength;
883 
884  mStartSelect = _start;
885  mEndSelect = _end;
886 
887  if (mClientText != nullptr)
888  {
889  if (mStartSelect > mEndSelect)
891  else
893  }
894 
896  return;
897  // курсор на конец выделения
899 
900  // обновляем по позиции
901  if (mClientText != nullptr)
903  }
904 
905  bool EditBox::deleteTextSelect(bool _history)
906  {
907  if (!isTextSelection())
908  return false;
909 
910  // начало и конец выделения
911  size_t start = getTextSelectionStart();
912  size_t end = getTextSelectionEnd();
913 
914  eraseText(start, end - start, _history);
915 
916  return true;
917  }
918 
919  void EditBox::resetSelect()
920  {
921  if (mStartSelect != ITEM_NONE)
922  {
924  if (mClientText != nullptr)
926  }
927  }
928 
929  void EditBox::commandPosition(size_t _undo, size_t _redo, size_t _length, VectorChangeInfo* _info)
930  {
931  if (_info != nullptr)
932  _info->push_back(TextCommandInfo(_undo, _redo, _length));
933  }
934 
935  void EditBox::commandMerge()
936  {
937  if (mVectorUndoChangeInfo.size() < 2)
938  return; // на всякий
939  // сохраняем последние набор отмен
941  mVectorUndoChangeInfo.pop_back();
942 
943  // объединяем последовательности
944  for (VectorChangeInfo::iterator iter = info.begin(); iter != info.end(); ++iter)
945  {
946  mVectorUndoChangeInfo.back().push_back((*iter));
947  }
948  }
949 
950  bool EditBox::commandUndo()
951  {
952  if (mVectorUndoChangeInfo.empty())
953  return false;
954 
955  resetSelect();
956 
957  // save last undo info
959  // move undo info to redo
960  mVectorUndoChangeInfo.pop_back();
961  mVectorRedoChangeInfo.push_back(info);
962 
963  UString::utf32string text = getRealString().asUTF32();
964 
965  // apply undo
966  for (VectorChangeInfo::const_reverse_iterator iter = info.rbegin(); iter != info.rend(); ++iter)
967  {
968  const auto& change = *iter;
969  switch (change.type)
970  {
972  text.erase(change.start, change.text.size());
973  break;
975  text.insert(change.start, change.text);
976  break;
978  mCursorPosition = change.undo;
979  mTextLength = change.length;
980  break;
981  }
982  }
983 
984  setRealString(UString(text));
985 
986  // restore cursor position
987  if (mClientText != nullptr)
989  updateSelectText();
990 
991  eventEditTextChange(this);
992 
993  return true;
994  }
995 
996  bool EditBox::commandRedo()
997  {
998  if (mVectorRedoChangeInfo.empty())
999  return false;
1000 
1001  // сбрасываем выделение
1002  resetSelect();
1003 
1004  // save last undo info
1006  // move redo info to undo
1007  mVectorRedoChangeInfo.pop_back();
1008  mVectorUndoChangeInfo.push_back(info);
1009 
1010  UString::utf32string text = getRealString().asUTF32();
1011 
1012  // apply redo
1013  for (const auto& change : info)
1014  {
1015  switch (change.type)
1016  {
1018  text.insert(change.start, change.text);
1019  break;
1021  text.erase(change.start, change.text.size());
1022  break;
1024  mCursorPosition = change.redo;
1025  mTextLength = change.length;
1026  break;
1027  }
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  void EditBox::saveInHistory(VectorChangeInfo* _info)
1044  {
1045  if (_info == nullptr)
1046  return;
1047  // если нет информации об изменении
1048  if ( _info->empty())
1049  return;
1050  if ((_info->size() == 1) && (_info->back().type == TextCommandInfo::COMMAND_POSITION))
1051  return;
1052 
1053  mVectorUndoChangeInfo.push_back(*_info);
1054  // проверяем на максимальный размер
1055  if (mVectorUndoChangeInfo.size() > EDIT_MAX_UNDO)
1056  mVectorUndoChangeInfo.pop_front();
1057  }
1058 
1059  // возвращает текст
1060  UString EditBox::getTextInterval(size_t _start, size_t _count) const
1061  {
1062  // подстраховка
1063  if (_start > mTextLength) _start = mTextLength;
1064  // конец диапазона
1065  size_t end = _start + _count;
1066 
1067  // итератор нашей строки
1068  TextIterator iterator(getRealString());
1069 
1070  // дефолтный цвет
1072 
1073  // нужно ли вставлять цвет
1074  bool need_colour = true;
1075 
1076  // цикл прохода по строке
1077  while (iterator.moveNext())
1078  {
1079  // текущаяя позиция
1080  size_t pos = iterator.getPosition();
1081 
1082  // еще рано
1083  if (pos < _start)
1084  {
1085  // берем цвет из позиции и запоминаем
1086  iterator.getTagColour(colour);
1087 
1088  continue;
1089  }
1090 
1091  // проверяем на надобность начального тега
1092  else if (pos == _start)
1093  {
1094  need_colour = ! iterator.getTagColour(colour);
1095  // сохраняем место откуда начинается
1096  iterator.saveStartPoint();
1097 
1098  }
1099 
1100  // а теперь просто до конца диапазона
1101  else if (pos == end)
1102  break;
1103 
1104  }
1105 
1106  // возвращаем строку
1107  if (need_colour)
1108  return colour + iterator.getFromStart();
1109  return iterator.getFromStart();
1110  }
1111 
1112  // выделяет цветом диапазон
1113  void EditBox::_setTextColour(size_t _start, size_t _count, const Colour& _colour, bool _history)
1114  {
1115  // история изменений
1116  VectorChangeInfo* history = nullptr;
1117  if (_history)
1118  history = new VectorChangeInfo();
1119 
1120  // конец диапазона
1121  size_t end = _start + _count;
1122 
1123  // итератор нашей строки
1124  TextIterator iterator(getRealString(), history);
1125 
1126  // дефолтный цвет
1128 
1129  // цикл прохода по строке
1130  while (iterator.moveNext())
1131  {
1132  // текущаяя позиция
1133  size_t pos = iterator.getPosition();
1134 
1135  // берем цвет из позиции и запоминаем
1136  iterator.getTagColour(colour);
1137 
1138  // еще рано
1139  if (pos < _start)
1140  continue;
1141 
1142  // ставим начальный тег
1143  else if (pos == _start)
1144  iterator.setTagColour(_colour);
1145 
1146  // внутри диапазона очищаем все
1147  else if (pos < end)
1148  iterator.clearTagColour();
1149 
1150  // на конец ставим последний найденный или дефолтный
1151  else if (pos == end)
1152  {
1153  iterator.setTagColour(colour);
1154  // и выходим из цикла
1155  break;
1156  }
1157 
1158  }
1159 
1160  // сохраняем позицию для восстановления курсора
1161  commandPosition(_start, _start + _count, mTextLength, history);
1162 
1163  // запоминаем в историю
1164  if (_history)
1165  {
1166  saveInHistory(history);
1167  delete history;
1168  }
1169  // сбрасываем историю
1170  else
1171  commandResetHistory();
1172 
1173  // и возвращаем строку на место
1174  setRealString(iterator.getText());
1175  }
1176 
1177  void EditBox::setTextSelectColour(const Colour& _colour, bool _history)
1178  {
1179  // нужно выделение
1180  if ( !isTextSelection())
1181  return;
1182  // начало и конец выделения
1183  size_t start = getTextSelectionStart();
1184  size_t end = getTextSelectionEnd();
1185  _setTextColour(start, end - start, _colour, _history);
1186  }
1187 
1189  {
1190  if ( !isTextSelection())
1191  return "";
1192  size_t start = getTextSelectionStart();
1193  size_t end = getTextSelectionEnd();
1194  return getTextInterval(start, end - start);
1195  }
1196 
1197  void EditBox::setEditPassword(bool _password)
1198  {
1199  if (mModePassword == _password)
1200  return;
1201  mModePassword = _password;
1202 
1203  if (mModePassword)
1204  {
1205  if (mClientText != nullptr)
1206  {
1209  }
1210  }
1211  else
1212  {
1213  if (mClientText != nullptr)
1214  {
1216  mPasswordText.clear();
1217  }
1218  }
1219  // обновляем по размерам
1220  updateView();
1221  // сбрасываем историю
1222  commandResetHistory();
1223  }
1224 
1225  void EditBox::setText(const UString& _caption, bool _history)
1226  {
1227  // сбрасываем выделение
1228  resetSelect();
1229 
1230  // история изменений
1231  VectorChangeInfo* history = nullptr;
1232  if (_history)
1233  history = new VectorChangeInfo();
1234 
1235  // итератор нашей строки
1236  TextIterator iterator(getRealString(), history);
1237 
1238  // вставляем текст
1239  iterator.setText(_caption, mModeMultiline || mModeWordWrap);
1240 
1241  if (mOverflowToTheLeft)
1242  {
1243  iterator.cutMaxLengthFromBeginning(mMaxTextLength);
1244  }
1245  else
1246  {
1247  // обрезаем по максимальной длинне
1248  iterator.cutMaxLength(mMaxTextLength);
1249  }
1250 
1251  // запоминаем размер строки
1252  size_t old = mTextLength;
1253  // новая позиция и положение на конец вставки
1254  mCursorPosition = mTextLength = iterator.getSize();
1255 
1256  // сохраняем позицию для восстановления курсора
1257  commandPosition(0, mTextLength, old, history);
1258 
1259  // запоминаем в историю
1260  if (_history)
1261  {
1262  saveInHistory(history);
1263  delete history;
1264  }
1265  // сбрасываем историю
1266  else
1267  commandResetHistory();
1268 
1269  // и возвращаем строку на место
1270  setRealString(iterator.getText());
1271 
1272  // обновляем по позиции
1273  if (mClientText != nullptr)
1275  updateSelectText();
1276  }
1277 
1278  void EditBox::insertText(const UString& _text, size_t _start, bool _history)
1279  {
1280  // сбрасываем выделение
1281  resetSelect();
1282 
1283  // если строка пустая, или размер максимален
1284  if (_text.empty())
1285  return;
1286 
1287  if ((mOverflowToTheLeft == false) && (mTextLength == mMaxTextLength))
1288  return;
1289 
1290  // история изменений
1291  VectorChangeInfo* history = nullptr;
1292  if (_history)
1293  history = new VectorChangeInfo();
1294 
1295  // итератор нашей строки
1296  TextIterator iterator(getRealString(), history);
1297 
1298  // дефолтный цвет
1299  UString colour = mClientText == nullptr ? "" : TextIterator::convertTagColour(mClientText->getTextColour());
1300  // нужен ли тег текста
1301  // потом переделать через TextIterator чтобы отвязать понятие тег от эдита
1302  bool need_colour = ( (_text.size() > 6) && (_text[0] == L'#') && (_text[1] != L'#') );
1303 
1304  // цикл прохода по строке
1305  while (iterator.moveNext())
1306  {
1307  // текущаяя позиция
1308  size_t pos = iterator.getPosition();
1309 
1310  // текущий цвет
1311  if (need_colour)
1312  iterator.getTagColour(colour);
1313 
1314  // если дошли то выходим
1315  if (pos == _start)
1316  break;
1317  }
1318 
1319  // если нужен цвет то вставляем
1320  if (need_colour)
1321  iterator.setTagColour(colour);
1322 
1323  // а теперь вставляем строку
1324  iterator.insertText(_text, mModeMultiline || mModeWordWrap);
1325 
1326  if (mOverflowToTheLeft)
1327  {
1328  iterator.cutMaxLengthFromBeginning(mMaxTextLength);
1329  }
1330  else
1331  {
1332  // обрезаем по максимальной длинне
1333  iterator.cutMaxLength(mMaxTextLength);
1334  }
1335 
1336  // запоминаем размер строки
1337  size_t old = mTextLength;
1338  // новая позиция и положение на конец вставки
1339  mTextLength = iterator.getSize();
1340  mCursorPosition += mTextLength - old;
1341 
1342  // сохраняем позицию для восстановления курсора
1343  commandPosition(_start, _start + mTextLength - old, old, history);
1344 
1345  // запоминаем в историю
1346  if (_history)
1347  {
1348  saveInHistory(history);
1349  delete history;
1350  }
1351  // сбрасываем историю
1352  else
1353  commandResetHistory();
1354 
1355  // и возвращаем строку на место
1356  setRealString(iterator.getText());
1357 
1358  // обновляем по позиции
1359  if (mClientText != nullptr)
1361  updateSelectText();
1362  }
1363 
1364  void EditBox::eraseText(size_t _start, size_t _count, bool _history)
1365  {
1366  // чета маловато
1367  if (_count == 0)
1368  return;
1369 
1370  // сбрасываем выделение
1371  resetSelect();
1372 
1373  // история изменений
1374  VectorChangeInfo* history = nullptr;
1375  if (_history)
1376  history = new VectorChangeInfo();
1377 
1378  // итератор нашей строки
1379  TextIterator iterator(getRealString(), history);
1380 
1381  // дефолтный цвет
1382  UString colour;
1383  // конец диапазона
1384  size_t end = _start + _count;
1385  bool need_colour = false;
1386 
1387  // цикл прохода по строке
1388  while (iterator.moveNext())
1389  {
1390  // текущаяя позиция
1391  size_t pos = iterator.getPosition();
1392 
1393  // еще рано
1394  if (pos < _start)
1395  {
1396  // берем цвет из позиции и запоминаем
1397  iterator.getTagColour(colour);
1398  continue;
1399  }
1400 
1401  // сохраняем место откуда начинается
1402  else if (pos == _start)
1403  {
1404  // если до диапазона был цвет, то нужно закрыть тег
1405  if (!colour.empty())
1406  {
1407  need_colour = true;
1408  colour.clear();
1409  }
1410  // берем цвет из позиции и запоминаем
1411  iterator.getTagColour(colour);
1412  iterator.saveStartPoint();
1413  }
1414 
1415  // внутри диапазона
1416  else if (pos < end)
1417  {
1418  // берем цвет из позиции и запоминаем
1419  iterator.getTagColour(colour);
1420  }
1421 
1422  // окончание диапазона
1423  else if (pos == end)
1424  {
1425  // нужно ставить тег или нет
1426  if (!colour.empty())
1427  need_colour = true;
1428  if (iterator.getTagColour(colour))
1429  need_colour = false;
1430 
1431  break;
1432  }
1433 
1434  }
1435 
1436  // удаляем диапазон
1437  iterator.eraseFromStart();
1438  // и вставляем последний цвет
1439  if (need_colour)
1440  iterator.setTagColour(colour);
1441 
1442  // сохраняем позицию для восстановления курсора
1443  commandPosition(_start + _count, _start, mTextLength, history);
1444 
1445  // на месте удаленного
1446  mCursorPosition = _start;
1447  mTextLength -= _count;
1448 
1449  // запоминаем в историю
1450  if (_history)
1451  {
1452  saveInHistory(history);
1453  delete history;
1454  }
1455  // сбрасываем историю
1456  else
1457  commandResetHistory();
1458 
1459  // и возвращаем строку на место
1460  setRealString(iterator.getText());
1461 
1462  // обновляем по позиции
1463  if (mClientText != nullptr)
1465  updateSelectText();
1466  }
1467 
1468  void EditBox::commandCut()
1469  {
1470  // вырезаем в буфер обмена
1471  if (isTextSelection() && (!mModePassword))
1472  {
1474  if (!mModeReadOnly)
1475  {
1476  deleteTextSelect(true);
1477  // отсылаем событие о изменении
1478  eventEditTextChange(this);
1479  }
1480  }
1481  else
1483  }
1484 
1485  void EditBox::commandCopy()
1486  {
1487  // копируем в буфер обмена
1488  if (isTextSelection() && (!mModePassword))
1490  else
1492  }
1493 
1494  void EditBox::commandPast()
1495  {
1496  // копируем из буфера обмена
1498  if ((!mModeReadOnly) && (!clipboard.empty()))
1499  {
1500  // попытка объединения двух комманд
1501  size_t size = mVectorUndoChangeInfo.size();
1502  // непосредственно операции
1503  deleteTextSelect(true);
1504  insertText(clipboard, mCursorPosition, true);
1505  // проверяем на возможность объединения
1506  if ((size + 2) == mVectorUndoChangeInfo.size())
1507  commandMerge();
1508  // отсылаем событие о изменении
1509  eventEditTextChange(this);
1510  }
1511  }
1512 
1513  const UString& EditBox::getRealString() const
1514  {
1515  if (mModePassword)
1516  return mPasswordText;
1517  else if (mClientText == nullptr)
1518  return mPasswordText;
1519 
1520  return mClientText->getCaption();
1521  }
1522 
1523  void EditBox::setRealString(const UString& _caption)
1524  {
1525  if (mModePassword)
1526  {
1527  mPasswordText = _caption;
1528  if (mClientText != nullptr)
1530  }
1531  else
1532  {
1533  if (mClientText != nullptr)
1534  mClientText->setCaption(_caption);
1535  }
1536  }
1537 
1539  {
1540  mCharPassword = _char;
1541  if (mModePassword)
1542  {
1543  if (mClientText != nullptr)
1545  }
1546  }
1547 
1548  void EditBox::updateEditState()
1549  {
1550  if (!getInheritedEnabled())
1551  {
1552  _setWidgetState("disabled");
1553  }
1554  else if (mIsPressed)
1555  {
1556  if (mIsFocus)
1557  _setWidgetState("pushed");
1558  else
1559  _setWidgetState("normal_checked");
1560  }
1561  else if (mIsFocus)
1562  {
1563  _setWidgetState("highlighted");
1564  }
1565  else
1566  {
1567  _setWidgetState("normal");
1568  }
1569  }
1570 
1571  void EditBox::setPosition(const IntPoint& _point)
1572  {
1573  Base::setPosition(_point);
1574  }
1575 
1577  {
1578  // если перенос, то сбрасываем размер текста
1579  if (mModeWordWrap)
1580  {
1581  if (mClientText != nullptr)
1582  mClientText->setWordWrap(true);
1583  }
1584 
1585  updateView();
1586  }
1587 
1588  void EditBox::setSize(const IntSize& _size)
1589  {
1590  Base::setSize(_size);
1591 
1592  eraseView();
1593  }
1594 
1595  void EditBox::setCoord(const IntCoord& _coord)
1596  {
1597  Base::setCoord(_coord);
1598 
1599  eraseView();
1600  }
1601 
1602  void EditBox::setCaption(const UString& _value)
1603  {
1604  setText(_value, false);
1605  }
1606 
1608  {
1609  return getRealString();
1610  }
1611 
1612  void EditBox::updateSelectText()
1613  {
1614  if (!mModeStatic)
1615  {
1617  if ((input.isShiftPressed()) && (mStartSelect != ITEM_NONE))
1618  {
1619  // меняем выделение
1620  mEndSelect = (size_t)mCursorPosition;
1621  if (mClientText != nullptr)
1622  {
1623  if (mStartSelect > mEndSelect)
1625  else
1627  }
1628 
1629  }
1630  else if (mStartSelect != ITEM_NONE)
1631  {
1632  // сбрасываем шифт
1634  if (mClientText != nullptr)
1636  }
1637  }
1638 
1639  // пытаемся показать курсор
1641  }
1642 
1644  {
1645  Base::setTextAlign(_value);
1646 
1647  if (mClientText != nullptr)
1648  mClientText->setTextAlign(_value);
1649 
1650  // так как мы сами рулим смещениями
1651  updateView();
1652  }
1653 
1654  void EditBox::setTextColour(const Colour& _value)
1655  {
1656  Base::setTextColour(_value);
1657 
1658  if (mClientText != nullptr)
1659  mClientText->setTextColour(_value);
1660  }
1661 
1663  {
1664  if (mClientText != nullptr)
1665  return mClientText->getCoord();
1666  return Base::getTextRegion();
1667  }
1668 
1670  {
1671  if (mClientText != nullptr)
1672  return mClientText->getTextSize();
1673  return Base::getTextSize();
1674  }
1675 
1676  void EditBox::notifyScrollChangePosition(ScrollBar* _sender, size_t _position)
1677  {
1678  if (mClientText == nullptr)
1679  return;
1680 
1681  if (_sender == mVScroll)
1682  {
1683  IntPoint point = mClientText->getViewOffset();
1684  point.top = _position;
1685  mClientText->setViewOffset(point);
1686  }
1687  else if (_sender == mHScroll)
1688  {
1689  IntPoint point = mClientText->getViewOffset();
1690  point.left = _position;
1691  mClientText->setViewOffset(point);
1692  }
1693  }
1694 
1695  void EditBox::notifyMouseWheel(Widget* _sender, int _rel)
1696  {
1697  if (mClientText == nullptr)
1698  return;
1699 
1700  if (mVRange != 0)
1701  {
1702  IntPoint point = mClientText->getViewOffset();
1703  int offset = point.top;
1704  if (_rel < 0)
1705  offset += EDIT_MOUSE_WHEEL;
1706  else
1707  offset -= EDIT_MOUSE_WHEEL;
1708 
1709  if (offset < 0)
1710  offset = 0;
1711  else if (offset > (int)mVRange)
1712  offset = mVRange;
1713 
1714  if (offset != point.top)
1715  {
1716  point.top = offset;
1717  if (mVScroll != nullptr)
1718  mVScroll->setScrollPosition(offset);
1719  mClientText->setViewOffset(point);
1720  }
1721  }
1722  else if (mHRange != 0)
1723  {
1724  IntPoint point = mClientText->getViewOffset();
1725  int offset = point.left;
1726  if (_rel < 0)
1727  offset += EDIT_MOUSE_WHEEL;
1728  else
1729  offset -= EDIT_MOUSE_WHEEL;
1730 
1731  if (offset < 0)
1732  offset = 0;
1733  else if (offset > (int)mHRange)
1734  offset = mHRange;
1735 
1736  if (offset != point.left)
1737  {
1738  point.left = offset;
1739  if (mHScroll != nullptr)
1740  mHScroll->setScrollPosition(offset);
1741  mClientText->setViewOffset(point);
1742  }
1743  }
1744  }
1745 
1746  void EditBox::setEditWordWrap(bool _value)
1747  {
1748  mModeWordWrap = _value;
1749  if (mClientText != nullptr)
1751 
1752  eraseView();
1753  }
1754 
1755  void EditBox::setFontName(const std::string& _value)
1756  {
1757  Base::setFontName(_value);
1758 
1759  if (mClientText != nullptr)
1760  mClientText->setFontName(_value);
1761 
1762  eraseView();
1763  }
1764 
1765  void EditBox::setFontHeight(int _value)
1766  {
1767  Base::setFontHeight(_value);
1768 
1769  if (mClientText != nullptr)
1770  mClientText->setFontHeight(_value);
1771 
1772  eraseView();
1773  }
1774 
1776  {
1777  return (nullptr == mClientText) ? 0 : mClientText->getFontHeight();
1778  }
1779 
1781  {
1782  updateScrollSize();
1784  }
1785 
1787  {
1788  updateScrollSize();
1789  updateCursorPosition();
1791  }
1792 
1793  void EditBox::updateCursorPosition()
1794  {
1795  if (mClientText == nullptr || getClientWidget() == nullptr)
1796  return;
1797 
1798  // размер контекста текста
1799  IntSize textSize = mClientText->getTextSize();
1800 
1801  // текущее смещение контекста текста
1802  IntPoint point = mClientText->getViewOffset();
1803  // расчетное смещение
1804  IntPoint offset = point;
1805 
1806  // абсолютные координаты курсора
1808  cursor.right ++;
1809 
1810  // абсолютные координаты вью
1811  const IntRect& view = getClientWidget()->getAbsoluteRect();
1812 
1813  // проверяем и показываем курсор
1814  if (!view.inside(cursor))
1815  {
1816  // горизонтальное смещение
1817  if (textSize.width > view.width())
1818  {
1819  if (cursor.left < view.left)
1820  {
1821  offset.left = point.left - (view.left - cursor.left);
1822  // добавляем смещение, только если курсор не перепрыгнет
1823  if ((float(view.width()) - EDIT_OFFSET_HORZ_CURSOR) > EDIT_OFFSET_HORZ_CURSOR)
1824  offset.left -= int(EDIT_OFFSET_HORZ_CURSOR);
1825  }
1826  else if (cursor.right > view.right)
1827  {
1828  offset.left = point.left + (cursor.right - view.right);
1829  // добавляем смещение, только если курсор не перепрыгнет
1830  if ((float(view.width()) - EDIT_OFFSET_HORZ_CURSOR) > EDIT_OFFSET_HORZ_CURSOR)
1831  offset.left += int(EDIT_OFFSET_HORZ_CURSOR);
1832  }
1833  }
1834 
1835  // вертикальное смещение
1836  if (textSize.height > view.height())
1837  {
1838  int delta = 0;
1839  if (cursor.height() > view.height())
1840  {
1841  // if text is bigger than edit height then place it in center
1842  delta = ((cursor.bottom - view.bottom) - (view.top - cursor.top)) / 2;
1843  }
1844  else if (cursor.top < view.top)
1845  {
1846  delta = - (view.top - cursor.top);
1847  }
1848  else if (cursor.bottom > view.bottom)
1849  {
1850  delta = (cursor.bottom - view.bottom);
1851  }
1852  offset.top = point.top + delta;
1853  }
1854 
1855  }
1856 
1857  if (offset != point)
1858  {
1859  mClientText->setViewOffset(offset);
1860  // обновить скролы
1861  if (mVScroll != nullptr)
1862  mVScroll->setScrollPosition(offset.top);
1863  if (mHScroll != nullptr)
1864  mHScroll->setScrollPosition(offset.left);
1865  }
1866  }
1867 
1868  void EditBox::setContentPosition(const IntPoint& _point)
1869  {
1870  if (mClientText != nullptr)
1871  mClientText->setViewOffset(_point);
1872  }
1873 
1874  IntSize EditBox::getViewSize() const
1875  {
1876  if (mClientText != nullptr)
1877  return mClientText->getSize();
1878  return ScrollViewBase::getViewSize();
1879  }
1880 
1881  IntSize EditBox::getContentSize() const
1882  {
1883  if (mClientText != nullptr)
1884  return mClientText->getTextSize();
1886  }
1887 
1888  size_t EditBox::getVScrollPage() const
1889  {
1890  if (mClientText != nullptr)
1891  return (size_t)mClientText->getFontHeight();
1893  }
1894 
1895  size_t EditBox::getHScrollPage() const
1896  {
1897  if (mClientText != nullptr)
1898  return (size_t)mClientText->getFontHeight();
1900  }
1901 
1902  IntPoint EditBox::getContentPosition() const
1903  {
1904  if (mClientText != nullptr)
1905  return mClientText->getViewOffset();
1907  }
1908 
1909  Align EditBox::getContentAlign() const
1910  {
1911  if (mClientText != nullptr)
1912  return mClientText->getTextAlign();
1914  }
1915 
1916  void EditBox::setTextIntervalColour(size_t _start, size_t _count, const Colour& _colour)
1917  {
1918  _setTextColour(_start, _count, _colour, false);
1919  }
1920 
1922  {
1924  }
1925 
1927  {
1929  }
1930 
1932  {
1933  return (mStartSelect != ITEM_NONE) && (mStartSelect != mEndSelect);
1934  }
1935 
1937  {
1938  deleteTextSelect(false);
1939  }
1940 
1942  {
1943  setTextSelectColour(_colour, false);
1944  }
1945 
1947  {
1948  return mEndSelect - mStartSelect;
1949  }
1950 
1951  void EditBox::setOnlyText(const UString& _text)
1952  {
1953  setText(TextIterator::toTagsString(_text), false);
1954  }
1955 
1957  {
1958  return TextIterator::getOnlyText(getRealString());
1959  }
1960 
1961  void EditBox::insertText(const UString& _text, size_t _index)
1962  {
1963  insertText(_text, _index, false);
1964  }
1965 
1966  void EditBox::addText(const UString& _text)
1967  {
1968  insertText(_text, ITEM_NONE, false);
1969  }
1970 
1971  void EditBox::eraseText(size_t _start, size_t _count)
1972  {
1973  eraseText(_start, _count, false);
1974  }
1975 
1976  void EditBox::setEditReadOnly(bool _value)
1977  {
1978  mModeReadOnly = _value;
1979  // сбрасываем историю
1980  commandResetHistory();
1981  }
1982 
1983  void EditBox::setEditMultiLine(bool _value)
1984  {
1985  mModeMultiline = _value;
1986  // на всякий, для убирания переносов
1987  if (!mModeMultiline)
1988  {
1989  setText(getRealString(), false);
1990  }
1991  // обновляем по размерам
1992  else
1993  {
1994  updateView();
1995  }
1996  // сбрасываем историю
1997  commandResetHistory();
1998  }
1999 
2000  void EditBox::setEditStatic(bool _value)
2001  {
2002  mModeStatic = _value;
2003  resetSelect();
2004 
2005  if (getClientWidget() != nullptr)
2006  {
2007  if (mModeStatic)
2008  getClientWidget()->setPointer("");
2009  else
2011  }
2012  }
2013 
2014  void EditBox::setPasswordChar(const UString& _value)
2015  {
2016  if (!_value.empty())
2017  setPasswordChar(_value[0]);
2018  }
2019 
2020  void EditBox::setVisibleVScroll(bool _value)
2021  {
2022  mVisibleVScroll = _value;
2023  updateView();
2024  }
2025 
2026  void EditBox::setVisibleHScroll(bool _value)
2027  {
2028  mVisibleHScroll = _value;
2029  updateView();
2030  }
2031 
2033  {
2034  return mVRange + 1;
2035  }
2036 
2038  {
2039  return mClientText == nullptr ? 0 : mClientText->getViewOffset().top;
2040  }
2041 
2042  void EditBox::setVScrollPosition(size_t _index)
2043  {
2044  if (mClientText == nullptr)
2045  return;
2046 
2047  if (_index > mVRange)
2048  _index = mVRange;
2049 
2050  IntPoint point = mClientText->getViewOffset();
2051  point.top = _index;
2052 
2053  mClientText->setViewOffset(point);
2054  // обновить скролы
2055  if (mVScroll != nullptr)
2056  mVScroll->setScrollPosition(point.top);
2057  }
2058 
2060  {
2061  return mHRange + 1;
2062  }
2063 
2065  {
2066  return mClientText == nullptr ? 0 : mClientText->getViewOffset().left;
2067  }
2068 
2069  void EditBox::setHScrollPosition(size_t _index)
2070  {
2071  if (mClientText == nullptr)
2072  return;
2073 
2074  if (_index > mHRange)
2075  _index = mHRange;
2076 
2077  IntPoint point = mClientText->getViewOffset();
2078  point.left = _index;
2079 
2080  mClientText->setViewOffset(point);
2081  // обновить скролы
2082  if (mHScroll != nullptr)
2084  }
2085 
2087  {
2088  return mClientText == nullptr ? false : mClientText->getInvertSelected();
2089  }
2090 
2091  void EditBox::setInvertSelected(bool _value)
2092  {
2093  if (mClientText != nullptr)
2094  mClientText->setInvertSelected(_value);
2095  }
2096 
2097  void EditBox::setPropertyOverride(const std::string& _key, const std::string& _value)
2098  {
2100  if (_key == "CursorPosition")
2101  setTextCursor(utility::parseValue<size_t>(_value));
2102 
2104  else if (_key == "TextSelect")
2106 
2108  else if (_key == "ReadOnly")
2109  setEditReadOnly(utility::parseValue<bool>(_value));
2110 
2112  else if (_key == "Password")
2113  setEditPassword(utility::parseValue<bool>(_value));
2114 
2116  else if (_key == "MultiLine")
2117  setEditMultiLine(utility::parseValue<bool>(_value));
2118 
2120  else if (_key == "PasswordChar")
2121  setPasswordChar(_value);
2122 
2124  else if (_key == "MaxTextLength")
2125  setMaxTextLength(utility::parseValue<size_t>(_value));
2126 
2128  else if (_key == "OverflowToTheLeft")
2129  setOverflowToTheLeft(utility::parseValue<bool>(_value));
2130 
2132  else if (_key == "Static")
2133  setEditStatic(utility::parseValue<bool>(_value));
2134 
2136  else if (_key == "VisibleVScroll")
2137  setVisibleVScroll(utility::parseValue<bool>(_value));
2138 
2140  else if (_key == "VisibleHScroll")
2141  setVisibleHScroll(utility::parseValue<bool>(_value));
2142 
2144  else if (_key == "WordWrap")
2145  setEditWordWrap(utility::parseValue<bool>(_value));
2146 
2148  else if (_key == "TabPrinting")
2149  setTabPrinting(utility::parseValue<bool>(_value));
2150 
2152  else if (_key == "InvertSelected")
2153  setInvertSelected(utility::parseValue<bool>(_value));
2154 
2155  else
2156  {
2157  Base::setPropertyOverride(_key, _value);
2158  return;
2159  }
2160 
2161  eventChangeProperty(this, _key, _value);
2162  }
2163 
2164  size_t EditBox::getTextCursor() const
2165  {
2166  return mCursorPosition;
2167  }
2168 
2169  size_t EditBox::getTextLength() const
2170  {
2171  return mTextLength;
2172  }
2173 
2175  {
2176  mOverflowToTheLeft = _value;
2177  }
2178 
2180  {
2181  return mOverflowToTheLeft;
2182  }
2183 
2184  void EditBox::setMaxTextLength(size_t _value)
2185  {
2186  mMaxTextLength = _value;
2187  }
2188 
2190  {
2191  return mMaxTextLength;
2192  }
2193 
2195  {
2196  return mModeReadOnly;
2197  }
2198 
2200  {
2201  return mModePassword;
2202  }
2203 
2205  {
2206  return mModeMultiline;
2207  }
2208 
2210  {
2211  return mModeStatic;
2212  }
2213 
2215  {
2216  return mCharPassword;
2217  }
2218 
2220  {
2221  return mModeWordWrap;
2222  }
2223 
2224  void EditBox::setTabPrinting(bool _value)
2225  {
2226  mTabPrinting = _value;
2227  }
2228 
2230  {
2231  return mTabPrinting;
2232  }
2233 
2235  {
2236  return mVisibleVScroll;
2237  }
2238 
2240  {
2241  return mVisibleHScroll;
2242  }
2243 
2244  void EditBox::commandResetRedo()
2245  {
2246  mVectorRedoChangeInfo.clear();
2247  }
2248 
2249  void EditBox::commandResetHistory()
2250  {
2251  mVectorRedoChangeInfo.clear();
2252  mVectorUndoChangeInfo.clear();
2253  }
2254 
2256  {
2257  Base::setTextShadowColour(_value);
2258 
2259  if (mClientText != nullptr)
2260  mClientText->setShadowColour(_value);
2261  }
2262 
2263  void EditBox::setTextShadow(bool _value)
2264  {
2265  Base::setTextShadow(_value);
2266 
2267  if (mClientText != nullptr)
2268  mClientText->setShadow(_value);
2269  }
2270 
2271 } // namespace MyGUI
void clearClipboardData(const std::string &_type)
static ClipboardManager & getInstance()
void setClipboardData(const std::string &_type, const std::string &_data)
std::string getClipboardData(const std::string &_type) const
DequeUndoRedoInfo mVectorUndoChangeInfo
void setFontHeight(int _value) override
void insertText(const UString &_text, size_t _index=ITEM_NONE)
void deleteTextSelection()
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 setCoord(const IntCoord &_value) override
void setTextShadow(bool _value) override
void setPasswordChar(Char _value)
ISubWidgetText * mClientText
void notifyMouseSetFocus(Widget *_sender, Widget *_old)
const UString & getCaption() const override
bool isVisibleVScroll() const
size_t mMaxTextLength
void setOnlyText(const UString &_value)
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 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 setFontName(const std::string &_value) override
bool isVisibleHScroll() const
void setEditWordWrap(bool _value)
DequeUndoRedoInfo mVectorRedoChangeInfo
size_t getHScrollRange() const
void setPropertyOverride(const std::string &_key, const std::string &_value) override
void onKeyButtonPressed(KeyCode _key, Char _char) override
void setPosition(const IntPoint &_value) override
void updateViewWithCursor()
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 setSize(const IntSize &_value) override
void onKeyLostFocus(Widget *_new) override
void setCaption(const UString &_value) override
void notifyMouseButtonDoubleClick(Widget *_sender)
void setVisibleHScroll(bool _value)
void setTextSelectionColour(const Colour &_value)
bool getEditReadOnly() const
void notifyScrollChangePosition(ScrollBar *_sender, size_t _position)
void setEditPassword(bool _value)
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
size_t getHScrollPosition() const
void addText(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)
float mActionMouseTimer
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)
size_t mCursorPosition
void onKeySetFocus(Widget *_old) override
void notifyMousePressed(Widget *_sender, int _left, int _top, MouseButton _id)
void initialiseOverride() override
void setTextCursor(size_t _index)
static Gui & getInstance()
EventHandle_FrameEventDelegate eventFrameStart
Definition: MyGUI_Gui.h:150
const IntCoord & getCoord() const
virtual void setTextAlign(Align _value)
virtual bool getInvertSelected() const
virtual void setViewOffset(const IntPoint &_point)
virtual IntPoint getViewOffset() const
virtual void setCursorPosition(size_t _index)
virtual void setShadowColour(const Colour &_value)
IntRect getCursorRect(size_t _position) const
IntPoint getCursorPoint(size_t _position) const
virtual void setInvertSelected(bool _value)
virtual IntSize getTextSize() const
virtual void setShadow(bool _value)
virtual size_t getCursorPosition() const
virtual int getFontHeight() const
virtual void setFontHeight(int _value)
virtual void setSelectBackground(bool _normal)
virtual void setTextColour(const Colour &_value)
virtual void setVisibleCursor(bool _value)
virtual const Colour & getTextColour() const
virtual const UString & getCaption() const
virtual Align getTextAlign() const
virtual void setFontName(const std::string &_value)
virtual void setWordWrap(bool _value)
virtual void setTextSelection(size_t _start, size_t _end)
virtual void setCaption(const UString &_value)
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 _value)
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)
UString getFromStart() const
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.
Definition: MyGUI_Widget.h:37
bool getInheritedEnabled() const
EventHandle_WidgetStringString eventChangeProperty
Definition: MyGUI_Widget.h:267
bool _setWidgetState(const std::string &_value)
void assignWidget(T *&_widget, const std::string &_name)
Definition: MyGUI_Widget.h:335
Widget * getClientWidget()
EventHandle_WidgetVoid eventMouseButtonDoubleClick
void setPointer(const std::string &_value)
EventHandle_WidgetIntIntButton eventMouseButtonReleased
const std::string & getPointer() const
void setNeedKeyFocus(bool _value)
EventHandle_WidgetIntIntButton eventMouseButtonPressed
EventHandle_WidgetWidget eventMouseSetFocus
EventHandle_WidgetWidget eventMouseLostFocus
EventPairAddParameter< EventHandle_WidgetIntInt, EventHandle_WidgetIntIntButton > eventMouseDrag
EventHandle_WidgetInt eventMouseWheel
T parseValue(const std::string &_value)
const int EDIT_MOUSE_WHEEL
const int EDIT_CURSOR_MIN_POSITION
const std::string EDIT_CLIPBOARD_TYPE_TEXT
const size_t EDIT_MAX_UNDO
const int EDIT_CURSOR_MAX_POSITION
const float EDIT_CURSOR_TIMER
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
const float EDIT_OFFSET_HORZ_CURSOR
types::TSize< int > IntSize
Definition: MyGUI_Types.h:29
const size_t ITEM_NONE
Definition: MyGUI_Macros.h:17
const float EDIT_ACTION_MOUSE_TIMER
types::TPoint< int > IntPoint
Definition: MyGUI_Types.h:26
const int EDIT_ACTION_MOUSE_ZONE
const size_t EDIT_DEFAULT_MAX_TEXT_LENGTH
bool isWhitespace(const UString::code_point &c)
types::TRect< int > IntRect
Definition: MyGUI_Types.h:32
unsigned int Char
Definition: MyGUI_Types.h:49
std::vector< TextCommandInfo > VectorChangeInfo
bool inside(const TRect< T > &_value) const
Definition: MyGUI_TRect.h:141