1
0
forked from 0ad/0ad

Generalize icon-specific tooltips to a tag, streamline code.

We can currently specify a custom tooltip for an icon. This extends that
to a generic tag `[tooltip='something']...[/tooltip]` for any particular
piece of text, and removes the iconTooltip hardcoding by instead using a
virtual `GetTooltipText` call since all IGUIObject descendants have a
tooltip. This is both cleaner & more efficient.
Removes the ability to set a custom tooltip style (that doesn't seem
particularly useful), it'll reuse the style of the CText itself.

Differential Revision: https://code.wildfiregames.com/D3895
This was SVN commit r25353.
This commit is contained in:
wraitii 2021-05-01 12:38:05 +00:00
parent 9107d6d8c7
commit d9748173c7
12 changed files with 61 additions and 101 deletions

View File

@ -390,10 +390,18 @@ bool CGUIText::AssembleCalls(
// Sprite call can exist within only a newline segment,
// therefore we need this.
m_SpriteCalls.insert(
m_SpriteCalls.end(),
std::make_move_iterator(Feedback2.m_SpriteCalls.begin()),
std::make_move_iterator(Feedback2.m_SpriteCalls.end()));
if (!Feedback2.m_SpriteCalls.empty())
{
auto newEnd = std::remove_if(Feedback2.m_TextCalls.begin(), Feedback2.m_TextCalls.end(), [](const STextCall& call) { return !call.m_pSpriteCall; });
m_TextCalls.insert(
m_TextCalls.end(),
std::make_move_iterator(Feedback2.m_TextCalls.begin()),
std::make_move_iterator(newEnd));
m_SpriteCalls.insert(
m_SpriteCalls.end(),
std::make_move_iterator(Feedback2.m_SpriteCalls.begin()),
std::make_move_iterator(Feedback2.m_SpriteCalls.end()));
}
break;
}
else if (x > width_range_to && j == temp_from)

View File

@ -75,16 +75,6 @@ public:
* Sprite from global GUI sprite database.
*/
CGUISpriteInstance m_Sprite;
/**
* Tooltip text
*/
CStrW m_Tooltip;
/**
* Tooltip style
*/
CStrW m_TooltipStyle;
};
/**
@ -136,6 +126,11 @@ public:
*/
bool m_Bold, m_Italic, m_Underlined;
/**
* Tooltip text
*/
CStrW m_Tooltip;
/**
* *IF* an icon, then this is not nullptr.
*/

View File

