s32 CGUIStaticText::getTextWidth() const { IGUIFont * font = OverrideFont; if(!OverrideFont) { IGUISkin * skin = Environment->getSkin(); if(skin) font = skin->getFont(); } 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(Text.c_str()).Width; } }
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; } }
void CGUIEditBox::calculateScrollPos() { #ifndef SERVER_ONLY if (!AutoScroll) return; // calculate horizontal scroll position s32 cursLine = getLineFromPos(CursorPos); setTextRect(cursLine); // don't do horizontal scrolling when wordwrap is enabled. if (!WordWrap) { // get cursor position IGUISkin* skin = Environment->getSkin(); if (!skin) return; IGUIFont* font = OverrideFont ? OverrideFont : skin->getFont(); if (!font) return; core::stringw *txtLine = MultiLine ? &BrokenText[cursLine] : &Text; s32 cPos = MultiLine ? CursorPos - BrokenTextPositions[cursLine] : CursorPos; s32 cStart = CurrentTextRect.UpperLeftCorner.X + HScrollPos + font->getDimension(txtLine->subString(0, cPos).c_str()).Width; s32 cEnd = cStart + font->getDimension(L"_ ").Width; if (FrameRect.LowerRightCorner.X < cEnd) HScrollPos = cEnd - FrameRect.LowerRightCorner.X; else if (FrameRect.UpperLeftCorner.X > cStart) HScrollPos = cStart - FrameRect.UpperLeftCorner.X; else HScrollPos = 0; // todo: adjust scrollbar } // vertical scroll position if (FrameRect.LowerRightCorner.Y < CurrentTextRect.LowerRightCorner.Y + VScrollPos) VScrollPos = CurrentTextRect.LowerRightCorner.Y - FrameRect.LowerRightCorner.Y + VScrollPos; else if (FrameRect.UpperLeftCorner.Y > CurrentTextRect.UpperLeftCorner.Y + VScrollPos) VScrollPos = CurrentTextRect.UpperLeftCorner.Y - FrameRect.UpperLeftCorner.Y + VScrollPos; else VScrollPos = 0; // todo: adjust scrollbar #if defined(_IRR_COMPILE_WITH_X11_DEVICE_) CIrrDeviceLinux* dl = dynamic_cast<CIrrDeviceLinux*>(irr_driver->getDevice()); if (dl) { dl->setIMELocation(calculateICPos()); } #endif #endif // SERVER_ONLY }
void CGUITabControl::selectTab(core::position2d<s32> p) { IGUISkin* skin = Environment->getSkin(); IGUIFont* font = skin->getFont(); core::rect<s32> frameRect(AbsoluteRect); s32 tabheight = skin->getSize(gui::EGDS_BUTTON_HEIGHT); frameRect.UpperLeftCorner.Y += 2; frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + tabheight; s32 pos = frameRect.UpperLeftCorner.X + 2; for (u32 i=0; i<Tabs.size(); ++i) { // get Text const wchar_t* text = 0; if (Tabs[i]) text = Tabs[i]->getText(); // get text length s32 len = 20; if (font) len += font->getDimension(text).Width; frameRect.UpperLeftCorner.X = pos; frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; pos += len; if (frameRect.isPointInside(p)) { setActiveTab(i); return; } } }
bool CGUIEditBox::processIMEEvent(const SEvent& event) { switch(event.InputMethodEvent.Event) { case EIME_CHAR_INPUT: inputChar(event.InputMethodEvent.Char); return true; case EIME_CHANGE_POS: { core::position2di pos = calculateICPos(); IGUIFont* font = OverrideFont; IGUISkin* skin = Environment->getSkin(); if (!OverrideFont) font = skin->getFont(); irr::updateICPos(event.InputMethodEvent.Handle, pos.X,pos.Y, font->getDimension(L"|").Height); return true; } default: break; } return false; }
void CGUIContextMenu::recalculateSize() { IGUISkin* skin = Environment->getSkin(); IGUIFont* font = skin->getFont(EGDF_MENU); if (!font) return; core::rect<s32> rect; rect.UpperLeftCorner = RelativeRect.UpperLeftCorner; s32 width = 100; s32 height = 3; u32 i; for (i=0; i<Items.size(); ++i) { if (Items[i].IsSeparator) { Items[i].Dim.Width = 100; Items[i].Dim.Height = 10; } else { Items[i].Dim = font->getDimension(Items[i].Text.c_str()); Items[i].Dim.Width += 40; if (Items[i].Dim.Width > width) width = Items[i].Dim.Width; } Items[i].PosY = height; height += Items[i].Dim.Height; } height += 5; if (height < 10) height = 10; rect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + width; rect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + height; setRelativePosition(rect); // recalculate submenus for (i=0; i<Items.size(); ++i) { if (Items[i].SubMenu) { // move submenu const s32 w = Items[i].SubMenu->getAbsolutePosition().getWidth(); const s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight(); Items[i].SubMenu->setRelativePosition( core::rect<s32>(width-5, Items[i].PosY, width+w-5, Items[i].PosY+h)); } } }
//! Adds a button to the tool bar IGUIButton* CGUIToolBar::addButton(SINT32 id, const wchar_t* text, const wchar_t* tooltiptext, ITexture* img, ITexture* pressed, bool isPushButton, bool useAlphaChannel) { ButtonX += 3; rect<SINT32> rectangle(ButtonX, 2, ButtonX + 1, 3); if (img) { const dimension2du &size = img->getOriginalSize(); rectangle.LowerRightCorner.x = rectangle.UpperLeftCorner.x + size.Width + 8; rectangle.LowerRightCorner.y = rectangle.UpperLeftCorner.y + size.Height + 6; } if (text) { IGUISkin* skin = Environment->getSkin(); IGUIFont * font = skin->getFont(EGDF_BUTTON); if (font) { dimension2d<UINT32> dim = font->getDimension(text); if ((SINT32)dim.Width > rectangle.getWidth()) rectangle.LowerRightCorner.x = rectangle.UpperLeftCorner.x + dim.Width + 8; if ((SINT32)dim.Height > rectangle.getHeight()) rectangle.LowerRightCorner.y = rectangle.UpperLeftCorner.y + dim.Height + 6; } } ButtonX += rectangle.getWidth(); IGUIButton* button = new CGUIButton(Environment, this, id, rectangle); button->drop(); if (text) button->setText(text); if (tooltiptext) button->setToolTipText(tooltiptext); if (img) button->setImage(img); if (pressed) button->setPressedImage(pressed); if (isPushButton) button->setIsPushButton(isPushButton); if (useAlphaChannel) button->setUseAlphaChannel(useAlphaChannel); return button; }
//! 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; }
//! calculate the position of input composition window core::position2di CGUIEditBox::calculateICPos() { core::position2di pos; IGUIFont* font = OverrideFont; IGUISkin* skin = Environment->getSkin(); if (!OverrideFont) font = skin->getFont(); //drop the text that clipping on the right side if (WordWrap | MultiLine) { // todo : It looks like a heavy drinker. Strange!! pos.X = CurrentTextRect.LowerRightCorner.X - font->getDimension(Text.subString(CursorPos, BrokenTextPositions[getLineFromPos(CursorPos)] + BrokenText[getLineFromPos(CursorPos)].size() - CursorPos).c_str()).Width; pos.Y = CurrentTextRect.UpperLeftCorner.Y + font->getDimension(L"|").Height + (Border ? 3 : 0) - ((MultiLine | WordWrap) ? 3 : 0); } else { pos.X = CurrentTextRect.LowerRightCorner.X - font->getDimension(Text.subString(CursorPos, Text.size() - CursorPos).c_str()).Width; pos.Y = AbsoluteRect.getCenter().Y + (Border ? 3 : 0); //bug? The text is always drawn in the height of the center. SetTextAlignment() doesn't influence. } return pos; }
bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl) { if ( startIndex >= (s32)Tabs.size() ) startIndex -= 1; if ( startIndex < 0 ) startIndex = 0; IGUISkin* skin = Environment->getSkin(); if (!skin) return false; IGUIFont* font = skin->getFont(); core::rect<s32> frameRect(AbsoluteRect); if (Tabs.empty()) return false; if (!font) return false; s32 pos = frameRect.UpperLeftCorner.X + 2; for (s32 i=startIndex; i<(s32)Tabs.size(); ++i) { // get Text const wchar_t* text = 0; if (Tabs[i]) text = Tabs[i]->getText(); // get text length s32 len = font->getDimension(text).Width + TabExtraWidth; frameRect.LowerRightCorner.X += len; frameRect.UpperLeftCorner.X = pos; frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; pos += len; if ( withScrollControl && pos > AbsoluteRect.LowerRightCorner.X - TabMaxWidth) return true; if ( !withScrollControl && pos > AbsoluteRect.LowerRightCorner.X ) return true; } return false; }
void CGUIComboBox::openCloseMenu() { if (ListBox) { // close list box Environment->setFocus(this); ListBox->remove(); ListBox = 0; } else { if (Parent) Parent->bringToFront(this); IGUISkin* skin = Environment->getSkin(); s32 h = Items.size(); if (h > 5) h = 5; if (h == 0) h = 1; IGUIFont* font = skin->getFont(); if (font) h *= (font->getDimension(L"A").Height + 4); // open list box core::rect<s32> r(0, AbsoluteRect.getHeight(), AbsoluteRect.getWidth(), AbsoluteRect.getHeight() + h); ListBox = new CGUIListBox(Environment, this, -1, r, false, true, true); ListBox->setSubElement(true); ListBox->setNotClipped(true); ListBox->drop(); // ensure that list box is always completely visible if (ListBox->getAbsolutePosition().LowerRightCorner.Y > Environment->getRootGUIElement()->getAbsolutePosition().getHeight()) ListBox->setRelativePosition( core::rect<s32>(0, -ListBox->getAbsolutePosition().getHeight(), AbsoluteRect.getWidth(), 0) ); for (s32 i=0; i<(s32)Items.size(); ++i) ListBox->addItem(Items[i].Name.c_str()); ListBox->setSelected(Selected); // set focus Environment->setFocus(ListBox); } }
bool CGUITabControl::selectTab(core::position2d<s32> p) { IGUISkin* skin = Environment->getSkin(); IGUIFont* font = skin->getFont(); core::rect<s32> frameRect(AbsoluteRect); if ( VerticalAlignment == EGUIA_UPPERLEFT ) { frameRect.UpperLeftCorner.Y += 2; frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + TabHeight; } else { frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - TabHeight; } s32 pos = frameRect.UpperLeftCorner.X + 2; if (!frameRect.isPointInside(p)) return false; for (s32 i=CurrentScrollTabIndex; i<(s32)Tabs.size(); ++i) { // get Text const wchar_t* text = 0; if (Tabs[i]) text = Tabs[i]->getText(); // get text length s32 len = font->getDimension(text).Width + TabExtraWidth; frameRect.UpperLeftCorner.X = pos; frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; if ( ScrollControl && pos > AbsoluteRect.LowerRightCorner.X) return false; pos += len; if (frameRect.isPointInside(p)) { setActiveTab(i); return true; } } return false; }
void CGUIComboBox::openCloseMenu() { if (ListBox) { // close list box Environment->setFocus(this); ListBox->remove(); ListBox = 0; } else { if (Parent) Parent->bringToFront(this); IGUISkin* skin = Environment->getSkin(); s32 h = Items.size(); if (h > 5) h = 5; if (h == 0) h = 1; IGUIFont* font = skin->getFont(); if (font) h *= (font->getDimension(L"A").Height + 4); // open list box core::rect<s32> r(0, AbsoluteRect.getHeight(), AbsoluteRect.getWidth(), AbsoluteRect.getHeight() + h); ListBox = new CGUIListBox(Environment, this, -1, r, false, true, true); ListBox->setSubElement(true); ListBox->drop(); for (s32 i=0; i<(s32)Items.size(); ++i) ListBox->addItem(Items[i].c_str()); ListBox->setSelected(Selected); // set focus Environment->setFocus(ListBox); } }
//! Returns the height of the text in pixels when it is drawn. s32 CGUIStaticText::getTextHeight() { IGUISkin* skin = Environment->getSkin(); if (!skin) return 0; IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); if (!font) return 0; s32 height = font->getDimension(L"A").Height; if (WordWrap) height *= BrokenText.size(); return height; }
void CGUIContextMenu::recalculateSize() { IGUIFont* font = Environment->getSkin()->getFont(EGDF_MENU); if (!font) return; core::rect<s32> rect; rect.UpperLeftCorner = RelativeRect.UpperLeftCorner; u32 width = 100; u32 height = 3; u32 i; for (i=0; i<Items.size(); ++i) { if (Items[i].IsSeparator) { Items[i].Dim.Width = 100; Items[i].Dim.Height = 10; } else { Items[i].Dim = font->getDimension(Items[i].Text.c_str()); Items[i].Dim.Width += 40; if (Items[i].Dim.Width > width) width = Items[i].Dim.Width; } Items[i].PosY = height; height += Items[i].Dim.Height; } height += 5; if (height < 10) height = 10; rect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + width; rect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + height; setRelativePosition(rect); // recalculate submenus for (i=0; i<Items.size(); ++i) { if (Items[i].SubMenu) { // move submenu const s32 w = Items[i].SubMenu->getAbsolutePosition().getWidth(); const s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight(); core::rect<s32> subRect(width-5, Items[i].PosY, width+w-5, Items[i].PosY+h); // if it would be drawn beyond the right border, then add it to the left side gui::IGUIElement * root = Environment->getRootGUIElement(); if ( root ) { core::rect<s32> rectRoot( root->getAbsolutePosition() ); if ( getAbsolutePosition().UpperLeftCorner.X+subRect.LowerRightCorner.X > rectRoot.LowerRightCorner.X ) { subRect.UpperLeftCorner.X = -w; subRect.LowerRightCorner.X = 0; } } Items[i].SubMenu->setRelativePosition(subRect); } } }
void CGUIMenu::recalculateSize() { rect<SINT32> clientRect; // client rect of parent if (Parent && Parent->hasType(EGUIET_WINDOW)) { clientRect = static_cast<IGUIWindow*>(Parent)->getClientRect(); } else if (Parent) { clientRect = rect<SINT32>(0, 0, Parent->getAbsolutePosition().getWidth(), Parent->getAbsolutePosition().getHeight()); } else { clientRect = RelativeRect; } IGUISkin* skin = Environment->getSkin(); IGUIFont* font = skin->getFont(EGDF_MENU); if (!font) { if (Parent && skin) RelativeRect = rect<SINT32>(clientRect.UpperLeftCorner.x, clientRect.UpperLeftCorner.y, clientRect.LowerRightCorner.x, clientRect.UpperLeftCorner.y + skin->getSize(EGDS_MENU_HEIGHT)); return; } rect<SINT32> rect; rect.UpperLeftCorner = clientRect.UpperLeftCorner; SINT32 height = font->getDimension(L"A").Height + 5; //if (skin && height < skin->getSize ( EGDS_MENU_HEIGHT )) // height = skin->getSize(EGDS_MENU_HEIGHT); SINT32 width = rect.UpperLeftCorner.x; SINT32 i; for (i = 0; i<(SINT32)Items.size(); ++i) { if (Items[i].IsSeparator) { Items[i].Dim.Width = 0; Items[i].Dim.Height = height; } else { Items[i].Dim = font->getDimension(Items[i].Text.c_str()); Items[i].Dim.Width += 20; } Items[i].PosY = width; width += Items[i].Dim.Width; } width = clientRect.getWidth(); rect.LowerRightCorner.x = rect.UpperLeftCorner.x + width; rect.LowerRightCorner.y = rect.UpperLeftCorner.y + height; setRelativePosition(rect); // recalculate submenus for (i = 0; i<(SINT32)Items.size(); ++i) if (Items[i].SubMenu) { // move submenu SINT32 w = Items[i].SubMenu->getAbsolutePosition().getWidth(); SINT32 h = Items[i].SubMenu->getAbsolutePosition().getHeight(); Items[i].SubMenu->setRelativePosition( Sapphire::rect<SINT32>(Items[i].PosY, height, Items[i].PosY + w - 5, height + h)); } }
void GUIFCCharacterItem::draw() { if ( !IsVisible ) return; SColor grey(255, 128, 128, 128); SColor white(255, 255, 255, 255); SColor charInset(255, 0, 64, 128); SColor blue(255, 64, 128, 255); core::rect<s32> rect = AbsoluteRect; wstringstream s; // draw the outline and background m_pDriver->draw2DRectangle( rect, grey, grey, grey, grey); rect.LowerRightCorner.X -= 2; rect.LowerRightCorner.Y -= 2; rect.UpperLeftCorner.X += 2; rect.UpperLeftCorner.Y += 2; if ( !m_bHighlight ) m_pDriver->draw2DRectangle( rect, white, white, white, white); else m_pDriver->draw2DRectangle( rect, white, white, blue, blue); // draw the 'character image' inset rect.UpperLeftCorner.X += 7; rect.UpperLeftCorner.Y += 7; rect.LowerRightCorner.Y -= 7; rect.LowerRightCorner.X = rect.UpperLeftCorner.X + rect.getHeight(); m_pDriver->draw2DRectangle( rect, charInset, charInset, charInset, charInset ); // update rectangle for lines of text rect.UpperLeftCorner.X = rect.LowerRightCorner.X + 10; rect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - 10; // create the character details string and textobject IGUIFont* pFont = Environment->getSkin()->getFont(); if ( !pFont ) pFont = Environment->getBuiltInFont(); wstring str = m_pCharacter->GetName(); core::dimension2d<s32> extents = pFont->getDimension( str.c_str() ); rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + extents.Height; pFont->draw( str.c_str(), rect, SColor(255, 0, 0, 0) ); rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y; rect.LowerRightCorner.Y += extents.Height; s << L"Level: " << m_pCharacter->GetLevel(); str = s.str(); pFont->draw( str.c_str(), rect, SColor(255, 0, 0, 0) ); rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y; rect.LowerRightCorner.Y += extents.Height; s.str(L""); s << L"XP: " << m_pCharacter->GetXP(); str = s.str(); pFont->draw( str.c_str(), rect, SColor(255, 0, 0, 0) ); IGUIElement::draw(); }
//! Breaks the single text line. void CGUIStaticText::breakText() { IGUISkin* skin = Environment->getSkin(); if (!WordWrap || !skin) return; BrokenText.clear(); IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); if (!font) return; LastBreakFont = font; core::stringw line; core::stringw word; core::stringw whitespace; s32 size = Text.size(); s32 length = 0; s32 elWidth = RelativeRect.getWidth(); if (Border) elWidth -= 2*skin->getSize(EGDS_TEXT_DISTANCE_X); wchar_t c; for (s32 i=0; i<size; ++i) { c = Text[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; } 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 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 += word; length += whitelgth + wordlgth; } word = L""; whitespace = L""; } if ( isWhitespace ) { whitespace += c; } // compute line break if (lineBreak) { line += whitespace; line += word; BrokenText.push_back(line); line = L""; word = L""; whitespace = L""; length = 0; } } } line += whitespace; line += word; BrokenText.push_back(line); }
void GUIForumPostItem::setItemData(ForumThread* pThread) { std::wstringstream ss; core::rect<s32> itemRect(5, 0, RelativeRect.getWidth()-5, RelativeRect.getHeight()), startRect; IGUIFont* pFont = Environment->getSkin()->getFont(); startRect = itemRect; itemRect.LowerRightCorner.Y = itemRect.UpperLeftCorner.Y + FPI_AUTHOR_HEIGHT; if ( !m_pTxtAuthor ) { ss << L"Author: " << pThread->getAuthorName().c_str(); m_pTxtAuthor = Environment->addStaticText(ss.str().c_str(), itemRect, false, false, this); m_pTxtAuthor->setOverrideColor(m_colText); m_pTxtAuthor->setTextAlignment( EGUIA_UPPERLEFT, EGUIA_CENTER ); ss.str(L""); } if ( pThread->getTitle().size() ) { offsetRect(itemRect, 0, itemRect.getHeight() + 5); if ( !m_pTxtSubject ) { ss << L"Subject: " << pThread->getTitle().c_str(); m_pTxtSubject = Environment->addStaticText(ss.str().c_str(), itemRect, false, false, this); m_pTxtSubject->setOverrideColor(m_colText); m_pTxtSubject->setTextAlignment( EGUIA_UPPERLEFT, EGUIA_CENTER ); ss.str(L""); } } offsetRect(itemRect, 0, itemRect.getHeight() + 5); if ( !m_pTxtContent ) { ss << pThread->getContent().c_str(); m_pTxtContent = Environment->addStaticText(ss.str().c_str(), itemRect, true, true, this); m_pTxtContent->setBackgroundColor(m_colBkg); m_pTxtContent->setOverrideColor(m_colText); itemRect.LowerRightCorner.Y = itemRect.UpperLeftCorner.Y + m_pTxtContent->getTextHeight(); m_pTxtContent->setRelativePosition( itemRect ); ss.str(L""); } // if this is a mission thread, then we need to create the button to accept the mission if ( pThread->getMissionID() ) { // check which options should be shown MissionMgr& missionMgr = FCModel::instance().GetMissionMgr(); bool bAccepted = missionMgr.isMissionAccepted(pThread->getMissionID()); bool bCompleted = missionMgr.isMissionComplete(pThread->getMissionID()); if ( !bAccepted && !bCompleted ) { offsetRect(itemRect, 0, itemRect.getHeight() + 5); itemRect.LowerRightCorner.Y = itemRect.UpperLeftCorner.Y + 20; core::rect<s32> btnRect = itemRect; ss << "Accept"; btnRect.LowerRightCorner.X = btnRect.UpperLeftCorner.X + pFont->getDimension(ss.str().c_str()).Width + 20; m_pBtnAccept = Environment->addButton(btnRect, this, BTN_ACCEPT, ss.str().c_str()); } } core::rect<s32> myRect = getRelativePosition(); myRect.LowerRightCorner.Y = myRect.UpperLeftCorner.Y + ( itemRect.LowerRightCorner.Y - startRect.UpperLeftCorner.Y ) + 5; setRelativePosition(myRect); m_pThread = pThread; }
//! Breaks the single text line. void CGUIStaticText::breakText() { IGUISkin* skin = Environment->getSkin(); if (!WordWrap || !skin) return; BrokenText.clear(); IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); if (!font) return; LastBreakFont = font; core::stringw line; core::stringw word; core::stringw whitespace; s32 size = Text.size(); s32 length = 0; s32 elWidth = RelativeRect.getWidth() - 6; wchar_t c; for (s32 i=0; i<size; ++i) { c = Text[i]; bool lineBreak = false; if (c == L'\n') { lineBreak = true; c = ' '; } if (c == L' ' || c == 0 || i == (size-1)) { if (word.size()) { // here comes the next whitespace, look if // we can break the last word to the next line. s32 whitelgth = font->getDimension(whitespace.c_str()).Width; s32 worldlgth = font->getDimension(word.c_str()).Width; if (length + worldlgth + whitelgth > elWidth) { // break to next line length = worldlgth; BrokenText.push_back(line); line = word; } else { // add word to line line += whitespace; line += word; length += whitelgth + worldlgth; } word = L""; whitespace = L""; } whitespace += c; // compute line break if (lineBreak) { line += whitespace; line += word; BrokenText.push_back(line); line = L""; word = L""; whitespace = L""; length = 0; } } else { // yippee this is a word.. word += c; } } line += whitespace; line += word; BrokenText.push_back(line); }
//! 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 }
//! draws the element and its children void CGUIStaticText::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); irr::video::IVideoDriver* driver = Environment->getVideoDriver(); core::rect<s32> frameRect(AbsoluteRect); // draw background if (Background) { driver->draw2DRectangle( skin->getColor(gui::EGDC_3D_FACE), frameRect, &AbsoluteClippingRect); } // draw the border if (Border) { skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect); frameRect.UpperLeftCorner.X += 3; } // draw the text if (Text.size()) { IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); if (font) { if (!WordWrap) font->draw(Text.c_str(), frameRect, OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), false, true, &AbsoluteClippingRect); else { if (font != LastBreakFont) breakText(); core::rect<s32> r = frameRect; s32 height = font->getDimension(L"A").Height; for (u32 i=0; i<BrokenText.size(); ++i) { font->draw(BrokenText[i].c_str(), r, OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), false, false, &AbsoluteClippingRect); r.LowerRightCorner.Y += height; r.UpperLeftCorner.Y += height; } } } } IGUIElement::draw(); }
void CGUIEditBox::setTextRect(s32 line) { core::dimension2du d; IGUISkin* skin = Environment->getSkin(); if (!skin) return; IGUIFont* font = OverrideFont ? OverrideFont : skin->getFont(); if (!font) return; // get text dimension const u32 lineCount = (WordWrap || MultiLine) ? BrokenText.size() : 1; if (WordWrap || MultiLine) { d = font->getDimension(BrokenText[line].c_str()); } else { d = font->getDimension(Text.c_str()); d.Height = AbsoluteRect.getHeight(); } d.Height += font->getKerningHeight(); // justification switch (HAlign) { case EGUIA_CENTER: // align to h centre CurrentTextRect.UpperLeftCorner.X = (FrameRect.getWidth()/2) - (d.Width/2); CurrentTextRect.LowerRightCorner.X = (FrameRect.getWidth()/2) + (d.Width/2); break; case EGUIA_LOWERRIGHT: // align to right edge CurrentTextRect.UpperLeftCorner.X = FrameRect.getWidth() - d.Width; CurrentTextRect.LowerRightCorner.X = FrameRect.getWidth(); break; default: // align to left edge CurrentTextRect.UpperLeftCorner.X = 0; CurrentTextRect.LowerRightCorner.X = d.Width; } switch (VAlign) { case EGUIA_CENTER: // align to v centre CurrentTextRect.UpperLeftCorner.Y = (FrameRect.getHeight()/2) - (lineCount*d.Height)/2 + d.Height*line; break; case EGUIA_LOWERRIGHT: // align to bottom edge CurrentTextRect.UpperLeftCorner.Y = FrameRect.getHeight() - lineCount*d.Height + d.Height*line; break; default: // align to top edge CurrentTextRect.UpperLeftCorner.Y = d.Height*line; break; } CurrentTextRect.UpperLeftCorner.X -= HScrollPos; CurrentTextRect.LowerRightCorner.X -= HScrollPos; CurrentTextRect.UpperLeftCorner.Y -= VScrollPos; CurrentTextRect.LowerRightCorner.Y = CurrentTextRect.UpperLeftCorner.Y + d.Height; CurrentTextRect += FrameRect.UpperLeftCorner; }
//! Breaks the single text line. void CGUIEditBox::breakText() { IGUISkin* skin = Environment->getSkin(); if ((!WordWrap && !MultiLine) || !skin) return; BrokenText.clear(); // need to reallocate :/ BrokenTextPositions.set_used(0); IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); if (!font) return; LastBreakFont = font; core::stringw line; core::stringw word; core::stringw whitespace; s32 lastLineStart = 0; s32 size = Text.size(); s32 length = 0; s32 elWidth = RelativeRect.getWidth() - 6; for (s32 i=0; i<size; ++i) { wchar_t c = Text[i]; bool lineBreak = false; if (c == L'\r') // Mac or Windows breaks { lineBreak = true; c = ' '; if (Text[i+1] == L'\n') // Windows breaks { Text.erase(i+1); --size; } } else if (c == L'\n') // Unix breaks { lineBreak = true; c = ' '; } // don't break if we're not a multi-line edit box if (!MultiLine) lineBreak = false; if (c == L' ' || c == 0 || i == (size-1)) { if (word.size()) { // here comes the next whitespace, look if // we can break the last word to the next line. s32 whitelgth = font->getDimension(whitespace.c_str()).Width; s32 worldlgth = font->getDimension(word.c_str()).Width; if (WordWrap && length + worldlgth + whitelgth > elWidth) { // break to next line length = worldlgth; BrokenText.push_back(line); BrokenTextPositions.push_back(lastLineStart); lastLineStart = i - (s32)word.size(); line = word; } else { // add word to line line += whitespace; line += word; length += whitelgth + worldlgth; } word = L""; whitespace = L""; } whitespace += c; // compute line break if (lineBreak) { line += whitespace; line += word; BrokenText.push_back(line); BrokenTextPositions.push_back(lastLineStart); lastLineStart = i+1; line = L""; word = L""; whitespace = L""; length = 0; } } else { // yippee this is a word.. word += c; } } line += whitespace; line += word; BrokenText.push_back(line); BrokenTextPositions.push_back(lastLineStart); }
/** Changes this dialog to confirm the changes. */ void PlayerInfoDialog::showConfirmDialog() { clearWindow(); IGUIFont* font = GUIEngine::getFont(); const int textHeight = GUIEngine::getFontHeight(); const int buttonHeight = textHeight + 10; irr::core::stringw message = //I18N: In the player info dialog (when deleting) _("Do you really want to delete player '%s' ?", m_player->getName()); if (PlayerManager::getCurrentPlayer() == m_player) { message = _("You cannot delete this player " "because it is currently in use."); } core::rect< s32 > area_left(5, 0, m_area.getWidth()-5, m_area.getHeight()/2); // When there is no need to tab through / click on images/labels, // we can add irrlicht labels directly // (more complicated uses require the use of our widget set) IGUIStaticText* a = GUIEngine::getGUIEnv()->addStaticText( message.c_str(), area_left, false /* border */, true /* word wrap */, m_irrlicht_window); a->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); if (PlayerManager::getCurrentPlayer() != m_player) { ButtonWidget* widget = new ButtonWidget(); widget->m_properties[PROP_ID] = "confirmremove"; //I18N: In the player info dialog (when deleting) widget->setText( _("Confirm Remove") ); const int textWidth = font->getDimension(widget->getText().c_str()).Width + 40; widget->m_x = m_area.getWidth()/2 - textWidth/2; widget->m_y = m_area.getHeight()/2; widget->m_w = textWidth; widget->m_h = buttonHeight; widget->setParent(m_irrlicht_window); m_widgets.push_back(widget); widget->add(); } { ButtonWidget* widget = new ButtonWidget(); widget->m_properties[PROP_ID] = "cancelremove"; //I18N: In the player info dialog (when deleting) widget->setText( _("Cancel Remove") ); const int textWidth = font->getDimension( widget->getText().c_str() ).Width + 40; widget->m_x = m_area.getWidth()/2 - textWidth/2; widget->m_y = m_area.getHeight()*3/4; widget->m_w = textWidth; widget->m_h = buttonHeight; widget->setParent(m_irrlicht_window); m_widgets.push_back(widget); widget->add(); widget->setFocusForPlayer( PLAYER_ID_GAME_MASTER ); } } // showConfirmDialog
//! draws the element and its children void CGUIStaticText::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); if (!skin) return; video::IVideoDriver* driver = Environment->getVideoDriver(); core::rect<s32> frameRect(AbsoluteRect); // draw background if (Background) { driver->draw2DRectangle(BGColor, frameRect, &AbsoluteClippingRect); } // draw the border if (Border) { skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect); frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X); } // draw the text if (Text.size()) { IGUIFont* font = OverrideFont; if (!OverrideFont) font = skin->getFont(); if (font) { if (!WordWrap) { if (VAlign == EGUIA_LOWERRIGHT) { frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - font->getDimension(L"A").Height - font->getKerningHeight(); } if (HAlign == EGUIA_LOWERRIGHT) { frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - font->getDimension(Text.c_str()).Width; } font->draw(Text.c_str(), frameRect, OverrideColorEnabled ? OverrideColor : skin->getColor(IsEnabled ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, &AbsoluteClippingRect); } else { if (font != LastBreakFont) breakText(); core::rect<s32> r = frameRect; s32 height = font->getDimension(L"A").Height + font->getKerningHeight(); s32 totalHeight = height * BrokenText.size(); if (VAlign == EGUIA_CENTER) { r.UpperLeftCorner.Y = r.getCenter().Y - (totalHeight / 2); } else if (VAlign == EGUIA_LOWERRIGHT) { r.UpperLeftCorner.Y = r.LowerRightCorner.Y - totalHeight; } for (u32 i=0; i<BrokenText.size(); ++i) { if (HAlign == EGUIA_LOWERRIGHT) { r.UpperLeftCorner.X = frameRect.LowerRightCorner.X - font->getDimension(BrokenText[i].c_str()).Width; } font->draw(BrokenText[i].c_str(), r, OverrideColorEnabled ? OverrideColor : skin->getColor(IsEnabled ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), HAlign == EGUIA_CENTER, false, &AbsoluteClippingRect); r.LowerRightCorner.Y += height; r.UpperLeftCorner.Y += height; } } } } IGUIElement::draw(); }
//! draws the element and its children void CGUITabControl::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); if (!skin) return; IGUIFont* font = skin->getFont(); core::rect<s32> frameRect(AbsoluteRect); if (Tabs.empty()) skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); if (!font) return; s32 tabheight = skin->getSize(gui::EGDS_BUTTON_HEIGHT); frameRect.UpperLeftCorner.Y += 2; frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + tabheight; core::rect<s32> tr; s32 pos = frameRect.UpperLeftCorner.X + 2; // left and right pos of the active tab s32 left = 0; s32 right = 0; const wchar_t* activetext = 0; for (u32 i=0; i<Tabs.size(); ++i) { // get Text const wchar_t* text = 0; if (Tabs[i]) text = Tabs[i]->getText(); // get text length s32 len = font->getDimension(text).Width + 20; frameRect.UpperLeftCorner.X = pos; frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; pos += len; if ((s32)i == ActiveTab) { left = frameRect.UpperLeftCorner.X; right = frameRect.LowerRightCorner.X; activetext = text; } else { skin->draw3DTabButton(this, false, frameRect, &AbsoluteClippingRect); // draw text font->draw(text, frameRect, skin->getColor(EGDC_BUTTON_TEXT), true, true, &AbsoluteClippingRect); } } // draw active tab if (left != 0 && right != 0) { frameRect.UpperLeftCorner.X = left-2; frameRect.LowerRightCorner.X = right+2; frameRect.UpperLeftCorner.Y -= 2; skin->draw3DTabButton(this, true, frameRect, &AbsoluteClippingRect); // draw text font->draw(activetext, frameRect, skin->getColor(EGDC_BUTTON_TEXT), true, true, &AbsoluteClippingRect); // draw upper highlight frame tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; tr.LowerRightCorner.X = left - 1; tr.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - 1; tr.LowerRightCorner.Y = frameRect.LowerRightCorner.Y; skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); tr.UpperLeftCorner.X = right; tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); } skin->draw3DTabBody(this, Border, FillBackground, AbsoluteRect, &AbsoluteClippingRect); IGUIElement::draw(); }
//! draws the element and its children void CGUITabControl::draw() { if (!IsVisible) return; IGUISkin* skin = Environment->getSkin(); if (!skin) return; IGUIFont* font = skin->getFont(); video::IVideoDriver* driver = Environment->getVideoDriver(); core::rect<s32> frameRect(AbsoluteRect); if (Tabs.empty()) driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); if (!font) return; if ( VerticalAlignment == EGUIA_UPPERLEFT ) { frameRect.UpperLeftCorner.Y += 2; frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + TabHeight; } else { frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - TabHeight - 1; frameRect.LowerRightCorner.Y -= 2; } core::rect<s32> tr; s32 pos = frameRect.UpperLeftCorner.X + 2; // left and right pos of the active tab s32 left = 0; s32 right = 0; //const wchar_t* activetext = 0; CGUITab *activeTab = 0; for (u32 i=0; i<Tabs.size(); ++i) { // get Text const wchar_t* text = 0; if (Tabs[i]) text = Tabs[i]->getText(); // get text length s32 len = font->getDimension(text).Width + TabExtraWidth; frameRect.LowerRightCorner.X += len; frameRect.UpperLeftCorner.X = pos; frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; if ( ScrollControl && pos > frameRect.LowerRightCorner.X ) break; pos += len; if ((s32)i == ActiveTab) { left = frameRect.UpperLeftCorner.X; right = frameRect.LowerRightCorner.X; //activetext = text; activeTab = Tabs[i]; } else { skin->draw3DTabButton(this, false, frameRect, &AbsoluteClippingRect, VerticalAlignment); // draw text font->draw(text, frameRect, Tabs[i]->getTextColor(), true, true, &AbsoluteClippingRect); } } // draw active tab if (left != 0 && right != 0 && activeTab != 0) { // draw upper highlight frame if ( VerticalAlignment == EGUIA_UPPERLEFT ) { frameRect.UpperLeftCorner.X = left-2; frameRect.LowerRightCorner.X = right+2; frameRect.UpperLeftCorner.Y -= 2; skin->draw3DTabButton(this, true, frameRect, &AbsoluteClippingRect, VerticalAlignment); // draw text font->draw(activeTab->getText(), frameRect, activeTab->getTextColor(), true, true, &AbsoluteClippingRect); tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; tr.LowerRightCorner.X = left - 1; tr.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - 1; tr.LowerRightCorner.Y = frameRect.LowerRightCorner.Y; driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); tr.UpperLeftCorner.X = right; tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); } else { frameRect.UpperLeftCorner.X = left-2; frameRect.LowerRightCorner.X = right+2; frameRect.LowerRightCorner.Y += 2; skin->draw3DTabButton(this, true, frameRect, &AbsoluteClippingRect, VerticalAlignment); // draw text font->draw(activeTab->getText(), frameRect, activeTab->getTextColor(), true, true, &AbsoluteClippingRect); tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; tr.LowerRightCorner.X = left - 1; tr.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - 1; tr.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y; driver->draw2DRectangle(skin->getColor(EGDC_3D_DARK_SHADOW), tr, &AbsoluteClippingRect); tr.UpperLeftCorner.X = right; tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; driver->draw2DRectangle(skin->getColor(EGDC_3D_DARK_SHADOW), tr, &AbsoluteClippingRect); } } else { if ( VerticalAlignment == EGUIA_UPPERLEFT ) { tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; tr.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - 1; tr.LowerRightCorner.Y = frameRect.LowerRightCorner.Y; driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); } else { tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; tr.LowerRightCorner.X = 1000; tr.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - 1; tr.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y; driver->draw2DRectangle(skin->getColor(EGDC_3D_DARK_SHADOW), tr, &AbsoluteClippingRect); } } skin->draw3DTabBody(this, Border, FillBackground, AbsoluteRect, &AbsoluteClippingRect, TabHeight, VerticalAlignment); IGUIElement::draw(); }
void CGUIMenu::recalculateSize() { IGUISkin* skin = Environment->getSkin(); IGUIFont* font = skin->getFont(EGDF_MENU); if (!font) { if (Parent && skin) RelativeRect = core::rect<s32>(0,0, Parent->getAbsolutePosition().LowerRightCorner.X, skin->getSize(EGDS_MENU_HEIGHT)); return; } core::rect<s32> rect; rect.UpperLeftCorner.X = 0; rect.UpperLeftCorner.Y = 0; s32 height = font->getDimension(L"A").Height + 5; //if (skin && height < skin->getSize ( EGDS_MENU_HEIGHT )) // height = skin->getSize(EGDS_MENU_HEIGHT); s32 width = 0; s32 i; for (i=0; i<(s32)Items.size(); ++i) { if (Items[i].IsSeparator) { Items[i].Dim.Width = 0; Items[i].Dim.Height = height; } else { Items[i].Dim = font->getDimension(Items[i].Text.c_str()); Items[i].Dim.Width += 20; } Items[i].PosY = width; width += Items[i].Dim.Width; } if (Parent) width = Parent->getAbsolutePosition().getWidth(); rect.LowerRightCorner.X = width; rect.LowerRightCorner.Y = height; setRelativePosition(rect); // recalculate submenus for (i=0; i<(s32)Items.size(); ++i) if (Items[i].SubMenu) { // move submenu s32 w = Items[i].SubMenu->getAbsolutePosition().getWidth(); s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight(); Items[i].SubMenu->setRelativePosition( core::rect<s32>(Items[i].PosY, height , Items[i].PosY+w-5, height+h)); } }
//! 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); } }