//! Sets the new caption of this element. void StaticText::setText(const EnrichedString &text) { IGUIElement::setText(text.c_str()); cText = text; if (text.hasBackground()) { setBackgroundColor(text.getBackground()); } breakText(); }
void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count) { setStaticText(m_guitext_chat, chat_text); // Update gui element size and position s32 chat_y = 5; if (m_flags.show_debug) chat_y += 2 * g_fontengine->getLineHeight(); // first pass to calculate height of text to be set const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize(); s32 width = std::min(g_fontengine->getTextWidth(chat_text.c_str()) + 10, window_size.X - 20); m_guitext_chat->setRelativePosition(core::rect<s32>(10, chat_y, width, chat_y + window_size.Y)); // now use real height of text and adjust rect according to this size m_guitext_chat->setRelativePosition(core::rect<s32>(10, chat_y, width, chat_y + m_guitext_chat->getTextHeight())); // Don't show chat if disabled or empty or profiler is enabled m_guitext_chat->setVisible(m_flags.show_chat && recent_chat_count != 0 && m_profiler_current_page == 0); }
//! 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); } }