X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2FguiFormSpecMenu.cpp;h=dca7618b9852f794aadea571cde6db73a7d6eb51;hb=e0b57c1140554fccbf3e57a036cc4100887ab8f1;hp=56729846e82c3988210d5a00c7692f8b9750026d;hpb=6d61375cc72bad5c569d25c253adca4e3701dd27;p=oweals%2Fminetest.git diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 56729846e..dca7618b9 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -44,7 +44,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettext.h" #include "scripting_game.h" #include "porting.h" -#include "main.h" #include "settings.h" #include "client.h" #include "fontengine.h" @@ -53,6 +52,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/string.h" // for parseColorString() #include "guiscalingfilter.h" +#if USE_FREETYPE && IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9 +#include "intlGUIEditBox.h" +#endif + #define MY_CHECKPOS(a,b) \ if (v_pos.size() != 2) { \ errorstream<< "Invalid pos for element " << a << "specified: \"" \ @@ -97,11 +100,11 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, m_form_src(fsrc), m_text_dst(tdst), m_formspec_version(0), - m_focused_element(L""), + m_focused_element(""), m_font(NULL), m_remap_dbl_click(remap_dbl_click) #ifdef __ANDROID__ - ,m_JavaDialogFieldName(L"") + , m_JavaDialogFieldName("") #endif { current_keys_pending.key_down = false; @@ -228,7 +231,7 @@ void GUIFormSpecMenu::setInitialFocus() Environment->setFocus(*(children.begin())); } -GUITable* GUIFormSpecMenu::getTable(std::wstring tablename) +GUITable* GUIFormSpecMenu::getTable(const std::string &tablename) { for (u32 i = 0; i < m_tables.size(); ++i) { if (tablename == m_tables[i].first.fname) @@ -237,28 +240,27 @@ GUITable* GUIFormSpecMenu::getTable(std::wstring tablename) return 0; } -std::vector split(const std::string &s, char delim) { +static std::vector split(const std::string &s, char delim) +{ std::vector tokens; std::string current = ""; bool last_was_escape = false; - for(unsigned int i=0; i < s.size(); i++) { + for (unsigned int i = 0; i < s.size(); i++) { + char si = s.c_str()[i]; if (last_was_escape) { current += '\\'; - current += s.c_str()[i]; + current += si; last_was_escape = false; - } - else { - if (s.c_str()[i] == delim) { + } else { + if (si == delim) { tokens.push_back(current); current = ""; last_was_escape = false; - } - else if (s.c_str()[i] == '\\'){ + } else if (si == '\\') { last_was_escape = true; - } - else { - current += s.c_str()[i]; + } else { + current += si; last_was_escape = false; } } @@ -350,6 +352,41 @@ void GUIFormSpecMenu::parseList(parserData* data,std::string element) errorstream<< "Invalid list element(" << parts.size() << "): '" << element << "'" << std::endl; } +void GUIFormSpecMenu::parseListRing(parserData* data, std::string element) +{ + if (m_gamedef == 0) { + errorstream << "WARNING: invalid use of 'listring' with m_gamedef==0" << std::endl; + return; + } + + std::vector parts = split(element, ';'); + + if (parts.size() == 2) { + std::string location = parts[0]; + std::string listname = parts[1]; + + InventoryLocation loc; + + if (location == "context" || location == "current_name") + loc = m_current_inventory_location; + else + loc.deSerialize(location); + + m_inventory_rings.push_back(ListRingSpec(loc, listname)); + return; + } else if ((element == "") && (m_inventorylists.size() > 1)) { + size_t siz = m_inventorylists.size(); + // insert the last two inv list elements into the list ring + const ListDrawSpec &spa = m_inventorylists[siz - 2]; + const ListDrawSpec &spb = m_inventorylists[siz - 1]; + m_inventory_rings.push_back(ListRingSpec(spa.inventoryloc, spa.listname)); + m_inventory_rings.push_back(ListRingSpec(spb.inventoryloc, spb.listname)); + return; + } + errorstream<< "Invalid list ring element(" << parts.size() << ", " + << m_inventorylists.size() << "): '" << element << "'" << std::endl; +} + void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) { std::vector parts = split(element,';'); @@ -376,7 +413,7 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) if (selected == "true") fselected = true; - std::wstring wlabel = narrow_to_wide(label); + std::wstring wlabel = utf8_to_wide(label); core::rect rect = core::rect( pos.X, pos.Y + ((imgsize.Y/2) - m_btn_height), @@ -384,7 +421,7 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) pos.Y + ((imgsize.Y/2) + m_btn_height)); FieldSpec spec( - narrow_to_wide(name), + name, wlabel, //Needed for displaying text on MSVC wlabel, 258+m_fields.size() @@ -436,7 +473,7 @@ void GUIFormSpecMenu::parseScrollBar(parserData* data, std::string element) core::rect(pos.X, pos.Y, pos.X + dim.X, pos.Y + dim.Y); FieldSpec spec( - narrow_to_wide(name), + name, L"", L"", 258+m_fields.size() @@ -574,10 +611,10 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element, label = unescape_string(label); - std::wstring wlabel = narrow_to_wide(label); + std::wstring wlabel = utf8_to_wide(label); FieldSpec spec( - narrow_to_wide(name), + name, wlabel, L"", 258+m_fields.size() @@ -699,10 +736,8 @@ void GUIFormSpecMenu::parseTable(parserData* data,std::string element) core::rect rect = core::rect(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); - std::wstring fname_w = narrow_to_wide(name); - FieldSpec spec( - fname_w, + name, L"", L"", 258+m_fields.size() @@ -724,8 +759,8 @@ void GUIFormSpecMenu::parseTable(parserData* data,std::string element) e->setTable(data->table_options, data->table_columns, items); - if (data->table_dyndata.find(fname_w) != data->table_dyndata.end()) { - e->setDynamicData(data->table_dyndata[fname_w]); + if (data->table_dyndata.find(name) != data->table_dyndata.end()) { + e->setDynamicData(data->table_dyndata[name]); } if ((str_initial_selection != "") && @@ -773,10 +808,8 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) core::rect rect = core::rect(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); - std::wstring fname_w = narrow_to_wide(name); - FieldSpec spec( - fname_w, + name, L"", L"", 258+m_fields.size() @@ -798,8 +831,8 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) e->setTextList(items, is_yes(str_transparent)); - if (data->table_dyndata.find(fname_w) != data->table_dyndata.end()) { - e->setDynamicData(data->table_dyndata[fname_w]); + if (data->table_dyndata.find(name) != data->table_dyndata.end()) { + e->setDynamicData(data->table_dyndata[name]); } if ((str_initial_selection != "") && @@ -838,10 +871,8 @@ void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) core::rect rect = core::rect(pos.X, pos.Y, pos.X + width, pos.Y + (m_btn_height * 2)); - std::wstring fname_w = narrow_to_wide(name); - FieldSpec spec( - fname_w, + name, L"", L"", 258+m_fields.size() @@ -858,7 +889,7 @@ void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) } for (unsigned int i=0; i < items.size(); i++) { - e->addItem(narrow_to_wide(items[i]).c_str()); + e->addItem(utf8_to_wide(items[i]).c_str()); } if (str_initial_selection != "") @@ -901,10 +932,10 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) label = unescape_string(label); - std::wstring wlabel = narrow_to_wide(label); + std::wstring wlabel = utf8_to_wide(label); FieldSpec spec( - narrow_to_wide(name), + name, wlabel, L"", 258+m_fields.size() @@ -967,12 +998,12 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data, default_val = unescape_string(default_val); label = unescape_string(label); - std::wstring wlabel = narrow_to_wide(label); + std::wstring wlabel = utf8_to_wide(label); FieldSpec spec( - narrow_to_wide(name), + name, wlabel, - narrow_to_wide(default_val), + utf8_to_wide(default_val), 258+m_fields.size() ); @@ -984,9 +1015,18 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data, else { spec.send = true; - gui::IGUIEditBox *e = - Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid); - + gui::IGUIElement *e; +#if USE_FREETYPE && IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9 + if (g_settings->getBool("freetype")) { + e = (gui::IGUIElement *) new gui::intlGUIEditBox(spec.fdefault.c_str(), + true, Environment, this, spec.fid, rect); + e->drop(); + } else { +#else + { +#endif + e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid); + } if (spec.fname == data->focused_fieldname) { Environment->setFocus(e); } @@ -1057,12 +1097,12 @@ void GUIFormSpecMenu::parseTextArea(parserData* data, default_val = unescape_string(default_val); label = unescape_string(label); - std::wstring wlabel = narrow_to_wide(label); + std::wstring wlabel = utf8_to_wide(label); FieldSpec spec( - narrow_to_wide(name), + name, wlabel, - narrow_to_wide(default_val), + utf8_to_wide(default_val), 258+m_fields.size() ); @@ -1074,8 +1114,19 @@ void GUIFormSpecMenu::parseTextArea(parserData* data, else { spec.send = true; - gui::IGUIEditBox *e = - Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid); + + gui::IGUIEditBox *e; +#if USE_FREETYPE && IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9 + if (g_settings->getBool("freetype")) { + e = (gui::IGUIEditBox *) new gui::intlGUIEditBox(spec.fdefault.c_str(), + true, Environment, this, spec.fid, rect); + e->drop(); + } else { +#else + { +#endif + e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid); + } if (spec.fname == data->focused_fieldname) { Environment->setFocus(e); @@ -1160,13 +1211,13 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element) // in the integer cases: 0.4 is not exactly // representable in binary floating point. s32 posy = pos.Y + ((float)i) * spacing.Y * 2.0 / 5.0; - std::wstring wlabel = narrow_to_wide(lines[i]); + std::wstring wlabel = utf8_to_wide(lines[i]); core::rect rect = core::rect( pos.X, posy - m_btn_height, pos.X + m_font->getDimension(wlabel.c_str()).Width, posy + m_btn_height); FieldSpec spec( - L"", + "", wlabel, L"", 258+m_fields.size() @@ -1192,7 +1243,7 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) ((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])); + std::wstring text = utf8_to_wide(unescape_string(parts[1])); MY_CHECKPOS("vertlabel",1); @@ -1219,7 +1270,7 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) } FieldSpec spec( - L"", + "", label, L"", 258+m_fields.size() @@ -1281,12 +1332,12 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, pressed_image_name = unescape_string(pressed_image_name); label = unescape_string(label); - std::wstring wlabel = narrow_to_wide(label); + std::wstring wlabel = utf8_to_wide(label); FieldSpec spec( - narrow_to_wide(name), + name, wlabel, - narrow_to_wide(image_name), + utf8_to_wide(image_name), 258+m_fields.size() ); spec.ftype = f_Button; @@ -1308,8 +1359,10 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, } e->setUseAlphaChannel(true); - e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y)); - e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y)); + e->setImage(guiScalingImageButton( + Environment->getVideoDriver(), texture, geom.X, geom.Y)); + e->setPressedImage(guiScalingImageButton( + Environment->getVideoDriver(), pressed_texture, geom.X, geom.Y)); e->setScaleImage(true); e->setNotClipped(noclip); e->setDrawBorder(drawborder); @@ -1346,7 +1399,7 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) } FieldSpec spec( - narrow_to_wide(name), + name, L"", L"", 258+m_fields.size() @@ -1376,8 +1429,8 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) e->setNotClipped(true); - for (unsigned int i=0; i< buttons.size(); i++) { - e->addTab(narrow_to_wide(buttons[i]).c_str(), -1); + for (unsigned int i = 0; i < buttons.size(); i++) { + e->addTab(utf8_to_wide(buttons[i]).c_str(), -1); } if ((tab_index >= 0) && @@ -1433,17 +1486,17 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) item.deSerialize(item_name, idef); video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef); - m_tooltips[narrow_to_wide(name)] = + m_tooltips[name] = TooltipSpec(item.getDefinition(idef).description, m_default_tooltip_bgcolor, m_default_tooltip_color); label = unescape_string(label); FieldSpec spec( - narrow_to_wide(name), - narrow_to_wide(label), - narrow_to_wide(item_name), - 258+m_fields.size() + name, + utf8_to_wide(label), + utf8_to_wide(item_name), + 258 + m_fields.size() ); gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str()); @@ -1552,14 +1605,14 @@ 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)] = TooltipSpec(unescape_string(parts[1]), + m_tooltips[name] = TooltipSpec(unescape_string(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 ( parseColorString(parts[2], tmp_color1, false) && parseColorString(parts[3], tmp_color2, false) ) { - m_tooltips[narrow_to_wide(name)] = TooltipSpec(unescape_string(parts[1]), + m_tooltips[name] = TooltipSpec(unescape_string(parts[1]), tmp_color1, tmp_color2); return; } @@ -1645,6 +1698,11 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element) return; } + if (type == "listring") { + parseListRing(data, description); + return; + } + if (type == "checkbox") { parseCheckbox(data,description); return; @@ -1772,7 +1830,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) //preserve tables for (u32 i = 0; i < m_tables.size(); ++i) { - std::wstring tablename = m_tables[i].first.fname; + std::string tablename = m_tables[i].first.fname; GUITable *table = m_tables[i].second; mydata.table_dyndata[tablename] = table->getDynamicData(); } @@ -1822,6 +1880,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) m_fields.clear(); m_boxes.clear(); m_tooltips.clear(); + m_inventory_rings.clear(); // Set default values (fits old formspec values) m_bgcolor = video::SColor(140,0,0,0); @@ -2027,7 +2086,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) bool GUIFormSpecMenu::getAndroidUIInput() { /* no dialog shown */ - if (m_JavaDialogFieldName == L"") { + if (m_JavaDialogFieldName == "") { return false; } @@ -2036,8 +2095,8 @@ bool GUIFormSpecMenu::getAndroidUIInput() return true; } - std::wstring fieldname = m_JavaDialogFieldName; - m_JavaDialogFieldName = L""; + std::string fieldname = m_JavaDialogFieldName; + m_JavaDialogFieldName = ""; /* no value abort dialog processing */ if (porting::getInputDialogState() != 0) { @@ -2045,7 +2104,7 @@ bool GUIFormSpecMenu::getAndroidUIInput() } for(std::vector::iterator iter = m_fields.begin(); - iter != m_fields.end(); iter++) { + iter != m_fields.end(); ++iter) { if (iter->fname != fieldname) { continue; @@ -2063,7 +2122,7 @@ bool GUIFormSpecMenu::getAndroidUIInput() std::string text = porting::getInputDialogValue(); ((gui::IGUIEditBox*) tochange)-> - setText(narrow_to_wide(text).c_str()); + setText(utf8_to_wide(text).c_str()); } return false; } @@ -2187,7 +2246,7 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase) 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()); + m_tooltip_element->setText(utf8_to_wide(tooltip_text).c_str()); s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height; s32 tooltip_height = m_tooltip_element->getTextHeight() * tt_rows.size() + 5; v2u32 screenSize = driver->getScreenSize(); @@ -2415,11 +2474,11 @@ void GUIFormSpecMenu::drawMenu() if (id != -1 && delta >= m_tooltip_show_delay) { for(std::vector::iterator iter = m_fields.begin(); - iter != m_fields.end(); iter++) { + iter != m_fields.end(); ++iter) { 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()); + m_tooltip_element->setText(utf8_to_wide(m_tooltips[iter->fname].tooltip).c_str()); std::vector tt_rows = str_split(m_tooltips[iter->fname].tooltip, '\n'); s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height; s32 tooltip_height = m_tooltip_element->getTextHeight() * tt_rows.size() + 5; @@ -2578,7 +2637,7 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no) { if(m_text_dst) { - std::map fields; + StringMap fields; if (quitmode == quit_mode_accept) { fields["quit"] = "true"; @@ -2613,11 +2672,10 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no) for(unsigned int i=0; icheckEvent(); @@ -2634,7 +2692,7 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no) s32 selected = e->getSelected(); if (selected >= 0) { fields[name] = - wide_to_narrow(e->getItem(selected)); + wide_to_utf8(e->getItem(selected)); } } else if (s.ftype == f_TabHeader) { @@ -2690,7 +2748,7 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no) { IGUIElement* e = getElementFromId(s.fid); if(e != NULL) { - fields[name] = wide_to_narrow(e->getText()); + fields[name] = wide_to_utf8(e->getText()); } } } @@ -2798,7 +2856,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event) } m_JavaDialogFieldName = getNameByID(hovered->getID()); std::string message = gettext("Enter "); - std::string label = wide_to_narrow(getLabelByID(hovered->getID())); + std::string label = wide_to_utf8(getLabelByID(hovered->getID())); if (label == "") { label = "text"; } @@ -2818,7 +2876,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event) } porting::showInputDialog(gettext("ok"), "", - wide_to_narrow(((gui::IGUIEditBox*) hovered)->getText()), + wide_to_utf8(((gui::IGUIEditBox*) hovered)->getText()), type); return retval; } @@ -2997,21 +3055,21 @@ bool GUIFormSpecMenu::DoubleClickDetection(const SEvent event) bool GUIFormSpecMenu::OnEvent(const SEvent& event) { - if(event.EventType==EET_KEY_INPUT_EVENT) { + if (event.EventType==EET_KEY_INPUT_EVENT) { KeyPress kp(event.KeyInput); if (event.KeyInput.PressedDown && ( (kp == EscapeKey) || - (kp == getKeySetting("keymap_inventory")) || (kp == CancelKey))) { + (kp == getKeySetting("keymap_inventory")) || (kp == CancelKey))) { if (m_allowclose) { doPause = false; acceptInput(quit_mode_cancel); quitMenu(); } else { - m_text_dst->gotText(narrow_to_wide("MenuQuit")); + m_text_dst->gotText(L"MenuQuit"); } return true; } else if (m_client != NULL && event.KeyInput.PressedDown && - (kp == getKeySetting("keymap_screenshot"))) { - m_client->makeScreenshot(m_device); + (kp == getKeySetting("keymap_screenshot"))) { + m_client->makeScreenshot(m_device); } if (event.KeyInput.PressedDown && (event.KeyInput.Key==KEY_RETURN || @@ -3062,8 +3120,9 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) Inventory *inv_selected = NULL; Inventory *inv_s = NULL; + InventoryList *list_s = NULL; - if(m_selected_item) { + if (m_selected_item) { inv_selected = m_invmgr->getInventory(m_selected_item->inventoryloc); sanity_check(inv_selected); sanity_check(inv_selected->getList(m_selected_item->listname) != NULL); @@ -3071,35 +3130,35 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) u32 s_count = 0; - if(s.isValid()) + if (s.isValid()) do { // breakable inv_s = m_invmgr->getInventory(s.inventoryloc); - if(!inv_s) { - errorstream<<"InventoryMenu: The selected inventory location " - <<"\""<getList(s.listname); - if(list == NULL) { - verbosestream<<"InventoryMenu: The selected inventory list \"" - <getList(s.listname); + if (list_s == NULL) { + verbosestream << "InventoryMenu: The selected inventory list \"" + << s.listname << "\" does not exist" << std::endl; s.i = -1; // make it invalid again break; } - if((u32)s.i >= list->getSize()) { - infostream<<"InventoryMenu: The selected inventory list \"" - <= list_s->getSize()) { + infostream << "InventoryMenu: The selected inventory list \"" + << s.listname << "\" is too small (i=" << s.i << ", size=" + << list_s->getSize() << ")" << std::endl; s.i = -1; // make it invalid again break; } - s_count = list->getItem(s.i).count; + s_count = list_s->getItem(s.i).count; } while(0); bool identical = (m_selected_item != NULL) && s.isValid() && @@ -3111,25 +3170,29 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) // up/down: 0 = down (press), 1 = up (release), 2 = unknown event, -1 movement int button = 0; int updown = 2; - if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { button = 0; updown = 0; } - else if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) + else if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) { button = 1; updown = 0; } - else if(event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN) + else if (event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN) { button = 2; updown = 0; } - else if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + else if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) { button = 0; updown = 1; } - else if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) + else if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) { button = 1; updown = 1; } - else if(event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP) + else if (event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP) { button = 2; updown = 1; } - else if(event.MouseInput.Event == EMIE_MOUSE_MOVED) + else if (event.MouseInput.Event == EMIE_MOUSE_MOVED) { updown = -1;} // Set this number to a positive value to generate a move action // from m_selected_item to s. u32 move_amount = 0; + // Set this number to a positive value to generate a move action + // from s to the next inventory ring. + u32 shift_move_amount = 0; + // Set this number to a positive value to generate a drop action // from m_selected_item. u32 drop_amount = 0; @@ -3137,7 +3200,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) // Set this number to a positive value to generate a craft action at s. u32 craft_amount = 0; - if(updown == 0) { + if (updown == 0) { // Some mouse button has been pressed //infostream<<"Mouse button "<= 1); - if(s.isValid()) { + if (s.isValid()) { // Clicked a slot: move - if(button == 1) // right + if (button == 1) // right move_amount = 1; - else if(button == 2) // middle + else if (button == 2) // middle move_amount = MYMIN(m_selected_amount, 10); else // left move_amount = m_selected_amount; - if(identical) { - if(move_amount >= m_selected_amount) + if (identical) { + if (move_amount >= m_selected_amount) m_selected_amount = 0; else m_selected_amount -= move_amount; @@ -3187,29 +3259,28 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } else if (!getAbsoluteClippingRect().isPointInside(m_pointer)) { // Clicked outside of the window: drop - if(button == 1) // right + if (button == 1) // right drop_amount = 1; - else if(button == 2) // middle + else if (button == 2) // middle drop_amount = MYMIN(m_selected_amount, 10); else // left drop_amount = m_selected_amount; } } } - else if(updown == 1) { + else if (updown == 1) { // Some mouse button has been released //infostream<<"Mouse button "<getList(m_selected_item->listname); - InventoryList *list_to = inv_s->getList(s.listname); + InventoryList *list_to = list_s; assert(list_from && list_to); ItemStack stack_from = list_from->getItem(m_selected_item->i); ItemStack stack_to = list_to->getItem(s.i); @@ -3244,8 +3314,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } // Possibly send inventory action to server - if(move_amount > 0) - { + if (move_amount > 0) { // Send IACTION_MOVE assert(m_selected_item && m_selected_item->isValid()); @@ -3253,7 +3322,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) assert(inv_selected && inv_s); InventoryList *list_from = inv_selected->getList(m_selected_item->listname); - InventoryList *list_to = inv_s->getList(s.listname); + InventoryList *list_to = list_s; assert(list_from && list_to); ItemStack stack_from = list_from->getItem(m_selected_item->i); ItemStack stack_to = list_to->getItem(s.i); @@ -3272,7 +3341,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) m_selected_content_guess_inventory = s.inventoryloc; } // Source stack goes fully into destination stack - else if(leftover.empty()) { + else if (leftover.empty()) { m_selected_amount -= move_amount; m_selected_content_guess = ItemStack(); // Clear } @@ -3283,7 +3352,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) m_selected_content_guess = ItemStack(); // Clear } - infostream<<"Handing IACTION_MOVE to manager"<count = move_amount; a->from_inv = m_selected_item->inventoryloc; @@ -3293,8 +3362,68 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) a->to_list = s.listname; a->to_i = s.i; m_invmgr->inventoryAction(a); - } - else if(drop_amount > 0) { + } else if (shift_move_amount > 0) { + u32 mis = m_inventory_rings.size(); + u32 i = 0; + for (; i < mis; i++) { + const ListRingSpec &sp = m_inventory_rings[i]; + if (sp.inventoryloc == s.inventoryloc + && sp.listname == s.listname) + break; + } + do { + if (i >= mis) // if not found + break; + u32 to_inv_ind = (i + 1) % mis; + const ListRingSpec &to_inv_sp = m_inventory_rings[to_inv_ind]; + InventoryList *list_from = list_s; + if (!s.isValid()) + break; + Inventory *inv_to = m_invmgr->getInventory(to_inv_sp.inventoryloc); + if (!inv_to) + break; + InventoryList *list_to = inv_to->getList(to_inv_sp.listname); + if (!list_to) + break; + ItemStack stack_from = list_from->getItem(s.i); + assert(shift_move_amount <= stack_from.count); + if (m_client->getProtoVersion() >= 25) { + infostream << "Handing IACTION_MOVE to manager" << std::endl; + IMoveAction *a = new IMoveAction(); + a->count = shift_move_amount; + a->from_inv = s.inventoryloc; + a->from_list = s.listname; + a->from_i = s.i; + a->to_inv = to_inv_sp.inventoryloc; + a->to_list = to_inv_sp.listname; + a->move_somewhere = true; + m_invmgr->inventoryAction(a); + } else { + // find a place (or more than one) to add the new item + u32 ilt_size = list_to->getSize(); + ItemStack leftover; + for (u32 slot_to = 0; slot_to < ilt_size + && shift_move_amount > 0; slot_to++) { + list_to->itemFits(slot_to, stack_from, &leftover); + if (leftover.count < stack_from.count) { + infostream << "Handing IACTION_MOVE to manager" << std::endl; + IMoveAction *a = new IMoveAction(); + a->count = MYMIN(shift_move_amount, + (u32) (stack_from.count - leftover.count)); + shift_move_amount -= a->count; + a->from_inv = s.inventoryloc; + a->from_list = s.listname; + a->from_i = s.i; + a->to_inv = to_inv_sp.inventoryloc; + a->to_list = to_inv_sp.listname; + a->to_i = slot_to; + m_invmgr->inventoryAction(a); + stack_from = leftover; + } + } + } + } while (0); + } else if (drop_amount > 0) { m_selected_content_guess = ItemStack(); // Clear // Send IACTION_DROP @@ -3310,15 +3439,14 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) assert(drop_amount > 0 && drop_amount <= m_selected_amount); m_selected_amount -= drop_amount; - infostream<<"Handing IACTION_DROP to manager"<count = drop_amount; a->from_inv = m_selected_item->inventoryloc; a->from_list = m_selected_item->listname; a->from_i = m_selected_item->i; m_invmgr->inventoryAction(a); - } - else if(craft_amount > 0) { + } else if (craft_amount > 0) { m_selected_content_guess = ItemStack(); // Clear // Send IACTION_CRAFT @@ -3326,7 +3454,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) assert(s.isValid()); assert(inv_s); - infostream<<"Handing IACTION_CRAFT to manager"<count = craft_amount; a->craft_inv = s.inventoryloc; @@ -3334,7 +3462,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } // If m_selected_amount has been decreased to zero, deselect - if(m_selected_amount == 0) { + if (m_selected_amount == 0) { delete m_selected_item; m_selected_item = NULL; m_selected_amount = 0; @@ -3343,12 +3471,12 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } m_old_pointer = m_pointer; } - if(event.EventType==EET_GUI_EVENT) { + if (event.EventType == EET_GUI_EVENT) { - if(event.GUIEvent.EventType==gui::EGET_TAB_CHANGED + if (event.GUIEvent.EventType == gui::EGET_TAB_CHANGED && isVisible()) { // find the element that was clicked - for(unsigned int i=0; igetID())) { @@ -3359,16 +3487,16 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } } } - if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST + if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST && isVisible()) { - if(!canTakeFocus(event.GUIEvent.Element)) { + if (!canTakeFocus(event.GUIEvent.Element)) { infostream<<"GUIFormSpecMenu: Not allowing focus change." <gotText(narrow_to_wide("ExitButton")); + m_text_dst->gotText(L"ExitButton"); } // quitMenu deallocates menu return true; } // find the element that was clicked - for(u32 i=0; igetID())) { s.send = true; - if(s.is_exit) { + if (s.is_exit) { if (m_allowclose) { acceptInput(quit_mode_accept); quitMenu(); } else { - m_text_dst->gotText(narrow_to_wide("ExitButton")); + m_text_dst->gotText(L"ExitButton"); } return true; } else { @@ -3407,11 +3535,10 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) s.send = false; return true; } - } - else 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())) - { + } else if ((s.ftype == f_ScrollBar) && + (s.fid == event.GUIEvent.Caller->getID())) { s.fdefault = L"Changed"; acceptInput(quit_mode_no); s.fdefault = L""; @@ -3440,8 +3565,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } } - if(event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) { - if(event.GUIEvent.Caller->getID() > 257) { + if (event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) { + if (event.GUIEvent.Caller->getID() > 257) { if (m_allowclose) { acceptInput(quit_mode_accept); @@ -3455,11 +3580,11 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) } } - if(event.GUIEvent.EventType == gui::EGET_TABLE_CHANGED) { + if (event.GUIEvent.EventType == gui::EGET_TABLE_CHANGED) { int current_id = event.GUIEvent.Caller->getID(); - if(current_id > 257) { + if (current_id > 257) { // find the element that was clicked - for(u32 i=0; i::iterator iter = m_fields.begin(); - iter != m_fields.end(); iter++) { + iter != m_fields.end(); ++iter) { if (iter->fid == id) { return iter->fname; } } - return L""; + return ""; } /** @@ -3501,7 +3626,7 @@ std::wstring GUIFormSpecMenu::getNameByID(s32 id) std::wstring GUIFormSpecMenu::getLabelByID(s32 id) { for(std::vector::iterator iter = m_fields.begin(); - iter != m_fields.end(); iter++) { + iter != m_fields.end(); ++iter) { if (iter->fid == id) { return iter->flabel; }