MyGUI 3.4.1
MyGUI_EditText.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_EditText.h"
9#include "MyGUI_RenderItem.h"
10#include "MyGUI_FontManager.h"
11#include "MyGUI_RenderManager.h"
13#include "MyGUI_TextIterator.h"
14#include "MyGUI_IRenderTarget.h"
15#include "MyGUI_FontData.h"
17
18namespace MyGUI
19{
20
22
25 mEmptyView(false),
26 mCurrentColourNative(0xFFFFFFFF),
27 mInverseColourNative(0xFF000000),
28 mShadowColourNative(0x00000000),
29 mTextOutDate(false),
30 mTextAlign(Align::Default),
31 mColour(Colour::White),
32 mShadowColour(Colour::Black),
33 mAlpha(ALPHA_MAX),
34 mFont(nullptr),
35 mTexture(nullptr),
36 mFontHeight(0),
37 mBackgroundNormal(true),
38 mStartSelect(0),
39 mEndSelect(0),
40 mCursorPosition(0),
41 mVisibleCursor(false),
42 mInvertSelect(true),
43 mShadow(false),
44 mNode(nullptr),
45 mRenderItem(nullptr),
46 mCountVertex(SIMPLETEXT_COUNT_VERTEX),
47 mIsAddCursorWidth(true),
48 mShiftText(false),
49 mWordWrap(false),
50 mManualColour(false),
51 mOldWidth(0)
52 {
54 }
55
56 void EditText::setVisible(bool _visible)
57 {
58 if (mVisible == _visible)
59 return;
60 mVisible = _visible;
61
62 if (nullptr != mNode)
64 }
65
67 {
68 if (nullptr != mNode)
70 }
71
72 void EditText::_setAlign(const IntSize& _oldsize)
73 {
74 if (mWordWrap)
75 {
76 // передается старая координата всегда
77 int width = mCroppedParent->getWidth();
78 if (mOldWidth != width)
79 {
80 mOldWidth = width;
81 mTextOutDate = true;
82 }
83 }
84
85 // первоначальное выравнивание
86 if (mAlign.isHStretch())
87 {
88 // растягиваем
90 mIsMargin = true; // при изменении размеров все пересчитывать
91 }
92 else if (mAlign.isRight())
93 {
94 // двигаем по правому краю
96 }
97 else if (mAlign.isHCenter())
98 {
99 // выравнивание по горизонтали без растяжения
101 }
102
103 if (mAlign.isVStretch())
104 {
105 // растягиваем
107 mIsMargin = true; // при изменении размеров все пересчитывать
108 }
109 else if (mAlign.isBottom())
110 {
111 // двигаем по нижнему краю
112 mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
113 }
114 else if (mAlign.isVCenter())
115 {
116 // выравнивание по вертикали без растяжения
118 }
119
121 _updateView();
122 }
123
125 {
126 bool margin = _checkMargin();
127
128 mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
129
132
133 // вьюпорт стал битым
134 if (margin)
135 {
136 // проверка на полный выход за границу
137 if (_checkOutside())
138 {
139 // запоминаем текущее состояние
140 mIsMargin = margin;
141
142 // обновить перед выходом
143 if (nullptr != mNode)
145 return;
146 }
147 }
148
149 // мы обрезаны или были обрезаны
150 if (mIsMargin || margin)
151 {
154 }
155
156 // запоминаем текущее состояние
157 mIsMargin = margin;
158
159 if (nullptr != mNode)
161 }
162
163 void EditText::setCaption(const UString& _value)
164 {
165 mCaption = _value;
167 mTextOutDate = true;
168
169 checkVertexSize();
170
171 if (nullptr != mNode)
173 }
174
175 void EditText::checkVertexSize()
176 {
177 // reallocate if we need more vertices (extra vertices for selection * 2 and cursor)
178 size_t need = (mUtf32Caption.size() * (mShadow ? 3 : 2) + 2) * VertexQuad::VertexCount;
179 if (mCountVertex < need)
180 {
182 if (nullptr != mRenderItem)
184 }
185 }
186
187 unsigned int EditText::getMixedNativeAlpha(float secondAlpha) const
188 {
189 return (uint8)(mAlpha * secondAlpha * 255) << 24;
190 }
191
193 {
194 return mCaption;
195 }
196
197 void EditText::setTextColour(const Colour& _value)
198 {
199 mManualColour = true;
200 _setTextColour(_value);
201 }
202
203 void EditText::_setTextColour(const Colour& _value)
204 {
205 if (mColour == _value)
206 return;
207
208 mColour = _value;
210
212
213 mCurrentColourNative = (mCurrentColourNative & 0x00FFFFFF) | getMixedNativeAlpha(mColour.alpha);
215
216 if (nullptr != mNode)
218 }
219
221 {
222 return mColour;
223 }
224
225 void EditText::setAlpha(float _value)
226 {
227 if (mAlpha == _value)
228 return;
229 mAlpha = _value;
230
231 mCurrentColourNative = (mCurrentColourNative & 0x00FFFFFF) | getMixedNativeAlpha(mColour.alpha);
232 mShadowColourNative = (mShadowColourNative & 0x00FFFFFF) | getMixedNativeAlpha(mShadowColour.alpha);
234
235 if (nullptr != mNode)
237 }
238
239 void EditText::setFontName(const std::string& _value)
240 {
241 mTexture = nullptr;
243 if (mFont != nullptr)
244 {
246
247 // если надо, устанавливаем дефолтный размер шрифта
248 if (mFont->getDefaultHeight() != 0)
249 {
251 }
252 }
253
254 mTextOutDate = true;
255
256 // если мы были приаттаченны, то удаляем себя
257 if (nullptr != mRenderItem)
258 {
260 mRenderItem = nullptr;
261 }
262
263 // если есть текстура, то приаттачиваемся
264 if (nullptr != mTexture && nullptr != mNode)
265 {
266 mRenderItem = mNode->addToRenderItem(mTexture, false, false);
268 }
269
270 if (nullptr != mNode)
272 }
273
274 const std::string& EditText::getFontName() const
275 {
276 return mFont->getResourceName();
277 }
278
279 void EditText::setFontHeight(int _value)
280 {
281 mFontHeight = _value;
282 mTextOutDate = true;
283
284 if (nullptr != mNode)
286 }
287
289 {
290 return mFontHeight;
291 }
292
294 {
295 mNode = _node;
296 // если уже есть текстура, то атачимся, актуально для смены леера
297 if (nullptr != mTexture)
298 {
299 MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
300
301 mRenderItem = mNode->addToRenderItem(mTexture, false, false);
303 }
304 }
305
307 {
308 if (nullptr != mRenderItem)
309 {
311 mRenderItem = nullptr;
312 }
313 mNode = nullptr;
314 }
315
317 {
318 return mStartSelect;
319 }
320
322 {
323 return mEndSelect;
324 }
325
326 void EditText::setTextSelection(size_t _start, size_t _end)
327 {
328 mStartSelect = _start;
329 mEndSelect = _end;
330
331 if (nullptr != mNode)
333 }
334
336 {
337 return mBackgroundNormal;
338 }
339
341 {
342 if (mBackgroundNormal == _normal)
343 return;
344 mBackgroundNormal = _normal;
345
346 if (nullptr != mNode)
348 }
349
351 {
352 return mVisibleCursor;
353 }
354
356 {
357 if (mVisibleCursor == _value)
358 return;
359 mVisibleCursor = _value;
360
361 if (nullptr != mNode)
363 }
364
366 {
367 return mCursorPosition;
368 }
369
370 void EditText::setCursorPosition(size_t _index)
371 {
372 if (mCursorPosition == _index)
373 return;
374 mCursorPosition = _index;
375
376 if (nullptr != mNode)
378 }
379
381 {
382 mTextAlign = _value;
383
384 if (nullptr != mNode)
386 }
387
389 {
390 return mTextAlign;
391 }
392
394 {
395 // если нуно обновить, или изменились пропорции экрана
396 if (mTextOutDate)
398
400 // плюс размер курсора
402 size.width += 2;
403
404 if (mShadow)
405 {
407 size.width ++;
408 size.height ++;
409 }
410
411 return size;
412 }
413
415 {
416 return mTextView.getData();
417 }
418
420 {
421 mViewOffset = _point;
422
423 if (nullptr != mNode)
425 }
426
428 {
429 return mViewOffset;
430 }
431
432 size_t EditText::getCursorPosition(const IntPoint& _point) const
433 {
434 if (nullptr == mFont)
435 return 0;
436
437 if (mTextOutDate)
439
440 IntPoint point = _point;
442 point += mViewOffset;
443 point -= mCoord.point();
444
445 return mTextView.getCursorPosition(point);
446 }
447
448 IntCoord EditText::getCursorCoord(size_t _position) const
449 {
450 if (nullptr == mFont)
451 return IntCoord();
452
453 if (mTextOutDate)
455
456 IntPoint point = mTextView.getCursorPoint(_position);
458 point -= mViewOffset;
459 point += mCoord.point();
460
461 return IntCoord(point.left, point.top, 2, mFontHeight);
462 }
463
464 void EditText::setShiftText(bool _value)
465 {
466 if (mShiftText == _value)
467 return;
468 mShiftText = _value;
469
470 if (nullptr != mNode)
472 }
473
474 void EditText::setWordWrap(bool _value)
475 {
476 mWordWrap = _value;
477 mTextOutDate = true;
478
479 if (nullptr != mNode)
481 }
482
484 {
485 if (nullptr == mFont)
486 return;
487 // сбрасывам флаги
488 mTextOutDate = false;
489
490 int width = -1;
491 if (mWordWrap)
492 {
493 width = mCoord.width;
494 // обрезать слова нужно по шарине, которую мы реально используем
496 width -= 2;
497 }
498
500 }
501
503 {
505 if (!mManualColour && data->getColour() != Colour::Zero)
506 _setTextColour(data->getColour());
507 setShiftText(data->getShift());
508 }
509
511 {
512 if (nullptr == mFont || !mVisible || mEmptyView)
513 return;
514
517
519
520 const RenderTargetInfo& renderTargetInfo = mRenderItem->getRenderTarget()->getInfo();
521
522 // колличество отрисованных вершин
523 size_t vertexCount = 0;
524
525 // текущие цвета
527 uint32 inverseColour = mInverseColourNative;
528 uint32 selectedColour = mInvertSelect ? inverseColour : colour | 0x00FFFFFF;
529
530 const VectorLineInfo& textViewData = mTextView.getData();
531
532 float top = (float)(-mViewOffset.top + mCoord.top);
533
534 FloatRect vertexRect;
535
537
538 size_t index = 0;
539
540 for (VectorLineInfo::const_iterator line = textViewData.begin(); line != textViewData.end(); ++line)
541 {
542 float left = (float)(line->offset - mViewOffset.left + mCoord.left);
543
544 for (VectorCharInfo::const_iterator sim = line->symbols.begin(); sim != line->symbols.end(); ++sim)
545 {
546 if (sim->isColour())
547 {
548 colour = sim->getColour() | (colour & 0xFF000000);
549 inverseColour = colour ^ 0x00FFFFFF;
550 selectedColour = mInvertSelect ? inverseColour : colour | 0x00FFFFFF;
551 continue;
552 }
553
554 // смещение текстуры для фона
555 bool select = index >= mStartSelect && index < mEndSelect;
556
557 float fullAdvance = sim->getBearingX() + sim->getAdvance();
558
559 // Render the selection, if any, first.
560 if (select)
561 {
562 vertexRect.set(left, top, left + fullAdvance, top + (float)mFontHeight);
563
564 drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, selectedUVRect, selectedColour);
565 }
566
567 // Render the glyph shadow, if any.
568 if (mShadow)
569 {
570 vertexRect.left = left + sim->getBearingX() + 1.0f;
571 vertexRect.top = top + sim->getBearingY() + 1.0f;
572 vertexRect.right = vertexRect.left + sim->getWidth();
573 vertexRect.bottom = vertexRect.top + sim->getHeight();
574
575 drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, sim->getUVRect(), mShadowColourNative);
576 }
577
578 // Render the glyph itself.
579 vertexRect.left = left + sim->getBearingX();
580 vertexRect.top = top + sim->getBearingY();
581 vertexRect.right = vertexRect.left + sim->getWidth();
582 vertexRect.bottom = vertexRect.top + sim->getHeight();
583
584 drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, sim->getUVRect(), (!select || !mInvertSelect) ? colour : inverseColour);
585
586 left += fullAdvance;
587 ++index;
588 }
589
590 top += mFontHeight;
591 ++index;
592 }
593
594 // Render the cursor, if any, last.
595 if (mVisibleCursor)
596 {
598 const GlyphInfo* cursorGlyph = mFont->getGlyphInfo(static_cast<Char>(FontCodeType::Cursor));
599 vertexRect.set((float)point.left, (float)point.top, (float)point.left + cursorGlyph->width, (float)(point.top + mFontHeight));
600
601 drawGlyph(renderTargetInfo, vertex, vertexCount, vertexRect, cursorGlyph->uvRect, mCurrentColourNative | 0x00FFFFFF);
602 }
603
604 // колличество реально отрисованных вершин
605 mRenderItem->setLastVertexCount(vertexCount);
606 }
607
609 {
610 if (mInvertSelect == _value)
611 return;
612 mInvertSelect = _value;
613
614 if (nullptr != mNode)
616 }
617
619 {
620 return mInvertSelect;
621 }
622
624 {
625 return mShadow;
626 }
627
628 void EditText::setShadow(bool _value)
629 {
630 mShadow = _value;
631 mTextOutDate = true;
632
633 checkVertexSize();
634
635 if (nullptr != mNode)
637 }
638
640 {
641 mShadowColour = _value;
643
645
646 mShadowColourNative = (mShadowColourNative & 0x00FFFFFF) | getMixedNativeAlpha(mShadowColour.alpha);
647
648 if (nullptr != mNode)
650 }
651
653 {
654 return mShadowColour;
655 }
656
657 void EditText::drawQuad(
658 Vertex*& _vertex,
659 size_t& _vertexCount,
660 const FloatRect& _vertexRect,
661 float _vertexZ,
662 const FloatRect& _textureRect,
663 uint32 _colour) const
664 {
665 _vertex[0].x = _vertexRect.left;
666 _vertex[0].y = _vertexRect.top;
667 _vertex[0].z = _vertexZ;
668 _vertex[0].colour = _colour;
669 _vertex[0].u = _textureRect.left;
670 _vertex[0].v = _textureRect.top;
671
672 _vertex[2].x = _vertexRect.left;
673 _vertex[2].y = _vertexRect.bottom;
674 _vertex[2].z = _vertexZ;
675 _vertex[2].colour = _colour;
676 _vertex[2].u = _textureRect.left;
677 _vertex[2].v = _textureRect.bottom;
678
679 _vertex[1].x = _vertexRect.right;
680 _vertex[1].y = _vertexRect.top;
681 _vertex[1].z = _vertexZ;
682 _vertex[1].colour = _colour;
683 _vertex[1].u = _textureRect.right;
684 _vertex[1].v = _textureRect.top;
685
686 _vertex[3].x = _vertexRect.right;
687 _vertex[3].y = _vertexRect.top;
688 _vertex[3].z = _vertexZ;
689 _vertex[3].colour = _colour;
690 _vertex[3].u = _textureRect.right;
691 _vertex[3].v = _textureRect.top;
692
693 _vertex[5].x = _vertexRect.left;
694 _vertex[5].y = _vertexRect.bottom;
695 _vertex[5].z = _vertexZ;
696 _vertex[5].colour = _colour;
697 _vertex[5].u = _textureRect.left;
698 _vertex[5].v = _textureRect.bottom;
699
700 _vertex[4].x = _vertexRect.right;
701 _vertex[4].y = _vertexRect.bottom;
702 _vertex[4].z = _vertexZ;
703 _vertex[4].colour = _colour;
704 _vertex[4].u = _textureRect.right;
705 _vertex[4].v = _textureRect.bottom;
706
707 _vertex += VertexQuad::VertexCount;
708 _vertexCount += VertexQuad::VertexCount;
709 }
710
711 void EditText::drawGlyph(
712 const RenderTargetInfo& _renderTargetInfo,
713 Vertex*& _vertex,
714 size_t& _vertexCount,
715 FloatRect _vertexRect,
716 FloatRect _textureRect,
717 uint32 _colour) const
718 {
719 // символ залазиет влево
720 float leftClip = (float)mCurrentCoord.left - _vertexRect.left;
721 if (leftClip > 0.0f)
722 {
723 if ((float)mCurrentCoord.left < _vertexRect.right)
724 {
725 _textureRect.left += _textureRect.width() * leftClip / _vertexRect.width();
726 _vertexRect.left += leftClip;
727 }
728 else
729 {
730 return;
731 }
732 }
733
734 // символ залазиет вправо
735 float rightClip = _vertexRect.right - (float)mCurrentCoord.right();
736 if (rightClip > 0.0f)
737 {
738 if (_vertexRect.left < (float)mCurrentCoord.right())
739 {
740 _textureRect.right -= _textureRect.width() * rightClip / _vertexRect.width();
741 _vertexRect.right -= rightClip;
742 }
743 else
744 {
745 return;
746 }
747 }
748
749 // символ залазиет вверх
750 float topClip = (float)mCurrentCoord.top - _vertexRect.top;
751 if (topClip > 0.0f)
752 {
753 if ((float)mCurrentCoord.top < _vertexRect.bottom)
754 {
755 _textureRect.top += _textureRect.height() * topClip / _vertexRect.height();
756 _vertexRect.top += topClip;
757 }
758 else
759 {
760 return;
761 }
762 }
763
764 // символ залазиет вниз
765 float bottomClip = _vertexRect.bottom - (float)mCurrentCoord.bottom();
766 if (bottomClip > 0.0f)
767 {
768 if (_vertexRect.top < (float)mCurrentCoord.bottom())
769 {
770 _textureRect.bottom -= _textureRect.height() * bottomClip / _vertexRect.height();
771 _vertexRect.bottom -= bottomClip;
772 }
773 else
774 {
775 return;
776 }
777 }
778
779 float pix_left = mCroppedParent->getAbsoluteLeft() - _renderTargetInfo.leftOffset + _vertexRect.left;
780 float pix_top = mCroppedParent->getAbsoluteTop() - _renderTargetInfo.topOffset + (mShiftText ? 1.0f : 0.0f) + _vertexRect.top;
781
782 FloatRect vertexRect(
783 ((_renderTargetInfo.pixScaleX * pix_left + _renderTargetInfo.hOffset) * 2.0f) - 1.0f,
784 -(((_renderTargetInfo.pixScaleY * pix_top + _renderTargetInfo.vOffset) * 2.0f) - 1.0f),
785 ((_renderTargetInfo.pixScaleX * (pix_left + _vertexRect.width()) + _renderTargetInfo.hOffset) * 2.0f) - 1.0f,
786 -(((_renderTargetInfo.pixScaleY * (pix_top + _vertexRect.height()) + _renderTargetInfo.vOffset) * 2.0f) - 1.0f));
787
788 drawQuad(_vertex, _vertexCount, vertexRect, mNode->getNodeDepth(), _textureRect, _colour);
789 }
790
791} // namespace MyGUI
#define MYGUI_ASSERT(exp, dest)
void setTextColour(const Colour &_value) override
VertexColourType mVertexFormat
size_t getTextSelectionEnd() const override
void setFontName(const std::string &_value) override
void setAlpha(float _value) override
uint32 mCurrentColourNative
void setSelectBackground(bool _normal) override
void setTextSelection(size_t _start, size_t _end) override
void setWordWrap(bool _value) override
void _setAlign(const IntSize &_oldsize) override
bool isVisibleCursor() const override
bool getShadow() const override
IntCoord getCursorCoord(size_t _position) const override
void _correctView() override
virtual const VectorLineInfo & getLineInfo() const
void setInvertSelected(bool _value) override
const Colour & getTextColour() const override
void setFontHeight(int _value) override
void setVisible(bool _value) override
uint32 mInverseColourNative
const Colour & getShadowColour() const override
ITexture * mTexture
void setShadowColour(const Colour &_value) override
ILayerNode * mNode
const UString & getCaption() const override
IntPoint mViewOffset
bool getInvertSelected() const override
void setCaption(const UString &_value) override
void setTextAlign(Align _value) override
void setStateData(IStateInfo *_data) override
int getFontHeight() const override
size_t getTextSelectionStart() const override
void doRender() override
IntPoint getViewOffset() const override
void setVisibleCursor(bool _value) override
bool getSelectBackground() const override
IntSize getTextSize() const override
const std::string & getFontName() const override
size_t getCursorPosition() const override
void setViewOffset(const IntPoint &_point) override
Align getTextAlign() const override
void _updateView() override
RenderItem * mRenderItem
uint32 mShadowColourNative
UString::utf32string mUtf32Caption
void createDrawItem(ITexture *_texture, ILayerNode *_node) override
void setCursorPosition(size_t _index) override
void setShiftText(bool _shift) override
void setShadow(bool _value) override
IntCoord mCurrentCoord
void updateRawData() const
void destroyDrawItem() override
const Colour & getColour() const
IFont * getByName(const std::string &_name) const
static FontManager & getInstance()
const IntPoint & getAbsolutePosition() const
ICroppedRectangle * mCroppedParent
virtual ITexture * getTextureFont() const =0
virtual int getDefaultHeight() const =0
virtual const GlyphInfo * getGlyphInfo(Char _id) const =0
virtual float getNodeDepth() const =0
virtual void outOfDate(RenderItem *_item)=0
virtual RenderItem * addToRenderItem(ITexture *_texture, bool _firstQueue, bool _separate)=0
Type * castType(bool _throw=true)
Definition: MyGUI_IObject.h:18
virtual const RenderTargetInfo & getInfo() const =0
const std::string & getResourceName() const
void addDrawItem(ISubWidget *_item, size_t _count)
bool getCurrentUpdate() const
IRenderTarget * getRenderTarget()
void reallockDrawItem(ISubWidget *_item, size_t _count)
void removeDrawItem(ISubWidget *_item)
Vertex * getCurrentVertexBuffer() const
void setLastVertexCount(size_t _count)
virtual VertexColourType getVertexFormat() const =0
static RenderManager & getInstance()
size_t getCursorPosition(const IntPoint &_value) const
IntPoint getCursorPoint(size_t _position) const
void update(const UString::utf32string &_text, IFont *_font, int _height, Align _align, VertexColourType _format, int _maxWidth=-1)
const VectorLineInfo & getData() const
const IntSize & getViewSize() 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 convertColour(uint32 &_colour, VertexColourType _format)
uint32 toColourARGB(const Colour &_colour)
uint8_t uint8
Definition: MyGUI_Types.h:45
types::TCoord< int > IntCoord
Definition: MyGUI_Types.h:35
const size_t SIMPLETEXT_COUNT_VERTEX
std::vector< LineInfo > VectorLineInfo
const float ALPHA_MAX
Definition: MyGUI_Macros.h:19
types::TRect< float > FloatRect
Definition: MyGUI_Types.h:33
unsigned int Char
Definition: MyGUI_Types.h:49
uint32_t uint32
Definition: MyGUI_Types.h:47
bool isHStretch() const
Definition: MyGUI_Align.h:69
bool isVCenter() const
Definition: MyGUI_Align.h:49
bool isVStretch() const
Definition: MyGUI_Align.h:84
bool isRight() const
Definition: MyGUI_Align.h:64
bool isHCenter() const
Definition: MyGUI_Align.h:44
bool isBottom() const
Definition: MyGUI_Align.h:79
static const Colour Zero
Definition: MyGUI_Colour.h:55
TPoint< T > point() const
Definition: MyGUI_TCoord.h:185
void set(T const &_left, T const &_top, T const &_right, T const &_bottom)
Definition: MyGUI_TRect.h:121