mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Add ellipsis flag to DoLabel
, support stop-at-end with max width
Add `SLabelProperties::m_EllipsisAtEnd` to render an ellipsis when using `DoLabel`. Fix `m_StopAtEnd` and `m_EllipsisAtEnd` not working together with the automatic font scaling. Now the stop-at-end and ellipsis flags will only have an effect when the automatic font scaling has reached the minimum font size already. Add `SLabelProperties` argument to `DoLabelStreamed` and adjust usages in server browser. Font scaling now has to be disabled explicitly for the server name, gametype and map, as these should use the stop-at-end flag without the font-scaling.
This commit is contained in:
parent
ac6ee58e08
commit
0a7361090f
|
@ -205,7 +205,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE);
|
||||
TextRender()->TextColor(TextColor);
|
||||
TextRender()->TextOutlineColor(TextOutlineColor);
|
||||
UI()->DoLabelStreamed(UIRect, pRect, pText, FontSize, TextAlign, -1.0f);
|
||||
UI()->DoLabelStreamed(UIRect, pRect, pText, FontSize, TextAlign);
|
||||
TextRender()->TextOutlineColor(TextRender()->DefaultTextOutlineColor());
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
TextRender()->SetRenderFlags(0);
|
||||
|
@ -250,6 +250,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
continue;
|
||||
}
|
||||
|
||||
const float FontSize = 12.0f;
|
||||
for(int c = 0; c < NumCols; c++)
|
||||
{
|
||||
CUIRect Button;
|
||||
|
@ -285,19 +286,21 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
}
|
||||
else if(ID == COL_NAME)
|
||||
{
|
||||
float FontSize = 12.0f;
|
||||
SLabelProperties Props;
|
||||
Props.m_MaxWidth = Button.w;
|
||||
Props.m_StopAtEnd = true;
|
||||
Props.m_EnableWidthCheck = false;
|
||||
bool Printed = false;
|
||||
|
||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_SERVERNAME))
|
||||
Printed = PrintHighlighted(pItem->m_aName, [this, pItem, FontSize, &Button](const char *pFilteredStr, const int FilterLen) {
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 0), &Button, pItem->m_aName, FontSize, TEXTALIGN_ML, Button.w, true, (int)(pFilteredStr - pItem->m_aName));
|
||||
Printed = PrintHighlighted(pItem->m_aName, [this, pItem, FontSize, Props, &Button](const char *pFilteredStr, const int FilterLen) {
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 0), &Button, pItem->m_aName, FontSize, TEXTALIGN_ML, Props, (int)(pFilteredStr - pItem->m_aName));
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 1), &Button, pFilteredStr, FontSize, TEXTALIGN_ML, Button.w, true, FilterLen, &pItem->m_pUIElement->Rect(gs_OffsetColName + 0)->m_Cursor);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 1), &Button, pFilteredStr, FontSize, TEXTALIGN_ML, Props, FilterLen, &pItem->m_pUIElement->Rect(gs_OffsetColName + 0)->m_Cursor);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 2), &Button, pFilteredStr + FilterLen, FontSize, TEXTALIGN_ML, Button.w, true, -1, &pItem->m_pUIElement->Rect(gs_OffsetColName + 1)->m_Cursor);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 2), &Button, pFilteredStr + FilterLen, FontSize, TEXTALIGN_ML, Props, -1, &pItem->m_pUIElement->Rect(gs_OffsetColName + 1)->m_Cursor);
|
||||
});
|
||||
if(!Printed)
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName), &Button, pItem->m_aName, FontSize, TEXTALIGN_ML, Button.w, true);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName), &Button, pItem->m_aName, FontSize, TEXTALIGN_ML, Props);
|
||||
}
|
||||
else if(ID == COL_MAP)
|
||||
{
|
||||
|
@ -314,18 +317,21 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
}
|
||||
}
|
||||
|
||||
float FontSize = 12.0f;
|
||||
SLabelProperties Props;
|
||||
Props.m_MaxWidth = Button.w;
|
||||
Props.m_StopAtEnd = true;
|
||||
Props.m_EnableWidthCheck = false;
|
||||
bool Printed = false;
|
||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_MAPNAME))
|
||||
Printed = PrintHighlighted(pItem->m_aMap, [this, pItem, FontSize, &Button](const char *pFilteredStr, const int FilterLen) {
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 0), &Button, pItem->m_aMap, FontSize, TEXTALIGN_ML, Button.w, true, (int)(pFilteredStr - pItem->m_aMap));
|
||||
Printed = PrintHighlighted(pItem->m_aMap, [this, pItem, FontSize, Props, &Button](const char *pFilteredStr, const int FilterLen) {
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 0), &Button, pItem->m_aMap, FontSize, TEXTALIGN_ML, Props, (int)(pFilteredStr - pItem->m_aMap));
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 1), &Button, pFilteredStr, FontSize, TEXTALIGN_ML, Button.w, true, FilterLen, &pItem->m_pUIElement->Rect(gs_OffsetColMap + 0)->m_Cursor);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 1), &Button, pFilteredStr, FontSize, TEXTALIGN_ML, Props, FilterLen, &pItem->m_pUIElement->Rect(gs_OffsetColMap + 0)->m_Cursor);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 2), &Button, pFilteredStr + FilterLen, FontSize, TEXTALIGN_ML, Button.w, true, -1, &pItem->m_pUIElement->Rect(gs_OffsetColMap + 1)->m_Cursor);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 2), &Button, pFilteredStr + FilterLen, FontSize, TEXTALIGN_ML, Props, -1, &pItem->m_pUIElement->Rect(gs_OffsetColMap + 1)->m_Cursor);
|
||||
});
|
||||
if(!Printed)
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap), &Button, pItem->m_aMap, FontSize, TEXTALIGN_ML, Button.w, true);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap), &Button, pItem->m_aMap, FontSize, TEXTALIGN_ML, Props);
|
||||
}
|
||||
else if(ID == COL_PLAYERS)
|
||||
{
|
||||
|
@ -350,8 +356,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
str_format(aTemp, sizeof(aTemp), "%i/%i", pItem->m_NumFilteredPlayers, ServerBrowser()->Max(*pItem));
|
||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_PLAYER))
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||
float FontSize = 12.0f;
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColPlayers), &Button, aTemp, FontSize, TEXTALIGN_MR, -1.0f, false);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColPlayers), &Button, aTemp, FontSize, TEXTALIGN_MR);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
}
|
||||
else if(ID == COL_PING)
|
||||
|
@ -364,20 +369,20 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
TextRender()->TextColor(rgb);
|
||||
}
|
||||
|
||||
float FontSize = 12.0f;
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColPing), &Button, aTemp, FontSize, TEXTALIGN_MR, -1.0f, false);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColPing), &Button, aTemp, FontSize, TEXTALIGN_MR);
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
else if(ID == COL_VERSION)
|
||||
{
|
||||
const char *pVersion = pItem->m_aVersion;
|
||||
float FontSize = 12.0f;
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColVersion), &Button, pVersion, FontSize, TEXTALIGN_MR, -1.0f, false);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColVersion), &Button, pVersion, FontSize, TEXTALIGN_MR);
|
||||
}
|
||||
else if(ID == COL_GAMETYPE)
|
||||
{
|
||||
float FontSize = 12.0f;
|
||||
|
||||
SLabelProperties Props;
|
||||
Props.m_MaxWidth = Button.w;
|
||||
Props.m_StopAtEnd = true;
|
||||
Props.m_EnableWidthCheck = false;
|
||||
if(g_Config.m_UiColorizeGametype)
|
||||
{
|
||||
ColorHSLA hsl = ColorHSLA(1.0f, 1.0f, 1.0f);
|
||||
|
@ -405,11 +410,11 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
|
||||
ColorRGBA rgb = color_cast<ColorRGBA>(hsl);
|
||||
TextRender()->TextColor(rgb);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, TEXTALIGN_ML, Button.w, true);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, TEXTALIGN_ML, Props);
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
else
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, TEXTALIGN_ML, Button.w, true);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, TEXTALIGN_ML, Props);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -580,24 +580,33 @@ struct SCursorAndBoundingBox
|
|||
|
||||
static SCursorAndBoundingBox CalcFontSizeCursorHeightAndBoundingBox(ITextRender *pTextRender, const char *pText, int Flags, float &Size, float MaxWidth, const SLabelProperties &LabelProps)
|
||||
{
|
||||
const float MinFontSize = 5.0f;
|
||||
const float MaxTextWidth = LabelProps.m_MaxWidth != -1.0f ? LabelProps.m_MaxWidth : MaxWidth;
|
||||
const int FlagsWithoutStop = Flags & ~(TEXTFLAG_STOP_AT_END | TEXTFLAG_ELLIPSIS_AT_END);
|
||||
const float MaxTextWidthWithoutStop = Flags == FlagsWithoutStop ? LabelProps.m_MaxWidth : -1.0f;
|
||||
|
||||
float TextBoundingHeight = 0.0f;
|
||||
float TextHeight = 0.0f;
|
||||
int LineCount = 0;
|
||||
float MaxTextWidth = LabelProps.m_MaxWidth != -1 ? LabelProps.m_MaxWidth : MaxWidth;
|
||||
STextSizeProperties TextSizeProps{};
|
||||
TextSizeProps.m_pHeight = &TextHeight;
|
||||
TextSizeProps.m_pMaxCharacterHeightInLine = &TextBoundingHeight;
|
||||
TextSizeProps.m_pLineCount = &LineCount;
|
||||
float TextWidth = pTextRender->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, Flags, TextSizeProps);
|
||||
while(TextWidth > MaxTextWidth + 0.001f)
|
||||
|
||||
float TextWidth;
|
||||
do
|
||||
{
|
||||
if(!LabelProps.m_EnableWidthCheck)
|
||||
Size = maximum(Size, MinFontSize);
|
||||
// Only consider stop-at-end and ellipsis-at-end when minimum font size reached or font scaling disabled
|
||||
if((Size == MinFontSize || !LabelProps.m_EnableWidthCheck) && Flags != FlagsWithoutStop)
|
||||
TextWidth = pTextRender->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, Flags, TextSizeProps);
|
||||
else
|
||||
TextWidth = pTextRender->TextWidth(Size, pText, -1, MaxTextWidthWithoutStop, FlagsWithoutStop, TextSizeProps);
|
||||
if(TextWidth <= MaxTextWidth + 0.001f || !LabelProps.m_EnableWidthCheck || Size == MinFontSize)
|
||||
break;
|
||||
if(Size < 4.0f)
|
||||
break;
|
||||
Size -= 1.0f;
|
||||
TextWidth = pTextRender->TextWidth(Size, pText, -1, LabelProps.m_MaxWidth, Flags, TextSizeProps);
|
||||
}
|
||||
Size--;
|
||||
} while(true);
|
||||
|
||||
SCursorAndBoundingBox Res{};
|
||||
Res.m_TextSize = vec2(TextWidth, TextHeight);
|
||||
Res.m_BiggestCharacterHeight = TextBoundingHeight;
|
||||
|
@ -605,6 +614,17 @@ static SCursorAndBoundingBox CalcFontSizeCursorHeightAndBoundingBox(ITextRender
|
|||
return Res;
|
||||
}
|
||||
|
||||
static int GetFlagsForLabelProperties(const SLabelProperties &LabelProps, const CTextCursor *pReadCursor)
|
||||
{
|
||||
if(pReadCursor != nullptr)
|
||||
return pReadCursor->m_Flags & ~TEXTFLAG_RENDER;
|
||||
|
||||
int Flags = 0;
|
||||
Flags |= LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0;
|
||||
Flags |= LabelProps.m_EllipsisAtEnd ? TEXTFLAG_ELLIPSIS_AT_END : 0;
|
||||
return Flags;
|
||||
}
|
||||
|
||||
vec2 CUI::CalcAlignedCursorPos(const CUIRect *pRect, vec2 TextSize, int Align, const float *pBiggestCharHeight)
|
||||
{
|
||||
vec2 Cursor(pRect->x, pRect->y);
|
||||
|
@ -634,7 +654,7 @@ vec2 CUI::CalcAlignedCursorPos(const CUIRect *pRect, vec2 TextSize, int Align, c
|
|||
|
||||
void CUI::DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps)
|
||||
{
|
||||
const int Flags = LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0;
|
||||
const int Flags = GetFlagsForLabelProperties(LabelProps, nullptr);
|
||||
const SCursorAndBoundingBox TextBounds = CalcFontSizeCursorHeightAndBoundingBox(TextRender(), pText, Flags, Size, pRect->w, LabelProps);
|
||||
const vec2 CursorPos = CalcAlignedCursorPos(pRect, TextBounds.m_TextSize, Align, TextBounds.m_LineCount == 1 ? &TextBounds.m_BiggestCharacterHeight : nullptr);
|
||||
|
||||
|
@ -646,7 +666,7 @@ void CUI::DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align
|
|||
|
||||
void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps, int StrLen, const CTextCursor *pReadCursor)
|
||||
{
|
||||
const int Flags = pReadCursor ? (pReadCursor->m_Flags & ~TEXTFLAG_RENDER) : LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0;
|
||||
const int Flags = GetFlagsForLabelProperties(LabelProps, pReadCursor);
|
||||
const SCursorAndBoundingBox TextBounds = CalcFontSizeCursorHeightAndBoundingBox(TextRender(), pText, Flags, Size, pRect->w, LabelProps);
|
||||
|
||||
CTextCursor Cursor;
|
||||
|
@ -671,7 +691,7 @@ void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, cons
|
|||
RectEl.m_Cursor = Cursor;
|
||||
}
|
||||
|
||||
void CUI::DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, float MaxWidth, bool StopAtEnd, int StrLen, const CTextCursor *pReadCursor)
|
||||
void CUI::DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps, int StrLen, const CTextCursor *pReadCursor)
|
||||
{
|
||||
bool NeedsRecreate = false;
|
||||
bool ColorChanged = RectEl.m_TextColor != TextRender()->GetTextColor() || RectEl.m_TextOutlineColor != TextRender()->GetTextOutlineColor();
|
||||
|
@ -714,10 +734,7 @@ void CUI::DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRe
|
|||
TmpRect.w = pRect->w;
|
||||
TmpRect.h = pRect->h;
|
||||
|
||||
SLabelProperties Props;
|
||||
Props.m_MaxWidth = MaxWidth;
|
||||
Props.m_StopAtEnd = StopAtEnd;
|
||||
DoLabel(RectEl, &TmpRect, pText, Size, TEXTALIGN_TL, Props, StrLen, pReadCursor);
|
||||
DoLabel(RectEl, &TmpRect, pText, Size, TEXTALIGN_TL, LabelProps, StrLen, pReadCursor);
|
||||
}
|
||||
|
||||
ColorRGBA ColorText(RectEl.m_TextColor);
|
||||
|
|
|
@ -193,6 +193,7 @@ struct SLabelProperties
|
|||
{
|
||||
float m_MaxWidth = -1;
|
||||
bool m_StopAtEnd = false;
|
||||
bool m_EllipsisAtEnd = false;
|
||||
bool m_EnableWidthCheck = true;
|
||||
};
|
||||
|
||||
|
@ -488,7 +489,7 @@ public:
|
|||
void DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps = {});
|
||||
|
||||
void DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps = {}, int StrLen = -1, const CTextCursor *pReadCursor = nullptr);
|
||||
void DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, float MaxWidth = -1, bool StopAtEnd = false, int StrLen = -1, const CTextCursor *pReadCursor = nullptr);
|
||||
void DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps = {}, int StrLen = -1, const CTextCursor *pReadCursor = nullptr);
|
||||
|
||||
bool DoEditBox(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, int Corners = IGraphics::CORNER_ALL);
|
||||
bool DoClearableEditBox(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, int Corners = IGraphics::CORNER_ALL);
|
||||
|
|
Loading…
Reference in a new issue