#include "tooltips.h" #include CTooltips::CTooltips() { OnReset(); } void CTooltips::OnReset() { HoverTime = -1; m_Tooltips.clear(); } void CTooltips::SetActiveTooltip(CTooltip &Tooltip) { if(m_ActiveTooltip.has_value()) return; m_ActiveTooltip.emplace(Tooltip); HoverTime = time_get(); } inline void CTooltips::ClearActiveTooltip() { m_ActiveTooltip.reset(); } void CTooltips::DoToolTip(const void *pID, const CUIRect *pNearRect, const char *pText, float WidthHint) { uintptr_t ID = reinterpret_cast(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() { 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); } }