X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=src%2FguiFormSpecMenu.cpp;h=73388114bd470365e4183da4ac5e1ba8201eea48;hb=198ed60cabd3066977df5360b7b32a6b895ea744;hp=dd96da5a99a9524279cdd07010d1c11318a84ad8;hpb=4330c63ea40a75d4b8fcf71dc749fed714b22a44;p=minetest.git diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index dd96da5a9..73388114b 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -279,6 +279,32 @@ void GUIFormSpecMenu::parseSize(parserData* data,std::string element) errorstream<< "Invalid size element (" << parts.size() << "): '" << element << "'" << std::endl; } +void GUIFormSpecMenu::parseContainer(parserData* data, std::string element) +{ + std::vector parts = split(element, ','); + + if (parts.size() >= 2) { + if (parts[1].find(';') != std::string::npos) + parts[1] = parts[1].substr(0, parts[1].find(';')); + + container_stack.push(pos_offset); + pos_offset.X += MYMAX(0, stof(parts[0])); + pos_offset.Y += MYMAX(0, stof(parts[1])); + return; + } + errorstream<< "Invalid container start element (" << parts.size() << "): '" << element << "'" << std::endl; +} + +void GUIFormSpecMenu::parseContainerEnd(parserData* data) +{ + if (container_stack.empty()) { + errorstream<< "Invalid container end element, no matching container start element" << std::endl; + } else { + pos_offset = container_stack.top(); + container_stack.pop(); + } +} + void GUIFormSpecMenu::parseList(parserData* data,std::string element) { if (m_gamedef == 0) { @@ -309,7 +335,7 @@ void GUIFormSpecMenu::parseList(parserData* data,std::string element) else loc.deSerialize(location); - v2s32 pos = padding + AbsoluteRect.UpperLeftCorner; + v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float)spacing.X; pos.Y += stof(v_pos[1]) * (float)spacing.Y; @@ -386,7 +412,7 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) MY_CHECKPOS("checkbox",0); - v2s32 pos = padding; + v2s32 pos = padding + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float) spacing.X; pos.Y += stof(v_pos[1]) * (float) spacing.Y; @@ -437,7 +463,7 @@ void GUIFormSpecMenu::parseScrollBar(parserData* data, std::string element) MY_CHECKPOS("scrollbar",0); - v2s32 pos = padding; + v2s32 pos = padding + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float) spacing.X; pos.Y += stof(v_pos[1]) * (float) spacing.Y; @@ -495,10 +521,10 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element) std::vector v_geom = split(parts[1],','); std::string name = unescape_string(parts[2]); - MY_CHECKPOS("image",0); - MY_CHECKGEOM("image",1); + MY_CHECKPOS("image", 0); + MY_CHECKGEOM("image", 1); - v2s32 pos = padding + AbsoluteRect.UpperLeftCorner; + v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float) spacing.X; pos.Y += stof(v_pos[1]) * (float) spacing.Y; @@ -506,23 +532,21 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element) geom.X = stof(v_geom[0]) * (float)imgsize.X; geom.Y = stof(v_geom[1]) * (float)imgsize.Y; - if(!data->explicit_size) + if (!data->explicit_size) warningstream<<"invalid use of image without a size[] element"< v_pos = split(parts[0],','); std::string name = unescape_string(parts[1]); - MY_CHECKPOS("image",0); + MY_CHECKPOS("image", 0); - v2s32 pos = padding + AbsoluteRect.UpperLeftCorner; + v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float) spacing.X; pos.Y += stof(v_pos[1]) * (float) spacing.Y; - if(!data->explicit_size) + if (!data->explicit_size) warningstream<<"invalid use of image without a size[] element"<explicit_size) + warningstream<<"invalid use of background without a size[] element"<explicit_size) - warningstream<<"invalid use of background without a size[] element"< parts = split(element,';'); + if (parts.size() == 2 || + (parts.size() > 2 && m_formspec_version > FORMSPEC_API_VERSION)) { + field_close_on_enter[parts[0]] = is_yes(parts[1]); + } +} + void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) { std::vector parts = split(element,';'); - if ((parts.size() == 4) || - ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION))) + 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],','); @@ -905,7 +939,7 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) MY_CHECKPOS("pwdfield",0); MY_CHECKGEOM("pwdfield",1); - v2s32 pos; + v2s32 pos = pos_offset * spacing; pos.X += stof(v_pos[0]) * (float)spacing.X; pos.Y += stof(v_pos[1]) * (float)spacing.Y; @@ -952,6 +986,14 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) evt.KeyInput.Shift = 0; evt.KeyInput.PressedDown = true; e->OnEvent(evt); + + if (parts.size() >= 5) { + // TODO: remove after 2016-11-03 + warningstream << "pwdfield: use field_close_on_enter[name, enabled]" << + " instead of the 5th param" << std::endl; + field_close_on_enter[name] = is_yes(parts[4]); + } + m_fields.push_back(spec); return; } @@ -970,7 +1012,7 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data, if(data->explicit_size) warningstream<<"invalid use of unpositioned \"field\" in inventory"<= 4) { + // TODO: remove after 2016-11-03 + warningstream << "field/simple: use field_close_on_enter[name, enabled]" << + " instead of the 4th param" << std::endl; + field_close_on_enter[name] = is_yes(parts[3]); + } + m_fields.push_back(spec); } @@ -1049,9 +1098,9 @@ void GUIFormSpecMenu::parseTextArea(parserData* data, MY_CHECKPOS(type,0); MY_CHECKGEOM(type,1); - v2s32 pos; - pos.X = stof(v_pos[0]) * (float) spacing.X; - pos.Y = stof(v_pos[1]) * (float) spacing.Y; + v2s32 pos = pos_offset * spacing; + pos.X += stof(v_pos[0]) * (float) spacing.X; + pos.Y += stof(v_pos[1]) * (float) spacing.Y; v2s32 geom; @@ -1137,6 +1186,14 @@ void GUIFormSpecMenu::parseTextArea(parserData* data, addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, 0); } } + + if (parts.size() >= 6) { + // TODO: remove after 2016-11-03 + warningstream << "field/textarea: use field_close_on_enter[name, enabled]" << + " instead of the 6th param" << std::endl; + field_close_on_enter[name] = is_yes(parts[5]); + } + m_fields.push_back(spec); } @@ -1150,8 +1207,8 @@ void GUIFormSpecMenu::parseField(parserData* data,std::string element, return; } - if ((parts.size() == 5) || - ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION))) + if ((parts.size() == 5) || (parts.size() == 6) || + ((parts.size() > 6) && (m_formspec_version > FORMSPEC_API_VERSION))) { parseTextArea(data,parts,type); return; @@ -1171,7 +1228,7 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element) MY_CHECKPOS("label",0); - v2s32 pos = padding; + v2s32 pos = padding + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float)spacing.X; pos.Y += (stof(v_pos[1]) + 7.0/30.0) * (float)spacing.Y; @@ -1228,7 +1285,7 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element) MY_CHECKPOS("vertlabel",1); - v2s32 pos = padding; + v2s32 pos = padding + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float)spacing.X; pos.Y += stof(v_pos[1]) * (float)spacing.Y; @@ -1282,7 +1339,7 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element, MY_CHECKPOS("imagebutton",0); MY_CHECKGEOM("imagebutton",1); - v2s32 pos = padding; + v2s32 pos = padding + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float)spacing.X; pos.Y += stof(v_pos[1]) * (float)spacing.Y; v2s32 geom; @@ -1387,7 +1444,7 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) spec.ftype = f_TabHeader; - v2s32 pos(0,0); + v2s32 pos = pos_offset * spacing; pos.X += stof(v_pos[0]) * (float)spacing.X; pos.Y += stof(v_pos[1]) * (float)spacing.Y - m_btn_height * 2; v2s32 geom; @@ -1452,7 +1509,7 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) MY_CHECKPOS("itemimagebutton",0); MY_CHECKGEOM("itemimagebutton",1); - v2s32 pos = padding; + v2s32 pos = padding + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float)spacing.X; pos.Y += stof(v_pos[1]) * (float)spacing.Y; v2s32 geom; @@ -1490,7 +1547,7 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element) rect+=data->basepos-padding; spec.rect=rect; m_fields.push_back(spec); - pos = padding + AbsoluteRect.UpperLeftCorner; + pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float) spacing.X; pos.Y += stof(v_pos[1]) * (float) spacing.Y; m_itemimages.push_back(ImageDrawSpec("", item_name, e, pos, geom)); @@ -1513,7 +1570,7 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element) MY_CHECKPOS("box",0); MY_CHECKGEOM("box",1); - v2s32 pos = padding + AbsoluteRect.UpperLeftCorner; + v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing; pos.X += stof(v_pos[0]) * (float) spacing.X; pos.Y += stof(v_pos[1]) * (float) spacing.Y; @@ -1675,8 +1732,18 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element) std::string type = trim(parts[0]); std::string description = trim(parts[1]); + if (type == "container") { + parseContainer(data, description); + return; + } + + if (type == "container_end") { + parseContainerEnd(data); + return; + } + if (type == "list") { - parseList(data,description); + parseList(data, description); return; } @@ -1686,22 +1753,22 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element) } if (type == "checkbox") { - parseCheckbox(data,description); + parseCheckbox(data, description); return; } if (type == "image") { - parseImage(data,description); + parseImage(data, description); return; } if (type == "item_image") { - parseItemImage(data,description); + parseItemImage(data, description); return; } - if ((type == "button") || (type == "button_exit")) { - parseButton(data,description,type); + if (type == "button" || type == "button_exit") { + parseButton(data, description, type); return; } @@ -1735,6 +1802,11 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element) return; } + if (type == "field_close_on_enter") { + parseFieldCloseOnEnter(data, description); + return; + } + if (type == "pwdfield") { parsePwdField(data,description); return; @@ -1878,7 +1950,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) m_slotbordercolor = video::SColor(200,0,0,0); m_slotborder = false; - m_clipbackground = false; // Add tooltip { assert(m_tooltip_element == NULL); @@ -2023,10 +2094,16 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) gui::IGUIFont *old_font = skin->getFont(); skin->setFont(m_font); + pos_offset = v2s32(); for (; i< elements.size(); i++) { parseElement(&mydata, elements[i]); } + if (!container_stack.empty()) { + errorstream << "Invalid formspec string: container was never closed!" + << std::endl; + } + // If there are fields without explicit size[], add a "Proceed" // button and adjust size to fit all the fields. if (m_fields.size() && !mydata.explicit_size) { @@ -2330,7 +2407,7 @@ void GUIFormSpecMenu::drawMenu() // Image rectangle on screen core::rect rect = imgrect + spec.pos; - if (m_clipbackground) { + if (spec.clip) { core::dimension2d absrec_size = AbsoluteRect.getSize(); rect = core::rect(AbsoluteRect.UpperLeftCorner.X - spec.pos.X, AbsoluteRect.UpperLeftCorner.Y - spec.pos.Y, @@ -2344,8 +2421,7 @@ void GUIFormSpecMenu::drawMenu() core::rect(core::position2d(0,0), core::dimension2di(texture->getOriginalSize())), NULL/*&AbsoluteClippingRect*/, colors, true); - } - else { + } else { errorstream << "GUIFormSpecMenu::drawMenu() Draw backgrounds unable to load texture:" << std::endl; errorstream << "\t" << spec.name << std::endl; } @@ -2698,6 +2774,7 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no) if (!current_field_enter_pending.empty()) { fields["key_enter_field"] = current_field_enter_pending; + current_field_enter_pending = ""; } if (current_keys_pending.key_escape) { @@ -3630,15 +3707,22 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) if (event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) { if (event.GUIEvent.Caller->getID() > 257) { + bool close_on_enter = true; for (u32 i = 0; i < m_fields.size(); i++) { FieldSpec &s = m_fields[i]; if (s.ftype == f_Unknown && s.fid == event.GUIEvent.Caller->getID()) { current_field_enter_pending = s.fname; + UNORDERED_MAP::const_iterator it = + field_close_on_enter.find(s.fname); + if (it != field_close_on_enter.end()) + close_on_enter = (*it).second; + + break; } } - if (m_allowclose) { + if (m_allowclose && close_on_enter) { current_keys_pending.key_enter = true; acceptInput(quit_mode_accept); quitMenu();