From d8337034b532638d246227d850154ee6b21c7ac9 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 15 Aug 2013 21:46:55 +0200 Subject: Formspec textlist: Black Irrlicht magic to detect fake doubleclicks --- src/guiFormSpecMenu.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 8 deletions(-) (limited to 'src/guiFormSpecMenu.cpp') diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 049341c14..79497dca1 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/string.h" #include "util/numeric.h" #include "filesys.h" +#include "gettime.h" #include "gettext.h" @@ -81,6 +82,10 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, m_selected_item(NULL), m_selected_amount(0), m_selected_dragging(false), + m_listbox_click_fname(), + m_listbox_click_index(-1), + m_listbox_click_time(0), + m_listbox_doubleclick(false), m_tooltip_element(NULL), m_allowclose(true), m_use_gettext(false), @@ -143,6 +148,42 @@ int GUIFormSpecMenu::getListboxIndex(std::string listboxname) { return -1; } +bool GUIFormSpecMenu::checkListboxClick(std::wstring wlistboxname, + int eventtype) +{ + // WARNING: BLACK IRRLICHT MAGIC + // Used to fix Irrlicht's subpar reporting of single clicks and double + // clicks in listboxes (gui::EGET_LISTBOX_CHANGED, + // gui::EGET_LISTBOX_SELECTED_AGAIN): + // 1. IGUIListBox::setSelected() is counted as a click. + // Including the initial setSelected() done by parseTextList(). + // 2. Clicking on a the selected item and then dragging for less + // than 500ms is counted as a doubleclick, no matter when the + // item was previously selected (e.g. more than 500ms ago) + + // So when Irrlicht reports a doubleclick, we need to check + // for ourselves if really was a doubleclick. Or just a fake. + + for(unsigned int i=0; i < m_listboxes.size(); i++) { + std::wstring name(m_listboxes[i].first.fname.c_str()); + int selected = m_listboxes[i].second->getSelected(); + if (name == wlistboxname && selected >= 0) { + u32 now = getTimeMs(); + bool doubleclick = + (eventtype == gui::EGET_LISTBOX_SELECTED_AGAIN) + && (name == m_listbox_click_fname) + && (selected == m_listbox_click_index) + && (m_listbox_click_time >= now - 500); + m_listbox_click_fname = name; + m_listbox_click_index = selected; + m_listbox_click_time = now; + m_listbox_doubleclick = doubleclick; + return true; + } + } + return false; +} + std::vector split(const std::string &s, char delim) { std::vector tokens; @@ -1920,7 +1961,7 @@ ItemStack GUIFormSpecMenu::verifySelectedItem() return ItemStack(); } -void GUIFormSpecMenu::acceptInput(int eventtype) +void GUIFormSpecMenu::acceptInput() { if(m_text_dst) { @@ -1957,11 +1998,12 @@ void GUIFormSpecMenu::acceptInput(int eventtype) } else if(s.ftype == f_ListBox) { std::stringstream ss; - if (eventtype == gui::EGET_LISTBOX_CHANGED) { - ss << "CHG:"; + + if (m_listbox_doubleclick) { + ss << "DCL:"; } else { - ss << "DCL:"; + ss << "CHG:"; } ss << (getListboxIndex(wide_to_narrow(s.fname.c_str()))+1); fields[wide_to_narrow(s.fname.c_str())] = ss.str(); @@ -2459,12 +2501,16 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) for(u32 i=0; isetFocus(this); -- cgit v1.2.3