コード例 #1
0
//! draws the element and its children
void CGUIEditBox::draw()
{
#ifndef SERVER_ONLY
    if (!IsVisible)
        return;

    const bool focus = Environment->hasFocus(this);

    IGUISkin* skin = Environment->getSkin();
    if (!skin)
        return;

    FrameRect = AbsoluteRect;

    // draw the border

    if (Border)
    {
        EGUI_DEFAULT_COLOR col = EGDC_GRAY_EDITABLE;
        if ( isEnabled() )
            col = focus ? EGDC_FOCUSED_EDITABLE : EGDC_EDITABLE;
        skin->draw3DSunkenPane(this, skin->getColor(col),
            false, true, FrameRect, &AbsoluteClippingRect);

        FrameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X)+1;
        FrameRect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y)+1;
        FrameRect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X)+1;
        FrameRect.LowerRightCorner.Y -= skin->getSize(EGDS_TEXT_DISTANCE_Y)+1;
    }
    core::rect<s32> localClipRect = FrameRect;
    localClipRect.clipAgainst(AbsoluteClippingRect);

    // draw the text

    IGUIFont* font = OverrideFont;
    if (!OverrideFont)
        font = skin->getFont();

    s32 cursorLine = 0;
    s32 charcursorpos = 0;

    if (font)
    {
        if (LastBreakFont != font)
        {
            breakText();
        }

        // calculate cursor pos

        core::stringw *txtLine = &Text;
        s32 startPos = 0;

        core::stringw s, s2;

        // get mark position
        const bool ml = (!PasswordBox && (WordWrap || MultiLine));
        const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
        const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
        const s32 hlineStart = ml ? getLineFromPos(realmbgn) : 0;
        const s32 hlineCount = ml ? getLineFromPos(realmend) - hlineStart + 1 : 1;
        const s32 lineCount = ml ? BrokenText.size() : 1;

        // Save the override color information.
        // Then, alter it if the edit box is disabled.
        const bool prevOver = OverrideColorEnabled;
        const video::SColor prevColor = OverrideColor;

        if (Text.size())
        {
            if (!isEnabled() && !OverrideColorEnabled)
            {
                OverrideColorEnabled = true;
                OverrideColor = skin->getColor(EGDC_GRAY_TEXT);
            }

            for (s32 i=0; i < lineCount; ++i)
            {
                setTextRect(i);

                // clipping test - don't draw anything outside the visible area
                core::rect<s32> c = localClipRect;
                c.clipAgainst(CurrentTextRect);
                if (!c.isValid())
                    continue;

                // get current line
                if (PasswordBox)
                {
                    if (BrokenText.size() != 1)
                    {
                        BrokenText.clear();
                        BrokenText.push_back(core::stringw());
                    }
                    if (BrokenText[0].size() != Text.size())
                    {
                        BrokenText[0] = Text;
                        for (u32 q = 0; q < Text.size(); ++q)
                        {
                            BrokenText[0] [q] = PasswordChar;
                        }
                    }
                    txtLine = &BrokenText[0];
                    startPos = 0;
                }
                else
                {
                    txtLine = ml ? &BrokenText[i] : &Text;
                    startPos = ml ? BrokenTextPositions[i] : 0;
                }

                font->draw(translations->fribidize(txtLine->c_str()), CurrentTextRect,
                           OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT),
                           false, true, &localClipRect);
                // draw with fribidize no matter what language, because in fribidize function,
                // it will return the input pointer if (this->isRTLLanguage()) from Translations::isRTLText
                // is false

                // draw mark and marked text
                if (focus && MarkBegin != MarkEnd && i >= hlineStart && i < hlineStart + hlineCount)
                {

                    s32 mbegin = 0, mend = 0;
                    s32 lineStartPos = 0, lineEndPos = txtLine->size();

                    if (i == hlineStart)
                    {
                        // highlight start is on this line
                        s = txtLine->subString(0, realmbgn - startPos);
                        mbegin = font->getDimension(s.c_str()).Width;

                        // deal with kerning
                        mbegin += font->getKerningWidth(
                            &((*txtLine)[realmbgn - startPos]),
                            realmbgn - startPos > 0 ? &((*txtLine)[realmbgn - startPos - 1]) : 0);

                        lineStartPos = realmbgn - startPos;
                    }
                    if (i == hlineStart + hlineCount - 1)
                    {
                        // highlight end is on this line
                        s2 = txtLine->subString(0, realmend - startPos);
                        mend = font->getDimension(s2.c_str()).Width;
                        lineEndPos = (s32)s2.size();
                    }
                    else
                        mend = font->getDimension(txtLine->c_str()).Width;

                    CurrentTextRect.UpperLeftCorner.X += mbegin;
                    CurrentTextRect.LowerRightCorner.X = CurrentTextRect.UpperLeftCorner.X + mend - mbegin;

                    // draw mark
                    skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), CurrentTextRect, &localClipRect);

                    // draw marked text
                    s = txtLine->subString(lineStartPos, lineEndPos - lineStartPos);

                    if (s.size())
                        font->draw(s.c_str(), CurrentTextRect,
                            OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_HIGH_LIGHT_TEXT),
                            false, true, &localClipRect);

                }
            }

            // Return the override color information to its previous settings.
            OverrideColorEnabled = prevOver;
            OverrideColor = prevColor;
        }

        // draw cursor

        if (WordWrap || MultiLine)
        {
            cursorLine = getLineFromPos(CursorPos);
            txtLine = &BrokenText[cursorLine];
            startPos = BrokenTextPositions[cursorLine];
        }
        s = txtLine->subString(0,CursorPos-startPos);
        charcursorpos = font->getDimension(s.c_str()).Width ;
        // + font->getKerningWidth(L"_", CursorPos-startPos > 0 ? &((*txtLine)[CursorPos-startPos-1]) : 0);

        if (focus && (getTime() - BlinkStartTime) % 2 == 0 && !m_rtl)
        {
            //setTextRect(cursorLine);
            //CurrentTextRect.UpperLeftCorner.X += charcursorpos;

            setTextRect(0);

            core::rect< s32 > caret_rect = CurrentTextRect;
            caret_rect.UpperLeftCorner.X += charcursorpos - 1;
            caret_rect.LowerRightCorner.X = caret_rect.UpperLeftCorner.X + 2;
            GL32_draw2DRectangle( video::SColor(255,0,0,0), caret_rect );

            /*
            font->draw(L"_", CurrentTextRect,
                OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT),
                false, true, &localClipRect);
             */
        }
    }

    // draw children
    IGUIElement::draw();
#endif
}