MyGUI  3.2.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 <ctype.h>
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  assignWidget(mClient, "Client");
70  if (mClient != nullptr)
71  {
80  }
81 
83  assignWidget(mVScroll, "VScroll");
84  if (mVScroll != nullptr)
85  {
87  }
88 
90  assignWidget(mHScroll, "HScroll");
91  if (mHScroll != nullptr)
92  {
94  }
95 
97  if (mClient != nullptr)
98  {
100  if (text)
101  mClientText = text;
102  }
103 
105 
106  // первоначальная инициализация курсора
107  if (mClientText != nullptr)
109 
110  updateSelectText();
111  }
112 
114  {
115  mClient = nullptr;
116  mClientText = nullptr;
117  mVScroll = nullptr;
118  mHScroll = nullptr;
119 
121  }
122 
124  {
125  if ((_old == mClient) || (mIsFocus))
126  return;
127 
128  mIsFocus = true;
129  updateEditState();
130  }
131 
133  {
134  if ((_new == mClient) || (!mIsFocus))
135  return;
136 
137  mIsFocus = false;
138  updateEditState();
139  }
140 
141  void EditBox::notifyMousePressed(Widget* _sender, int _left, int _top, MouseButton _id)
142  {
143  if (mClientText == nullptr)
144  return;
145 
146  // в статике все недоступно
147  if (mModeStatic)
148  return;
149 
154  mCursorTimer = 0;
155  updateSelectText();
156 
157  if (_id == MouseButton::Left)
158  mMouseLeftPressed = true;
159  }
160 
161  void EditBox::notifyMouseReleased(Widget* _sender, int _left, int _top, MouseButton _id)
162  {
163  // сбрасываем всегда
164  mMouseLeftPressed = false;
165  }
166 
167  void EditBox::notifyMouseDrag(Widget* _sender, int _left, int _top, MouseButton _id)
168  {
169  if (_id != MouseButton::Left)
170  return;
171 
172  if (mClientText == nullptr)
173  return;
174 
175  // в статике все недоступно
176  if (mModeStatic)
177  return;
178 
179  // останавливаем курсор
181 
182  // сбрасываем все таймеры
183  mCursorTimer = 0;
184  mActionMouseTimer = 0;
185 
186  size_t Old = mCursorPosition;
187  IntPoint point(_left, _top);
189  if (Old == mCursorPosition)
190  return;
191 
193 
194  // если не было выделения
195  if (mStartSelect == ITEM_NONE)
196  mStartSelect = Old;
197 
198  // меняем выделение
199  mEndSelect = (size_t)mCursorPosition;
200  if (mStartSelect > mEndSelect)
202  else
204 
205  }
206 
208  {
209  if (mClientText == nullptr)
210  return;
211 
212  // в статике все недоступно
213  if (mModeStatic)
214  return;
215 
217 
218  size_t cursorPosition = mClientText->getCursorPosition(lastPressed);
219  mStartSelect = cursorPosition;
220  mEndSelect = cursorPosition;
221 
222  UString text = this->getOnlyText();
223  UString::reverse_iterator iterBack = text.rend() - cursorPosition;
224  UString::iterator iterForw = text.begin() + cursorPosition;
225 
226  while (iterBack != text.rend())
227  {
228  if (((*iterBack) < 265) && (ispunct(*iterBack) || isspace(*iterBack)))
229  break;
230  ++iterBack;
231  mStartSelect--;
232  }
233  while (iterForw != text.end())
234  {
235  if (((*iterForw) < 265) && (ispunct(*iterForw) || isspace(*iterForw)))
236  break;
237  ++iterForw;
238  mEndSelect++;
239  }
240 
243  }
244 
245  void EditBox::onMouseDrag(int _left, int _top, MouseButton _id)
246  {
247  notifyMouseDrag(nullptr, _left, _top, _id);
248 
249  Base::onMouseDrag(_left, _top, _id);
250  }
251 
253  {
254  if (!mIsPressed)
255  {
256  mIsPressed = true;
257  updateEditState();
258 
259  if (!mModeStatic)
260  {
261  if (mClientText != nullptr)
262  {
263  mCursorActive = true;
264  Gui::getInstance().eventFrameStart += newDelegate(this, &EditBox::frameEntered);
267  mCursorTimer = 0;
268  }
269  }
270  }
271 
272  Base::onKeySetFocus(_old);
273  }
274 
276  {
277  if (mIsPressed)
278  {
279  mIsPressed = false;
280  updateEditState();
281 
282  if (mClientText != nullptr)
283  {
284  mCursorActive = false;
285  Gui::getInstance().eventFrameStart -= newDelegate(this, &EditBox::frameEntered);
288  }
289  }
290 
291  Base::onKeyLostFocus(_new);
292  }
293 
295  {
296  if (mClientText == nullptr || mClient == nullptr)
297  {
298  Base::onKeyButtonPressed(_key, _char);
299  return;
300  }
301 
302  // в статическом режиме ничего не доступно
303  if (mModeStatic)
304  {
305  Base::onKeyButtonPressed(_key, _char);
306  return;
307  }
308 
310 
312  mCursorTimer = 0.0f;
313 
314  if (_key == KeyCode::Escape)
315  {
317  }
318  else if (_key == KeyCode::Backspace)
319  {
320  // если нуно то удаляем выделенный текст
321  if (!mModeReadOnly)
322  {
323  // сбрасываем повтор
324  commandResetRedo();
325 
326  if (!deleteTextSelect(true))
327  {
328  // прыгаем на одну назад и удаляем
329  if (mCursorPosition != 0)
330  {
331  mCursorPosition--;
332  eraseText(mCursorPosition, 1, true);
333  }
334  }
335  // отсылаем событие о изменении
336  eventEditTextChange(this);
337  }
338 
339  }
340  else if (_key == KeyCode::Delete)
341  {
342  if (input.isShiftPressed())
343  {
344  // сбрасываем повтор
345  commandResetRedo();
346 
347  commandCut();
348  }
349  else if (!mModeReadOnly)
350  {
351  // сбрасываем повтор
352  commandResetRedo();
353 
354  // если нуно то удаляем выделенный текст
355  if (!deleteTextSelect(true))
356  {
358  {
359  eraseText(mCursorPosition, 1, true);
360  }
361  }
362  // отсылаем событие о изменении
363  eventEditTextChange(this);
364  }
365 
366  }
367  else if (_key == KeyCode::Insert)
368  {
369  if (input.isShiftPressed())
370  {
371  // сбрасываем повтор
372  commandResetRedo();
373 
374  commandPast();
375  }
376  else if (input.isControlPressed())
377  {
378  commandCopy();
379  }
380 
381  }
382  else if ((_key == KeyCode::Return) || (_key == KeyCode::NumpadEnter))
383  {
384  // работаем только в режиме редактирования
385  if (!mModeReadOnly)
386  {
387  if ((mModeMultiline) && (!input.isControlPressed()))
388  {
389  // сбрасываем повтор
390  commandResetRedo();
391 
392  // попытка объединения двух комманд
393  size_t size = mVectorUndoChangeInfo.size();
394  // непосредственно операции
395  deleteTextSelect(true);
397  // проверяем на возможность объединения
398  if ((size + 2) == mVectorUndoChangeInfo.size())
399  commandMerge();
400  // отсылаем событие о изменении
401  eventEditTextChange(this);
402  }
403  // при сингл лайн и и мульти+сонтрол шлем эвент
404  else
405  {
406  eventEditSelectAccept(this);
407  }
408  }
409 
410  }
411  else if (_key == KeyCode::ArrowRight)
412  {
414  {
415  mCursorPosition ++;
417  updateSelectText();
418  }
419  // сбрасываем выделение
420  else if (isTextSelection() && !input.isShiftPressed())
421  {
422  resetSelect();
423  }
424 
425  }
426  else if (_key == KeyCode::ArrowLeft)
427  {
428  if (mCursorPosition != 0)
429  {
430  mCursorPosition --;
432  updateSelectText();
433  }
434  // сбрасываем выделение
435  else if (isTextSelection() && !input.isShiftPressed())
436  {
437  resetSelect();
438  }
439 
440  }
441  else if (_key == KeyCode::ArrowUp)
442  {
444  point.top -= mClientText->getFontHeight();
445  size_t old = mCursorPosition;
447  // самая верхняя строчка
448  if (old == mCursorPosition)
449  {
450  if (mCursorPosition != 0)
451  {
452  mCursorPosition = 0;
454  updateSelectText();
455  }
456  // сбрасываем выделение
457  else if (isTextSelection() && !input.isShiftPressed())
458  {
459  resetSelect();
460  }
461  }
462  else
463  {
465  updateSelectText();
466  }
467 
468  }
469  else if (_key == KeyCode::ArrowDown)
470  {
472  point.top += mClientText->getFontHeight();
473  size_t old = mCursorPosition;
475  // самая нижняя строчка
476  if (old == mCursorPosition)
477  {
479  {
482  updateSelectText();
483  }
484  // сбрасываем выделение
485  else if (isTextSelection() && !input.isShiftPressed())
486  {
487  resetSelect();
488  }
489  }
490  else
491  {
493  updateSelectText();
494  }
495 
496  }
497  else if (_key == KeyCode::Home)
498  {
499  // в начало строки
500  if (!input.isControlPressed())
501  {
504  size_t old = mCursorPosition;
506  if (old != mCursorPosition)
507  {
509  updateSelectText();
510  }
511  else if (isTextSelection() && !input.isShiftPressed())
512  {
513  resetSelect();
514  }
515  }
516  // в начало всего текста
517  else
518  {
519  if (0 != mCursorPosition)
520  {
521  mCursorPosition = 0;
523  updateSelectText();
524  }
525  else if (isTextSelection() && !input.isShiftPressed())
526  {
527  resetSelect();
528  }
529  }
530 
531  }
532  else if (_key == KeyCode::End)
533  {
534  // в конец строки
535  if (!input.isControlPressed())
536  {
539  size_t old = mCursorPosition;
541  if (old != mCursorPosition)
542  {
544  updateSelectText();
545  }
546  else if (isTextSelection() && !input.isShiftPressed())
547  {
548  resetSelect();
549  }
550  }
551  // в самый конец
552  else
553  {
555  {
558  updateSelectText();
559  }
560  else if (isTextSelection() && !input.isShiftPressed())
561  {
562  resetSelect();
563  }
564  }
565 
566  }
567  else if (_key == KeyCode::PageUp)
568  {
569  // на размер окна, но не меньше одной строки
572  size_t old = mCursorPosition;
574  // самая верхняя строчка
575  if (old == mCursorPosition)
576  {
577  if (mCursorPosition != 0)
578  {
579  mCursorPosition = 0;
581  updateSelectText();
582  }
583  // сбрасываем выделение
584  else if (isTextSelection() && !input.isShiftPressed())
585  {
586  resetSelect();
587  }
588  }
589  else
590  {
592  updateSelectText();
593  }
594 
595  }
596  else if (_key == KeyCode::PageDown)
597  {
598  // на размер окна, но не меньше одной строки
601  size_t old = mCursorPosition;
603  // самая нижняя строчка
604  if (old == mCursorPosition)
605  {
607  {
610  updateSelectText();
611  }
612  // сбрасываем выделение
613  else if (isTextSelection() && !input.isShiftPressed())
614  {
615  resetSelect();
616  }
617  }
618  else
619  {
621  updateSelectText();
622  }
623 
624  }
625  else if ((_key == KeyCode::LeftShift) || (_key == KeyCode::RightShift))
626  {
627  // для правильно выделения
628  if (mStartSelect == ITEM_NONE)
629  {
631  }
632  }
633  else
634  {
635  // если не нажат контрл, то обрабатываем как текст
636  if (!input.isControlPressed())
637  {
638  if (!mModeReadOnly && _char != 0)
639  {
640  // сбрасываем повтор
641  commandResetRedo();
642 
643  // таб только если нужно
644  if (_char != '\t' || mTabPrinting)
645  {
646  // попытка объединения двух комманд
647  size_t size = mVectorUndoChangeInfo.size();
648  // непосредственно операции
649  deleteTextSelect(true);
651  // проверяем на возможность объединения
652  if ((size + 2) == mVectorUndoChangeInfo.size())
653  commandMerge();
654  // отсылаем событие о изменении
655  eventEditTextChange(this);
656  }
657  }
658  }
659  else if (_key == KeyCode::C)
660  {
661  commandCopy();
662 
663  }
664  else if (_key == KeyCode::X)
665  {
666  // сбрасываем повтор
667  commandResetRedo();
668 
669  commandCut();
670 
671  }
672  else if (_key == KeyCode::V)
673  {
674  // сбрасываем повтор
675  commandResetRedo();
676 
677  commandPast();
678 
679  }
680  else if (_key == KeyCode::A)
681  {
682  // выделяем весь текст
684 
685  }
686  else if (_key == KeyCode::Z)
687  {
688  // отмена
689  commandUndo();
690 
691  }
692  else if (_key == KeyCode::Y)
693  {
694  // повтор
695  commandRedo();
696 
697  }
698  }
699 
700  Base::onKeyButtonPressed(_key, _char);
701  }
702 
703  void EditBox::frameEntered(float _frame)
704  {
705  if (mClientText == nullptr)
706  return;
707 
708  // в статике все недоступно
709  if (mModeStatic)
710  return;
711 
712  if (mCursorActive)
713  {
714  mCursorTimer += _frame;
715 
717  {
721  }
722  }
723 
724  // сдвигаем курсор по положению мыши
725  if (mMouseLeftPressed)
726  {
727  mActionMouseTimer += _frame;
728 
730  {
732  const IntRect& view = mClient->getAbsoluteRect();
733  mouse.left -= view.left;
734  mouse.top -= view.top;
735  IntPoint point;
736 
737  bool action = false;
738 
739  // вверх на одну строчку
740  if ((mouse.top < 0) && (mouse.top > -EDIT_ACTION_MOUSE_ZONE))
741  {
742  if ((mouse.left > 0) && (mouse.left <= mClient->getWidth()))
743  {
745  point.top -= mClientText->getFontHeight();
746  action = true;
747  }
748  }
749  // вниз на одну строчку
750  else if ((mouse.top > mClient->getHeight()) && (mouse.top < (mClient->getHeight() + EDIT_ACTION_MOUSE_ZONE)))
751  {
752  if ((mouse.left > 0) && (mouse.left <= mClient->getWidth()))
753  {
755  point.top += mClientText->getFontHeight();
756  action = true;
757  }
758  }
759 
760  // влево на небольшое расстояние
761  if ((mouse.left < 0) && (mouse.left > -EDIT_ACTION_MOUSE_ZONE))
762  {
764  point.left -= (int)EDIT_OFFSET_HORZ_CURSOR;
765  action = true;
766  }
767  // вправо на небольшое расстояние
768  else if ((mouse.left > mClient->getWidth()) && (mouse.left < (mClient->getWidth() + EDIT_ACTION_MOUSE_ZONE)))
769  {
771  point.left += (int)EDIT_OFFSET_HORZ_CURSOR;
772  action = true;
773  }
774 
775  if (action)
776  {
777  size_t old = mCursorPosition;
779 
780  if (old != mCursorPosition)
781  {
783 
784  mEndSelect = (size_t)mCursorPosition;
785  if (mStartSelect > mEndSelect)
787  else
789 
790  // пытаемся показать курсор
792  }
793  }
794  // если в зону не попадает то сбрасываем
795  else
796  {
797  mActionMouseTimer = 0;
798  }
799 
802  }
803 
804  } // if (mMouseLeftPressed)
805  }
806 
807  void EditBox::setTextCursor(size_t _index)
808  {
809  // сбрасываем выделение
810  resetSelect();
811 
812  // новая позиция
813  if (_index > mTextLength)
814  _index = mTextLength;
815 
816  if (mCursorPosition == _index)
817  return;
818 
819  mCursorPosition = _index;
820 
821  // обновляем по позиции
822  if (mClientText != nullptr)
824 
825  updateSelectText();
826  }
827 
828  void EditBox::setTextSelection(size_t _start, size_t _end)
829  {
830  if (_start > mTextLength)
831  _start = mTextLength;
832  if (_end > mTextLength)
833  _end = mTextLength;
834 
835  mStartSelect = _start;
836  mEndSelect = _end;
837 
838  if (mClientText != nullptr)
839  {
840  if (mStartSelect > mEndSelect)
842  else
844  }
845 
847  return;
848  // курсор на конец выделения
850 
851  // обновляем по позиции
852  if (mClientText != nullptr)
854  }
855 
856  bool EditBox::deleteTextSelect(bool _history)
857  {
858  if (!isTextSelection())
859  return false;
860 
861  // начало и конец выделения
862  size_t start = getTextSelectionStart();
863  size_t end = getTextSelectionEnd();
864 
865  eraseText(start, end - start, _history);
866 
867  return true;
868  }
869 
870  void EditBox::resetSelect()
871  {
872  if (mStartSelect != ITEM_NONE)
873  {
875  if (mClientText != nullptr)
877  }
878  }
879 
880  void EditBox::commandPosition(size_t _undo, size_t _redo, size_t _length, VectorChangeInfo* _info)
881  {
882  if (_info != nullptr)
883  _info->push_back(TextCommandInfo(_undo, _redo, _length));
884  }
885 
886  void EditBox::commandMerge()
887  {
888  if (mVectorUndoChangeInfo.size() < 2)
889  return; // на всякий
890  // сохраняем последние набор отмен
892  mVectorUndoChangeInfo.pop_back();
893 
894  // объединяем последовательности
895  for (VectorChangeInfo::iterator iter = info.begin(); iter != info.end(); ++iter)
896  {
897  mVectorUndoChangeInfo.back().push_back((*iter));
898  }
899  }
900 
901  bool EditBox::commandUndo()
902  {
903  if (mVectorUndoChangeInfo.empty())
904  return false;
905 
906  // сбрасываем выделение
907  resetSelect();
908 
909  // сохраняем последние набор отмен
911  // перекидываем последний набор отмен
912  mVectorUndoChangeInfo.pop_back();
913  mVectorRedoChangeInfo.push_back(info);
914 
915  // берем текст для издевательств
916  UString text = getRealString();
917 
918  // восстанавливаем последовательность
919  for (VectorChangeInfo::reverse_iterator iter = info.rbegin(); iter != info.rend(); ++iter)
920  {
921  if ((*iter).type == TextCommandInfo::COMMAND_INSERT)
922  text.erase((*iter).start, (*iter).text.size());
923  else if ((*iter).type == TextCommandInfo::COMMAND_ERASE)
924  text.insert((*iter).start, (*iter).text);
925  else
926  {
927  mCursorPosition = (*iter).undo;
928  mTextLength = (*iter).length;
929  }
930  }
931 
932  // возвращаем текст
933  setRealString(text);
934 
935  // обновляем по позиции
936  if (mClientText != nullptr)
938  updateSelectText();
939 
940  // отсылаем событие о изменении
941  eventEditTextChange(this);
942 
943  return true;
944  }
945 
946  bool EditBox::commandRedo()
947  {
948  if (mVectorRedoChangeInfo.empty())
949  return false;
950 
951  // сбрасываем выделение
952  resetSelect();
953 
954  // сохраняем последние набор отмен
956  // перекидываем последний набор отмен
957  mVectorRedoChangeInfo.pop_back();
958  mVectorUndoChangeInfo.push_back(info);
959 
960  // берем текст для издевательств
961  UString text = getRealString();
962 
963  // восстанавливаем последовательность
964  for (VectorChangeInfo::iterator iter = info.begin(); iter != info.end(); ++iter)
965  {
966  if ((*iter).type == TextCommandInfo::COMMAND_INSERT)
967  text.insert((*iter).start, (*iter).text);
968  else if ((*iter).type == TextCommandInfo::COMMAND_ERASE)
969  text.erase((*iter).start, (*iter).text.size());
970  else
971  {
972  mCursorPosition = (*iter).redo;
973  mTextLength = (*iter).length;
974  }
975 
976  }
977 
978  // возвращаем текст
979  setRealString(text);
980 
981  // обновляем по позиции
982  if (mClientText != nullptr)
984  updateSelectText();
985 
986  // отсылаем событие о изменении
987  eventEditTextChange(this);
988 
989  return true;
990  }
991 
992  void EditBox::saveInHistory(VectorChangeInfo* _info)
993  {
994  if (_info == nullptr)
995  return;
996  // если нет информации об изменении
997  if ( _info->empty())
998  return;
999  if ((_info->size() == 1) && (_info->back().type == TextCommandInfo::COMMAND_POSITION))
1000  return;
1001 
1002  mVectorUndoChangeInfo.push_back(*_info);
1003  // проверяем на максимальный размер
1004  if (mVectorUndoChangeInfo.size() > EDIT_MAX_UNDO)
1005  mVectorUndoChangeInfo.pop_front();
1006  }
1007 
1008  // возвращает текст
1009  UString EditBox::getTextInterval(size_t _start, size_t _count)
1010  {
1011  // подстраховка
1012  if (_start > mTextLength) _start = mTextLength;
1013  // конец диапазона
1014  size_t end = _start + _count;
1015 
1016  // итератор нашей строки
1017  TextIterator iterator(getRealString());
1018 
1019  // дефолтный цвет
1021 
1022  // нужно ли вставлять цвет
1023  bool need_colour = true;
1024 
1025  // цикл прохода по строке
1026  while (iterator.moveNext())
1027  {
1028  // текущаяя позиция
1029  size_t pos = iterator.getPosition();
1030 
1031  // еще рано
1032  if (pos < _start)
1033  {
1034  // берем цвет из позиции и запоминаем
1035  iterator.getTagColour(colour);
1036 
1037  continue;
1038  }
1039 
1040  // проверяем на надобность начального тега
1041  else if (pos == _start)
1042  {
1043  need_colour = ! iterator.getTagColour(colour);
1044  // сохраняем место откуда начинается
1045  iterator.saveStartPoint();
1046 
1047  }
1048 
1049  // а теперь просто до конца диапазона
1050  else if (pos == end)
1051  break;
1052 
1053  }
1054 
1055  // возвращаем строку
1056  if (need_colour)
1057  return colour + iterator.getFromStart();
1058  return iterator.getFromStart();
1059  }
1060 
1061  // выделяет цветом диапазон
1062  void EditBox::_setTextColour(size_t _start, size_t _count, const Colour& _colour, bool _history)
1063  {
1064  // история изменений
1065  VectorChangeInfo* history = nullptr;
1066  if (_history)
1067  history = new VectorChangeInfo();
1068 
1069  // конец диапазона
1070  size_t end = _start + _count;
1071 
1072  // итератор нашей строки
1073  TextIterator iterator(getRealString(), history);
1074 
1075  // дефолтный цвет
1077 
1078  // цикл прохода по строке
1079  while (iterator.moveNext())
1080  {
1081  // текущаяя позиция
1082  size_t pos = iterator.getPosition();
1083 
1084  // берем цвет из позиции и запоминаем
1085  iterator.getTagColour(colour);
1086 
1087  // еще рано
1088  if (pos < _start)
1089  continue;
1090 
1091  // ставим начальный тег
1092  else if (pos == _start)
1093  iterator.setTagColour(_colour);
1094 
1095  // внутри диапазона очищаем все
1096  else if (pos < end)
1097  iterator.clearTagColour();
1098 
1099  // на конец ставим последний найденный или дефолтный
1100  else if (pos == end)
1101  {
1102  iterator.setTagColour(colour);
1103  // и выходим из цикла
1104  break;
1105  }
1106 
1107  }
1108 
1109  // сохраняем позицию для восстановления курсора
1110  commandPosition(_start, _start + _count, mTextLength, history);
1111 
1112  // запоминаем в историю
1113  if (_history)
1114  {
1115  saveInHistory(history);
1116  delete history;
1117  }
1118  // сбрасываем историю
1119  else
1120  commandResetHistory();
1121 
1122  // и возвращаем строку на место
1123  setRealString(iterator.getText());
1124  }
1125 
1126  void EditBox::setTextSelectColour(const Colour& _colour, bool _history)
1127  {
1128  // нужно выделение
1129  if ( !isTextSelection())
1130  return;
1131  // начало и конец выделения
1132  size_t start = getTextSelectionStart();
1133  size_t end = getTextSelectionEnd();
1134  _setTextColour(start, end - start, _colour, _history);
1135  }
1136 
1138  {
1139  if ( !isTextSelection())
1140  return "";
1141  size_t start = getTextSelectionStart();
1142  size_t end = getTextSelectionEnd();
1143  return getTextInterval(start, end - start);
1144  }
1145 
1146  void EditBox::setEditPassword(bool _password)
1147  {
1148  if (mModePassword == _password)
1149  return;
1150  mModePassword = _password;
1151 
1152  if (mModePassword)
1153  {
1154  if (mClientText != nullptr)
1155  {
1158  }
1159  }
1160  else
1161  {
1162  if (mClientText != nullptr)
1163  {
1165  mPasswordText.clear();
1166  }
1167  }
1168  // обновляем по размерам
1169  updateView();
1170  // сбрасываем историю
1171  commandResetHistory();
1172  }
1173 
1174  void EditBox::setText(const UString& _caption, bool _history)
1175  {
1176  // сбрасываем выделение
1177  resetSelect();
1178 
1179  // история изменений
1180  VectorChangeInfo* history = nullptr;
1181  if (_history)
1182  history = new VectorChangeInfo();
1183 
1184  // итератор нашей строки
1185  TextIterator iterator(getRealString(), history);
1186 
1187  // вставляем текст
1188  iterator.setText(_caption, mModeMultiline || mModeWordWrap);
1189 
1190  if (mOverflowToTheLeft)
1191  {
1192  iterator.cutMaxLengthFromBeginning(mMaxTextLength);
1193  }
1194  else
1195  {
1196  // обрезаем по максимальной длинне
1197  iterator.cutMaxLength(mMaxTextLength);
1198  }
1199 
1200  // запоминаем размер строки
1201  size_t old = mTextLength;
1202  // новая позиция и положение на конец вставки
1203  mCursorPosition = mTextLength = iterator.getSize();
1204 
1205  // сохраняем позицию для восстановления курсора
1206  commandPosition(0, mTextLength, old, history);
1207 
1208  // запоминаем в историю
1209  if (_history)
1210  {
1211  saveInHistory(history);
1212  delete history;
1213  }
1214  // сбрасываем историю
1215  else
1216  commandResetHistory();
1217 
1218  // и возвращаем строку на место
1219  setRealString(iterator.getText());
1220 
1221  // обновляем по позиции
1222  if (mClientText != nullptr)
1224  updateSelectText();
1225  }
1226 
1227  void EditBox::insertText(const UString& _text, size_t _start, bool _history)
1228  {
1229  // сбрасываем выделение
1230  resetSelect();
1231 
1232  // если строка пустая, или размер максимален
1233  if (_text.empty())
1234  return;
1235 
1236  if ((mOverflowToTheLeft == false) && (mTextLength == mMaxTextLength))
1237  return;
1238 
1239  // история изменений
1240  VectorChangeInfo* history = nullptr;
1241  if (_history)
1242  history = new VectorChangeInfo();
1243 
1244  // итератор нашей строки
1245  TextIterator iterator(getRealString(), history);
1246 
1247  // дефолтный цвет
1248  UString colour = mClientText == nullptr ? "" : TextIterator::convertTagColour(mClientText->getTextColour());
1249  // нужен ли тег текста
1250  // потом переделать через TextIterator чтобы отвязать понятие тег от эдита
1251  bool need_colour = ( (_text.size() > 6) && (_text[0] == L'#') && (_text[1] != L'#') );
1252 
1253  // цикл прохода по строке
1254  while (iterator.moveNext())
1255  {
1256  // текущаяя позиция
1257  size_t pos = iterator.getPosition();
1258 
1259  // текущий цвет
1260  if (need_colour)
1261  iterator.getTagColour(colour);
1262 
1263  // если дошли то выходим
1264  if (pos == _start)
1265  break;
1266  }
1267 
1268  // если нужен цвет то вставляем
1269  if (need_colour)
1270  iterator.setTagColour(colour);
1271 
1272  // а теперь вставляем строку
1273  iterator.insertText(_text, mModeMultiline || mModeWordWrap);
1274 
1275  if (mOverflowToTheLeft)
1276  {
1277  iterator.cutMaxLengthFromBeginning(mMaxTextLength);
1278  }
1279  else
1280  {
1281  // обрезаем по максимальной длинне
1282  iterator.cutMaxLength(mMaxTextLength);
1283  }
1284 
1285  // запоминаем размер строки
1286  size_t old = mTextLength;
1287  // новая позиция и положение на конец вставки
1288  mTextLength = iterator.getSize();
1289  mCursorPosition += mTextLength - old;
1290 
1291  // сохраняем позицию для восстановления курсора
1292  commandPosition(_start, _start + mTextLength - old, old, history);
1293 
1294  // запоминаем в историю
1295  if (_history)
1296  {
1297  saveInHistory(history);
1298  delete history;
1299  }
1300  // сбрасываем историю
1301  else
1302  commandResetHistory();
1303 
1304  // и возвращаем строку на место
1305  setRealString(iterator.getText());
1306 
1307  // обновляем по позиции
1308  if (mClientText != nullptr)
1310  updateSelectText();
1311  }
1312 
1313  void EditBox::eraseText(size_t _start, size_t _count, bool _history)
1314  {
1315  // чета маловато
1316  if (_count == 0)
1317  return;
1318 
1319  // сбрасываем выделение
1320  resetSelect();
1321 
1322  // история изменений
1323  VectorChangeInfo* history = nullptr;
1324  if (_history)
1325  history = new VectorChangeInfo();
1326 
1327  // итератор нашей строки
1328  TextIterator iterator(getRealString(), history);
1329 
1330  // дефолтный цвет
1331  UString colour;
1332  // конец диапазона
1333  size_t end = _start + _count;
1334  bool need_colour = false;
1335 
1336  // цикл прохода по строке
1337  while (iterator.moveNext())
1338  {
1339  // текущаяя позиция
1340  size_t pos = iterator.getPosition();
1341 
1342  // еще рано
1343  if (pos < _start)
1344  {
1345  // берем цвет из позиции и запоминаем
1346  iterator.getTagColour(colour);
1347  continue;
1348  }
1349 
1350  // сохраняем место откуда начинается
1351  else if (pos == _start)
1352  {
1353  // если до диапазона был цвет, то нужно закрыть тег
1354  if (!colour.empty())
1355  {
1356  need_colour = true;
1357  colour.clear();
1358  }
1359  // берем цвет из позиции и запоминаем
1360  iterator.getTagColour(colour);
1361  iterator.saveStartPoint();
1362  }
1363 
1364  // внутри диапазона
1365  else if (pos < end)
1366  {
1367  // берем цвет из позиции и запоминаем
1368  iterator.getTagColour(colour);
1369  }
1370 
1371  // окончание диапазона
1372  else if (pos == end)
1373  {
1374  // нужно ставить тег или нет
1375  if (!colour.empty())
1376  need_colour = true;
1377  if (iterator.getTagColour(colour))
1378  need_colour = false;
1379 
1380  break;
1381  }
1382 
1383  }
1384 
1385  // удаляем диапазон
1386  iterator.eraseFromStart();
1387  // и вставляем последний цвет
1388  if (need_colour)
1389  iterator.setTagColour(colour);
1390 
1391  // сохраняем позицию для восстановления курсора
1392  commandPosition(_start + _count, _start, mTextLength, history);
1393 
1394  // на месте удаленного
1395  mCursorPosition = _start;
1396  mTextLength -= _count;
1397 
1398  // запоминаем в историю
1399  if (_history)
1400  {
1401  saveInHistory(history);
1402  delete history;
1403  }
1404  // сбрасываем историю
1405  else
1406  commandResetHistory();
1407 
1408  // и возвращаем строку на место
1409  setRealString(iterator.getText());
1410 
1411  // обновляем по позиции
1412  if (mClientText != nullptr)
1414  updateSelectText();
1415  }
1416 
1417  void EditBox::commandCut()
1418  {
1419  // вырезаем в буфер обмена
1420  if (isTextSelection() && (!mModePassword))
1421  {
1423  if (!mModeReadOnly)
1424  {
1425  deleteTextSelect(true);
1426  // отсылаем событие о изменении
1427  eventEditTextChange(this);
1428  }
1429  }
1430  else
1432  }
1433 
1434  void EditBox::commandCopy()
1435  {
1436  // копируем в буфер обмена
1437  if (isTextSelection() && (!mModePassword))
1439  else
1441  }
1442 
1443  void EditBox::commandPast()
1444  {
1445  // копируем из буфера обмена
1447  if ((!mModeReadOnly) && (!clipboard.empty()))
1448  {
1449  // попытка объединения двух комманд
1450  size_t size = mVectorUndoChangeInfo.size();
1451  // непосредственно операции
1452  deleteTextSelect(true);
1453  insertText(clipboard, mCursorPosition, true);
1454  // проверяем на возможность объединения
1455  if ((size + 2) == mVectorUndoChangeInfo.size())
1456  commandMerge();
1457  // отсылаем событие о изменении
1458  eventEditTextChange(this);
1459  }
1460  }
1461 
1462  const UString& EditBox::getRealString()
1463  {
1464  if (mModePassword)
1465  return mPasswordText;
1466  else if (mClientText == nullptr)
1467  return mPasswordText;
1468 
1469  return mClientText->getCaption();
1470  }
1471 
1472  void EditBox::setRealString(const UString& _caption)
1473  {
1474  if (mModePassword)
1475  {
1476  mPasswordText = _caption;
1477  if (mClientText != nullptr)
1479  }
1480  else
1481  {
1482  if (mClientText != nullptr)
1483  mClientText->setCaption(_caption);
1484  }
1485  }
1486 
1488  {
1489  mCharPassword = _char;
1490  if (mModePassword)
1491  {
1492  if (mClientText != nullptr)
1494  }
1495  }
1496 
1497  void EditBox::updateEditState()
1498  {
1499  if (!getInheritedEnabled())
1500  {
1501  _setWidgetState("disabled");
1502  }
1503  else if (mIsPressed)
1504  {
1505  if (mIsFocus)
1506  _setWidgetState("pushed");
1507  else
1508  _setWidgetState("normal_checked");
1509  }
1510  else if (mIsFocus)
1511  {
1512  _setWidgetState("highlighted");
1513  }
1514  else
1515  {
1516  _setWidgetState("normal");
1517  }
1518  }
1519 
1520  void EditBox::setPosition(const IntPoint& _point)
1521  {
1522  Base::setPosition(_point);
1523  }
1524 
1526  {
1527  // если перенос, то сбрасываем размер текста
1528  if (mModeWordWrap)
1529  {
1530  if (mClientText != nullptr)
1531  mClientText->setWordWrap(true);
1532  }
1533 
1534  updateView();
1535  }
1536 
1537  void EditBox::setSize(const IntSize& _size)
1538  {
1539  Base::setSize(_size);
1540 
1541  eraseView();
1542  }
1543 
1544  void EditBox::setCoord(const IntCoord& _coord)
1545  {
1546  Base::setCoord(_coord);
1547 
1548  eraseView();
1549  }
1550 
1551  void EditBox::setCaption(const UString& _value)
1552  {
1553  setText(_value, false);
1554  }
1555 
1557  {
1558  return getRealString();
1559  }
1560 
1561  void EditBox::updateSelectText()
1562  {
1563  if (!mModeStatic)
1564  {
1566  if ((input.isShiftPressed()) && (mStartSelect != ITEM_NONE))
1567  {
1568  // меняем выделение
1569  mEndSelect = (size_t)mCursorPosition;
1570  if (mClientText != nullptr)
1571  {
1572  if (mStartSelect > mEndSelect)
1574  else
1576  }
1577 
1578  }
1579  else if (mStartSelect != ITEM_NONE)
1580  {
1581  // сбрасываем шифт
1583  if (mClientText != nullptr)
1585  }
1586  }
1587 
1588  // пытаемся показать курсор
1590  }
1591 
1593  {
1594  Base::setTextAlign(_value);
1595 
1596  if (mClientText != nullptr)
1597  mClientText->setTextAlign(_value);
1598 
1599  // так как мы сами рулим смещениями
1600  updateView();
1601  }
1602 
1603  void EditBox::setTextColour(const Colour& _value)
1604  {
1605  Base::setTextColour(_value);
1606 
1607  if (mClientText != nullptr)
1608  mClientText->setTextColour(_value);
1609  }
1610 
1612  {
1613  if (mClientText != nullptr)
1614  return mClientText->getCoord();
1615  return Base::getTextRegion();
1616  }
1617 
1619  {
1620  if (mClientText != nullptr)
1621  return mClientText->getTextSize();
1622  return Base::getTextSize();
1623  }
1624 
1625  void EditBox::notifyScrollChangePosition(ScrollBar* _sender, size_t _position)
1626  {
1627  if (mClientText == nullptr)
1628  return;
1629 
1630  if (_sender == mVScroll)
1631  {
1632  IntPoint point = mClientText->getViewOffset();
1633  point.top = _position;
1634  mClientText->setViewOffset(point);
1635  }
1636  else if (_sender == mHScroll)
1637  {
1638  IntPoint point = mClientText->getViewOffset();
1639  point.left = _position;
1640  mClientText->setViewOffset(point);
1641  }
1642  }
1643 
1644  void EditBox::notifyMouseWheel(Widget* _sender, int _rel)
1645  {
1646  if (mClientText == nullptr)
1647  return;
1648 
1649  if (mVRange != 0)
1650  {
1651  IntPoint point = mClientText->getViewOffset();
1652  int offset = point.top;
1653  if (_rel < 0)
1654  offset += EDIT_MOUSE_WHEEL;
1655  else
1656  offset -= EDIT_MOUSE_WHEEL;
1657 
1658  if (offset < 0)
1659  offset = 0;
1660  else if (offset > (int)mVRange)
1661  offset = mVRange;
1662 
1663  if (offset != point.top)
1664  {
1665  point.top = offset;
1666  if (mVScroll != nullptr)
1667  mVScroll->setScrollPosition(offset);
1668  mClientText->setViewOffset(point);
1669  }
1670  }
1671  else if (mHRange != 0)
1672  {
1673  IntPoint point = mClientText->getViewOffset();
1674  int offset = point.left;
1675  if (_rel < 0)
1676  offset += EDIT_MOUSE_WHEEL;
1677  else
1678  offset -= EDIT_MOUSE_WHEEL;
1679 
1680  if (offset < 0)
1681  offset = 0;
1682  else if (offset > (int)mHRange)
1683  offset = mHRange;
1684 
1685  if (offset != point.left)
1686  {
1687  point.left = offset;
1688  if (mHScroll != nullptr)
1689  mHScroll->setScrollPosition(offset);
1690  mClientText->setViewOffset(point);
1691  }
1692  }
1693  }
1694 
1695  void EditBox::setEditWordWrap(bool _value)
1696  {
1697  mModeWordWrap = _value;
1698  if (mClientText != nullptr)
1700 
1701  eraseView();
1702  }
1703 
1704  void EditBox::setFontName(const std::string& _value)
1705  {
1706  Base::setFontName(_value);
1707 
1708  if (mClientText != nullptr)
1709  mClientText->setFontName(_value);
1710 
1711  eraseView();
1712  }
1713 
1714  void EditBox::setFontHeight(int _value)
1715  {
1716  Base::setFontHeight(_value);
1717 
1718  if (mClientText != nullptr)
1719  mClientText->setFontHeight(_value);
1720 
1721  eraseView();
1722  }
1723 
1725  {
1726  updateScrollSize();
1728  }
1729 
1731  {
1732  updateScrollSize();
1733  updateCursorPosition();
1735  }
1736 
1737  void EditBox::updateCursorPosition()
1738  {
1739  if (mClientText == nullptr || mClient == nullptr)
1740  return;
1741 
1742  // размер контекста текста
1743  IntSize textSize = mClientText->getTextSize();
1744 
1745  // текущее смещение контекста текста
1746  IntPoint point = mClientText->getViewOffset();
1747  // расчетное смещение
1748  IntPoint offset = point;
1749 
1750  // абсолютные координаты курсора
1752  cursor.right ++;
1753 
1754  // абсолютные координаты вью
1755  const IntRect& view = mClient->getAbsoluteRect();
1756 
1757  // проверяем и показываем курсор
1758  if (!view.inside(cursor))
1759  {
1760  // горизонтальное смещение
1761  if (textSize.width > view.width())
1762  {
1763  if (cursor.left < view.left)
1764  {
1765  offset.left = point.left - (view.left - cursor.left);
1766  // добавляем смещение, только если курсор не перепрыгнет
1767  if ((float(view.width()) - EDIT_OFFSET_HORZ_CURSOR) > EDIT_OFFSET_HORZ_CURSOR)
1768  offset.left -= int(EDIT_OFFSET_HORZ_CURSOR);
1769  }
1770  else if (cursor.right > view.right)
1771  {
1772  offset.left = point.left + (cursor.right - view.right);
1773  // добавляем смещение, только если курсор не перепрыгнет
1774  if ((float(view.width()) - EDIT_OFFSET_HORZ_CURSOR) > EDIT_OFFSET_HORZ_CURSOR)
1775  offset.left += int(EDIT_OFFSET_HORZ_CURSOR);
1776  }
1777  }
1778 
1779  // вертикальное смещение
1780  if (textSize.height > view.height())
1781  {
1782  int delta = 0;
1783  if (cursor.height() > view.height())
1784  {
1785  // if text is bigger than edit height then place it in center
1786  delta = ((cursor.bottom - view.bottom) - (view.top - cursor.top)) / 2;
1787  }
1788  else if (cursor.top < view.top)
1789  {
1790  delta = - (view.top - cursor.top);
1791  }
1792  else if (cursor.bottom > view.bottom)
1793  {
1794  delta = (cursor.bottom - view.bottom);
1795  }
1796  offset.top = point.top + delta;
1797  }
1798 
1799  }
1800 
1801  if (offset != point)
1802  {
1803  mClientText->setViewOffset(offset);
1804  // обновить скролы
1805  if (mVScroll != nullptr)
1806  mVScroll->setScrollPosition(offset.top);
1807  if (mHScroll != nullptr)
1808  mHScroll->setScrollPosition(offset.left);
1809  }
1810  }
1811 
1812  void EditBox::setContentPosition(const IntPoint& _point)
1813  {
1814  if (mClientText != nullptr)
1815  mClientText->setViewOffset(_point);
1816  }
1817 
1818  IntSize EditBox::getViewSize()
1819  {
1820  if (mClientText != nullptr)
1821  return mClientText->getSize();
1822  return ScrollViewBase::getViewSize();
1823  }
1824 
1825  IntSize EditBox::getContentSize()
1826  {
1827  if (mClientText != nullptr)
1828  return mClientText->getTextSize();
1830  }
1831 
1832  size_t EditBox::getVScrollPage()
1833  {
1834  if (mClientText != nullptr)
1835  return (size_t)mClientText->getFontHeight();
1837  }
1838 
1839  size_t EditBox::getHScrollPage()
1840  {
1841  if (mClientText != nullptr)
1842  return (size_t)mClientText->getFontHeight();
1844  }
1845 
1846  IntPoint EditBox::getContentPosition()
1847  {
1848  if (mClientText != nullptr)
1849  return mClientText->getViewOffset();
1851  }
1852 
1853  Align EditBox::getContentAlign()
1854  {
1855  if (mClientText != nullptr)
1856  return mClientText->getTextAlign();
1858  }
1859 
1860  void EditBox::setTextIntervalColour(size_t _start, size_t _count, const Colour& _colour)
1861  {
1862  _setTextColour(_start, _count, _colour, false);
1863  }
1864 
1866  {
1868  }
1869 
1871  {
1873  }
1874 
1876  {
1877  return (mStartSelect != ITEM_NONE) && (mStartSelect != mEndSelect);
1878  }
1879 
1881  {
1882  deleteTextSelect(false);
1883  }
1884 
1886  {
1887  setTextSelectColour(_colour, false);
1888  }
1889 
1891  {
1892  return mEndSelect - mStartSelect;
1893  }
1894 
1895  void EditBox::setOnlyText(const UString& _text)
1896  {
1897  setText(TextIterator::toTagsString(_text), false);
1898  }
1899 
1901  {
1902  return TextIterator::getOnlyText(getRealString());
1903  }
1904 
1905  void EditBox::insertText(const UString& _text, size_t _index)
1906  {
1907  insertText(_text, _index, false);
1908  }
1909 
1910  void EditBox::addText(const UString& _text)
1911  {
1912  insertText(_text, ITEM_NONE, false);
1913  }
1914 
1915  void EditBox::eraseText(size_t _start, size_t _count)
1916  {
1917  eraseText(_start, _count, false);
1918  }
1919 
1920  void EditBox::setEditReadOnly(bool _value)
1921  {
1922  mModeReadOnly = _value;
1923  // сбрасываем историю
1924  commandResetHistory();
1925  }
1926 
1927  void EditBox::setEditMultiLine(bool _value)
1928  {
1929  mModeMultiline = _value;
1930  // на всякий, для убирания переносов
1931  if (!mModeMultiline)
1932  {
1933  setText(getRealString(), false);
1934  }
1935  // обновляем по размерам
1936  else
1937  {
1938  updateView();
1939  }
1940  // сбрасываем историю
1941  commandResetHistory();
1942  }
1943 
1944  void EditBox::setEditStatic(bool _value)
1945  {
1946  mModeStatic = _value;
1947  resetSelect();
1948 
1949  if (mClient != nullptr)
1950  {
1951  if (mModeStatic)
1952  mClient->setPointer("");
1953  else
1955  }
1956  }
1957 
1958  void EditBox::setPasswordChar(const UString& _value)
1959  {
1960  if (!_value.empty())
1961  setPasswordChar(_value[0]);
1962  }
1963 
1964  void EditBox::setVisibleVScroll(bool _value)
1965  {
1966  mVisibleVScroll = _value;
1967  updateView();
1968  }
1969 
1970  void EditBox::setVisibleHScroll(bool _value)
1971  {
1972  mVisibleHScroll = _value;
1973  updateView();
1974  }
1975 
1977  {
1978  return mVRange + 1;
1979  }
1980 
1982  {
1983  return mClientText == nullptr ? 0 : mClientText->getViewOffset().top;
1984  }
1985 
1986  void EditBox::setVScrollPosition(size_t _index)
1987  {
1988  if (mClientText == nullptr)
1989  return;
1990 
1991  if (_index > mVRange)
1992  _index = mVRange;
1993 
1994  IntPoint point = mClientText->getViewOffset();
1995  point.top = _index;
1996 
1997  mClientText->setViewOffset(point);
1998  // обновить скролы
1999  if (mVScroll != nullptr)
2000  mVScroll->setScrollPosition(point.top);
2001  }
2002 
2004  {
2005  return mHRange + 1;
2006  }
2007 
2009  {
2010  return mClientText == nullptr ? 0 : mClientText->getViewOffset().left;
2011  }
2012 
2013  void EditBox::setHScrollPosition(size_t _index)
2014  {
2015  if (mClientText == nullptr)
2016  return;
2017 
2018  if (_index > mHRange)
2019  _index = mHRange;
2020 
2021  IntPoint point = mClientText->getViewOffset();
2022  point.left = _index;
2023 
2024  mClientText->setViewOffset(point);
2025  // обновить скролы
2026  if (mHScroll != nullptr)
2028  }
2029 
2031  {
2032  return mClientText == nullptr ? false : mClientText->getInvertSelected();
2033  }
2034 
2035  void EditBox::setInvertSelected(bool _value)
2036  {
2037  if (mClientText != nullptr)
2038  mClientText->setInvertSelected(_value);
2039  }
2040 
2041  void EditBox::setPropertyOverride(const std::string& _key, const std::string& _value)
2042  {
2044  if (_key == "CursorPosition")
2045  setTextCursor(utility::parseValue<size_t>(_value));
2046 
2048  else if (_key == "TextSelect")
2050 
2052  else if (_key == "ReadOnly")
2053  setEditReadOnly(utility::parseValue<bool>(_value));
2054 
2056  else if (_key == "Password")
2057  setEditPassword(utility::parseValue<bool>(_value));
2058 
2060  else if (_key == "MultiLine")
2061  setEditMultiLine(utility::parseValue<bool>(_value));
2062 
2064  else if (_key == "PasswordChar")
2065  setPasswordChar(_value);
2066 
2068  else if (_key == "MaxTextLength")
2069  setMaxTextLength(utility::parseValue<size_t>(_value));
2070 
2072  else if (_key == "OverflowToTheLeft")
2073  setOverflowToTheLeft(utility::parseValue<bool>(_value));
2074 
2076  else if (_key == "Static")
2077  setEditStatic(utility::parseValue<bool>(_value));
2078 
2080  else if (_key == "VisibleVScroll")
2081  setVisibleVScroll(utility::parseValue<bool>(_value));
2082 
2084  else if (_key == "VisibleHScroll")
2085  setVisibleHScroll(utility::parseValue<bool>(_value));
2086 
2088  else if (_key == "WordWrap")
2089  setEditWordWrap(utility::parseValue<bool>(_value));
2090 
2092  else if (_key == "TabPrinting")
2093  setTabPrinting(utility::parseValue<bool>(_value));
2094 
2096  else if (_key == "InvertSelected")
2097  setInvertSelected(utility::parseValue<bool>(_value));
2098 
2099  else
2100  {
2101  Base::setPropertyOverride(_key, _value);
2102  return;
2103  }
2104 
2105  eventChangeProperty(this, _key, _value);
2106  }
2107 
2108  size_t EditBox::getTextCursor() const
2109  {
2110  return mCursorPosition;
2111  }
2112 
2113  size_t EditBox::getTextLength() const
2114  {
2115  return mTextLength;
2116  }
2117 
2119  {
2120  mOverflowToTheLeft = _value;
2121  }
2122 
2124  {
2125  return mOverflowToTheLeft;
2126  }
2127 
2128  void EditBox::setMaxTextLength(size_t _value)
2129  {
2130  mMaxTextLength = _value;
2131  }
2132 
2134  {
2135  return mMaxTextLength;
2136  }
2137 
2139  {
2140  return mModeReadOnly;
2141  }
2142 
2144  {
2145  return mModePassword;
2146  }
2147 
2149  {
2150  return mModeMultiline;
2151  }
2152 
2154  {
2155  return mModeStatic;
2156  }
2157 
2159  {
2160  return mCharPassword;
2161  }
2162 
2164  {
2165  return mModeWordWrap;
2166  }
2167 
2168  void EditBox::setTabPrinting(bool _value)
2169  {
2170  mTabPrinting = _value;
2171  }
2172 
2174  {
2175  return mTabPrinting;
2176  }
2177 
2178  void EditBox::setPosition(int _left, int _top)
2179  {
2180  setPosition(IntPoint(_left, _top));
2181  }
2182 
2183  void EditBox::setSize(int _width, int _height)
2184  {
2185  setSize(IntSize(_width, _height));
2186  }
2187 
2188  void EditBox::setCoord(int _left, int _top, int _width, int _height)
2189  {
2190  setCoord(IntCoord(_left, _top, _width, _height));
2191  }
2192 
2194  {
2195  return mVisibleVScroll;
2196  }
2197 
2199  {
2200  return mVisibleHScroll;
2201  }
2202 
2203  void EditBox::commandResetRedo()
2204  {
2205  mVectorRedoChangeInfo.clear();
2206  }
2207 
2208  void EditBox::commandResetHistory()
2209  {
2210  mVectorRedoChangeInfo.clear();
2211  mVectorUndoChangeInfo.clear();
2212  }
2213 
2215  {
2216  Base::setTextShadowColour(_value);
2217 
2218  if (mClientText != nullptr)
2219  mClientText->setShadowColour(_value);
2220  }
2221 
2222  void EditBox::setTextShadow(bool _value)
2223  {
2224  Base::setTextShadow(_value);
2225 
2226  if (mClientText != nullptr)
2227  mClientText->setShadow(_value);
2228  }
2229 
2230 } // namespace MyGUI