From 27538ecef51ebcc7622f13956d2f8e101d0f71a7 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Tue, 24 Jun 2014 12:28:24 +0200 Subject: Tooltips rework. Separate element for tooltips. Delayed showing, use global color or given ones. --- src/guiFormSpecMenu.cpp | 127 +++++++++++++++++++++++++++++++++--------------- src/guiFormSpecMenu.h | 29 +++++++++-- 2 files changed, 114 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 802093284..3ff0274f8 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -405,7 +405,7 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() >= 3) || (parts.size() <= 5)) { + if ((parts.size() >= 3) || (parts.size() <= 4)) { std::vector v_pos = split(parts[0],','); std::string name = parts[1]; std::string label = parts[2]; @@ -446,8 +446,7 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) if (spec.fname == data->focused_fieldname) { Environment->setFocus(e); } - if (parts.size() >= 5) - spec.tooltip = parts[4]; + m_checkboxes.push_back(std::pair(spec,e)); m_fields.push_back(spec); return; @@ -532,7 +531,7 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element, { std::vector parts = split(element,';'); - if (parts.size() == 4 || parts.size() == 5) { + if (parts.size() == 4) { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string name = parts[2]; @@ -575,8 +574,6 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element, if (spec.fname == data->focused_fieldname) { Environment->setFocus(e); } - if (parts.size() >= 5) - spec.tooltip = parts[4]; m_fields.push_back(spec); return; @@ -1202,7 +1199,7 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, { std::vector parts = split(element,';'); - if (((parts.size() >= 5) && (parts.size() <= 9)) && (parts.size() != 6)) { + if (((parts.size() >= 5) && (parts.size() <= 8)) && (parts.size() != 6)) { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string image_name = parts[2]; @@ -1268,9 +1265,7 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, if (spec.fname == data->focused_fieldname) { Environment->setFocus(e); } - if (parts.size() >= 9) - spec.tooltip = parts[8]; - + e->setUseAlphaChannel(true); e->setImage(texture); e->setPressedImage(pressed_texture); @@ -1392,7 +1387,11 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) ItemStack item; item.deSerialize(item_name, idef); video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef); - std::string tooltip = item.getDefinition(idef).description; + + m_tooltips[narrow_to_wide(name.c_str())] = + TooltipSpec (item.getDefinition(idef).description, + m_default_tooltip_bgcolor, + m_default_tooltip_color); label = unescape_string(label); FieldSpec spec( @@ -1415,7 +1414,6 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) spec.ftype = f_Button; rect+=data->basepos-padding; spec.rect=rect; - spec.tooltip = tooltip; m_fields.push_back(spec); return; } @@ -1489,15 +1487,33 @@ void GUIFormSpecMenu::parseListColors(parserData* data,std::string element) video::SColor tmp_color; if (parseColor(parts[3], tmp_color, false)) - m_tooltip_element->setBackgroundColor(tmp_color); + m_default_tooltip_bgcolor = tmp_color; if (parseColor(parts[4], tmp_color, false)) - m_tooltip_element->setOverrideColor(tmp_color); + m_default_tooltip_color = tmp_color; } return; } errorstream<< "Invalid listcolors element(" << parts.size() << "): '" << element << "'" << std::endl; } +void GUIFormSpecMenu::parseTooltip(parserData* data, std::string element) +{ + std::vector parts = split(element,';'); + if (parts.size() == 2) { + std::string name = parts[0]; + m_tooltips[narrow_to_wide(name.c_str())] = TooltipSpec (parts[1], m_default_tooltip_bgcolor, m_default_tooltip_color); + return; + } else if (parts.size() == 4) { + std::string name = parts[0]; + video::SColor tmp_color1, tmp_color2; + if ( parseColor(parts[2], tmp_color1, false) && parseColor(parts[3], tmp_color2, false) ) { + m_tooltips[narrow_to_wide(name.c_str())] = TooltipSpec (parts[1], tmp_color1, tmp_color2); + return; + } + } + errorstream<< "Invalid tooltip element(" << parts.size() << "): '" << element << "'" << std::endl; +} + void GUIFormSpecMenu::parseElement(parserData* data,std::string element) { //some prechecks @@ -1639,6 +1655,11 @@ void GUIFormSpecMenu::parseElement(parserData* data,std::string element) return; } + if (type == "tooltip") { + parseTooltip(data,description); + return; + } + // Ignore others infostream << "Unknown DrawSpec: type="<addStaticText(L"",core::rect(0,0,110,18)); m_tooltip_element->enableOverrideColor(true); - m_tooltip_element->setBackgroundColor(video::SColor(255,110,130,60)); + m_tooltip_element->setBackgroundColor(m_default_tooltip_bgcolor); m_tooltip_element->setDrawBackground(true); m_tooltip_element->setDrawBorder(true); - m_tooltip_element->setOverrideColor(video::SColor(255,255,255,255)); + m_tooltip_element->setOverrideColor(m_default_tooltip_color); m_tooltip_element->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER); m_tooltip_element->setWordWrap(false); //we're not parent so no autograb for this one! @@ -1899,6 +1924,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase) tooltip_text = item.getDefinition(m_gamedef->idef()).description; if(tooltip_text != "") { + m_tooltip_element->setBackgroundColor(m_default_tooltip_bgcolor); + m_tooltip_element->setOverrideColor(m_default_tooltip_color); m_tooltip_element->setVisible(true); this->bringToFront(m_tooltip_element); m_tooltip_element->setText(narrow_to_wide(tooltip_text).c_str()); @@ -2101,32 +2128,49 @@ void GUIFormSpecMenu::drawMenu() if (hovered != NULL) { s32 id = hovered->getID(); - for(std::vector::iterator iter = m_fields.begin(); + if (id == -1) { + m_old_tooltip_id = id; + m_old_tooltip = ""; + } else if (id != m_old_tooltip_id) { + m_hoovered_time = getTimeMs(); + m_old_tooltip_id = id; + } else if (id == m_old_tooltip_id) { + u32 delta = porting::getDeltaMs(m_hoovered_time, getTimeMs()); + if (delta <= 400) + goto skip_tooltip; + for(std::vector::iterator iter = m_fields.begin(); iter != m_fields.end(); iter++) { - if ( (iter->fid == id) && (iter->tooltip != "") ) { - m_tooltip_element->setVisible(true); - this->bringToFront(m_tooltip_element); - m_tooltip_element->setText(narrow_to_wide(iter->tooltip).c_str()); - s32 tooltip_x = m_pointer.X + m_btn_height; - s32 tooltip_y = m_pointer.Y + m_btn_height; - s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height; - if (tooltip_x + tooltip_width > (s32)screenSize.X) - tooltip_x = (s32)screenSize.X - tooltip_width - m_btn_height; - int lines_count = 1; - size_t i = 0; - while ((i = iter->tooltip.find("\n", i)) != std::string::npos) { - lines_count++; - i += 2; - } - s32 tooltip_height = m_tooltip_element->getTextHeight() * lines_count + 5; - m_tooltip_element->setRelativePosition(core::rect( - core::position2d(tooltip_x, tooltip_y), - core::dimension2d(tooltip_width, tooltip_height))); - break; + if ( (iter->fid == id) && (m_tooltips[iter->fname].tooltip != "") ){ + if (m_old_tooltip != m_tooltips[iter->fname].tooltip) { + m_old_tooltip = m_tooltips[iter->fname].tooltip; + m_tooltip_element->setText(narrow_to_wide(m_tooltips[iter->fname].tooltip).c_str()); + s32 tooltip_x = m_pointer.X + m_btn_height; + s32 tooltip_y = m_pointer.Y + m_btn_height; + s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height; + if (tooltip_x + tooltip_width > (s32)screenSize.X) + tooltip_x = (s32)screenSize.X - tooltip_width - m_btn_height; + int lines_count = 1; + size_t i = 0; + while ((i = m_tooltips[iter->fname].tooltip.find("\n", i)) != std::string::npos) { + lines_count++; + i += 2; + } + s32 tooltip_height = m_tooltip_element->getTextHeight() * lines_count + 5; + m_tooltip_element->setRelativePosition(core::rect( + core::position2d(tooltip_x, tooltip_y), + core::dimension2d(tooltip_width, tooltip_height))); + } + m_tooltip_element->setBackgroundColor(m_tooltips[iter->fname].bgcolor); + m_tooltip_element->setOverrideColor(m_tooltips[iter->fname].color); + m_tooltip_element->setVisible(true); + this->bringToFront(m_tooltip_element); + break; + } } } } + skip_tooltip: /* Draw dragged item stack */ @@ -2403,7 +2447,10 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event) gui::IGUIElement *hovered = Environment->getRootGUIElement()->getElementFromPoint( core::position2d(x, y)); - + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { + m_old_tooltip_id = -1; + m_old_tooltip = ""; + } if (!isChild(hovered,this)) { if (DoubleClickDetection(event)) { return true; @@ -2504,12 +2551,14 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } } + if(event.EventType==EET_MOUSE_INPUT_EVENT && event.MouseInput.Event != EMIE_MOUSE_MOVED) { // Mouse event other than movement // Get selected item and hovered/clicked item (s) + m_old_tooltip_id = -1; updateSelectedItem(); ItemSpec s = getItemAtPos(m_pointer); diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 81dd7ba16..da0826681 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -159,7 +159,6 @@ class GUIFormSpecMenu : public GUIModalMenu send = false; ftype = f_Unknown; is_exit = false; - tooltip=""; } std::wstring fname; std::wstring flabel; @@ -169,7 +168,6 @@ class GUIFormSpecMenu : public GUIModalMenu FormspecFieldType ftype; bool is_exit; core::rect rect; - std::string tooltip; }; struct BoxDrawSpec { @@ -184,6 +182,22 @@ class GUIFormSpecMenu : public GUIModalMenu irr::video::SColor color; }; + struct TooltipSpec { + TooltipSpec() + { + } + TooltipSpec(std::string a_tooltip, irr::video::SColor a_bgcolor, + irr::video::SColor a_color): + tooltip(a_tooltip), + bgcolor(a_bgcolor), + color(a_color) + { + } + std::string tooltip; + irr::video::SColor bgcolor; + irr::video::SColor color; + }; + public: GUIFormSpecMenu(irr::IrrlichtDevice* dev, gui::IGUIElement* parent, s32 id, @@ -286,7 +300,8 @@ protected: std::vector m_fields; std::vector > m_tables; std::vector > m_checkboxes; - + std::map m_tooltips; + ItemSpec *m_selected_item; u32 m_selected_amount; bool m_selected_dragging; @@ -300,6 +315,10 @@ protected: v2s32 m_pointer; gui::IGUIStaticText *m_tooltip_element; + s32 m_hoovered_time; + s32 m_old_tooltip_id; + std::string m_old_tooltip; + bool m_allowclose; bool m_lock; v2u32 m_lockscreensize; @@ -311,6 +330,9 @@ protected: video::SColor m_slotbg_n; video::SColor m_slotbg_h; video::SColor m_slotbordercolor; + video::SColor m_default_tooltip_bgcolor; + video::SColor m_default_tooltip_color; + private: IFormSource *m_form_src; TextDest *m_text_dst; @@ -366,6 +388,7 @@ private: void parseBox(parserData* data,std::string element); void parseBackgroundColor(parserData* data,std::string element); void parseListColors(parserData* data,std::string element); + void parseTooltip(parserData* data,std::string element); /** * check if event is part of a double click -- cgit v1.2.3