X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2FguiFormSpecMenu.cpp;h=d6ca12b707ef23e256de7e5b030bf805fa6cd086;hb=5884236046c4405eec7cfc12cdde0be9f48058b6;hp=3ff0274f8ef4fbda96538d9401d2592cb4b3778a;hpb=27538ecef51ebcc7622f13956d2f8e101d0f71a7;p=minetest.git diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 3ff0274f8..d6ca12b70 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -81,12 +81,17 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, m_selected_amount(0), m_selected_dragging(false), m_tooltip_element(NULL), + m_old_tooltip_id(-1), m_allowclose(true), m_lock(false), m_form_src(fsrc), m_text_dst(tdst), m_ext_ptr(ext_ptr), - m_font(dev->getGUIEnvironment()->getSkin()->getFont()) + m_font(dev->getGUIEnvironment()->getSkin()->getFont()), + m_formspec_version(0) +#ifdef __ANDROID__ + ,m_JavaDialogFieldName(L"") +#endif { current_keys_pending.key_down = false; current_keys_pending.key_up = false; @@ -99,6 +104,8 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, m_doubleclickdetect[0].pos = v2s32(0, 0); m_doubleclickdetect[1].pos = v2s32(0, 0); + m_tooltip_show_delay = (u32)g_settings->getS32("tooltip_show_delay"); + m_btn_height = g_settings->getS32("font_size") +2; assert(m_btn_height > 0); } @@ -263,7 +270,9 @@ void GUIFormSpecMenu::parseSize(parserData* data,std::string element) { std::vector parts = split(element,','); - if ((parts.size() == 2) || parts.size() == 3) { + if (((parts.size() == 2) || parts.size() == 3) || + ((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION))) + { v2f invsize; if (parts[1].find(';') != std::string::npos) @@ -357,7 +366,9 @@ void GUIFormSpecMenu::parseList(parserData* data,std::string element) std::vector parts = split(element,';'); - if ((parts.size() == 4) || (parts.size() == 5)) { + if (((parts.size() == 4) || (parts.size() == 5)) || + ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::string location = parts[0]; std::string listname = parts[1]; std::vector v_pos = split(parts[2],','); @@ -405,7 +416,9 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() >= 3) || (parts.size() <= 4)) { + if (((parts.size() >= 3) || (parts.size() <= 4)) || + ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::string name = parts[1]; std::string label = parts[2]; @@ -440,6 +453,7 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) ); spec.ftype = f_CheckBox; + gui::IGUICheckBox* e = Environment->addCheckBox(fselected, rect, this, spec.fid, spec.flabel.c_str()); @@ -454,11 +468,101 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) errorstream<< "Invalid checkbox element(" << parts.size() << "): '" << element << "'" << std::endl; } +void GUIFormSpecMenu::parseScrollBar(parserData* data, std::string element) +{ + std::vector parts = split(element,';'); + + if (parts.size() >= 5) { + std::vector v_pos = split(parts[0],','); + std::vector v_dim = split(parts[1],','); + std::string name = parts[2]; + std::string value = parts[4]; + + MY_CHECKPOS("scrollbar",0); + + v2s32 pos = padding; + pos.X += stof(v_pos[0]) * (float) spacing.X; + pos.Y += stof(v_pos[1]) * (float) spacing.Y; + + if (v_dim.size() != 2) { + errorstream<< "Invalid size for element " << "scrollbar" + << "specified: \"" << parts[1] << "\"" << std::endl; + return; + } + + v2s32 dim; + dim.X = stof(v_dim[0]) * (float) spacing.X; + dim.Y = stof(v_dim[1]) * (float) spacing.Y; + + core::rect rect = + core::rect(pos.X, pos.Y, pos.X + dim.X, pos.Y + dim.Y); + + FieldSpec spec( + narrow_to_wide(name.c_str()), + L"", + L"", + 258+m_fields.size() + ); + + bool is_horizontal = true; + + if (parts[2] == "vertical") + is_horizontal = false; + + spec.ftype = f_ScrollBar; + spec.send = true; + gui::IGUIScrollBar* e = + Environment->addScrollBar(is_horizontal,rect,this,spec.fid); + + e->setMax(1000); + e->setMin(0); + e->setPos(stoi(parts[4])); + e->setSmallStep(10); + e->setLargeStep(100); + + if (!m_lock) { + core::rect relative_rect = e->getRelativePosition(); + + if (!is_horizontal) { + s32 original_width = relative_rect.getWidth(); + s32 width = (original_width/(2.0/3.0)) + * porting::getDisplayDensity() + * g_settings->getFloat("gui_scaling"); + e->setRelativePosition(core::rect( + relative_rect.UpperLeftCorner.X, + relative_rect.UpperLeftCorner.Y, + relative_rect.LowerRightCorner.X + (width - original_width), + relative_rect.LowerRightCorner.Y + )); + } + else { + s32 original_height = relative_rect.getHeight(); + s32 height = (original_height/(2.0/3.0)) + * porting::getDisplayDensity() + * g_settings->getFloat("gui_scaling"); + e->setRelativePosition(core::rect( + relative_rect.UpperLeftCorner.X, + relative_rect.UpperLeftCorner.Y, + relative_rect.LowerRightCorner.X, + relative_rect.LowerRightCorner.Y + (height - original_height) + )); + } + } + + m_scrollbars.push_back(std::pair(spec,e)); + m_fields.push_back(spec); + return; + } + errorstream<< "Invalid scrollbar element(" << parts.size() << "): '" << element << "'" << std::endl; +} + void GUIFormSpecMenu::parseImage(parserData* data,std::string element) { std::vector parts = split(element,';'); - if (parts.size() == 3) { + if ((parts.size() == 3) || + ((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string name = unescape_string(parts[2]); @@ -502,7 +606,9 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element) { std::vector parts = split(element,';'); - if (parts.size() == 3) { + if ((parts.size() == 3) || + ((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string name = parts[2]; @@ -515,8 +621,8 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element) pos.Y += stof(v_pos[1]) * (float) spacing.Y; v2s32 geom; - geom.X = stoi(v_geom[0]) * (float)imgsize.X; - geom.Y = stoi(v_geom[1]) * (float)imgsize.Y; + geom.X = stof(v_geom[0]) * (float)imgsize.X; + geom.Y = stof(v_geom[1]) * (float)imgsize.Y; if(data->bp_set != 2) errorstream<<"WARNING: invalid use of item_image without a size[] element"< parts = split(element,';'); - if (parts.size() == 4) { + if ((parts.size() == 4) || + ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string name = parts[2]; @@ -585,7 +693,9 @@ void GUIFormSpecMenu::parseBackground(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() == 3) || (parts.size() == 4)) { + if (((parts.size() == 3) || (parts.size() == 4)) || + ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string name = unescape_string(parts[2]); @@ -653,7 +763,9 @@ void GUIFormSpecMenu::parseTable(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() == 4) || (parts.size() == 5)) { + if (((parts.size() == 4) || (parts.size() == 5)) || + ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string name = parts[2]; @@ -722,7 +834,9 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() == 4) || (parts.size() == 5) || (parts.size() == 6)) { + if (((parts.size() == 4) || (parts.size() == 5) || (parts.size() == 6)) || + ((parts.size() > 6) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string name = parts[2]; @@ -795,7 +909,9 @@ void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) { std::vector parts = split(element,';'); - if (parts.size() == 5) { + if ((parts.size() == 5) || + ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::string name = parts[2]; std::vector items = split(parts[3],','); @@ -850,7 +966,9 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) { std::vector parts = split(element,';'); - if (parts.size() == 4) { + if ((parts.size() == 4) || + ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string name = parts[2]; @@ -1101,7 +1219,9 @@ void GUIFormSpecMenu::parseField(parserData* data,std::string element, return; } - if (parts.size() == 5) { + if ((parts.size() == 5) || + ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION))) + { parseTextArea(data,parts,type); return; } @@ -1112,7 +1232,9 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element) { std::vector parts = split(element,';'); - if (parts.size() == 2) { + if ((parts.size() == 2) || + ((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::string text = parts[1]; @@ -1151,7 +1273,9 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) { std::vector parts = split(element,';'); - if (parts.size() == 2) { + if ((parts.size() == 2) || + ((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::wstring text = narrow_to_wide(unescape_string(parts[1])); @@ -1199,7 +1323,9 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, { std::vector parts = split(element,';'); - if (((parts.size() >= 5) && (parts.size() <= 8)) && (parts.size() != 6)) { + if ((((parts.size() >= 5) && (parts.size() <= 8)) && (parts.size() != 6)) || + ((parts.size() > 8) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string image_name = parts[2]; @@ -1265,7 +1391,7 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, if (spec.fname == data->focused_fieldname) { Environment->setFocus(e); } - + e->setUseAlphaChannel(true); e->setImage(texture); e->setPressedImage(pressed_texture); @@ -1284,7 +1410,9 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() == 4) || (parts.size() == 6)) { + if (((parts.size() == 4) || (parts.size() == 6)) || + ((parts.size() > 6) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::string name = parts[1]; std::vector buttons = split(parts[2],','); @@ -1361,7 +1489,9 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) std::vector parts = split(element,';'); - if (parts.size() == 5) { + if ((parts.size() == 5) || + ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); std::string item_name = parts[2]; @@ -1424,7 +1554,9 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element) { std::vector parts = split(element,';'); - if (parts.size() == 3) { + if ((parts.size() == 3) || + ((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION))) + { std::vector v_pos = split(parts[0],','); std::vector v_geom = split(parts[1],','); @@ -1458,7 +1590,9 @@ void GUIFormSpecMenu::parseBackgroundColor(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() == 1) || (parts.size() == 2)) { + if (((parts.size() == 1) || (parts.size() == 2)) || + ((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION))) + { parseColor(parts[0],m_bgcolor,false); if (parts.size() == 2) { @@ -1474,7 +1608,9 @@ void GUIFormSpecMenu::parseListColors(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) { + if (((parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) || + ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION))) + { parseColor(parts[0], m_slotbg_n, false); parseColor(parts[1], m_slotbg_h, false); @@ -1501,12 +1637,12 @@ 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); + 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) ) { + 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; } @@ -1514,7 +1650,31 @@ void GUIFormSpecMenu::parseTooltip(parserData* data, std::string element) errorstream<< "Invalid tooltip element(" << parts.size() << "): '" << element << "'" << std::endl; } -void GUIFormSpecMenu::parseElement(parserData* data,std::string element) +bool GUIFormSpecMenu::parseVersionDirect(std::string data) +{ + //some prechecks + if (data == "") + return false; + + std::vector parts = split(data,'['); + + if (parts.size() < 2) { + return false; + } + + if (parts[0] != "formspec_version") { + return false; + } + + if (is_number(parts[1])) { + m_formspec_version = mystoi(parts[1]); + return true; + } + + return false; +} + +void GUIFormSpecMenu::parseElement(parserData* data, std::string element) { //some prechecks if (element == "") @@ -1660,6 +1820,11 @@ void GUIFormSpecMenu::parseElement(parserData* data,std::string element) return; } + if (type == "scrollbar") { + parseScrollBar(data, description); + return; + } + // Ignore others infostream << "Unknown DrawSpec: type="<grab(); } - std::vector elements = split(m_formspec_string,']'); - for (unsigned int i=0; i< elements.size(); i++) { - parseElement(&mydata,elements[i]); + unsigned int i = 0; + + /* try to read version from first element only */ + if (elements.size() >= 1) { + if ( parseVersionDirect(elements[0]) ) { + i++; + } + } + + for (; i< elements.size(); i++) { + parseElement(&mydata, elements[i]); } // If there's fields, add a Proceed button @@ -1803,6 +1977,52 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) setInitialFocus(); } +#ifdef __ANDROID__ +bool GUIFormSpecMenu::getAndroidUIInput() +{ + /* no dialog shown */ + if (m_JavaDialogFieldName == L"") { + return false; + } + + /* still waiting */ + if (porting::getInputDialogState() == -1) { + return true; + } + + std::wstring fieldname = m_JavaDialogFieldName; + m_JavaDialogFieldName = L""; + + /* no value abort dialog processing */ + if (porting::getInputDialogState() != 0) { + return false; + } + + for(std::vector::iterator iter = m_fields.begin(); + iter != m_fields.end(); iter++) { + + if (iter->fname != fieldname) { + continue; + } + IGUIElement* tochange = getElementFromId(iter->fid); + + if (tochange == 0) { + return false; + } + + if (tochange->getType() != irr::gui::EGUIET_EDIT_BOX) { + return false; + } + + std::string text = porting::getInputDialogValue(); + + ((gui::IGUIEditBox*) tochange)-> + setText(narrow_to_wide(text).c_str()); + } + return false; +} +#endif + GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const { core::rect imgrect(0,0,imgsize.X,imgsize.Y); @@ -1811,8 +2031,7 @@ GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const { const ListDrawSpec &s = m_inventorylists[i]; - for(s32 i=0; igetCursorControl()->getPosition(); - updateSelectedItem(); gui::IGUISkin* skin = Environment->getSkin(); @@ -2120,6 +2337,11 @@ void GUIFormSpecMenu::drawMenu() */ gui::IGUIElement::draw(); +/* TODO find way to show tooltips on touchscreen */ +#ifndef HAVE_TOUCHSCREENGUI + m_pointer = m_device->getCursorControl()->getPosition(); +#endif + /* Draw fields/buttons tooltips */ @@ -2128,16 +2350,19 @@ void GUIFormSpecMenu::drawMenu() if (hovered != NULL) { s32 id = hovered->getID(); + u32 delta; if (id == -1) { m_old_tooltip_id = id; m_old_tooltip = ""; + delta = 0; } else if (id != m_old_tooltip_id) { m_hoovered_time = getTimeMs(); m_old_tooltip_id = id; + delta = 0; } else if (id == m_old_tooltip_id) { - u32 delta = porting::getDeltaMs(m_hoovered_time, getTimeMs()); - if (delta <= 400) - goto skip_tooltip; + delta = porting::getDeltaMs(m_hoovered_time, getTimeMs()); + } + if (id != -1 && delta >= m_tooltip_show_delay) { for(std::vector::iterator iter = m_fields.begin(); iter != m_fields.end(); iter++) { if ( (iter->fid == id) && (m_tooltips[iter->fname].tooltip != "") ){ @@ -2165,12 +2390,11 @@ void GUIFormSpecMenu::drawMenu() m_tooltip_element->setVisible(true); this->bringToFront(m_tooltip_element); break; - } + } } } } - skip_tooltip: /* Draw dragged item stack */ @@ -2386,6 +2610,24 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no) fields[name] = "false"; } } + else if (s.ftype == f_ScrollBar) { + // no dynamic cast possible due to some distributions shipped + // without rtti support in irrlicht + IGUIElement * element = getElementFromId(s.fid); + gui::IGUIScrollBar *e = NULL; + if ((element) && (element->getType() == gui::EGUIET_SCROLL_BAR)) { + e = static_cast(element); + } + + if (e != 0) { + std::stringstream os; + os << e->getPos(); + if (s.fdefault == L"Changed") + fields[name] = "CHG:" + os.str(); + else + fields[name] = "VAL:" + os.str(); + } + } else { IGUIElement* e = getElementFromId(s.fid); @@ -2416,7 +2658,8 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event) // Fix Esc/Return key being eaten by checkboxen and tables if(event.EventType==EET_KEY_INPUT_EVENT) { KeyPress kp(event.KeyInput); - if (kp == EscapeKey || kp == getKeySetting("keymap_inventory") + if (kp == EscapeKey || kp == CancelKey + || kp == getKeySetting("keymap_inventory") || event.KeyInput.Key==KEY_RETURN) { gui::IGUIElement *focused = Environment->getFocus(); if (focused && isMyChild(focused) && @@ -2458,6 +2701,156 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event) } } + #ifdef __ANDROID__ + // display software keyboard when clicking edit boxes + if (event.EventType == EET_MOUSE_INPUT_EVENT + && event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { + gui::IGUIElement *hovered = + Environment->getRootGUIElement()->getElementFromPoint( + core::position2d(event.MouseInput.X, event.MouseInput.Y)); + if ((hovered) && (hovered->getType() == irr::gui::EGUIET_EDIT_BOX)) { + bool retval = hovered->OnEvent(event); + if (retval) { + Environment->setFocus(hovered); + } + m_JavaDialogFieldName = getNameByID(hovered->getID()); + std::string message = gettext("Enter "); + std::string label = wide_to_narrow(getLabelByID(hovered->getID())); + if (label == "") { + label = "text"; + } + message += gettext(label) + ":"; + + /* single line text input */ + int type = 2; + + /* multi line text input */ + if (((gui::IGUIEditBox*) hovered)->isMultiLineEnabled()) { + type = 1; + } + + /* passwords are always single line */ + if (((gui::IGUIEditBox*) hovered)->isPasswordBox()) { + type = 3; + } + + porting::showInputDialog(gettext("ok"), "", + wide_to_narrow(((gui::IGUIEditBox*) hovered)->getText()), + type); + return retval; + } + } + + if (event.EventType == EET_TOUCH_INPUT_EVENT) + { + SEvent translated; + memset(&translated, 0, sizeof(SEvent)); + translated.EventType = EET_MOUSE_INPUT_EVENT; + gui::IGUIElement* root = Environment->getRootGUIElement(); + + if (!root) { + errorstream + << "GUIFormSpecMenu::preprocessEvent unable to get root element" + << std::endl; + return false; + } + gui::IGUIElement* hovered = root->getElementFromPoint( + core::position2d( + event.TouchInput.X, + event.TouchInput.Y)); + + translated.MouseInput.X = event.TouchInput.X; + translated.MouseInput.Y = event.TouchInput.Y; + translated.MouseInput.Control = false; + + bool dont_send_event = false; + + if (event.TouchInput.touchedCount == 1) { + switch (event.TouchInput.Event) { + case ETIE_PRESSED_DOWN: + m_pointer = v2s32(event.TouchInput.X,event.TouchInput.Y); + translated.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN; + translated.MouseInput.ButtonStates = EMBSM_LEFT; + m_down_pos = m_pointer; + break; + case ETIE_MOVED: + m_pointer = v2s32(event.TouchInput.X,event.TouchInput.Y); + translated.MouseInput.Event = EMIE_MOUSE_MOVED; + translated.MouseInput.ButtonStates = EMBSM_LEFT; + break; + case ETIE_LEFT_UP: + translated.MouseInput.Event = EMIE_LMOUSE_LEFT_UP; + translated.MouseInput.ButtonStates = 0; + hovered = root->getElementFromPoint(m_down_pos); + /* we don't have a valid pointer element use last + * known pointer pos */ + translated.MouseInput.X = m_pointer.X; + translated.MouseInput.Y = m_pointer.Y; + + /* reset down pos */ + m_down_pos = v2s32(0,0); + break; + default: + dont_send_event = true; + //this is not supposed to happen + errorstream + << "GUIFormSpecMenu::preprocessEvent unexpected usecase Event=" + << event.TouchInput.Event << std::endl; + } + } else if ( (event.TouchInput.touchedCount == 2) && + (event.TouchInput.Event == ETIE_PRESSED_DOWN) ) { + hovered = root->getElementFromPoint(m_down_pos); + + translated.MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN; + translated.MouseInput.ButtonStates = EMBSM_LEFT | EMBSM_RIGHT; + translated.MouseInput.X = m_pointer.X; + translated.MouseInput.Y = m_pointer.Y; + + if (hovered) { + hovered->OnEvent(translated); + } + + translated.MouseInput.Event = EMIE_RMOUSE_LEFT_UP; + translated.MouseInput.ButtonStates = EMBSM_LEFT; + + + if (hovered) { + hovered->OnEvent(translated); + } + dont_send_event = true; + } + /* ignore unhandled 2 touch events ... accidental moving for example */ + else if (event.TouchInput.touchedCount == 2) { + dont_send_event = true; + } + else if (event.TouchInput.touchedCount > 2) { + errorstream + << "GUIFormSpecMenu::preprocessEvent to many multitouch events " + << event.TouchInput.touchedCount << " ignoring them" << std::endl; + } + + if (dont_send_event) { + return true; + } + + /* check if translated event needs to be preprocessed again */ + if (preprocessEvent(translated)) { + return true; + } + if (hovered) { + grab(); + bool retval = hovered->OnEvent(translated); + + if (event.TouchInput.Event == ETIE_LEFT_UP) { + /* reset pointer */ + m_pointer = v2s32(0,0); + } + drop(); + return retval; + } + } + #endif + return false; } @@ -2509,8 +2902,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) { if(event.EventType==EET_KEY_INPUT_EVENT) { KeyPress kp(event.KeyInput); - if (event.KeyInput.PressedDown && (kp == EscapeKey || - kp == getKeySetting("keymap_inventory"))) { + if (event.KeyInput.PressedDown && ( (kp == EscapeKey) || + (kp == getKeySetting("keymap_inventory")) || (kp == CancelKey))) { if (m_allowclose) { doPause = false; acceptInput(quit_mode_cancel); @@ -2551,7 +2944,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } } - + if(event.EventType==EET_MOUSE_INPUT_EVENT && event.MouseInput.Event != EMIE_MOUSE_MOVED) { // Mouse event other than movement @@ -2842,7 +3235,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } if((event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) || (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED) || - (event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED)) { + (event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED) || + (event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED)) { unsigned int btn_id = event.GUIEvent.Caller->getID(); if (btn_id == 257) { @@ -2879,7 +3273,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) return true; } } - if ((s.ftype == f_DropDown) && + else if ((s.ftype == f_DropDown) && (s.fid == event.GUIEvent.Caller->getID())) { // only send the changed dropdown for(u32 i=0; igetID())) + { + s.fdefault = L"Changed"; + acceptInput(quit_mode_no); + s.fdefault = L""; + } } } + if(event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) { if(event.GUIEvent.Caller->getID() > 257) { @@ -2940,6 +3342,38 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) return Parent ? Parent->OnEvent(event) : false; } +/** + * get name of element by element id + * @param id of element + * @return name string or empty string + */ +std::wstring GUIFormSpecMenu::getNameByID(s32 id) +{ + for(std::vector::iterator iter = m_fields.begin(); + iter != m_fields.end(); iter++) { + if (iter->fid == id) { + return iter->fname; + } + } + return L""; +} + +/** + * get label of element by id + * @param id of element + * @return label string or empty string + */ +std::wstring GUIFormSpecMenu::getLabelByID(s32 id) +{ + for(std::vector::iterator iter = m_fields.begin(); + iter != m_fields.end(); iter++) { + if (iter->fid == id) { + return iter->flabel; + } + } + return L""; +} + bool GUIFormSpecMenu::parseColor(const std::string &value, video::SColor &color, bool quiet) {