s32 StaticText::getTextWidth() const { IGUIFont * font = getActiveFont(); if(!font) return 0; if(WordWrap) { s32 widest = 0; for(u32 line = 0; line < BrokenText.size(); ++line) { s32 width = font->getDimension(BrokenText[line].c_str()).Width; if(width > widest) widest = width; } return widest; } else { return font->getDimension(cText.c_str()).Width; } }
//! Returns the height of the text in pixels when it is drawn. s32 StaticText::getTextHeight() const { IGUIFont* font = getActiveFont(); if (!font) return 0; s32 height = font->getDimension(L"A").Height + font->getKerningHeight(); if (WordWrap) height *= BrokenText.size(); return height; }
//! draws the element and its children void CGUIButton::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); video::IVideoDriver* driver = Environment->getVideoDriver(); if (DrawBorder) { if (!Pressed) { skin->draw3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect); } else { skin->draw3DButtonPanePressed(this, AbsoluteRect, &AbsoluteClippingRect); } } const core::position2di buttonCenter(AbsoluteRect.getCenter()); EGUI_BUTTON_IMAGE_STATE imageState = getImageState(Pressed); if ( ButtonImages[(u32)imageState].Texture ) { core::position2d<s32> pos(buttonCenter); core::rect<s32> sourceRect(ButtonImages[(u32)imageState].SourceRect); if ( sourceRect.getWidth() == 0 && sourceRect.getHeight() == 0 ) sourceRect = core::rect<s32>(core::position2di(0,0), ButtonImages[(u32)imageState].Texture->getOriginalSize()); pos.X -= sourceRect.getWidth() / 2; pos.Y -= sourceRect.getHeight() / 2; if ( Pressed ) { // Create a pressed-down effect by moving the image when it looks identical to the unpressed state image EGUI_BUTTON_IMAGE_STATE unpressedState = getImageState(false); if ( unpressedState == imageState || ButtonImages[(u32)imageState] == ButtonImages[(u32)unpressedState] ) { pos.X += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X); pos.Y += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y); } } driver->draw2DImage(ButtonImages[(u32)imageState].Texture, ScaleImage? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()), sourceRect, &AbsoluteClippingRect, 0, UseAlphaChannel); } if (SpriteBank) { core::position2di pos(buttonCenter); if ( Pressed ) { IGUISkin* skin = Environment->getSkin(); pos.X += skin->getSize(EGDS_BUTTON_PRESSED_SPRITE_OFFSET_X); pos.Y += skin->getSize(EGDS_BUTTON_PRESSED_SPRITE_OFFSET_Y); } if (isEnabled()) { // pressed / unpressed animation EGUI_BUTTON_STATE state = Pressed ? EGBS_BUTTON_DOWN : EGBS_BUTTON_UP; drawSprite(state, ClickTime, pos); // focused / unfocused animation state = Environment->hasFocus(this) ? EGBS_BUTTON_FOCUSED : EGBS_BUTTON_NOT_FOCUSED; drawSprite(state, FocusTime, pos); // mouse over / off animation state = Environment->getHovered() == this ? EGBS_BUTTON_MOUSE_OVER : EGBS_BUTTON_MOUSE_OFF; drawSprite(state, HoverTime, pos); } else { // draw disabled drawSprite(EGBS_BUTTON_DISABLED, 0, pos); } } if (Text.size()) { IGUIFont* font = getActiveFont(); core::rect<s32> rect = AbsoluteRect; if (Pressed) { rect.UpperLeftCorner.X += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_X); rect.UpperLeftCorner.Y += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y); } if (font) font->draw(Text.c_str(), rect, skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), true, true, &AbsoluteClippingRect); } IGUIElement::draw(); }
//! draws the element and its children void CGUIButton::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); IVideoDriver* driver = Environment->getVideoDriver(); // todo: move sprite up and text down if the pressed state has a sprite const Position2d spritePos = AbsoluteRect.getCenter(); if (!Pressed) { if (DrawBorder) skin->draw3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect); if (Image) { Position2d pos = spritePos; pos.x -= ImageRect.getWidth() / 2; pos.y -= ImageRect.getHeight() / 2; driver->draw2DImage(Image, ScaleImage ? AbsoluteRect : recti(pos, ImageRect.getSize()), ImageRect, &AbsoluteClippingRect, 0, UseAlphaChannel); } } else { if (DrawBorder) skin->draw3DButtonPanePressed(this, AbsoluteRect, &AbsoluteClippingRect); if (PressedImage) { Position2d pos = spritePos; pos.x -= PressedImageRect.getWidth() / 2; pos.y -= PressedImageRect.getHeight() / 2; if (Image == PressedImage && PressedImageRect == ImageRect) { pos.x += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X); pos.y += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y); } driver->draw2DImage(PressedImage, ScaleImage ? AbsoluteRect : recti(pos, PressedImageRect.getSize()), PressedImageRect, &AbsoluteClippingRect, 0, UseAlphaChannel); } } if (SpriteBank) { // pressed / unpressed animation UINT32 state = Pressed ? (UINT32)EGBS_BUTTON_DOWN : (UINT32)EGBS_BUTTON_UP; if (ButtonSprites[state].Index != -1) { SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos, &AbsoluteClippingRect, ButtonSprites[state].Color, ClickTime, Timer::getTime(), ButtonSprites[state].Loop, true); } // focused / unfocused animation state = Environment->hasFocus(this) ? (UINT32)EGBS_BUTTON_FOCUSED : (UINT32)EGBS_BUTTON_NOT_FOCUSED; if (ButtonSprites[state].Index != -1) { SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos, &AbsoluteClippingRect, ButtonSprites[state].Color, FocusTime, Timer::getTime(), ButtonSprites[state].Loop, true); } // mouse over / off animation if (isEnabled()) { state = Environment->getHovered() == this ? (UINT32)EGBS_BUTTON_MOUSE_OVER : (UINT32)EGBS_BUTTON_MOUSE_OFF; if (ButtonSprites[state].Index != -1) { SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos, &AbsoluteClippingRect, ButtonSprites[state].Color, HoverTime, Timer::getTime(), ButtonSprites[state].Loop, true); } } } if (Text.size()) { IGUIFont* font = getActiveFont(); rect<SINT32> rect = AbsoluteRect; if (Pressed) { rect.UpperLeftCorner.x += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_X); rect.UpperLeftCorner.y += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y); } if (font) font->draw(Text, rect, skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), true, true, &AbsoluteClippingRect); } IGUIElement::draw(); }
//! Breaks the single text line. void StaticText::breakText() { if (!WordWrap) return; BrokenText.clear(); IGUISkin* skin = Environment->getSkin(); IGUIFont* font = getActiveFont(); if (!font) return; LastBreakFont = font; EnrichedString line; EnrichedString word; EnrichedString whitespace; s32 size = cText.size(); s32 length = 0; s32 elWidth = RelativeRect.getWidth(); if (Border) elWidth -= 2*skin->getSize(EGDS_TEXT_DISTANCE_X); wchar_t c; //std::vector<irr::video::SColor> colors; // We have to deal with right-to-left and left-to-right differently // However, most parts of the following code is the same, it's just // some order and boundaries which change. if (!RightToLeft) { // regular (left-to-right) for (s32 i=0; i<size; ++i) { c = cText.getString()[i]; bool lineBreak = false; if (c == L'\r') // Mac or Windows breaks { lineBreak = true; //if (Text[i+1] == L'\n') // Windows breaks //{ // Text.erase(i+1); // --size; //} c = '\0'; } else if (c == L'\n') // Unix breaks { lineBreak = true; c = '\0'; } bool isWhitespace = (c == L' ' || c == 0); if ( !isWhitespace ) { // part of a word //word += c; word.addChar(cText, i); } if ( isWhitespace || i == (size-1)) { if (word.size()) { // here comes the next whitespace, look if // we must break the last word to the next line. const s32 whitelgth = font->getDimension(whitespace.c_str()).Width; //const std::wstring sanitized = removeEscapes(word.c_str()); const s32 wordlgth = font->getDimension(word.c_str()).Width; if (wordlgth > elWidth) { // This word is too long to fit in the available space, look for // the Unicode Soft HYphen (SHY / 00AD) character for a place to // break the word at int where = core::stringw(word.c_str()).findFirst( wchar_t(0x00AD) ); if (where != -1) { EnrichedString first = word.substr(0, where); EnrichedString second = word.substr(where, word.size() - where); first.addCharNoColor(L'-'); BrokenText.push_back(line + first); const s32 secondLength = font->getDimension(second.c_str()).Width; length = secondLength; line = second; } else { // No soft hyphen found, so there's nothing more we can do // break to next line if (length) BrokenText.push_back(line); length = wordlgth; line = word; } } else if (length && (length + wordlgth + whitelgth > elWidth)) { // break to next line BrokenText.push_back(line); length = wordlgth; line = word; } else { // add word to line line += whitespace; line += word; length += whitelgth + wordlgth; } word.clear(); whitespace.clear(); } if ( isWhitespace && c != 0) { whitespace.addChar(cText, i); } // compute line break if (lineBreak) { line += whitespace; line += word; BrokenText.push_back(line); line.clear(); word.clear(); whitespace.clear(); length = 0; } } } line += whitespace; line += word; BrokenText.push_back(line); } else { // right-to-left for (s32 i=size; i>=0; --i) { c = cText.getString()[i]; bool lineBreak = false; if (c == L'\r') // Mac or Windows breaks { lineBreak = true; //if ((i>0) && Text[i-1] == L'\n') // Windows breaks //{ // Text.erase(i-1); // --size; //} c = '\0'; } else if (c == L'\n') // Unix breaks { lineBreak = true; c = '\0'; } if (c==L' ' || c==0 || i==0) { if (word.size()) { // here comes the next whitespace, look if // we must break the last word to the next line. const s32 whitelgth = font->getDimension(whitespace.c_str()).Width; const s32 wordlgth = font->getDimension(word.c_str()).Width; if (length && (length + wordlgth + whitelgth > elWidth)) { // break to next line BrokenText.push_back(line); length = wordlgth; line = word; } else { // add word to line line = whitespace + line; line = word + line; length += whitelgth + wordlgth; } word.clear(); whitespace.clear(); } if (c != 0) // whitespace = core::stringw(&c, 1) + whitespace; whitespace = cText.substr(i, 1) + whitespace; // compute line break if (lineBreak) { line = whitespace + line; line = word + line; BrokenText.push_back(line); line.clear(); word.clear(); whitespace.clear(); length = 0; } } else { // yippee this is a word.. //word = core::stringw(&c, 1) + word; word = cText.substr(i, 1) + word; } } line = whitespace + line; line = word + line; BrokenText.push_back(line); } }