void GUIInventoryMenu::regenerateGui(v2u32 screensize) { // Remove children removeChildren(); padding = v2s32(screensize.Y/40, screensize.Y/40); spacing = v2s32(screensize.Y/12, screensize.Y/13); imgsize = v2s32(screensize.Y/15, screensize.Y/15); s32 helptext_h = 15; v2s32 size( padding.X*2+spacing.X*(m_menu_size.X-1)+imgsize.X, padding.Y*2+spacing.Y*(m_menu_size.Y-1)+imgsize.Y + helptext_h ); core::rect<s32> rect( screensize.X/2 - size.X/2, screensize.Y/2 - size.Y/2, screensize.X/2 + size.X/2, screensize.Y/2 + size.Y/2 ); DesiredRect = rect; recalculateAbsolutePosition(false); v2s32 basepos = getBasePos(); m_draw_spec.clear(); for(u16 i=0; i<m_init_draw_spec.size(); i++) { DrawSpec &s = m_init_draw_spec[i]; if(s.type == "list") { m_draw_spec.push_back(ListDrawSpec(s.name, s.subname, basepos + v2s32(spacing.X*s.pos.X, spacing.Y*s.pos.Y), s.geom)); } } // Add children { core::rect<s32> rect(0, 0, size.X-padding.X*2, helptext_h); rect = rect + v2s32(size.X/2 - rect.getWidth()/2, size.Y-rect.getHeight()-15); const wchar_t *text = L"Left click: Move all items, Right click: Move single item"; Environment->addStaticText(text, rect, false, true, this, 256); } }
void GUIFormSpecMenu::regenerateGui(v2u32 screensize) { // Remove children removeChildren(); v2s32 size(100,100); s32 helptext_h = 15; core::rect<s32> rect; // Base position of contents of form v2s32 basepos = getBasePos(); // State of basepos, 0 = not set, 1= set by formspec, 2 = set by size[] element // Used to adjust form size automatically if needed // A proceed button is added if there is no size[] element int bp_set = 0; /* Convert m_init_draw_spec to m_inventorylists */ m_inventorylists.clear(); m_images.clear(); m_fields.clear(); Strfnd f(m_formspec_string); while(f.atend() == false) { std::string type = trim(f.next("[")); if(type == "invsize" || type == "size") { v2f invsize; invsize.X = stof(f.next(",")); if(type == "size") { invsize.Y = stof(f.next("]")); } else{ invsize.Y = stof(f.next(";")); f.next("]"); } infostream<<"Form size ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl; padding = v2s32(screensize.Y/40, screensize.Y/40); spacing = v2s32(screensize.Y/12, screensize.Y/13); imgsize = v2s32(screensize.Y/15, screensize.Y/15); size = v2s32( padding.X*2+spacing.X*(invsize.X-1.0)+imgsize.X, padding.Y*2+spacing.Y*(invsize.Y-1.0)+imgsize.Y + (helptext_h-5) ); rect = core::rect<s32>( screensize.X/2 - size.X/2, screensize.Y/2 - size.Y/2, screensize.X/2 + size.X/2, screensize.Y/2 + size.Y/2 ); DesiredRect = rect; recalculateAbsolutePosition(false); basepos = getBasePos(); bp_set = 2; } else if(type == "list") { std::string name = f.next(";"); InventoryLocation loc; if(name == "context" || name == "current_name") loc = m_current_inventory_location; else loc.deSerialize(name); std::string listname = f.next(";"); v2s32 pos = basepos; pos.X += stof(f.next(",")) * (float)spacing.X; pos.Y += stof(f.next(";")) * (float)spacing.Y; v2s32 geom; geom.X = stoi(f.next(",")); geom.Y = stoi(f.next(";")); infostream<<"list inv="<<name<<", listname="<<listname <<", pos=("<<pos.X<<","<<pos.Y<<")" <<", geom=("<<geom.X<<","<<geom.Y<<")" <<std::endl; std::string start_i_s = f.next("]"); s32 start_i = 0; if(start_i_s != "") start_i = stoi(start_i_s); if(bp_set != 2) errorstream<<"WARNING: invalid use of list without a size[] element"<<std::endl; m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom, start_i)); } else if(type == "image") { v2s32 pos = basepos; pos.X += stof(f.next(",")) * (float)spacing.X; pos.Y += stof(f.next(";")) * (float)spacing.Y; v2s32 geom; geom.X = stof(f.next(",")) * (float)imgsize.X; geom.Y = stof(f.next(";")) * (float)imgsize.Y; std::string name = f.next("]"); infostream<<"image name="<<name <<", pos=("<<pos.X<<","<<pos.Y<<")" <<", geom=("<<geom.X<<","<<geom.Y<<")" <<std::endl; if(bp_set != 2) errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl; m_images.push_back(ImageDrawSpec(name, pos, geom)); } else if(type == "field") { std::string fname = f.next(";"); std::string flabel = f.next(";"); if(fname.find(",") == std::string::npos && flabel.find(",") == std::string::npos) { if(!bp_set) { rect = core::rect<s32>( screensize.X/2 - 580/2, screensize.Y/2 - 300/2, screensize.X/2 + 580/2, screensize.Y/2 + 300/2 ); DesiredRect = rect; recalculateAbsolutePosition(false); basepos = getBasePos(); bp_set = 1; } else if(bp_set == 2) errorstream<<"WARNING: invalid use of unpositioned field in inventory"<<std::endl; v2s32 pos = basepos; pos.Y = ((m_fields.size()+2)*60); v2s32 size = DesiredRect.getSize(); rect = core::rect<s32>(size.X/2-150, pos.Y, (size.X/2-150)+300, pos.Y+30); } else { v2s32 pos; pos.X = stof(fname.substr(0,fname.find(","))) * (float)spacing.X; pos.Y = stof(fname.substr(fname.find(",")+1)) * (float)spacing.Y; v2s32 geom; geom.X = (stof(flabel.substr(0,flabel.find(","))) * (float)spacing.X)-(spacing.X-imgsize.X); pos.Y += (stof(flabel.substr(flabel.find(",")+1)) * (float)imgsize.Y)/2; rect = core::rect<s32>(pos.X, pos.Y-15, pos.X+geom.X, pos.Y+15); fname = f.next(";"); flabel = f.next(";"); if(bp_set != 2) errorstream<<"WARNING: invalid use of positioned field without a size[] element"<<std::endl; } std::string odefault = f.next("]"); std::string fdefault; // fdefault may contain a variable reference, which // needs to be resolved from the node metadata if(m_form_src) fdefault = m_form_src->resolveText(odefault); else fdefault = odefault; FieldSpec spec = FieldSpec( narrow_to_wide(fname.c_str()), narrow_to_wide(flabel.c_str()), narrow_to_wide(fdefault.c_str()), 258+m_fields.size() ); // three cases: field and no label, label and no field, label and field if (flabel == "") { spec.send = true; gui::IGUIElement *e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid); Environment->setFocus(e); irr::SEvent evt; evt.EventType = EET_KEY_INPUT_EVENT; evt.KeyInput.Key = KEY_END; evt.KeyInput.PressedDown = true; e->OnEvent(evt); } else if (fname == "") { // set spec field id to 0, this stops submit searching for a value that isn't there Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, spec.fid); } else { spec.send = true; gui::IGUIElement *e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid); Environment->setFocus(e); rect.UpperLeftCorner.Y -= 15; rect.LowerRightCorner.Y -= 15; Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0); irr::SEvent evt; evt.EventType = EET_KEY_INPUT_EVENT; evt.KeyInput.Key = KEY_END; evt.KeyInput.PressedDown = true; e->OnEvent(evt); } m_fields.push_back(spec); } else if(type == "label") { v2s32 pos = padding; pos.X += stof(f.next(",")) * (float)spacing.X; pos.Y += stof(f.next(";")) * (float)spacing.Y; rect = core::rect<s32>(pos.X, pos.Y+((imgsize.Y/2)-15), pos.X+300, pos.Y+((imgsize.Y/2)+15)); std::string flabel = f.next("]"); if(bp_set != 2) errorstream<<"WARNING: invalid use of label without a size[] element"<<std::endl; FieldSpec spec = FieldSpec( narrow_to_wide(""), narrow_to_wide(flabel.c_str()), narrow_to_wide(""), 258+m_fields.size() ); Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, spec.fid); m_fields.push_back(spec); } else if(type == "button" || type == "button_exit") { v2s32 pos = padding; pos.X += stof(f.next(",")) * (float)spacing.X; pos.Y += stof(f.next(";")) * (float)spacing.Y; v2s32 geom; geom.X = (stof(f.next(",")) * (float)spacing.X)-(spacing.X-imgsize.X); pos.Y += (stof(f.next(";")) * (float)imgsize.Y)/2; rect = core::rect<s32>(pos.X, pos.Y-15, pos.X+geom.X, pos.Y+15); std::string fname = f.next(";"); std::string flabel = f.next("]"); if(bp_set != 2) errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl; FieldSpec spec = FieldSpec( narrow_to_wide(fname.c_str()), narrow_to_wide(flabel.c_str()), narrow_to_wide(""), 258+m_fields.size() ); spec.is_button = true; if(type == "button_exit") spec.is_exit = true; Environment->addButton(rect, this, spec.fid, spec.flabel.c_str()); m_fields.push_back(spec); } else if(type == "image_button" || type == "image_button_exit") { v2s32 pos = padding; pos.X += stof(f.next(",")) * (float)spacing.X; pos.Y += stof(f.next(";")) * (float)spacing.Y; v2s32 geom; geom.X = (stof(f.next(",")) * (float)spacing.X)-(spacing.X-imgsize.X); geom.Y = (stof(f.next(";")) * (float)spacing.Y)-(spacing.Y-imgsize.Y); rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y); std::string fimage = f.next(";"); std::string fname = f.next(";"); std::string flabel = f.next("]"); if(bp_set != 2) errorstream<<"WARNING: invalid use of image_button without a size[] element"<<std::endl; FieldSpec spec = FieldSpec( narrow_to_wide(fname.c_str()), narrow_to_wide(flabel.c_str()), narrow_to_wide(fimage.c_str()), 258+m_fields.size() ); spec.is_button = true; if(type == "image_button_exit") spec.is_exit = true; video::ITexture *texture = m_gamedef->tsrc()->getTextureRaw(fimage); gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str()); e->setImage(texture); e->setPressedImage(texture); e->setScaleImage(true); m_fields.push_back(spec); } else { // Ignore others std::string ts = f.next("]"); infostream<<"Unknown DrawSpec: type="<<type<<", data=\""<<ts<<"\"" <<std::endl; } } // If there's inventory, put the usage string at the bottom if (m_inventorylists.size()) { changeCtype(""); core::rect<s32> rect(0, 0, size.X-padding.X*2, helptext_h); rect = rect + v2s32(size.X/2 - rect.getWidth()/2, size.Y-rect.getHeight()-5); const wchar_t *text = wgettext("Left click: Move all items, Right click: Move single item"); Environment->addStaticText(text, rect, false, true, this, 256); changeCtype("C"); } // If there's fields, add a Proceed button if (m_fields.size() && bp_set != 2) { // if the size wasn't set by an invsize[] or size[] adjust it now to fit all the fields rect = core::rect<s32>( screensize.X/2 - 580/2, screensize.Y/2 - 300/2, screensize.X/2 + 580/2, screensize.Y/2 + 240/2+(m_fields.size()*60) ); DesiredRect = rect; recalculateAbsolutePosition(false); basepos = getBasePos(); changeCtype(""); { v2s32 pos = basepos; pos.Y = ((m_fields.size()+2)*60); v2s32 size = DesiredRect.getSize(); rect = core::rect<s32>(size.X/2-70, pos.Y, (size.X/2-70)+140, pos.Y+30); Environment->addButton(rect, this, 257, wgettext("Proceed")); } changeCtype("C"); } // Add tooltip { // Note: parent != this so that the tooltip isn't clipped by the menu rectangle m_tooltip_element = Environment->addStaticText(L"",core::rect<s32>(0,0,110,18)); m_tooltip_element->enableOverrideColor(true); m_tooltip_element->setBackgroundColor(video::SColor(255,110,130,60)); m_tooltip_element->setDrawBackground(true); m_tooltip_element->setDrawBorder(true); m_tooltip_element->setOverrideColor(video::SColor(255,255,255,255)); m_tooltip_element->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER); m_tooltip_element->setWordWrap(false); } }