@ -83,31 +83,16 @@ const double CooldownTime = 0.25; // TODO: Don't hard-code this value
bool GUITooltip::GetTooltip(IGUIObject* obj, CStr& style)
{
if (obj && obj->SettingExists("_icon_tooltip_style") && obj->MouseOverIcon())
{
style = obj->GetSetting<CStr>("_icon_tooltip_style");
if (!obj->GetSetting<CStrW>("_icon_tooltip").empty())
{
if (style.empty())
style = "default";
m_IsIconTooltip = true;
return true;
}
}
if (!obj)
return false;
if (obj && obj->SettingExists("tooltip_style"))
{
style = obj->GetSetting<CStr>("tooltip_style");
if (!obj->GetSetting<CStrW>("tooltip").empty())
{
if (style.empty())
style = "default";
m_IsIconTooltip = false;
return true;
}
}
if (obj->GetTooltipText().empty())
return false;
return false;
style = obj->GetTooltipStyle();
if (style.empty())
style = "default";
return true;
}
void GUITooltip::ShowTooltip(IGUIObject* obj, const CVector2D& pos, const CStr& style, CGUI& pGUI)
@ -154,7 +139,7 @@ void GUITooltip::ShowTooltip(IGUIObject* obj, const CVector2D& pos, const CStr&
if (usedobj->SettingExists("caption"))
{
const CStrW& text = obj->GetSetting<CStrW>(m_IsIconTooltip ? "_icon_tooltip" : "tooltip");
const CStrW& text = obj->GetTooltipText();
usedobj->SetSettingFromString("caption", text, true);
}
else
@ -271,12 +256,14 @@ void GUITooltip::Update(IGUIObject* Nearest, const CVector2D& MousePos, CGUI& GU
break;
case ST_SHOWING:
// Handle special case of icon tooltips
if (Nearest == m_PreviousObject && (!m_IsIconTooltip || Nearest->MouseOverIcon()))
// Handle sub-object tooltips.
if (Nearest == m_PreviousObject)
{
// Still showing the same object's tooltip, but the text might have changed
if (GetTooltip(Nearest, style))
ShowTooltip(Nearest, MousePos, style, GUI);
else
nextstate = ST_COOLING;
}
else
{

View File

@ -44,7 +44,6 @@ private:
CStr m_PreviousTooltipName;
CVector2D m_PreviousMousePos;
double m_Time;
bool m_IsIconTooltip;
};
#endif // INCLUDED_GUITOOLTIP

View File

@ -181,11 +181,6 @@ bool IGUIObject::IsMouseOver() const
return m_CachedActualSize.PointInside(m_pGUI.GetMousePos());
}
bool IGUIObject::MouseOverIcon()
{
return false;
}
void IGUIObject::UpdateMouseOver(IGUIObject* const& pMouseOver)
{
if (pMouseOver == this)

View File

@ -86,11 +86,6 @@ public:
*/
virtual bool IsMouseHovering() const { return m_MouseHovering; }
/**
* Test if mouse position is over an icon
*/
virtual bool MouseOverIcon();
//--------------------------------------------------------
/** @name Leaf Functions */
//--------------------------------------------------------
@ -220,6 +215,9 @@ public:
*/
CRect GetComputedSize();
virtual const CStrW& GetTooltipText() const { return m_Tooltip; }
virtual const CStr& GetTooltipStyle() const { return m_TooltipStyle; }
/**
* Reset internal state of this object.
*/

View File

@ -59,8 +59,7 @@ void IGUITextOwner::HandleMessage(SGUIMessage& Message)
// it is assumed that the text of the object will be dependent on
// these. Although that is not certain, but one will have to manually
// change it and disregard this function.
// TODO Gee: (2004-09-07) Make sure this is all options that can affect the text.
if (Message.value == "size" || Message.value == "z" ||
if (Message.value == "size" || Message.value == "tooltip" ||
Message.value == "absolute" || Message.value == "caption" ||
Message.value == "font" || Message.value == "textcolor" ||
Message.value == "text_align" || Message.value == "text_valign" ||
@ -122,8 +121,3 @@ void IGUITextOwner::CalculateTextPosition(CRect& ObjSize, CVector2D& TextPos, CG
break;
}
}
bool IGUITextOwner::MouseOverIcon()
{
return false;
}

View File

@ -86,11 +86,6 @@ public:
*/
virtual void DrawText(size_t index, const CGUIColor& color, const CVector2D& pos, float z, const CRect& clipping = CRect());
/**
* Test if mouse position is over an icon
*/
virtual bool MouseOverIcon();
protected:
/**
* Setup texts. Functions that sets up all texts when changes have been made.

View File

@ -40,9 +40,7 @@ CText::CText(CGUI& pGUI)
m_TextAlign(),
m_TextVAlign(),
m_TextColor(),
m_TextColorDisabled(),
m_IconTooltip(),
m_IconTooltipStyle()
m_TextColorDisabled()
{
RegisterSetting("buffer_zone", m_BufferZone);
RegisterSetting("caption", m_Caption);
@ -57,9 +55,6 @@ CText::CText(CGUI& pGUI)
RegisterSetting("text_valign", m_TextVAlign);
RegisterSetting("textcolor", m_TextColor);
RegisterSetting("textcolor_disabled", m_TextColorDisabled);
// Private settings
RegisterSetting("_icon_tooltip", m_IconTooltip);
RegisterSetting("_icon_tooltip_style", m_IconTooltipStyle);
//SetSetting<bool>("ghost", true, true);
SetSetting<bool>("scrollbar", false, true);
@ -138,6 +133,20 @@ CSize2D CText::GetTextSize()
return m_GeneratedTexts[0].GetSize();
}
const CStrW& CText::GetTooltipText() const
{
for (const CGUIText& text : m_GeneratedTexts)
for (const CGUIText::STextCall& textChunk : text.GetTextCalls())
{
if (textChunk.m_Tooltip.empty())
continue;
CRect area(textChunk.m_Pos - CVector2D(0.f, textChunk.m_Size.Height), textChunk.m_Size);
if (area.PointInside(m_pGUI.GetMousePos() - m_CachedActualSize.TopLeft()))
return textChunk.m_Tooltip;
}
return m_Tooltip;
}
void CText::HandleMessage(SGUIMessage& Message)
{
IGUIObject::HandleMessage(Message);
@ -233,25 +242,3 @@ void CText::Draw()
else
DrawText(0, color, m_TextPos, bz + 0.1f, cliparea);
}
bool CText::MouseOverIcon()
{
for (const CGUIText& guitext : m_GeneratedTexts)
for (const CGUIText::SSpriteCall& spritecall : guitext.GetSpriteCalls())
{
// Check mouse over sprite
if (!spritecall.m_Area.PointInside(m_pGUI.GetMousePos() - m_CachedActualSize.TopLeft()))
continue;
// If tooltip exists, set the property
if (!spritecall.m_Tooltip.empty())
{
SetSettingFromString("_icon_tooltip_style", spritecall.m_TooltipStyle, true);
SetSettingFromString("_icon_tooltip", spritecall.m_Tooltip, true);
}
return true;
}
return false;
}

View File

@ -49,10 +49,7 @@ public:
*/
CSize2D GetTextSize();
/**
* Test if mouse position is over an icon
*/
virtual bool MouseOverIcon();
virtual const CStrW& GetTooltipText() const;
protected:
/**
* Sets up text, should be called every time changes has been
@ -91,8 +88,6 @@ protected:
EVAlign m_TextVAlign;
CGUIColor m_TextColor;
CGUIColor m_TextColorDisabled;
CStrW m_IconTooltip;
CStr m_IconTooltipStyle;
};
#endif // INCLUDED_CTEXT

View File

@ -153,9 +153,10 @@ void CGUIString::GenerateTextCall(const CGUI& pGUI, SFeedback& Feedback, CStrInt
SpriteCall.m_Area += displacement;
}
else if (tagAttrib.attrib == L"tooltip")
SpriteCall.m_Tooltip = tagAttrib.value;
else if (tagAttrib.attrib == L"tooltip_style")
SpriteCall.m_TooltipStyle = tagAttrib.value;
{
TextCall.m_Tooltip = tagAttrib.value;
LOGWARNING("setting tooltip to %s", TextCall.m_Tooltip.ToUTF8().c_str());
}
}
SpriteCall.m_Sprite = icon.m_SpriteName;
@ -199,6 +200,9 @@ void CGUIString::GenerateTextCall(const CGUI& pGUI, SFeedback& Feedback, CStrInt
// TODO Gee: (2004-08-15) Check if Font exists?
TextCall.m_Font = CStrIntern(utf8_from_wstring(tag.m_TagValue));
break;
case TextChunk::Tag::TAG_TOOLTIP:
TextCall.m_Tooltip = tag.m_TagValue;
break;
default:
LOGERROR("Encountered unexpected tag applied to text");
break;
@ -256,6 +260,8 @@ CGUIString::TextChunk::Tag::TagType CGUIString::TextChunk::Tag::GetTagType(const
return TAG_IMGLEFT;
if (tagtype == L"imgright")
return TAG_IMGRIGHT;
if (tagtype == L"tooltip")
return TAG_TOOLTIP;
return TAG_INVALID;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -66,6 +66,7 @@ public:
TAG_IMGLEFT,
TAG_IMGRIGHT,
TAG_ICON,
TAG_TOOLTIP,
TAG_INVALID
};