Reshape inventory menu code

This commit is contained in:
Perttu Ahola 2012-06-03 16:03:19 +03:00
parent e4bc76f55c
commit 7bf446f671
4 changed files with 79 additions and 181 deletions

@ -630,7 +630,7 @@ button[<X>,<Y>;<W>,<H>;<name>;<label>]
^ Not implemented ^ Not implemented
Inventory location: Inventory location:
- "current_name": Selected node metadata - "context": Selected node metadata (deprecated: "current_name")
- "current_player": Player to whom the menu is shown - "current_player": Player to whom the menu is shown
- "player:<name>": Any player - "player:<name>": Any player
- "nodemeta:<X>,<Y>,<Z>": Any node metadata - "nodemeta:<X>,<Y>,<Z>": Any node metadata

@ -1569,24 +1569,18 @@ void the_game(
GUIInventoryMenu *menu = GUIInventoryMenu *menu =
new GUIInventoryMenu(guienv, guiroot, -1, new GUIInventoryMenu(guienv, guiroot, -1,
&g_menumgr, v2s16(8,7), &g_menumgr,
&client, gamedef); &client, gamedef);
InventoryLocation inventoryloc; InventoryLocation inventoryloc;
inventoryloc.setCurrentPlayer(); inventoryloc.setCurrentPlayer();
core::array<GUIInventoryMenu::DrawSpec> draw_spec; menu->setFormSpec(
draw_spec.push_back(GUIInventoryMenu::DrawSpec( "invsize[8,7;]"
"list", inventoryloc, "main", "list[current_player;main;0,3;8,4;]"
v2s32(0, 3), v2s32(8, 4))); "list[current_player;craft;3,0;3,3;]"
draw_spec.push_back(GUIInventoryMenu::DrawSpec( "list[current_player;craftpreview;7,1;1,1;]"
"list", inventoryloc, "craft", , inventoryloc);
v2s32(3, 0), v2s32(3, 3)));
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
"list", inventoryloc, "craftpreview",
v2s32(7, 1), v2s32(1, 1)));
menu->setDrawSpec(draw_spec);
menu->drop(); menu->drop();
} }
@ -2345,23 +2339,14 @@ void the_game(
InventoryLocation inventoryloc; InventoryLocation inventoryloc;
inventoryloc.setNodeMeta(nodepos); inventoryloc.setNodeMeta(nodepos);
/* Create menu */
/*
Create menu
*/
core::array<GUIInventoryMenu::DrawSpec> draw_spec;
v2s16 invsize =
GUIInventoryMenu::makeDrawSpecArrayFromString(
draw_spec,
meta->getString("formspec"),
inventoryloc);
GUIInventoryMenu *menu = GUIInventoryMenu *menu =
new GUIInventoryMenu(guienv, guiroot, -1, new GUIInventoryMenu(guienv, guiroot, -1,
&g_menumgr, invsize, &g_menumgr,
&client, gamedef); &client, gamedef);
menu->setDrawSpec(draw_spec); menu->setFormSpec(meta->getString("formspec"),
inventoryloc);
menu->drop(); menu->drop();
} }
// Otherwise report right click to server // Otherwise report right click to server

