From 88efebdf864baeb422cbe4d992a44ff7c99373fb Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Wed, 20 Jun 2018 21:55:39 +0100 Subject: [PATCH] Formspecs: Add tooltip element for area --- doc/lua_api.txt | 5 +++ src/gui/guiFormSpecMenu.cpp | 70 +++++++++++++++++++++++++++++-------- src/gui/guiFormSpecMenu.h | 1 + 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 2f2a921b2..c9e6e485a 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1883,6 +1883,11 @@ Elements * `` tooltip background color as `ColorString` (optional) * `` tooltip font color as `ColorString` (optional) +### `tooltip[,;,;;;]` +* Adds tooltip for an area. Other tooltips will take priority when present. +* `` tooltip background color as `ColorString` (optional) +* `` tooltip font color as `ColorString` (optional) + ### `image[,;,;]` * Show an image diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 9656af3a7..f39eb70ab 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -1605,23 +1605,54 @@ void GUIFormSpecMenu::parseListColors(parserData* data, const std::string &eleme void GUIFormSpecMenu::parseTooltip(parserData* data, const std::string &element) { std::vector parts = split(element,';'); - if (parts.size() == 2) { - std::string name = parts[0]; - m_tooltips[name] = TooltipSpec(utf8_to_wide(unescape_string(parts[1])), - m_default_tooltip_bgcolor, m_default_tooltip_color); + if (parts.size() < 2) { + errorstream << "Invalid tooltip element(" << parts.size() << "): '" + << element << "'" << std::endl; return; } - if (parts.size() == 4) { - std::string name = parts[0]; - video::SColor tmp_color1, tmp_color2; - if ( parseColorString(parts[2], tmp_color1, false) && parseColorString(parts[3], tmp_color2, false) ) { - m_tooltips[name] = TooltipSpec(utf8_to_wide(unescape_string(parts[1])), - tmp_color1, tmp_color2); - return; - } + // Get mode and check size + bool rect_mode = parts[0].find(',') != std::string::npos; + size_t base_size = rect_mode ? 3 : 2; + if (parts.size() != base_size && parts.size() != base_size + 2) { + errorstream << "Invalid tooltip element(" << parts.size() << "): '" + << element << "'" << std::endl; + return; + } + + // Read colors + video::SColor bgcolor = m_default_tooltip_bgcolor; + video::SColor color = m_default_tooltip_color; + if (parts.size() == base_size + 2 && + (!parseColorString(parts[base_size], bgcolor, false) || + !parseColorString(parts[base_size + 1], color, false))) { + errorstream << "Invalid color in tooltip element(" << parts.size() + << "): '" << element << "'" << std::endl; + return; + } + + // Make tooltip spec + std::string text = unescape_string(parts[rect_mode ? 2 : 1]); + TooltipSpec spec(utf8_to_wide(text), bgcolor, color); + + // Add tooltip + if (rect_mode) { + std::vector v_pos = split(parts[0], ','); + std::vector v_geom = split(parts[1], ','); + + MY_CHECKPOS("tooltip", 0); + MY_CHECKGEOM("tooltip", 1); + + v2s32 pos = getElementBasePos(true, &v_pos); + v2s32 geom; + geom.X = stof(v_geom[0]) * spacing.X; + geom.Y = stof(v_geom[1]) * spacing.Y; + + irr::core::rect rect(pos, pos + geom); + m_tooltip_rects.emplace_back(rect, spec); + } else { + m_tooltips[parts[0]] = spec; } - errorstream<< "Invalid tooltip element(" << parts.size() << "): '" << element << "'" << std::endl; } bool GUIFormSpecMenu::parseVersionDirect(const std::string &data) @@ -1967,6 +1998,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) m_fields.clear(); m_boxes.clear(); m_tooltips.clear(); + m_tooltip_rects.clear(); m_inventory_rings.clear(); m_static_texts.clear(); m_dropdowns.clear(); @@ -2458,6 +2490,16 @@ void GUIFormSpecMenu::drawMenu() m_tooltip_element->setVisible(false); + for (const auto &pair : m_tooltip_rects) { + if (pair.first.isPointInside(m_pointer)) { + const std::wstring &text = pair.second.tooltip; + if (!text.empty()) { + showTooltip(text, pair.second.color, pair.second.bgcolor); + break; + } + } + } + /* Draw backgrounds */ @@ -3436,7 +3478,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) count = (s_count + 1) / 2; else if (button == BET_MIDDLE) count = MYMIN(s_count, 10); - else if (button == BET_WHEEL_DOWN) + else if (button == BET_WHEEL_DOWN) count = 1; else // left count = s_count; diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h index 501b4db1b..926faa350 100644 --- a/src/gui/guiFormSpecMenu.h +++ b/src/gui/guiFormSpecMenu.h @@ -402,6 +402,7 @@ protected: std::vector > m_tables; std::vector > m_checkboxes; std::map m_tooltips; + std::vector, TooltipSpec>> m_tooltip_rects; std::vector > m_scrollbars; std::vector > > m_dropdowns; -- 2.25.1