ddnet/src/game/client/components/tooltips.cpp

118 lines
2.6 KiB
C++
Raw Normal View History

#include "tooltips.h"
#include <game/client/render.h>
CTooltips::CTooltips()
{
2022-04-18 07:34:21 +00:00
OnReset();
}
void CTooltips::OnReset()
{
2022-04-18 07:34:21 +00:00
HoverTime = -1;
m_Tooltips.clear();
}
void CTooltips::SetActiveTooltip(CTooltip &Tooltip)
{
2022-04-18 07:34:21 +00:00
if(m_ActiveTooltip.has_value())
return;
m_ActiveTooltip.emplace(Tooltip);
HoverTime = time_get();
}
inline void CTooltips::ClearActiveTooltip()
{
2022-04-18 07:34:21 +00:00
m_ActiveTooltip.reset();
}
void CTooltips::DoToolTip(const void *pID, const CUIRect *pNearRect, const char *pText, float WidthHint)
{
2022-04-18 07:34:21 +00:00
uintptr_t ID = reinterpret_cast<uintptr_t>(pID);
const auto &it = m_Tooltips.find(ID);
if(it == m_Tooltips.end())
{
CTooltip NewTooltip = {
.m_Rect = *pNearRect,
.m_pText = pText,
.m_WidthHint = WidthHint,
};
m_Tooltips[ID] = NewTooltip;
CTooltip &Tooltip = m_Tooltips[ID];
if(UI()->MouseInside(&Tooltip.m_Rect))
{
SetActiveTooltip(Tooltip);
}
}
else
{
if(UI()->MouseInside(&it->second.m_Rect))
{
SetActiveTooltip(it->second);
}
}
}
void CTooltips::OnRender()
{
2022-04-18 07:34:21 +00:00
if(m_ActiveTooltip.has_value())
{
CTooltip &Tooltip = m_ActiveTooltip.value();
if(!UI()->MouseInside(&Tooltip.m_Rect))
{
ClearActiveTooltip();
return;
}
// Delay tooltip until 1 second passed.
if(HoverTime > time_get() - time_freq())
return;
const float MARGIN = 5.0f;
CUIRect Rect;
Rect.w = Tooltip.m_WidthHint;
if(Tooltip.m_WidthHint < 0.0f)
Rect.w = TextRender()->TextWidth(0, 14.0f, Tooltip.m_pText, -1, -1.0f) + 4.0f;
Rect.h = 30.0f;
CUIRect *pScreen = UI()->Screen();
// Try the top side.
if(Tooltip.m_Rect.y - Rect.h - MARGIN > pScreen->y)
{
Rect.x = clamp(UI()->MouseX() - Rect.w / 2.0f, MARGIN, pScreen->w - Rect.w - MARGIN);
Rect.y = Tooltip.m_Rect.y - Rect.h - MARGIN;
}
// Try the bottom side.
else if(Tooltip.m_Rect.y + Tooltip.m_Rect.h + MARGIN < pScreen->h)
{
Rect.x = clamp(UI()->MouseX() - Rect.w / 2.0f, MARGIN, pScreen->w - Rect.w - MARGIN);
Rect.y = Tooltip.m_Rect.y + Tooltip.m_Rect.h + MARGIN;
}
// Try the right side.
else if(Tooltip.m_Rect.x + Tooltip.m_Rect.w + MARGIN + Rect.w < pScreen->w)
{
Rect.x = Tooltip.m_Rect.x + Tooltip.m_Rect.w + MARGIN;
Rect.y = clamp(UI()->MouseY() - Rect.h / 2.0f, MARGIN, pScreen->h - Rect.h - MARGIN);
}
// Try the left side.
else if(Tooltip.m_Rect.x - Rect.w - MARGIN > pScreen->x)
{
Rect.x = Tooltip.m_Rect.x - Rect.w - MARGIN;
Rect.y = clamp(UI()->MouseY() - Rect.h / 2.0f, MARGIN, pScreen->h - Rect.h - MARGIN);
}
RenderTools()->DrawUIRect(&Rect, ColorRGBA(0.2, 0.2, 0.2, 0.80f), CUI::CORNER_ALL, 5.0f);
Rect.Margin(2.0f, &Rect);
UI()->DoLabel(&Rect, Tooltip.m_pText, 14.0f, TEXTALIGN_LEFT);
}
}