@ -123,12 +123,10 @@ void drawItemStack(video::IVideoDriver *driver,
GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env, GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id, gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr, IMenuManager *menumgr,
v2s16 menu_size,
InventoryManager *invmgr, InventoryManager *invmgr,
IGameDef *gamedef IGameDef *gamedef
): ):
GUIModalMenu(env, parent, id, menumgr), GUIModalMenu(env, parent, id, menumgr),
m_menu_size(menu_size),
m_invmgr(invmgr), m_invmgr(invmgr),
m_gamedef(gamedef) m_gamedef(gamedef)
{ {
@ -178,42 +176,72 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
// Remove children // Remove children
removeChildren(); removeChildren();
/*padding = v2s32(24,24); v2s32 size(100,100);
spacing = v2s32(60,56);
imgsize = v2s32(48,48);*/
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; s32 helptext_h = 15;
core::rect<s32> rect;
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(); v2s32 basepos = getBasePos();
/* Convert m_init_draw_spec to m_draw_spec */
m_draw_spec.clear(); m_draw_spec.clear();
for(u16 i=0; i<m_init_draw_spec.size(); i++)
Strfnd f(m_formspec_string);
while(f.atend() == false)
{ {
DrawSpec &s = m_init_draw_spec[i]; std::string type = trim(f.next("["));
if(s.type == "list") if(type == "invsize")
{ {
m_draw_spec.push_back(ListDrawSpec(s.name, s.subname, v2s16 invsize;
basepos + v2s32(spacing.X*s.pos.X, spacing.Y*s.pos.Y), invsize.X = stoi(f.next(","));
s.geom)); invsize.Y = stoi(f.next(";"));
infostream<<"invsize ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
f.next("]");
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)+imgsize.X,
padding.Y*2+spacing.Y*(invsize.Y-1)+imgsize.Y + helptext_h
);
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();
}
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(";");
s32 pos_x = stoi(f.next(","));
s32 pos_y = stoi(f.next(";"));
s32 geom_w = stoi(f.next(","));
s32 geom_h = stoi(f.next(";"));
infostream<<"list inv="<<name<<", listname="<<listname
<<", pos=("<<pos_x<<","<<pos_y<<")"
<<", geom=("<<geom_w<<","<<geom_h<<")"
<<std::endl;
f.next("]");
m_draw_spec.push_back(ListDrawSpec(loc, listname,
basepos + v2s32(spacing.X*pos_x, spacing.Y*pos_y),
v2s32(geom_w,geom_h)));
}
else
{
// Ignore others
std::string ts = f.next("]");
infostream<<"Unknown DrawSpec: type="<<type<<", data=\""<<ts<<"\""
<<std::endl;
} }
} }
@ -820,88 +848,3 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
return Parent ? Parent->OnEvent(event) : false; return Parent ? Parent->OnEvent(event) : false;
} }
/*
Here is an example traditional set-up sequence for a DrawSpec list:
std::string furnace_inv_id = "nodemetadata:0,1,2";
core::array<GUIInventoryMenu::DrawSpec> draw_spec;
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
"list", furnace_inv_id, "fuel",
v2s32(2, 3), v2s32(1, 1)));
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
"list", furnace_inv_id, "src",
v2s32(2, 1), v2s32(1, 1)));
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
"list", furnace_inv_id, "dst",
v2s32(5, 1), v2s32(2, 2)));
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
"list", "current_player", "main",
v2s32(0, 5), v2s32(8, 4)));
setDrawSpec(draw_spec);
Here is the string for creating the same DrawSpec list (a single line,
spread to multiple lines here):
GUIInventoryMenu::makeDrawSpecArrayFromString(
draw_spec,
"nodemetadata:0,1,2",
"invsize[8,9;]"
"list[current_name;fuel;2,3;1,1;]"
"list[current_name;src;2,1;1,1;]"
"list[current_name;dst;5,1;2,2;]"
"list[current_player;main;0,5;8,4;]");
Returns inventory menu size defined by invsize[].
*/
v2s16 GUIInventoryMenu::makeDrawSpecArrayFromString(
core::array<GUIInventoryMenu::DrawSpec> &draw_spec,
const std::string &data,
const InventoryLocation &current_location)
{
v2s16 invsize(8,9);
Strfnd f(data);
while(f.atend() == false)
{
std::string type = trim(f.next("["));
//infostream<<"type="<<type<<std::endl;
if(type == "list")
{
std::string name = f.next(";");
InventoryLocation loc;
if(name == "current_name")
loc = current_location;
else
loc.deSerialize(name);
std::string subname = f.next(";");
s32 pos_x = stoi(f.next(","));
s32 pos_y = stoi(f.next(";"));
s32 geom_x = stoi(f.next(","));
s32 geom_y = stoi(f.next(";"));
infostream<<"list name="<<name<<", subname="<<subname
<<", pos=("<<pos_x<<","<<pos_y<<")"
<<", geom=("<<geom_x<<","<<geom_y<<")"
<<std::endl;
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
type, loc, subname,
v2s32(pos_x,pos_y),v2s32(geom_x,geom_y)));
f.next("]");
}
else if(type == "invsize")
{
invsize.X = stoi(f.next(","));
invsize.Y = stoi(f.next(";"));
infostream<<"invsize ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
f.next("]");
}
else
{
// Ignore others
std::string ts = f.next("]");
infostream<<"Unknown DrawSpec: type="<<type<<", data=\""<<ts<<"\""
<<std::endl;
}
}
return invsize;
}

@ -84,49 +84,20 @@ class GUIInventoryMenu : public GUIModalMenu
v2s32 geom; v2s32 geom;
}; };
public: public:
struct DrawSpec
{
DrawSpec()
{
}
DrawSpec(const std::string &a_type,
const InventoryLocation &a_name,
const std::string &a_subname,
v2s32 a_pos,
v2s32 a_geom)
{
type = a_type;
name = a_name;
subname = a_subname;
pos = a_pos;
geom = a_geom;
}
std::string type;
InventoryLocation name;
std::string subname;
v2s32 pos;
v2s32 geom;
};
// See .cpp for format
static v2s16 makeDrawSpecArrayFromString(
core::array<GUIInventoryMenu::DrawSpec> &draw_spec,
const std::string &data,
const InventoryLocation &current_location);
GUIInventoryMenu(gui::IGUIEnvironment* env, GUIInventoryMenu(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id, gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr, IMenuManager *menumgr,
v2s16 menu_size,
InventoryManager *invmgr, InventoryManager *invmgr,
IGameDef *gamedef IGameDef *gamedef
); );
~GUIInventoryMenu(); ~GUIInventoryMenu();
void setDrawSpec(core::array<DrawSpec> &init_draw_spec) void setFormSpec(const std::string &formspec_string,
InventoryLocation current_inventory_location)
{ {
m_init_draw_spec = init_draw_spec; m_formspec_string = formspec_string;
m_current_inventory_location = current_inventory_location;
regenerateGui(m_screensize_old);
} }
void removeChildren(); void removeChildren();
@ -149,8 +120,6 @@ protected:
return padding + AbsoluteRect.UpperLeftCorner; return padding + AbsoluteRect.UpperLeftCorner;
} }
v2s16 m_menu_size;
v2s32 padding; v2s32 padding;
v2s32 spacing; v2s32 spacing;
v2s32 imgsize; v2s32 imgsize;
@ -158,7 +127,8 @@ protected:
InventoryManager *m_invmgr; InventoryManager *m_invmgr;
IGameDef *m_gamedef; IGameDef *m_gamedef;
core::array<DrawSpec> m_init_draw_spec; std::string m_formspec_string;
InventoryLocation m_current_inventory_location;
core::array<ListDrawSpec> m_draw_spec; core::array<ListDrawSpec> m_draw_spec;
ItemSpec *m_selected_item; ItemSpec *m_selected_item;