MyGUI  3.0.3
MyGUI_EditText.cpp
Go to the documentation of this file.
00001 
00007 /*
00008     This file is part of MyGUI.
00009 
00010     MyGUI is free software: you can redistribute it and/or modify
00011     it under the terms of the GNU Lesser General Public License as published by
00012     the Free Software Foundation, either version 3 of the License, or
00013     (at your option) any later version.
00014 
00015     MyGUI is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public License
00021     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00022 */
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_EditText.h"
00025 #include "MyGUI_RenderItem.h"
00026 #include "MyGUI_FontManager.h"
00027 #include "MyGUI_RenderManager.h"
00028 #include "MyGUI_LanguageManager.h"
00029 #include "MyGUI_TextIterator.h"
00030 #include "MyGUI_IRenderTarget.h"
00031 #include "MyGUI_FontData.h"
00032 #include "MyGUI_CommonStateInfo.h"
00033 
00034 namespace MyGUI
00035 {
00036 
00037     const size_t VERTEX_IN_QUAD = 6;
00038     const size_t SIMPLETEXT_COUNT_VERTEX = 32 * VERTEX_IN_QUAD;
00039 
00040     MYGUI_FORCEINLINE void DrawQuad(
00041         MyGUI::Vertex*& _buff,
00042         float v_left,
00043         float v_top,
00044         float v_rignt,
00045         float v_bottom,
00046         float v_z,
00047         MyGUI::uint32 _colour,
00048         float t_left,
00049         float t_top,
00050         float t_right,
00051         float t_bottom,
00052         size_t& _count)
00053     {
00054         _buff[0].x = v_left;
00055         _buff[0].y = v_top;
00056         _buff[0].z = v_z;
00057         _buff[0].colour = _colour;
00058         _buff[0].u = t_left;
00059         _buff[0].v = t_top;
00060 
00061         _buff[1].x = v_left;
00062         _buff[1].y = v_bottom;
00063         _buff[1].z = v_z;
00064         _buff[1].colour = _colour;
00065         _buff[1].u = t_left;
00066         _buff[1].v = t_bottom;
00067 
00068         _buff[2].x = v_rignt;
00069         _buff[2].y = v_top;
00070         _buff[2].z = v_z;
00071         _buff[2].colour = _colour;
00072         _buff[2].u = t_right;
00073         _buff[2].v = t_top;
00074 
00075         _buff[3].x = v_rignt;
00076         _buff[3].y = v_top;
00077         _buff[3].z = v_z;
00078         _buff[3].colour = _colour;
00079         _buff[3].u = t_right;
00080         _buff[3].v = t_top;
00081 
00082         _buff[4].x = v_left;
00083         _buff[4].y = v_bottom;
00084         _buff[4].z = v_z;
00085         _buff[4].colour = _colour;
00086         _buff[4].u = t_left;
00087         _buff[4].v = t_bottom;
00088 
00089         _buff[5].x = v_rignt;
00090         _buff[5].y = v_bottom;
00091         _buff[5].z = v_z;
00092         _buff[5].colour = _colour;
00093         _buff[5].u = t_right;
00094         _buff[5].v = t_bottom;
00095 
00096         _buff += VERTEX_IN_QUAD;
00097         _count += VERTEX_IN_QUAD;
00098     }
00099 
00100     EditText::EditText() :
00101         ISubWidgetText(),
00102         mEmptyView(false),
00103         mCurrentColour(0x00FFFFFF),
00104         mInverseColour(0x00000000),
00105         mCurrentAlpha(0xFF000000),
00106         mTextOutDate(false),
00107         mTextAlign(Align::Default),
00108         mColour(Colour::White),
00109         mAlpha(ALPHA_MAX),
00110         mFont(nullptr),
00111         mTexture(nullptr),
00112         mFontHeight(0),
00113         mBackgroundNormal(true),
00114         mStartSelect(0),
00115         mEndSelect(0),
00116         mCursorPosition(0),
00117         mVisibleCursor(false),
00118         mInvertSelect(true),
00119         mNode(nullptr),
00120         mRenderItem(nullptr),
00121         mCountVertex(SIMPLETEXT_COUNT_VERTEX),
00122         mIsAddCursorWidth(true),
00123         mShiftText(false),
00124         mWordWrap(false),
00125         mOldWidth(0),
00126         mManualColour(false)
00127     {
00128         mVertexFormat = RenderManager::getInstance().getVertexFormat();
00129 
00130         mCurrentColour = texture_utility::toColourARGB(mColour);
00131         texture_utility::convertColour(mCurrentColour, mVertexFormat);
00132 
00133         mCurrentColour = (mCurrentColour & 0x00FFFFFF) | mCurrentAlpha;
00134         mInverseColour = mCurrentColour ^ 0x00FFFFFF;
00135     }
00136 
00137     EditText::~EditText()
00138     {
00139     }
00140 
00141     void EditText::setVisible(bool _visible)
00142     {
00143         if (mVisible == _visible) return;
00144         mVisible = _visible;
00145 
00146         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00147     }
00148 
00149     void EditText::_correctView()
00150     {
00151         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00152     }
00153 
00154     void EditText::_setAlign(const IntCoord& _oldcoord, bool _update)
00155     {
00156         _setAlign(_oldcoord.size(), _update);
00157     }
00158 
00159     void EditText::_setAlign(const IntSize& _oldsize, bool _update)
00160     {
00161 
00162         if (mWordWrap)
00163         {
00164             // передается старая координата всегда
00165             int width = mCroppedParent->getWidth();
00166             if (mOldWidth != width)
00167             {
00168                 mOldWidth = width;
00169                 mTextOutDate = true;
00170             }
00171         }
00172 
00173         // необходимо разобраться
00174         bool need_update = true;//_update;
00175 
00176         // первоначальное выравнивание
00177         if (mAlign.isHStretch())
00178         {
00179             // растягиваем
00180             mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
00181             need_update = true;
00182             mIsMargin = true; // при изменении размеров все пересчитывать
00183         }
00184         else if (mAlign.isRight())
00185         {
00186             // двигаем по правому краю
00187             mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
00188             need_update = true;
00189         }
00190         else if (mAlign.isHCenter())
00191         {
00192             // выравнивание по горизонтали без растяжения
00193             mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
00194             need_update = true;
00195         }
00196 
00197         if (mAlign.isVStretch())
00198         {
00199             // растягиваем
00200             mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
00201             need_update = true;
00202             mIsMargin = true; // при изменении размеров все пересчитывать
00203         }
00204         else if (mAlign.isBottom())
00205         {
00206             // двигаем по нижнему краю
00207             mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
00208             need_update = true;
00209         }
00210         else if (mAlign.isVCenter())
00211         {
00212             // выравнивание по вертикали без растяжения
00213             mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
00214             need_update = true;
00215         }
00216 
00217         if (need_update)
00218         {
00219             mCurrentCoord = mCoord;
00220             _updateView();
00221         }
00222 
00223     }
00224 
00225     void EditText::_updateView()
00226     {
00227         bool margin = _checkMargin();
00228 
00229         mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
00230 
00231         mCurrentCoord.left = mCoord.left + mMargin.left;
00232         mCurrentCoord.top = mCoord.top + mMargin.top;
00233 
00234         // вьюпорт стал битым
00235         if (margin)
00236         {
00237             // проверка на полный выход за границу
00238             if (_checkOutside())
00239             {
00240                 // запоминаем текущее состояние
00241                 mIsMargin = margin;
00242 
00243                 // обновить перед выходом
00244                 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00245                 return;
00246             }
00247         }
00248 
00249         // мы обрезаны или были обрезаны
00250         if ((mIsMargin) || (margin))
00251         {
00252             mCurrentCoord.width = _getViewWidth();
00253             mCurrentCoord.height = _getViewHeight();
00254         }
00255 
00256         // запоминаем текущее состояние
00257         mIsMargin = margin;
00258 
00259         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00260     }
00261 
00262     void EditText::setCaption(const UString& _value)
00263     {
00264         mCaption = _value;
00265         mTextOutDate = true;
00266 
00267         // если вершин не хватит, делаем реалок, с учетом выделения * 2 и курсора
00268         size_t need = (mCaption.size() * 2 + 2) * VERTEX_IN_QUAD;
00269         if (mCountVertex < need)
00270         {
00271             mCountVertex = need + SIMPLETEXT_COUNT_VERTEX;
00272             if (nullptr != mRenderItem) mRenderItem->reallockDrawItem(this, mCountVertex);
00273         }
00274         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00275     }
00276 
00277     const UString& EditText::getCaption()
00278     {
00279         return mCaption;
00280     }
00281 
00282     void EditText::setTextColour(const Colour& _value)
00283     {
00284         mManualColour = true;
00285         _setTextColour(_value);
00286     }
00287 
00288     void EditText::_setTextColour(const Colour& _value)
00289     {
00290         if (mColour == _value)
00291             return;
00292 
00293         mColour = _value;
00294         mCurrentColour = texture_utility::toColourARGB(mColour);
00295 
00296         texture_utility::convertColour(mCurrentColour, mVertexFormat);
00297 
00298         mCurrentColour = (mCurrentColour & 0x00FFFFFF) | mCurrentAlpha;
00299         mInverseColour = mCurrentColour ^ 0x00FFFFFF;
00300 
00301         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00302     }
00303 
00304     const Colour& EditText::getTextColour()
00305     {
00306         return mColour;
00307     }
00308 
00309     void EditText::setAlpha(float _value)
00310     {
00311         if (mAlpha == _value) return;
00312         mAlpha = _value;
00313         mCurrentAlpha = ((uint8)(mAlpha*255) << 24);
00314         mCurrentColour = (mCurrentColour & 0x00FFFFFF) | mCurrentAlpha;
00315         mInverseColour = mCurrentColour ^ 0x00FFFFFF;
00316 
00317         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00318     }
00319 
00320     float EditText::getAlpha()
00321     {
00322         return mAlpha;
00323     }
00324 
00325     void EditText::setFontName(const std::string& _value)
00326     {
00327         mTexture = 0;
00328         mFont = FontManager::getInstance().getByName(_value);
00329         if (mFont != nullptr)
00330         {
00331             mTexture = mFont->getTextureFont();
00332 
00333             // если надо, устанавливаем дефолтный размер шрифта
00334             if (mFont->getDefaultHeight() != 0)
00335             {
00336                 mFontHeight = mFont->getDefaultHeight();
00337             }
00338         }
00339 
00340         mTextOutDate = true;
00341 
00342         // если мы были приаттаченны, то удаляем себя
00343         if (nullptr != mRenderItem)
00344         {
00345             mRenderItem->removeDrawItem(this);
00346             mRenderItem = nullptr;
00347         }
00348 
00349         // если есть текстура, то приаттачиваемся
00350         if (nullptr != mTexture && nullptr != mNode)
00351         {
00352             mRenderItem = mNode->addToRenderItem(mTexture, this);
00353             mRenderItem->addDrawItem(this, mCountVertex);
00354         }
00355 
00356         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00357     }
00358 
00359     const std::string& EditText::getFontName()
00360     {
00361         return mFont->getResourceName();
00362     }
00363 
00364     void EditText::setFontHeight(int _value)
00365     {
00366         mFontHeight = _value;
00367         mTextOutDate = true;
00368         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00369     }
00370 
00371     int EditText::getFontHeight()
00372     {
00373         return mFontHeight;
00374     }
00375 
00376     void EditText::createDrawItem(ITexture* _texture, ILayerNode * _node)
00377     {
00378         mNode = _node;
00379         // если уже есть текстура, то атачимся, актуально для смены леера
00380         if (nullptr != mTexture)
00381         {
00382             MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
00383 
00384             mRenderItem = mNode->addToRenderItem(mTexture, this);
00385             mRenderItem->addDrawItem(this, mCountVertex);
00386         }
00387     }
00388 
00389     void EditText::destroyDrawItem()
00390     {
00391         if (nullptr != mRenderItem)
00392         {
00393             mRenderItem->removeDrawItem(this);
00394             mRenderItem = nullptr;
00395         }
00396         mNode = nullptr;
00397     }
00398 
00399     size_t EditText::getTextSelectionStart()
00400     {
00401         return mStartSelect;
00402     }
00403 
00404     size_t EditText::getTextSelectionEnd()
00405     {
00406         return mEndSelect;
00407     }
00408 
00409     void EditText::setTextSelection(size_t _start, size_t _end)
00410     {
00411         mStartSelect=_start;
00412         mEndSelect=_end;
00413         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00414     }
00415 
00416     bool EditText::getSelectBackground()
00417     {
00418         return mBackgroundNormal;
00419     }
00420 
00421     void EditText::setSelectBackground(bool _normal)
00422     {
00423         if (mBackgroundNormal == _normal) return;
00424         mBackgroundNormal = _normal;
00425         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00426     }
00427 
00428     bool EditText::isVisibleCursor()
00429     {
00430         return mVisibleCursor;
00431     }
00432 
00433     void EditText::setVisibleCursor(bool _value)
00434     {
00435         if (mVisibleCursor == _value) return;
00436         mVisibleCursor = _value;
00437         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00438     }
00439 
00440     size_t EditText::getCursorPosition()
00441     {
00442         return mCursorPosition;
00443     }
00444 
00445     void EditText::setCursorPosition(size_t _index)
00446     {
00447         if (mCursorPosition == _index) return;
00448         mCursorPosition = _index;
00449         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00450     }
00451 
00452     void EditText::setTextAlign(Align _value)
00453     {
00454         mTextAlign = _value;
00455         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00456     }
00457 
00458     Align EditText::getTextAlign()
00459     {
00460         return mTextAlign;
00461     }
00462 
00463     IntSize EditText::getTextSize()
00464     {
00465         // если нуно обновить, или изменились пропорции экрана
00466         if (mTextOutDate) updateRawData();
00467 
00468         IntSize size = mTextView.getViewSize();
00469         // плюс размер курсора
00470         if (mIsAddCursorWidth)
00471             size.width += 2;
00472         return size;
00473     }
00474 
00475     void EditText::setViewOffset(const IntPoint& _point)
00476     {
00477         mViewOffset = _point;
00478         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00479     }
00480 
00481     IntPoint EditText::getViewOffset()
00482     {
00483         return mViewOffset;
00484     }
00485 
00486     size_t EditText::getCursorPosition(const IntPoint& _point)
00487     {
00488         if (nullptr == mFont) return 0;
00489         if (mTextOutDate) updateRawData();
00490 
00491         IntPoint point = _point;
00492         point -= mCroppedParent->getAbsolutePosition();
00493         point += mViewOffset;
00494         point -= mCoord.point();
00495 
00496         return mTextView.getCursorPosition(point);
00497     }
00498 
00499     IntCoord EditText::getCursorCoord(size_t _position)
00500     {
00501         if (nullptr == mFont) return IntCoord();
00502         if (mTextOutDate) updateRawData();
00503 
00504         IntPoint point = mTextView.getCursorPoint(_position);
00505         point += mCroppedParent->getAbsolutePosition();
00506         point -= mViewOffset;
00507         point += mCoord.point();
00508 
00509         return IntCoord(point.left, point.top, 2, mFontHeight);
00510     }
00511 
00512     void EditText::setShiftText(bool _value)
00513     {
00514         if (mShiftText == _value) return;
00515         mShiftText = _value;
00516         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00517     }
00518 
00519     void EditText::setWordWrap(bool _value)
00520     {
00521         mWordWrap = _value;
00522         mTextOutDate = true;
00523         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00524     }
00525 
00526     void EditText::updateRawData()
00527     {
00528         if (nullptr == mFont) return;
00529         // сбрасывам флаги
00530         mTextOutDate = false;
00531 
00532         int width = -1;
00533         if (mWordWrap)
00534         {
00535             width = mCoord.width;
00536             // обрезать слова нужно по шарине, которую мы реально используем
00537             if (mIsAddCursorWidth)
00538                 width -= 2;
00539         }
00540 
00541         mTextView.update(mCaption, mFont, mFontHeight, mTextAlign, mVertexFormat, width);
00542     }
00543 
00544     void EditText::setStateData(IStateInfo* _data)
00545     {
00546         EditTextStateInfo* data = _data->castType<EditTextStateInfo>();
00547         if (!mManualColour && data->getColour() != Colour::Zero)
00548             _setTextColour(data->getColour());
00549         setShiftText(data->getShift());
00550     }
00551 
00552     void EditText::doRender()
00553     {
00554         if (nullptr == mFont) return;
00555         if (!mVisible || mEmptyView) return;
00556 
00557         bool _update = mRenderItem->getCurrentUpdate();
00558         if (_update) mTextOutDate = true;
00559 
00560         if (mTextOutDate) updateRawData();
00561 
00562         Vertex* _vertex = mRenderItem->getCurrentVertextBuffer();
00563 
00564         const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
00565 
00566         // колличество отрисованных вершин
00567         size_t vertex_count = 0;
00568 
00569         // текущие цвета
00570         uint32 colour_current = mCurrentColour;
00571         uint32 colour = mCurrentColour;
00572         uint32 colour_inverse = mInverseColour;
00573 
00574         GlyphInfo* back_glyph = mFont->getGlyphInfo(mBackgroundNormal ? FontCodeType::Selected : FontCodeType::SelectedBack);
00575 
00576         float vertex_z = info.maximumDepth;
00577 
00578         const VectorLineInfo& data = mTextView.getData();
00579 
00580         int left = - mViewOffset.left + mCoord.left;
00581         int top = - mViewOffset.top + mCoord.top;
00582         int width = 0;
00583         const int height = mFontHeight;
00584 
00585         size_t index = 0;
00586         for (VectorLineInfo::const_iterator line=data.begin(); line!=data.end(); ++line)
00587         {
00588             left = line->offset - mViewOffset.left + mCoord.left;
00589             for (VectorCharInfo::const_iterator sim=line->simbols.begin(); sim!=line->simbols.end(); ++sim)
00590             {
00591                 if (sim->isColour())
00592                 {
00593                     colour = sim->getColour() | (colour & 0xFF000000);
00594                     colour_inverse = colour ^ 0x00FFFFFF;
00595                     continue;
00596                 }
00597 
00598                 // смещение текстуры для фона
00599                 bool select = !((index >= mEndSelect) || (index < mStartSelect));
00600 
00601                 uint32 back_colour = 0;
00602 
00603                 // выделение символа
00604                 if (!select || !mInvertSelect)
00605                 {
00606                     colour_current = colour;
00607                     back_colour = colour | 0x00FFFFFF;
00608                 }
00609                 else
00610                 {
00611                     colour_current = colour_inverse;
00612                     back_colour = colour_inverse;
00613                 }
00614 
00615                 bool draw = true;
00616 
00617                 // текущие размеры
00618                 MyGUI::FloatRect texture_rect = sim->getUVRect();
00619                 width = sim->getWidth();
00620 
00621                 // конечные размеры
00622                 int result_left = left;
00623                 int result_top = top;
00624                 int result_right = left + width;
00625                 int result_bottom = top + height;
00626 
00627                 float texture_width = texture_rect.right - texture_rect.left;
00628                 float texture_height = texture_rect.bottom - texture_rect.top;
00629 
00630                 // символ залазиет влево
00631                 if (left < mCurrentCoord.left)
00632                 {
00633                     // символ вообще не виден
00634                     if (left + width <= mCurrentCoord.left)
00635                     {
00636                         draw = false;
00637                     }
00638                     // символ обрезан
00639                     else
00640                     {
00641                         result_left = mCurrentCoord.left;
00642                         texture_rect.left += (texture_width * (float)(result_left - left) / (float)width);
00643                     }
00644                 }
00645 
00646                 // символ залазиет вправо
00647                 if (left + width > mCurrentCoord.right())
00648                 {
00649                     // символ вообще не виден
00650                     if (left >= mCurrentCoord.right())
00651                     {
00652                         draw = false;
00653                     }
00654                     // символ обрезан
00655                     else
00656                     {
00657                         result_right = mCurrentCoord.right();
00658                         texture_rect.right -= (texture_width * (float)((left + width) - result_right) / (float)width);
00659                     }
00660                 }
00661 
00662                 // символ залазиет вверх
00663                 if (top < mCurrentCoord.top)
00664                 {
00665                     // символ вообще не виден
00666                     if (top + height <= mCurrentCoord.top)
00667                     {
00668                         draw = false;
00669                     }
00670                     // символ обрезан
00671                     else
00672                     {
00673                         result_top = mCurrentCoord.top;
00674                         texture_rect.top += (texture_height * (float)(result_top - top) / (float)height);
00675                     }
00676                 }
00677 
00678                 // символ залазиет вниз
00679                 if (top + height > mCurrentCoord.bottom())
00680                 {
00681                     // символ вообще не виден
00682                     if (top >= mCurrentCoord.bottom())
00683                     {
00684                         draw = false;
00685                     }
00686                     // символ обрезан
00687                     else
00688                     {
00689                         result_bottom = mCurrentCoord.bottom();
00690                         texture_rect.bottom -= (texture_height * (float)((top + height) - result_bottom) / (float)height);
00691                     }
00692                 }
00693 
00694                 if (draw)
00695                 {
00696                     int pix_left = mCroppedParent->getAbsoluteLeft() - info.leftOffset + result_left;
00697                     int pix_top = mCroppedParent->getAbsoluteTop() - info.topOffset + (mShiftText ? 1 : 0) + result_top;
00698 
00699                     float real_left = ((info.pixScaleX * (float)(pix_left) + info.hOffset) * 2) - 1;
00700                     float real_top = - (((info.pixScaleY * (float)(pix_top) + info.vOffset) * 2) - 1);
00701                     float real_right = ((info.pixScaleX * (float)(pix_left + result_right - result_left) + info.hOffset) * 2) - 1;
00702                     float real_bottom = - (((info.pixScaleY * (float)(pix_top + result_bottom - result_top) + info.vOffset) * 2) - 1);
00703 
00704                     // если нужно рисуем выделение
00705                     if (select)
00706                     {
00707                         const FloatRect& background_current = back_glyph->uvRect;
00708                         DrawQuad(_vertex, real_left, real_top, real_right, real_bottom, vertex_z, back_colour,
00709                             background_current.left, background_current.top, background_current.left, background_current.top, vertex_count);
00710                     }
00711 
00712                     DrawQuad(_vertex, real_left, real_top, real_right, real_bottom, vertex_z, colour_current,
00713                         texture_rect.left, texture_rect.top, texture_rect.right, texture_rect.bottom, vertex_count);
00714                 }
00715 
00716                 left += width;
00717                 index++;
00718             }
00719 
00720             top += height;
00721             index++;
00722         }
00723 
00724         if (mVisibleCursor)
00725         {
00726             MyGUI::IntPoint point = mTextView.getCursorPoint(mCursorPosition);
00727             point -= mViewOffset;
00728             point += mCoord.point();
00729 
00730             bool draw = true;
00731 
00732             GlyphInfo* cursor_glyph = mFont->getGlyphInfo(FontCodeType::Cursor);
00733             MyGUI::FloatRect texture_rect = cursor_glyph->uvRect;
00734             left = point.left;
00735             top = point.top;
00736             width = 2;//cursor_glyph->width;
00737 
00738             // конечные размеры
00739             int result_left = left;
00740             int result_top = top;
00741             int result_width = width;
00742             int result_height = height;
00743 
00744             // символ залазиет влево
00745             if (left < mCurrentCoord.left)
00746             {
00747                 // символ вообще не виден
00748                 if (left + width <= mCurrentCoord.left)
00749                 {
00750                     draw = false;
00751                 }
00752                 // символ обрезан
00753                 else
00754                 {
00755                     result_left = mCurrentCoord.left;
00756                     result_width = width - (mCurrentCoord.left - left);
00757 
00758                     float texture_width = texture_rect.right - texture_rect.left;
00759                     texture_rect.left = texture_rect.right - (texture_width * (float)result_width / (float)width);
00760                 }
00761             }
00762 
00763             // символ залазиет вправо
00764             if (left + width > mCurrentCoord.right())
00765             {
00766                 // символ вообще не виден
00767                 if (left >= mCurrentCoord.right())
00768                 {
00769                     draw = false;
00770                 }
00771                 // символ обрезан
00772                 else
00773                 {
00774                     result_width = mCurrentCoord.right() - left;
00775 
00776                     float texture_width = texture_rect.right - texture_rect.left;
00777                     texture_rect.right = texture_rect.left + (texture_width * (float)result_width / (float)width);
00778                 }
00779             }
00780 
00781             // символ залазиет вверх
00782             if (top < mCurrentCoord.top)
00783             {
00784                 // символ вообще не виден
00785                 if (top + height <= mCurrentCoord.top)
00786                 {
00787                     draw = false;
00788                 }
00789                 // символ обрезан
00790                 else
00791                 {
00792                     result_top = mCurrentCoord.top;
00793                     result_height = height - (mCurrentCoord.top - top);
00794 
00795                     float texture_height = texture_rect.bottom - texture_rect.top;
00796                     texture_rect.top = texture_rect.bottom - (texture_height * (float)result_height / (float)height);
00797                 }
00798             }
00799 
00800             // символ залазиет вниз
00801             if (top + height > mCurrentCoord.bottom())
00802             {
00803                 // символ вообще не виден
00804                 if (top >= mCurrentCoord.bottom())
00805                 {
00806                     draw = false;
00807                 }
00808                 // символ обрезан
00809                 else
00810                 {
00811                     result_height = mCurrentCoord.bottom() - top;
00812 
00813                     float texture_height = texture_rect.bottom - texture_rect.top;
00814                     texture_rect.bottom = texture_rect.top + (texture_height * (float)result_height / (float)height);
00815                 }
00816             }
00817 
00818             if (draw)
00819             {
00820                 int pix_left = mCroppedParent->getAbsoluteLeft() - info.leftOffset + result_left;
00821                 int pix_top = mCroppedParent->getAbsoluteTop() - info.topOffset + (mShiftText ? 1 : 0) + result_top;
00822 
00823                 float real_left = ((info.pixScaleX * (float)(pix_left) + info.hOffset) * 2) - 1;
00824                 float real_top = - (((info.pixScaleY * (float)(pix_top) + info.vOffset) * 2) - 1);
00825                 float real_right = ((info.pixScaleX * (float)(pix_left + result_width) + info.hOffset) * 2) - 1;
00826                 float real_bottom = - (((info.pixScaleY * (float)(pix_top + result_height) + info.vOffset) * 2) - 1);
00827 
00828                 DrawQuad(_vertex, real_left, real_top, real_right, real_bottom, vertex_z, colour_current | 0x00FFFFFF,
00829                     texture_rect.left, texture_rect.top, texture_rect.right, texture_rect.bottom, vertex_count);
00830             }
00831         }
00832 
00833         // колличество реально отрисованных вершин
00834         mRenderItem->setLastVertexCount(vertex_count);
00835     }
00836 
00837     void EditText::setInvertSelected(bool _value)
00838     {
00839         if (mInvertSelect == _value) return;
00840         mInvertSelect = _value;
00841         if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00842     }
00843 
00844 } // namespace MyGUI