diff --git a/src/game.cpp b/src/game.cpp index 768bb5602..69b3c321a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -132,6 +132,28 @@ private: Client *m_client; }; +/* Form update callback */ + +class NodeMetadataFormSource: public IFormSource +{ +public: + NodeMetadataFormSource(ClientMap *map, v3s16 p): + m_map(map), + m_p(p) + { + } + std::string getForm() + { + NodeMetadata *meta = m_map->getNodeMetadata(m_p); + if(!meta) + return ""; + return meta->getString("formspec"); + } + + ClientMap *m_map; + v3s16 m_p; +}; + /* Hotbar draw routine */ @@ -2348,6 +2370,8 @@ void the_game( &client, gamedef); menu->setFormSpec(meta->getString("formspec"), inventoryloc); + menu->setFormSource(new NodeMetadataFormSource( + &client.getEnv().getClientMap(), nodepos)); menu->drop(); } // Otherwise report right click to server diff --git a/src/guiInventoryMenu.cpp b/src/guiInventoryMenu.cpp index 492ea1c19..9898fd5aa 100644 --- a/src/guiInventoryMenu.cpp +++ b/src/guiInventoryMenu.cpp @@ -126,23 +126,24 @@ GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env, IMenuManager *menumgr, InventoryManager *invmgr, IGameDef *gamedef - ): +): GUIModalMenu(env, parent, id, menumgr), m_invmgr(invmgr), - m_gamedef(gamedef) + m_gamedef(gamedef), + m_form_src(NULL), + m_selected_item(NULL), + m_selected_amount(0), + m_selected_dragging(false), + m_tooltip_element(NULL) { - m_selected_item = NULL; - m_selected_amount = 0; - m_selected_dragging = false; - m_tooltip_element = NULL; } GUIInventoryMenu::~GUIInventoryMenu() { removeChildren(); - if(m_selected_item) - delete m_selected_item; + delete m_selected_item; + delete m_form_src; } void GUIInventoryMenu::removeChildren() @@ -244,8 +245,6 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize) pos.X += stof(f.next(",")) * (float)spacing.X; pos.Y += stof(f.next(";")) * (float)spacing.Y; v2s32 geom; - /*geom.X = imgsize.X + ((stoi(f.next(","))-1) * spacing.X); - geom.Y = imgsize.Y + ((stoi(f.next(";"))-1) * spacing.Y);*/ geom.X = stof(f.next(",")) * (float)imgsize.X; geom.Y = stof(f.next(";")) * (float)imgsize.Y; std::string name = f.next("]"); @@ -430,6 +429,14 @@ void GUIInventoryMenu::drawSelectedItem() void GUIInventoryMenu::drawMenu() { + if(m_form_src){ + std::string newform = m_form_src->getForm(); + if(newform != m_formspec_string){ + m_formspec_string = newform; + regenerateGui(m_screensize_old); + } + } + updateSelectedItem(); gui::IGUISkin* skin = Environment->getSkin(); diff --git a/src/guiInventoryMenu.h b/src/guiInventoryMenu.h index beb6ef2e8..3f03064df 100644 --- a/src/guiInventoryMenu.h +++ b/src/guiInventoryMenu.h @@ -30,6 +30,13 @@ with this program; if not, write to the Free Software Foundation, Inc., class IGameDef; class InventoryManager; +class IFormSource +{ +public: + virtual ~IFormSource(){} + virtual std::string getForm() = 0; +}; + void drawItemStack(video::IVideoDriver *driver, gui::IGUIFont *font, const ItemStack &item, @@ -117,6 +124,12 @@ public: m_current_inventory_location = current_inventory_location; regenerateGui(m_screensize_old); } + + // form_src is deleted by this GUIInventoryMenu + void setFormSource(IFormSource *form_src) + { + m_form_src = form_src; + } void removeChildren(); /* @@ -147,6 +160,7 @@ protected: std::string m_formspec_string; InventoryLocation m_current_inventory_location; + IFormSource *m_form_src; core::array m_inventorylists; core::array m_images;