Index: binaries/data/mods/mod/gui/gui.rng =================================================================== --- binaries/data/mods/mod/gui/gui.rng +++ binaries/data/mods/mod/gui/gui.rng @@ -484,6 +484,11 @@ + + + + + Index: binaries/data/mods/public/gui/common/OverlayCounterManager.js =================================================================== --- binaries/data/mods/public/gui/common/OverlayCounterManager.js +++ binaries/data/mods/public/gui/common/OverlayCounterManager.js @@ -14,7 +14,6 @@ this.lastTick = undefined; this.resizeHandlers = []; this.lastHeight = undefined; - this.initSize = this.dataCounter.size; for (let name of this.availableCounterNames()) { @@ -79,29 +78,26 @@ this.lastTick = now; - let lineCount = 0; let txt = ""; for (let counter of this.enabledCounters) { let newTxt = counter.get(); - if (!newTxt) - continue; - - ++lineCount; - txt += newTxt + "\n"; + if (newTxt) + txt += newTxt + "\n"; } + // The caption changes more often than not, but the size changes rarely. + let textSize = this.dataCounter.getTextSize(); + let size = this.dataCounter.size; + if (size.height == textSize.height && size.width == textSize.width) + return; + let height; - if (lineCount) + if (txt) { this.dataCounter.caption = txt; - // Just using the previous size for getting the size of the new text - // could lead to unneeded linebreaks. - // Therefore we set the overlay to the maximum size before reading the text size. - this.dataCounter.size = this.initSize; - let textSize = this.dataCounter.getTextSize(); - let size = this.dataCounter.size; + size.bottom = size.top + textSize.height; size.left = size.right - textSize.width; this.dataCounter.size = size; @@ -110,7 +106,7 @@ else height = 0; - this.dataCounter.hidden = !lineCount; + this.dataCounter.hidden = !txt; if (this.lastHeight != height) { Index: binaries/data/mods/public/gui/common/global.xml =================================================================== --- binaries/data/mods/public/gui/common/global.xml +++ binaries/data/mods/public/gui/common/global.xml @@ -44,6 +44,7 @@ textcolor="white" text_align="right" text_valign="top" + text_nowrap="true" sprite="color: 0 0 0 100" > Index: source/gui/CGUIText.h =================================================================== --- source/gui/CGUIText.h +++ source/gui/CGUIText.h @@ -158,13 +158,14 @@ * @param Text Text to generate CGUIText object from * @param Font Default font, notice both Default color and default font * can be changed by tags. - * @param Width Width, 0 if no word-wrapping. + * @param Width Width, if 0 no word wrapping is used. * @param BufferZone space between text and edge, and space between text and images. * @param Align Horizontal alignment (left / center / right). + * @param noWrap Disable word wrapping. * @param pObject Optional parameter for error output. Used *only* if error parsing fails, * and we need to be able to output which object the error occurred in to aid the user. */ - CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const EAlign align, const IGUIObject* pObject); + CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const EAlign align, const bool noWrap, const IGUIObject* pObject); /** * Draw this CGUIText object @@ -185,6 +186,7 @@ const IGUIObject* pObject, const SGenerateTextImages& Images, const EAlign align, + const bool noWrap, const float prelim_line_height, const float Width, const float BufferZone, @@ -212,6 +214,7 @@ void ComputeLineRange( const SGenerateTextImages& Images, + const bool noWrap, const float y, const float Width, const float prelim_line_height, @@ -222,6 +225,7 @@ const CGUI& pGUI, const CGUIString& string, const CStrIntern& Font, + const bool noWrap, const bool FirstLine, const float Width, const float width_range_to, @@ -234,6 +238,7 @@ const CGUI& pGUI, const CGUIString& string, const CStrIntern& Font, + const bool noWrap, const IGUIObject* pObject, const bool FirstLine, const float Width, Index: source/gui/CGUIText.cpp =================================================================== --- source/gui/CGUIText.cpp +++ source/gui/CGUIText.cpp @@ -60,7 +60,7 @@ m_Indentation = Size.Width + BufferZone * 2; } -CGUIText::CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const EAlign align, const IGUIObject* pObject) +CGUIText::CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const EAlign align, const bool noWrap, const IGUIObject* pObject) { if (string.m_Words.empty()) return; @@ -100,8 +100,8 @@ prelim_line_height = std::max(prelim_line_height, Feedback.m_Size.Height); // If Width is 0, then there's no word-wrapping, disable NewLine. - if (((Width != 0 && (x > Width - BufferZone || Feedback.m_NewLine)) || i == static_cast(string.m_Words.size()) - 2) && - ProcessLine(pGUI, string, Font, pObject, Images, align, prelim_line_height, Width, BufferZone, FirstLine, x, y, i, from)) + if (((Width != 0 && ((!noWrap && x > Width - BufferZone) || Feedback.m_NewLine)) || i == static_cast(string.m_Words.size()) - 2) && + ProcessLine(pGUI, string, Font, pObject, Images, align, noWrap, prelim_line_height, Width, BufferZone, FirstLine, x, y, i, from)) return; } } @@ -159,6 +159,7 @@ const CGUI& pGUI, const CGUIString& string, const CStrIntern& Font, + const bool noWrap, const bool FirstLine, const float Width, const float width_range_to, @@ -180,7 +181,7 @@ // Append X value. x += Feedback2.m_Size.Width; - if (Width != 0 && x > width_range_to && j != temp_from && !Feedback2.m_NewLine) + if (Width != 0 && !noWrap && x > width_range_to && j != temp_from && !Feedback2.m_NewLine) { // The calculated width of each word includes the space between the current // word and the next. When we're wrapping, we need subtract the width of the @@ -211,6 +212,7 @@ const IGUIObject* pObject, const SGenerateTextImages& Images, const EAlign align, + const bool noWrap, const float prelim_line_height, const float Width, const float BufferZone, @@ -225,30 +227,32 @@ from = i; float width_range_from = BufferZone; + // If we don't wrap, make sure we have enough space. float width_range_to = Width - BufferZone; - ComputeLineRange(Images, y, Width, prelim_line_height, width_range_from, width_range_to); + ComputeLineRange(Images, noWrap, y, Width, prelim_line_height, width_range_from, width_range_to); - // Reset X for the next loop + // Reset X for the next loop. x = width_range_from; CSize2D line_size; - ComputeLineSize(pGUI, string, Font, FirstLine, Width, width_range_to, i, temp_from, x, line_size); + ComputeLineSize(pGUI, string, Font, noWrap, FirstLine, Width, width_range_to, i, temp_from, x, line_size); - // Reset x once more + // Reset x once more. x = width_range_from; - // Move down, because font drawing starts from the baseline + // Move down, because font drawing starts from the baseline. y += line_size.Height; const float dx = GetLineOffset(align, width_range_from, width_range_to, line_size); - // Do the real processing now - const bool done = AssembleCalls(pGUI, string, Font, pObject, FirstLine, Width, width_range_to, dx, y, temp_from, i, x, from); + // Do the real processing now. + const bool done = AssembleCalls(pGUI, string, Font, noWrap, pObject, FirstLine, Width, width_range_to, dx, y, temp_from, i, x, from); - // Reset X + + // Reset X. x = BufferZone; - // Update dimensions + // Update dimensions. m_Size.Width = std::max(m_Size.Width, line_size.Width + BufferZone * 2); m_Size.Height = std::max(m_Size.Height, y + BufferZone); @@ -273,6 +277,7 @@ // Loop through left and right side, from and to. void CGUIText::ComputeLineRange( const SGenerateTextImages& Images, + const bool noWrap, const float y, const float Width, const float prelim_line_height, @@ -280,7 +285,7 @@ float& width_range_to) const { // Floating images are only applicable if word-wrapping is enabled. - if (Width == 0) + if (Width == 0 || noWrap) return; for (int j = 0; j < 2; ++j) @@ -333,6 +338,7 @@ const CGUI& pGUI, const CGUIString& string, const CStrIntern& Font, + const bool noWrap, const IGUIObject* pObject, const bool FirstLine, const float Width, @@ -398,12 +404,12 @@ } break; } - else if (x > width_range_to && j == temp_from) + else if (!noWrap && x > width_range_to && j == temp_from) { from = j+1; // do not break, since we want it to be added to m_TextCalls } - else if (x > width_range_to) + else if (!noWrap && x > width_range_to) { from = j; break; Index: source/gui/ObjectBases/IGUITextOwner.h =================================================================== --- source/gui/ObjectBases/IGUITextOwner.h +++ source/gui/ObjectBases/IGUITextOwner.h @@ -117,6 +117,7 @@ CGUISimpleSetting m_TextAlign; CGUISimpleSetting m_TextVAlign; + CGUISimpleSetting m_TextNoWrap; private: /** Index: source/gui/ObjectBases/IGUITextOwner.cpp =================================================================== --- source/gui/ObjectBases/IGUITextOwner.cpp +++ source/gui/ObjectBases/IGUITextOwner.cpp @@ -31,7 +31,8 @@ : m_pObject(pObject), m_GeneratedTextsValid(), m_TextAlign(&pObject, "text_align", EAlign::LEFT), - m_TextVAlign(&pObject, "text_valign", EVAlign::TOP) + m_TextVAlign(&pObject, "text_valign", EVAlign::TOP), + m_TextNoWrap(&pObject, "text_nowrap", false) { } @@ -48,7 +49,7 @@ CGUIText& IGUITextOwner::AddText(const CGUIString& Text, const CStrW& Font, const float& Width, const float& BufferZone) { // Avoids a move constructor - m_GeneratedTexts.emplace_back(m_pObject.GetGUI(), Text, Font, Width, BufferZone, m_TextAlign, &m_pObject); + m_GeneratedTexts.emplace_back(m_pObject.GetGUI(), Text, Font, Width, BufferZone, m_TextAlign, m_TextNoWrap, &m_pObject); return m_GeneratedTexts.back(); } Index: source/gui/ObjectTypes/CButton.cpp =================================================================== --- source/gui/ObjectTypes/CButton.cpp +++ source/gui/ObjectTypes/CButton.cpp @@ -51,7 +51,7 @@ { ENSURE(m_GeneratedTexts.size() == 1); - m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_CachedActualSize.GetWidth(), m_BufferZone, m_TextAlign, this); + m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_CachedActualSize.GetWidth(), m_BufferZone, m_TextAlign, m_TextNoWrap, this); CalculateTextPosition(m_CachedActualSize, m_TextPos, m_GeneratedTexts[0]); } Index: source/gui/ObjectTypes/CInput.cpp =================================================================== --- source/gui/ObjectTypes/CInput.cpp +++ source/gui/ObjectTypes/CInput.cpp @@ -603,7 +603,7 @@ void CInput::SetupGeneratedPlaceholderText() { - m_GeneratedPlaceholderText = CGUIText(m_pGUI, m_PlaceholderText, m_Font, 0, m_BufferZone, EAlign::LEFT, this); + m_GeneratedPlaceholderText = CGUIText(m_pGUI, m_PlaceholderText, m_Font, 0, m_BufferZone, EAlign::LEFT, false, this); m_GeneratedPlaceholderTextValid = true; } Index: source/gui/ObjectTypes/CText.cpp =================================================================== --- source/gui/ObjectTypes/CText.cpp +++ source/gui/ObjectTypes/CText.cpp @@ -63,7 +63,7 @@ if (m_ScrollBar && GetScrollBar(0).GetStyle()) width -= GetScrollBar(0).GetStyle()->m_Width; - m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, width, m_BufferZone, m_TextAlign, this); + m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, width, m_BufferZone, m_TextAlign, m_TextNoWrap, this); if (!m_ScrollBar) CalculateTextPosition(m_CachedActualSize, m_TextPos, m_GeneratedTexts[0]); Index: source/gui/ObjectTypes/CTooltip.cpp =================================================================== --- source/gui/ObjectTypes/CTooltip.cpp +++ source/gui/ObjectTypes/CTooltip.cpp @@ -59,7 +59,7 @@ { ENSURE(m_GeneratedTexts.size() == 1); - m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_MaxWidth, m_BufferZone, m_TextAlign, this); + m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_MaxWidth, m_BufferZone, m_TextAlign, m_TextNoWrap, this); // Position the tooltip relative to the mouse: