ddnet/src/game/client/ui.cpp

702 lines
16 KiB
C++
Raw Normal View History

2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#include "ui.h"
#include <base/math.h>
2010-05-29 07:25:38 +00:00
#include <engine/graphics.h>
#include <engine/input.h>
#include <engine/keys.h>
#include <engine/shared/config.h>
2022-03-11 16:34:48 +00:00
#include <limits>
2007-05-22 15:03:32 +00:00
2021-09-13 21:48:10 +00:00
void CUIElement::Init(CUI *pUI, int RequestedRectCount)
2020-10-12 10:29:47 +00:00
{
pUI->AddUIElement(this);
2021-09-13 21:48:10 +00:00
if(RequestedRectCount > 0)
m_vUIRects.resize(RequestedRectCount);
2020-10-12 10:29:47 +00:00
}
2021-09-13 21:48:10 +00:00
void CUIElement::InitRects(int RequestedRectCount)
2020-11-25 12:05:53 +00:00
{
dbg_assert(m_vUIRects.empty(), "UI rects can only be initialized once, create another ui element instead.");
m_vUIRects.resize(RequestedRectCount);
2021-09-13 21:48:10 +00:00
}
CUIElement::SUIElementRect::SUIElementRect() { Reset(); }
void CUIElement::SUIElementRect::Reset()
{
m_UIRectQuadContainer = -1;
m_UITextContainer = -1;
m_X = -1;
m_Y = -1;
m_Width = -1;
m_Height = -1;
m_Text.clear();
2020-11-25 12:05:53 +00:00
mem_zero(&m_Cursor, sizeof(m_Cursor));
2021-09-13 21:48:10 +00:00
m_TextColor.Set(-1, -1, -1, -1);
m_TextOutlineColor.Set(-1, -1, -1, -1);
m_QuadColor = ColorRGBA(-1, -1, -1, -1);
2020-11-25 12:05:53 +00:00
}
2007-05-22 15:03:32 +00:00
/********************************************************
UI
2007-05-22 15:03:32 +00:00
*********************************************************/
2009-10-27 14:38:53 +00:00
2021-12-03 18:49:22 +00:00
float CUI::ms_FontmodHeight = 0.8f;
void CUI::Init(IInput *pInput, IGraphics *pGraphics, ITextRender *pTextRender)
{
m_pInput = pInput;
m_pGraphics = pGraphics;
m_pTextRender = pTextRender;
}
2009-10-27 14:38:53 +00:00
CUI::CUI()
{
m_Enabled = true;
2009-10-27 14:38:53 +00:00
m_pHotItem = 0;
m_pActiveItem = 0;
m_pLastActiveItem = 0;
m_pBecomingHotItem = 0;
2022-04-07 07:46:02 +00:00
m_pActiveTooltipItem = 0;
2009-10-27 14:38:53 +00:00
m_MouseX = 0;
m_MouseY = 0;
m_MouseWorldX = 0;
m_MouseWorldY = 0;
m_MouseButtons = 0;
m_LastMouseButtons = 0;
2009-10-27 14:38:53 +00:00
m_Screen.x = 0;
m_Screen.y = 0;
m_Screen.w = 848.0f;
m_Screen.h = 480.0f;
}
2020-10-12 10:29:47 +00:00
CUI::~CUI()
{
for(CUIElement *&pEl : m_vpOwnUIElements)
2020-10-12 10:29:47 +00:00
{
delete pEl;
}
m_vpOwnUIElements.clear();
2020-10-12 10:29:47 +00:00
}
2021-09-13 21:48:10 +00:00
CUIElement *CUI::GetNewUIElement(int RequestedRectCount)
2020-10-12 10:29:47 +00:00
{
2021-09-13 21:48:10 +00:00
CUIElement *pNewEl = new CUIElement(this, RequestedRectCount);
2020-10-12 10:29:47 +00:00
m_vpOwnUIElements.push_back(pNewEl);
2020-10-12 10:29:47 +00:00
return pNewEl;
}
void CUI::AddUIElement(CUIElement *pElement)
{
m_vpUIElements.push_back(pElement);
2020-10-12 10:29:47 +00:00
}
void CUI::ResetUIElement(CUIElement &UIElement)
{
for(CUIElement::SUIElementRect &Rect : UIElement.m_vUIRects)
2020-10-12 10:29:47 +00:00
{
if(Rect.m_UIRectQuadContainer != -1)
Graphics()->DeleteQuadContainer(Rect.m_UIRectQuadContainer);
Rect.m_UIRectQuadContainer = -1;
if(Rect.m_UITextContainer != -1)
TextRender()->DeleteTextContainer(Rect.m_UITextContainer);
Rect.m_UITextContainer = -1;
2021-09-13 21:48:10 +00:00
Rect.Reset();
}
2020-10-12 10:29:47 +00:00
}
void CUI::OnElementsReset()
{
for(CUIElement *pEl : m_vpUIElements)
2020-10-12 10:29:47 +00:00
{
ResetUIElement(*pEl);
}
}
void CUI::OnWindowResize()
{
OnElementsReset();
}
void CUI::OnLanguageChange()
{
OnElementsReset();
}
void CUI::Update(float MouseX, float MouseY, float MouseWorldX, float MouseWorldY)
2007-05-22 15:03:32 +00:00
{
unsigned MouseButtons = 0;
if(Enabled())
{
if(Input()->KeyIsPressed(KEY_MOUSE_1))
MouseButtons |= 1;
if(Input()->KeyIsPressed(KEY_MOUSE_2))
MouseButtons |= 2;
if(Input()->KeyIsPressed(KEY_MOUSE_3))
MouseButtons |= 4;
}
m_MouseDeltaX = MouseX - m_MouseX;
m_MouseDeltaY = MouseY - m_MouseY;
m_MouseX = MouseX;
m_MouseY = MouseY;
m_MouseWorldX = MouseWorldX;
m_MouseWorldY = MouseWorldY;
m_LastMouseButtons = m_MouseButtons;
m_MouseButtons = MouseButtons;
m_pHotItem = m_pBecomingHotItem;
if(m_pActiveItem)
m_pHotItem = m_pActiveItem;
m_pBecomingHotItem = 0;
2007-05-22 15:03:32 +00:00
}
2009-10-27 14:38:53 +00:00
2021-11-26 20:55:31 +00:00
bool CUI::MouseInside(const CUIRect *pRect) const
2007-05-22 15:03:32 +00:00
{
2021-11-26 20:55:31 +00:00
return pRect->Inside(m_MouseX, m_MouseY);
2007-05-22 15:03:32 +00:00
}
void CUI::ConvertMouseMove(float *x, float *y) const
{
float Fac = (float)(g_Config.m_UiMousesens) / g_Config.m_InpMousesens;
*x = *x * Fac;
*y = *y * Fac;
}
2021-11-26 20:55:31 +00:00
float CUI::ButtonColorMul(const void *pID)
{
if(CheckActiveItem(pID))
2021-11-26 20:55:31 +00:00
return ButtonColorMulActive();
else if(HotItem() == pID)
return ButtonColorMulHot();
return ButtonColorMulDefault();
}
2009-10-27 14:38:53 +00:00
CUIRect *CUI::Screen()
2007-05-22 15:03:32 +00:00
{
float Aspect = Graphics()->ScreenAspect();
float w, h;
2007-05-22 15:03:32 +00:00
h = 600;
w = Aspect * h;
2007-05-22 15:03:32 +00:00
m_Screen.w = w;
m_Screen.h = h;
2007-05-27 18:14:24 +00:00
return &m_Screen;
2007-05-22 15:03:32 +00:00
}
2021-09-22 19:48:55 +00:00
void CUI::MapScreen()
{
const CUIRect *pScreen = Screen();
Graphics()->MapScreen(pScreen->x, pScreen->y, pScreen->w, pScreen->h);
}
float CUI::PixelSize()
{
return Screen()->w / Graphics()->ScreenWidth();
}
2009-10-27 14:38:53 +00:00
void CUI::SetScale(float s)
2007-10-29 18:40:04 +00:00
{
g_Config.m_UiScale = (int)(s * 100.0f);
2007-10-29 18:40:04 +00:00
}
float CUI::Scale() const
2007-10-29 18:40:04 +00:00
{
return g_Config.m_UiScale / 100.0f;
}
float CUIRect::Scale() const
{
return g_Config.m_UiScale / 100.0f;
}
2007-10-29 18:40:04 +00:00
void CUI::ClipEnable(const CUIRect *pRect)
2007-10-29 18:40:04 +00:00
{
2022-05-13 18:20:04 +00:00
if(IsClipped())
{
const CUIRect *pOldRect = ClipArea();
CUIRect Intersection;
Intersection.x = std::max(pRect->x, pOldRect->x);
Intersection.y = std::max(pRect->y, pOldRect->y);
Intersection.w = std::min(pRect->x + pRect->w, pOldRect->x + pOldRect->w) - pRect->x;
Intersection.h = std::min(pRect->y + pRect->h, pOldRect->y + pOldRect->h) - pRect->y;
m_vClips.push_back(Intersection);
2022-05-13 18:20:04 +00:00
}
else
{
m_vClips.push_back(*pRect);
2022-05-13 18:20:04 +00:00
}
UpdateClipping();
2007-10-29 18:40:04 +00:00
}
2009-10-27 14:38:53 +00:00
void CUI::ClipDisable()
2007-10-29 18:40:04 +00:00
{
2022-05-13 18:20:04 +00:00
dbg_assert(IsClipped(), "no clip region");
m_vClips.pop_back();
2022-05-13 18:20:04 +00:00
UpdateClipping();
}
const CUIRect *CUI::ClipArea() const
{
dbg_assert(IsClipped(), "no clip region");
return &m_vClips.back();
2022-05-13 18:20:04 +00:00
}
void CUI::UpdateClipping()
{
if(IsClipped())
{
const CUIRect *pRect = ClipArea();
const float XScale = Graphics()->ScreenWidth() / Screen()->w;
const float YScale = Graphics()->ScreenHeight() / Screen()->h;
Graphics()->ClipEnable((int)(pRect->x * XScale), (int)(pRect->y * YScale), (int)(pRect->w * XScale), (int)(pRect->h * YScale));
}
else
{
Graphics()->ClipDisable();
}
2007-10-29 18:40:04 +00:00
}
void CUIRect::HSplitMid(CUIRect *pTop, CUIRect *pBottom, float Spacing) const
2011-03-26 15:19:37 +00:00
{
CUIRect r = *this;
const float Cut = r.h / 2;
const float HalfSpacing = Spacing / 2;
if(pTop)
{
pTop->x = r.x;
pTop->y = r.y;
pTop->w = r.w;
pTop->h = Cut - HalfSpacing;
}
if(pBottom)
{
pBottom->x = r.x;
pBottom->y = r.y + Cut + HalfSpacing;
pBottom->w = r.w;
pBottom->h = r.h - Cut - HalfSpacing;
}
2011-03-26 15:19:37 +00:00
}
2010-05-29 07:25:38 +00:00
void CUIRect::HSplitTop(float Cut, CUIRect *pTop, CUIRect *pBottom) const
2007-10-29 18:40:04 +00:00
{
CUIRect r = *this;
Cut *= Scale();
if(pTop)
{
pTop->x = r.x;
pTop->y = r.y;
pTop->w = r.w;
pTop->h = Cut;
}
if(pBottom)
{
pBottom->x = r.x;
pBottom->y = r.y + Cut;
pBottom->w = r.w;
pBottom->h = r.h - Cut;
}
2007-10-29 18:40:04 +00:00
}
2010-05-29 07:25:38 +00:00
void CUIRect::HSplitBottom(float Cut, CUIRect *pTop, CUIRect *pBottom) const
2007-10-29 18:40:04 +00:00
{
CUIRect r = *this;
Cut *= Scale();
if(pTop)
{
pTop->x = r.x;
pTop->y = r.y;
pTop->w = r.w;
pTop->h = r.h - Cut;
}
if(pBottom)
{
pBottom->x = r.x;
pBottom->y = r.y + r.h - Cut;
pBottom->w = r.w;
pBottom->h = Cut;
}
2007-10-29 18:40:04 +00:00
}
void CUIRect::VSplitMid(CUIRect *pLeft, CUIRect *pRight, float Spacing) const
2007-10-29 18:40:04 +00:00
{
CUIRect r = *this;
const float Cut = r.w / 2;
const float HalfSpacing = Spacing / 2;
if(pLeft)
{
pLeft->x = r.x;
pLeft->y = r.y;
pLeft->w = Cut - HalfSpacing;
pLeft->h = r.h;
}
if(pRight)
{
pRight->x = r.x + Cut + HalfSpacing;
pRight->y = r.y;
pRight->w = r.w - Cut - HalfSpacing;
pRight->h = r.h;
}
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
void CUIRect::VSplitLeft(float Cut, CUIRect *pLeft, CUIRect *pRight) const
2008-01-12 12:27:55 +00:00
{
CUIRect r = *this;
Cut *= Scale();
if(pLeft)
{
pLeft->x = r.x;
pLeft->y = r.y;
pLeft->w = Cut;
pLeft->h = r.h;
}
if(pRight)
{
pRight->x = r.x + Cut;
pRight->y = r.y;
pRight->w = r.w - Cut;
pRight->h = r.h;
}
2007-10-29 18:40:04 +00:00
}
2010-05-29 07:25:38 +00:00
void CUIRect::VSplitRight(float Cut, CUIRect *pLeft, CUIRect *pRight) const
2007-10-29 18:40:04 +00:00
{
CUIRect r = *this;
Cut *= Scale();
if(pLeft)
{
pLeft->x = r.x;
pLeft->y = r.y;
pLeft->w = r.w - Cut;
pLeft->h = r.h;
}
if(pRight)
{
pRight->x = r.x + r.w - Cut;
pRight->y = r.y;
pRight->w = Cut;
pRight->h = r.h;
}
2008-01-12 12:27:55 +00:00
}
2007-10-29 18:40:04 +00:00
2010-05-29 07:25:38 +00:00
void CUIRect::Margin(float Cut, CUIRect *pOtherRect) const
2008-01-12 12:27:55 +00:00
{
CUIRect r = *this;
2010-05-29 07:25:38 +00:00
Cut *= Scale();
2008-01-12 12:27:55 +00:00
pOtherRect->x = r.x + Cut;
pOtherRect->y = r.y + Cut;
pOtherRect->w = r.w - 2 * Cut;
pOtherRect->h = r.h - 2 * Cut;
2008-01-12 12:27:55 +00:00
}
2010-05-29 07:25:38 +00:00
void CUIRect::VMargin(float Cut, CUIRect *pOtherRect) const
2008-01-12 12:27:55 +00:00
{
CUIRect r = *this;
2010-05-29 07:25:38 +00:00
Cut *= Scale();
2008-01-12 12:27:55 +00:00
pOtherRect->x = r.x + Cut;
pOtherRect->y = r.y;
pOtherRect->w = r.w - 2 * Cut;
pOtherRect->h = r.h;
2007-10-29 18:40:04 +00:00
}
2010-05-29 07:25:38 +00:00
void CUIRect::HMargin(float Cut, CUIRect *pOtherRect) const
2007-10-29 18:40:04 +00:00
{
CUIRect r = *this;
2010-05-29 07:25:38 +00:00
Cut *= Scale();
2007-10-29 18:40:04 +00:00
pOtherRect->x = r.x;
pOtherRect->y = r.y + Cut;
pOtherRect->w = r.w;
pOtherRect->h = r.h - 2 * Cut;
2008-01-12 12:27:55 +00:00
}
bool CUIRect::Inside(float x_, float y_) const
2021-11-26 20:55:31 +00:00
{
return x_ >= this->x && x_ < this->x + this->w && y_ >= this->y && y_ < this->y + this->h;
2021-11-26 20:55:31 +00:00
}
2020-10-12 10:29:47 +00:00
int CUI::DoButtonLogic(const void *pID, int Checked, const CUIRect *pRect)
2008-01-12 12:27:55 +00:00
{
// logic
int ReturnValue = 0;
const bool Inside = MouseHovered(pRect);
static int s_ButtonUsed = -1;
2009-10-27 14:38:53 +00:00
if(CheckActiveItem(pID))
2009-10-27 14:38:53 +00:00
{
if(s_ButtonUsed >= 0 && !MouseButton(s_ButtonUsed))
2009-10-27 14:38:53 +00:00
{
if(Inside && Checked >= 0)
ReturnValue = 1 + s_ButtonUsed;
SetActiveItem(nullptr);
s_ButtonUsed = -1;
2009-10-27 14:38:53 +00:00
}
}
else if(HotItem() == pID)
{
for(int i = 0; i < 3; ++i)
2009-10-27 14:38:53 +00:00
{
if(MouseButton(i))
{
SetActiveItem(pID);
s_ButtonUsed = i;
}
2009-10-27 14:38:53 +00:00
}
}
if(Inside && !MouseButton(0) && !MouseButton(1) && !MouseButton(2))
2009-10-27 14:38:53 +00:00
SetHotItem(pID);
return ReturnValue;
2009-10-27 14:38:53 +00:00
}
int CUI::DoPickerLogic(const void *pID, const CUIRect *pRect, float *pX, float *pY)
{
if(MouseHovered(pRect))
SetHotItem(pID);
2020-12-14 00:51:31 +00:00
if(HotItem() == pID && MouseButtonClicked(0))
SetActiveItem(pID);
if(CheckActiveItem(pID) && !MouseButton(0))
SetActiveItem(nullptr);
2020-12-14 00:51:31 +00:00
if(!CheckActiveItem(pID))
return 0;
if(pX)
*pX = clamp(m_MouseX - pRect->x, 0.0f, pRect->w) / Scale();
if(pY)
*pY = clamp(m_MouseY - pRect->y, 0.0f, pRect->h) / Scale();
return 1;
}
2022-03-11 16:34:48 +00:00
float CUI::DoTextLabel(float x, float y, float w, float h, const char *pText, float Size, int Align, const SLabelProperties &LabelProps)
2008-01-12 12:27:55 +00:00
{
2020-10-06 10:25:10 +00:00
float AlignedSize = 0;
float MaxCharacterHeightInLine = 0;
2022-03-11 16:34:48 +00:00
float tw = std::numeric_limits<float>::max();
float MaxTextWidth = LabelProps.m_MaxWidth != -1 ? LabelProps.m_MaxWidth : w;
tw = TextRender()->TextWidth(0, Size, pText, -1, LabelProps.m_MaxWidth, &AlignedSize, &MaxCharacterHeightInLine);
while(tw > MaxTextWidth + 0.001f)
{
if(!LabelProps.m_EnableWidthCheck)
break;
if(Size < 4.0f)
break;
Size -= 1.0f;
tw = TextRender()->TextWidth(0, Size, pText, -1, LabelProps.m_MaxWidth, &AlignedSize, &MaxCharacterHeightInLine);
}
2021-09-13 21:48:10 +00:00
2022-03-11 16:34:48 +00:00
int Flags = TEXTFLAG_RENDER | (LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0);
2021-09-13 21:48:10 +00:00
float AlignmentVert = y + (h - AlignedSize) / 2.f;
float AlignmentHori = 0;
2022-03-11 16:34:48 +00:00
if(LabelProps.m_AlignVertically == 0)
2020-10-06 10:25:10 +00:00
{
2021-09-13 21:48:10 +00:00
AlignmentVert = y + (h - AlignedSize) / 2.f - (AlignedSize - MaxCharacterHeightInLine) / 2.f;
2020-10-06 10:25:10 +00:00
}
// if(Align == 0)
if(Align & TEXTALIGN_CENTER)
{
2021-09-13 21:48:10 +00:00
AlignmentHori = x + (w - tw) / 2.f;
2008-01-12 12:27:55 +00:00
}
// else if(Align < 0)
else if(Align & TEXTALIGN_LEFT)
{
2021-09-13 21:48:10 +00:00
AlignmentHori = x;
}
// else if(Align > 0)
else if(Align & TEXTALIGN_RIGHT)
2008-01-12 12:27:55 +00:00
{
2021-09-13 21:48:10 +00:00
AlignmentHori = x + w - tw;
2008-01-12 12:27:55 +00:00
}
2021-09-13 21:48:10 +00:00
CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, AlignmentHori, AlignmentVert, Size, Flags);
2022-03-11 16:34:48 +00:00
Cursor.m_LineWidth = (float)LabelProps.m_MaxWidth;
if(LabelProps.m_pSelCursor)
{
2022-03-11 16:34:48 +00:00
Cursor.m_CursorMode = LabelProps.m_pSelCursor->m_CursorMode;
Cursor.m_CursorCharacter = LabelProps.m_pSelCursor->m_CursorCharacter;
Cursor.m_CalculateSelectionMode = LabelProps.m_pSelCursor->m_CalculateSelectionMode;
Cursor.m_PressMouseX = LabelProps.m_pSelCursor->m_PressMouseX;
Cursor.m_PressMouseY = LabelProps.m_pSelCursor->m_PressMouseY;
Cursor.m_ReleaseMouseX = LabelProps.m_pSelCursor->m_ReleaseMouseX;
Cursor.m_ReleaseMouseY = LabelProps.m_pSelCursor->m_ReleaseMouseY;
2022-03-11 16:34:48 +00:00
Cursor.m_SelectionStart = LabelProps.m_pSelCursor->m_SelectionStart;
Cursor.m_SelectionEnd = LabelProps.m_pSelCursor->m_SelectionEnd;
}
2021-09-13 21:48:10 +00:00
TextRender()->TextEx(&Cursor, pText, -1);
2022-03-11 16:34:48 +00:00
if(LabelProps.m_pSelCursor)
{
2022-03-11 16:34:48 +00:00
*LabelProps.m_pSelCursor = Cursor;
}
2021-09-13 21:48:10 +00:00
return tw;
}
2022-03-11 16:34:48 +00:00
void CUI::DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps)
2021-09-13 21:48:10 +00:00
{
2022-03-11 16:34:48 +00:00
DoTextLabel(pRect->x, pRect->y, pRect->w, pRect->h, pText, Size, Align, LabelProps);
2007-10-29 18:40:04 +00:00
}
2022-03-11 16:34:48 +00:00
void CUI::DoLabelScaled(const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps)
{
2022-03-11 16:34:48 +00:00
DoLabel(pRect, pText, Size * Scale(), Align, LabelProps);
}
2020-10-12 10:29:47 +00:00
2022-03-11 16:34:48 +00:00
void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps, int StrLen, CTextCursor *pReadCursor)
2020-10-12 10:29:47 +00:00
{
float AlignedSize = 0;
float MaxCharacterHeightInLine = 0;
2022-03-11 16:34:48 +00:00
float tw = std::numeric_limits<float>::max();
float MaxTextWidth = LabelProps.m_MaxWidth != -1 ? LabelProps.m_MaxWidth : pRect->w;
tw = TextRender()->TextWidth(0, Size, pText, -1, LabelProps.m_MaxWidth, &AlignedSize, &MaxCharacterHeightInLine);
while(tw > MaxTextWidth + 0.001f)
{
if(!LabelProps.m_EnableWidthCheck)
break;
if(Size < 4.0f)
break;
Size -= 1.0f;
tw = TextRender()->TextWidth(0, Size, pText, -1, LabelProps.m_MaxWidth, &AlignedSize, &MaxCharacterHeightInLine);
}
2020-10-12 10:29:47 +00:00
float AlignmentVert = pRect->y + (pRect->h - AlignedSize) / 2.f;
float AlignmentHori = 0;
CTextCursor Cursor;
2022-03-11 16:34:48 +00:00
int Flags = TEXTFLAG_RENDER | (LabelProps.m_StopAtEnd ? TEXTFLAG_STOP_AT_END : 0);
2020-10-12 10:29:47 +00:00
2022-03-11 16:34:48 +00:00
if(LabelProps.m_AlignVertically == 0)
2020-10-12 10:29:47 +00:00
{
AlignmentVert = pRect->y + (pRect->h - AlignedSize) / 2.f - (AlignedSize - MaxCharacterHeightInLine) / 2.f;
}
// if(Align == 0)
if(Align & TEXTALIGN_CENTER)
2020-10-12 10:29:47 +00:00
{
AlignmentHori = pRect->x + (pRect->w - tw) / 2.f;
}
// else if(Align < 0)
else if(Align & TEXTALIGN_LEFT)
2020-10-12 10:29:47 +00:00
{
AlignmentHori = pRect->x;
}
// else if(Align > 0)
else if(Align & TEXTALIGN_RIGHT)
2020-10-12 10:29:47 +00:00
{
AlignmentHori = pRect->x + pRect->w - tw;
}
if(pReadCursor)
{
Cursor = *pReadCursor;
}
else
{
TextRender()->SetCursor(&Cursor, AlignmentHori, AlignmentVert, Size, Flags);
}
2022-03-11 16:34:48 +00:00
Cursor.m_LineWidth = LabelProps.m_MaxWidth;
2020-10-12 10:29:47 +00:00
2020-11-08 18:41:16 +00:00
RectEl.m_TextColor = TextRender()->GetTextColor();
RectEl.m_TextOutlineColor = TextRender()->GetTextOutlineColor();
2021-09-13 21:48:10 +00:00
TextRender()->TextColor(TextRender()->DefaultTextColor());
TextRender()->TextOutlineColor(TextRender()->DefaultTextOutlineColor());
RectEl.m_UITextContainer = TextRender()->CreateTextContainer(&Cursor, pText, StrLen);
TextRender()->TextColor(RectEl.m_TextColor);
TextRender()->TextOutlineColor(RectEl.m_TextOutlineColor);
RectEl.m_Cursor = Cursor;
2020-10-12 10:29:47 +00:00
}
2021-09-13 21:48:10 +00:00
void CUI::DoLabelStreamed(CUIElement::SUIElementRect &RectEl, float x, float y, float w, float h, const char *pText, float Size, int Align, float MaxWidth, int AlignVertically, bool StopAtEnd, int StrLen, CTextCursor *pReadCursor)
2020-10-12 10:29:47 +00:00
{
bool NeedsRecreate = false;
2020-11-08 18:41:16 +00:00
bool ColorChanged = RectEl.m_TextColor != TextRender()->GetTextColor() || RectEl.m_TextOutlineColor != TextRender()->GetTextOutlineColor();
2021-09-13 21:48:10 +00:00
if(RectEl.m_UITextContainer == -1 || RectEl.m_X != x || RectEl.m_Y != y || RectEl.m_Width != w || RectEl.m_Height != h || ColorChanged)
2020-10-12 10:29:47 +00:00
{
NeedsRecreate = true;
}
else
{
if(StrLen <= -1)
{
if(str_comp(RectEl.m_Text.c_str(), pText) != 0)
NeedsRecreate = true;
}
else
{
if(StrLen != (int)RectEl.m_Text.size() || str_comp_num(RectEl.m_Text.c_str(), pText, StrLen) != 0)
NeedsRecreate = true;
}
}
if(NeedsRecreate)
{
if(RectEl.m_UITextContainer != -1)
TextRender()->DeleteTextContainer(RectEl.m_UITextContainer);
RectEl.m_UITextContainer = -1;
2021-09-13 21:48:10 +00:00
RectEl.m_X = x;
RectEl.m_Y = y;
RectEl.m_Width = w;
RectEl.m_Height = h;
2020-10-12 10:29:47 +00:00
if(StrLen > 0)
RectEl.m_Text = std::string(pText, StrLen);
else if(StrLen < 0)
RectEl.m_Text = pText;
else
RectEl.m_Text.clear();
2021-09-13 21:48:10 +00:00
CUIRect TmpRect;
TmpRect.x = x;
TmpRect.y = y;
TmpRect.w = w;
TmpRect.h = h;
2022-03-11 16:34:48 +00:00
SLabelProperties Props;
Props.m_MaxWidth = MaxWidth;
Props.m_AlignVertically = AlignVertically;
Props.m_StopAtEnd = StopAtEnd;
DoLabel(RectEl, &TmpRect, pText, Size, Align, Props, StrLen, pReadCursor);
2020-10-12 10:29:47 +00:00
}
2021-09-13 21:48:10 +00:00
STextRenderColor ColorText(RectEl.m_TextColor);
STextRenderColor ColorTextOutline(RectEl.m_TextOutlineColor);
2020-10-12 10:29:47 +00:00
if(RectEl.m_UITextContainer != -1)
TextRender()->RenderTextContainer(RectEl.m_UITextContainer, &ColorText, &ColorTextOutline);
}
2021-09-13 21:48:10 +00:00
void CUI::DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, float MaxWidth, int AlignVertically, bool StopAtEnd, int StrLen, CTextCursor *pReadCursor)
{
DoLabelStreamed(RectEl, pRect->x, pRect->y, pRect->w, pRect->h, pText, Size, Align, MaxWidth, AlignVertically, StopAtEnd, StrLen, pReadCursor);
}