redoing gui stuff
authorPerttu Ahola <celeron55@gmail.com>
Thu, 23 Dec 2010 13:31:50 +0000 (15:31 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Thu, 23 Dec 2010 13:31:50 +0000 (15:31 +0200)
Makefile
src/guiInventoryMenu.cpp
src/guiInventoryMenu.h
src/guiPauseMenu.cpp
src/guiPauseMenu.h
src/main.cpp
src/modalMenu.h [new file with mode: 0644]

index 5dcee0d9a7beac69af7751f80c39fc5e8b191c3b..25e58a99a7005e05741f87f80b1c4c52382d78a0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,9 +22,9 @@ IRRLICHTPATH = ../irrlicht/irrlicht-1.7.1
 JTHREADPATH = ../jthread/jthread-1.2.1\r
 \r
 #CXXFLAGS = -O2 -ffast-math -Wall -fomit-frame-pointer -pipe\r
-CXXFLAGS = -O2 -ffast-math -Wall -g -pipe\r
+#CXXFLAGS = -O2 -ffast-math -Wall -g -pipe\r
 #CXXFLAGS = -O1 -ffast-math -Wall -g\r
-#CXXFLAGS = -Wall -g -O0\r
+CXXFLAGS = -Wall -g -O0\r
 \r
 all: fast_linux\r
 \r
index 88cb8c830592f80e01b9a3bb8c3821861918bd43..bba23e719abf91a6d781ad4e1064a96c9750b167 100644 (file)
@@ -77,17 +77,14 @@ void drawInventoryItem(gui::IGUIEnvironment* env,
 
 GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
                gui::IGUIElement* parent, s32 id,
-               Inventory *inventory):
-       IGUIElement(gui::EGUIET_ELEMENT, env, parent, id,
-                       core::rect<s32>(0,0,100,100))
+               Inventory *inventory,
+               Queue<InventoryAction*> *actions,
+               int *active_menu_count):
+       GUIModalMenu(env, parent, id, active_menu_count)
 {
        m_inventory = inventory;
-       m_screensize_old = v2u32(0,0);
        m_selected_item = NULL;
-
-       resizeGui();
-
-       setVisible(false);
+       m_actions = actions;
 
        /*m_selected_item = new ItemSpec;
        m_selected_item->listname = "main";
@@ -100,14 +97,8 @@ GUIInventoryMenu::~GUIInventoryMenu()
                delete m_selected_item;
 }
 
-void GUIInventoryMenu::resizeGui()
+void GUIInventoryMenu::regenerateGui(v2u32 screensize)
 {
-       video::IVideoDriver* driver = Environment->getVideoDriver();
-       v2u32 screensize = driver->getScreenSize();
-       if(screensize == m_screensize_old)
-               return;
-       m_screensize_old = screensize;
-
        padding = v2s32(24,24);
        spacing = v2s32(60,56);
        imgsize = v2s32(48,48);
@@ -194,11 +185,8 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s)
        }
 }
 
-void GUIInventoryMenu::draw()
+void GUIInventoryMenu::drawMenu()
 {
-       if(!IsVisible)
-               return;
-               
        gui::IGUISkin* skin = Environment->getSkin();
        if (!skin)
                return;
@@ -229,12 +217,12 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
        {
                if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
                {
-                       setVisible(false);
+                       quitMenu();
                        return true;
                }
                if(event.KeyInput.Key==KEY_KEY_I && event.KeyInput.PressedDown)
                {
-                       setVisible(false);
+                       quitMenu();
                        return true;
                }
        }
@@ -265,7 +253,7 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
                                                a->from_i = m_selected_item->i;
                                                a->to_name = s.listname;
                                                a->to_i = s.i;
-                                               m_actions.push_back(a);
+                                               m_actions->push_back(a);
                                        }
                                        delete m_selected_item;
                                        m_selected_item = NULL;
@@ -322,11 +310,5 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
        return Parent ? Parent->OnEvent(event) : false;
 }
 
-InventoryAction* GUIInventoryMenu::getNextAction()
-{
-       if(m_actions.size() == 0)
-               return NULL;
-       return m_actions.pop_front();
-}
 
 
index 0032ce66aa64b15403b7d7db952a26ff906b827e..b6766484ebf69f835e50c5de3fcd48e8720c904e 100644 (file)
@@ -24,12 +24,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "common_irrlicht.h"
 #include "inventory.h"
 #include "utility.h"
+#include "modalMenu.h"
 
 void drawInventoryItem(gui::IGUIEnvironment* env,
                InventoryItem *item, core::rect<s32> rect,
                const core::rect<s32> *clip=0);
 
-class GUIInventoryMenu : public gui::IGUIElement
+class GUIInventoryMenu : public GUIModalMenu
 {
        struct ItemSpec
        {
@@ -71,35 +72,22 @@ class GUIInventoryMenu : public gui::IGUIElement
 public:
        GUIInventoryMenu(gui::IGUIEnvironment* env,
                        gui::IGUIElement* parent, s32 id,
-                       Inventory *inventory);
+                       Inventory *inventory,
+                       Queue<InventoryAction*> *actions,
+                       int *active_menu_count);
        ~GUIInventoryMenu();
 
        /*
                Remove and re-add (or reposition) stuff
        */
-       void resizeGui();
+       void regenerateGui(v2u32 screensize);
        
        ItemSpec getItemAtPos(v2s32 p) const;
        void drawList(const ListDrawSpec &s);
-       void draw();
-
-       void launch()
-       {
-               setVisible(true);
-               Environment->setFocus(this);
-       }
-
-       bool canTakeFocus(gui::IGUIElement *e)
-       {
-               return (e && (e == this || isMyChild(e)));
-       }
+       void drawMenu();
 
        bool OnEvent(const SEvent& event);
        
-       // Actions returned by this are sent to the server.
-       // Server replies by updating the inventory.
-       InventoryAction* getNextAction();
-       
 private:
        v2s32 getBasePos() const
        {
@@ -113,11 +101,9 @@ private:
        core::array<ListDrawSpec> m_draw_positions;
 
        Inventory *m_inventory;
-       v2u32 m_screensize_old;
 
        ItemSpec *m_selected_item;
-       
-       Queue<InventoryAction*> m_actions;
+       Queue<InventoryAction*> *m_actions;
 };
 
 #endif
index b8f0473e88c0b1e0240650fa8eae6692915b34c5..ed4f0cd6f5bcb0685041656f60f5c56cfaf71f77 100644 (file)
@@ -1,8 +1,6 @@
 /*\r
 Minetest-c55\r
 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>\r
-Original author Kabak Dmitry <userdima@gmail.com>, contributed under\r
-the minetest contributor agreement.\r
 \r
 This program is free software; you can redistribute it and/or modify\r
 it under the terms of the GNU General Public License as published by\r
@@ -26,33 +24,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 \r
 GUIPauseMenu::GUIPauseMenu(gui::IGUIEnvironment* env,\r
                gui::IGUIElement* parent, s32 id,\r
-               IrrlichtDevice *dev):\r
-       IGUIElement(gui::EGUIET_ELEMENT, env, parent, id,\r
-                       core::rect<s32>(0,0,100,100))\r
+               IrrlichtDevice *dev,\r
+               int *active_menu_count):\r
+       GUIModalMenu(env, parent, id, active_menu_count)\r
 {\r
        m_dev = dev;\r
-       m_screensize_old = v2u32(0,0);\r
-       \r
-       resizeGui();\r
-\r
-       setVisible(false);\r
 }\r
 \r
 GUIPauseMenu::~GUIPauseMenu()\r
 {\r
+       removeChildren();\r
 }\r
 \r
-void GUIPauseMenu::resizeGui()\r
+void GUIPauseMenu::removeChildren()\r
 {\r
-       video::IVideoDriver* driver = Environment->getVideoDriver();\r
-       v2u32 screensize = driver->getScreenSize();\r
-       if(screensize == m_screensize_old)\r
-               return;\r
-       m_screensize_old = screensize;\r
-\r
-       /*\r
-               Remove stuff\r
-       */\r
        {\r
                gui::IGUIElement *e = getElementFromId(256);\r
                if(e != NULL)\r
@@ -73,7 +58,18 @@ void GUIPauseMenu::resizeGui()
                if(e != NULL)\r
                        e->remove();\r
        }\r
+}\r
 \r
+void GUIPauseMenu::regenerateGui(v2u32 screensize)\r
+{\r
+       /*\r
+               Remove stuff\r
+       */\r
+       removeChildren();\r
+       \r
+       /*\r
+               Calculate new sizes and positions\r
+       */\r
        core::rect<s32> rect(\r
                        screensize.X/2 - 580/2,\r
                        screensize.Y/2 - 300/2,\r
@@ -129,11 +125,8 @@ void GUIPauseMenu::resizeGui()
        }\r
 }\r
 \r
-void GUIPauseMenu::draw()\r
+void GUIPauseMenu::drawMenu()\r
 {\r
-       if(!IsVisible)\r
-               return;\r
-               \r
        gui::IGUISkin* skin = Environment->getSkin();\r
        if (!skin)\r
                return;\r
@@ -151,7 +144,7 @@ bool GUIPauseMenu::OnEvent(const SEvent& event)
        {\r
                if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)\r
                {\r
-                       setVisible(false);\r
+                       quitMenu();\r
                        return true;\r
                }\r
        }\r
@@ -173,7 +166,7 @@ bool GUIPauseMenu::OnEvent(const SEvent& event)
                        switch(event.GUIEvent.Caller->getID())\r
                        {\r
                        case 256: // continue\r
-                               setVisible(false);\r
+                               quitMenu();\r
                                break;\r
                        case 257: // exit\r
                                m_dev->closeDevice();\r
@@ -185,104 +178,3 @@ bool GUIPauseMenu::OnEvent(const SEvent& event)
        return Parent ? Parent->OnEvent(event) : false;\r
 }\r
 \r
-#if 0\r
-GUIPauseMenu::GUIPauseMenu(IrrlichtDevice *device, IEventReceiver *recv):\r
-       dev(device),\r
-       oldRecv(recv)\r
-{\r
-       if(!dev)\r
-               return;\r
-       guienv=dev->getGUIEnvironment();\r
-\r
-       if (!loadMenu())\r
-               return;\r
-\r
-       device->setEventReceiver(this); // now WE are the input receiver! ahhaha! \r
-}\r
-\r
-GUIPauseMenu::~GUIPauseMenu(void)\r
-{\r
-}\r
-\r
-void GUIPauseMenu::scaleGui() // this function scales gui from the size stored in file to screen size\r
-{\r
-       core::dimension2du screen=dev->getVideoDriver()->getScreenSize();\r
-       core::vector2di real=root->getAbsolutePosition().LowerRightCorner; // determine gui size stored in file (which is size of my menu root node)\r
-       float factorX=(float)screen.Width/(float)real.X;\r
-       float factorY=(float)screen.Height/(float)real.Y;\r
-       scaleGui(guienv->getRootGUIElement(),factorX,factorY);\r
-}\r
-void GUIPauseMenu::scaleGui(gui::IGUIElement *node,float factorX,float factorY) // recursive set scale\r
-{\r
-       if((node->getParent() && node->getParent()->getID()==255) || node->getID()==255) // modify only menu's elements\r
-       {\r
-               int lx,rx,ly,ry;\r
-               lx=(float)node->getRelativePosition().UpperLeftCorner.X*factorX;\r
-               ly=(float)node->getRelativePosition().UpperLeftCorner.Y*factorY;\r
-               rx=(float)node->getRelativePosition().LowerRightCorner.X*factorX;\r
-               ry=(float)node->getRelativePosition().LowerRightCorner.Y*factorY;\r
-               node->setRelativePosition(core::recti(lx,ly,rx,ry));\r
-       }\r
-\r
-       core::list<gui::IGUIElement*>::ConstIterator it = node->getChildren().begin();\r
-       for(; it != node->getChildren().end(); ++it)\r
-               scaleGui((*it),factorX,factorY);\r
-}\r
-\r
-bool GUIPauseMenu::loadMenu()\r
-{\r
-       guienv->loadGUI("../data/pauseMenu.gui");\r
-\r
-       root=(gui::IGUIStaticText*)guienv->getRootGUIElement()->getElementFromId(255,true);\r
-       if(!root) // if there is no my root node then menu file not found or corrupted\r
-               return false;\r
-\r
-       scaleGui(); // scale gui to our screen size\r
-\r
-       root->setVisible(false); // hide our menu\r
-       // make it transparent\r
-       //root->setBackgroundColor(video::SColor(100,128,100,128));\r
-       root->setBackgroundColor(video::SColor(140,0,0,0));\r
-\r
-       return true;\r
-}\r
-\r
-bool GUIPauseMenu::OnEvent(const SEvent& event)\r
-{\r
-       if(!dev->isWindowFocused())\r
-               setVisible(true);\r
-\r
-       bool ret=false;\r
-       if(oldRecv && !isVisible()) // call master if we have it and if we are inactive\r
-               ret=oldRecv->OnEvent(event);\r
-\r
-       if(ret==true)\r
-               return true; // if the master receiver does the work\r
-\r
-       if(event.EventType==EET_KEY_INPUT_EVENT)\r
-       {\r
-               if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)\r
-               {\r
-                       setVisible(!isVisible());\r
-               }\r
-       }\r
-       if(event.EventType==EET_GUI_EVENT)\r
-       {\r
-               if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)\r
-               {\r
-                       switch(event.GUIEvent.Caller->getID())\r
-                       {\r
-                       case 256: // continue\r
-                               setVisible(false);\r
-                               break;\r
-                       case 257: // exit\r
-                               dev->closeDevice();\r
-                               break;\r
-                       }\r
-               }\r
-       }\r
-\r
-       return false;\r
-}\r
-#endif\r
-\r
index f26a261494ea8e1386b7be699f18809ad4622b64..7c37af8efac7989336b84a717a7e50aba6403ff3 100644 (file)
@@ -1,8 +1,6 @@
 /*\r
 Minetest-c55\r
 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>\r
-Original author Kabak Dmitry <userdima@gmail.com>, contributed under\r
-the minetest contributor agreement.\r
 \r
 This program is free software; you can redistribute it and/or modify\r
 it under the terms of the GNU General Public License as published by\r
@@ -24,63 +22,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define GUIPAUSEMENU_HEADER\r
 \r
 #include "common_irrlicht.h"\r
+#include "modalMenu.h"\r
 \r
-class GUIPauseMenu : public gui::IGUIElement\r
+class GUIPauseMenu : public GUIModalMenu\r
 {\r
 public:\r
        GUIPauseMenu(gui::IGUIEnvironment* env,\r
                        gui::IGUIElement* parent, s32 id,\r
-                       IrrlichtDevice *dev);\r
+                       IrrlichtDevice *dev,\r
+                       int *active_menu_count);\r
        ~GUIPauseMenu();\r
        \r
+       void removeChildren();\r
        /*\r
                Remove and re-add (or reposition) stuff\r
        */\r
-       void resizeGui();\r
+       void regenerateGui(v2u32 screensize);\r
 \r
-       void draw();\r
-\r
-       void launch()\r
-       {\r
-               setVisible(true);\r
-               Environment->setFocus(this);\r
-       }\r
-\r
-       bool canTakeFocus(gui::IGUIElement *e)\r
-       {\r
-               return (e && (e == this || isMyChild(e)));\r
-       }\r
+       void drawMenu();\r
 \r
        bool OnEvent(const SEvent& event);\r
        \r
 private:\r
        IrrlichtDevice *m_dev;\r
-       v2u32 m_screensize_old;\r
 };\r
 \r
-/*class GUIPauseMenu : public IEventReceiver\r
-{\r
-public:\r
-       void scaleGui();\r
-\r
-       GUIPauseMenu(IrrlichtDevice *device,IEventReceiver *recv);\r
-       ~GUIPauseMenu(void);\r
-\r
-       void setVisible(bool visible){root->setVisible(visible);};\r
-       bool isVisible(){return root->isVisible();};\r
-\r
-       bool OnEvent(const SEvent& event);\r
-\r
-private:\r
-       bool loadMenu();\r
-       void scaleGui(gui::IGUIElement *node,float factorX,float factorY);\r
-\r
-       IrrlichtDevice *dev;\r
-       gui::IGUIEnvironment *guienv;\r
-       IEventReceiver *oldRecv;\r
-\r
-       gui::IGUIStaticText *root;\r
-};*/\r
-\r
 #endif\r
 \r
index aacf4d7757e9dbc4994225eef7f50e8b67daea37..4d8a952ba406e615b962cca5ad47c9cd35b6d229 100644 (file)
@@ -268,22 +268,25 @@ extern void set_default_settings();
 //u16 g_selected_material = 0;\r
 u16 g_selected_item = 0;\r
 \r
+IrrlichtDevice *g_device = NULL;\r
+\r
 /*\r
        GUI Stuff\r
 */\r
 gui::IGUIEnvironment* guienv = NULL;\r
-GUIPauseMenu *pauseMenu = NULL;\r
-GUIInventoryMenu *inventoryMenu = NULL;\r
+gui::IGUIStaticText *guiroot = NULL;\r
+int g_active_menu_count = 0;\r
 \r
 bool noMenuActive()\r
 {\r
-       if(pauseMenu && pauseMenu->isVisible())\r
-               return false;\r
-       if(inventoryMenu && inventoryMenu->isVisible())\r
-               return false;\r
-       return true;\r
+       return (g_active_menu_count == 0);\r
 }\r
 \r
+// Inventory actions from the menu are buffered here before sending\r
+Queue<InventoryAction*> inventory_action_queue;\r
+// This is a copy of the inventory that the client's environment has\r
+Inventory local_inventory;\r
+\r
 std::wstring g_text_buffer;\r
 bool g_text_buffer_accepted = false;\r
 \r
@@ -360,7 +363,8 @@ public:
                                        }\r
                                }\r
                                \r
-                               if(pauseMenu != NULL)\r
+                               //if(pauseMenu != NULL)\r
+                               if(guienv != NULL && guiroot != NULL && g_device != NULL)\r
                                {\r
                                        if(event.KeyInput.Key == irr::KEY_ESCAPE)\r
                                        {\r
@@ -368,13 +372,18 @@ public:
                                                {\r
                                                        dstream<<DTIME<<"MyEventReceiver: "\r
                                                                        <<"Launching pause menu"<<std::endl;\r
-                                                       pauseMenu->launch();\r
+                                                       // It will delete itself by itself\r
+                                                       GUIPauseMenu *menu = new\r
+                                                                       GUIPauseMenu(guienv, guiroot, -1, g_device,\r
+                                                                       &g_active_menu_count);\r
+                                                       menu->drop();\r
                                                        return true;\r
                                                }\r
                                        }\r
                                }\r
 \r
-                               if(inventoryMenu != NULL)\r
+                               //if(inventoryMenu != NULL)\r
+                               if(guienv != NULL && guiroot != NULL && g_device != NULL)\r
                                {\r
                                        if(event.KeyInput.Key == irr::KEY_KEY_I)\r
                                        {\r
@@ -382,7 +391,11 @@ public:
                                                {\r
                                                        dstream<<DTIME<<"MyEventReceiver: "\r
                                                                        <<"Launching inventory"<<std::endl;\r
-                                                       inventoryMenu->launch();\r
+                                                       GUIInventoryMenu *inventoryMenu = new\r
+                                                                       GUIInventoryMenu(guienv, guiroot, -1,\r
+                                                                       &local_inventory, &inventory_action_queue,\r
+                                                                       &g_active_menu_count);\r
+                                                       inventoryMenu->drop();\r
                                                        return true;\r
                                                }\r
                                        }\r
@@ -523,6 +536,7 @@ private:
        bool keyIsDown[KEY_KEY_CODES_COUNT];\r
        //s32 mouseX;\r
        //s32 mouseY;\r
+       IrrlichtDevice *m_device;\r
 };\r
 \r
 class InputHandler\r
@@ -997,6 +1011,68 @@ private:
        s32 m_selection;\r
 };\r
 \r
+/*\r
+       Text input system\r
+*/\r
+\r
+struct TextDest\r
+{\r
+       virtual void sendText(std::string text) = 0;\r
+};\r
+\r
+struct TextDestSign : public TextDest\r
+{\r
+       TextDestSign(v3s16 blockpos, s16 id, Client *client)\r
+       {\r
+               m_blockpos = blockpos;\r
+               m_id = id;\r
+               m_client = client;\r
+       }\r
+       void sendText(std::string text)\r
+       {\r
+               dstream<<"Changing text of a sign object: "\r
+                               <<text<<std::endl;\r
+               m_client->sendSignText(m_blockpos, m_id, text);\r
+       }\r
+\r
+       v3s16 m_blockpos;\r
+       s16 m_id;\r
+       Client *m_client;\r
+};\r
+\r
+struct TextInput\r
+{\r
+       TextDest *dest;\r
+       gui::IGUIStaticText* guitext;\r
+       /*std::wstring buffer;\r
+       bool buffer_accepted;*/\r
+\r
+       TextInput()\r
+       {\r
+               dest = NULL;\r
+               guitext = NULL;\r
+               //buffer_accepted = false;\r
+       }\r
+\r
+       void start(TextDest *a_dest)\r
+       {\r
+               unFocusGame();\r
+\r
+               guitext = guienv->addStaticText(L"",\r
+                               core::rect<s32>(150,100,550,120),\r
+                               true, // border?\r
+                               false, // wordwrap?\r
+                               NULL);\r
+\r
+               guitext->setDrawBackground(true);\r
+\r
+               g_text_buffer = L"";\r
+               g_text_buffer_accepted = false;\r
+\r
+               dest = a_dest;\r
+       }\r
+};\r
+\r
 int main(int argc, char *argv[])\r
 {\r
        /*\r
@@ -1306,6 +1382,7 @@ int main(int argc, char *argv[])
        if (device == 0)\r
                return 1; // could not create selected driver.\r
        \r
+       g_device = device;\r
        g_irrlicht = new IrrlichtWrapper(device);\r
 \r
        //g_device = device;\r
@@ -1362,34 +1439,10 @@ int main(int argc, char *argv[])
        driver->endScene();\r
 \r
        /*\r
-               Preload some random textures that are used in threads\r
-       */\r
-#if 0\r
-       g_texturecache.set("torch", driver->getTexture("../data/torch.png"));\r
-       g_texturecache.set("torch_on_floor", driver->getTexture("../data/torch_on_floor.png"));\r
-       g_texturecache.set("torch_on_ceiling", driver->getTexture("../data/torch_on_ceiling.png"));\r
-       g_texturecache.set("crack", driver->getTexture("../data/crack.png"));\r
-       \r
-       /*\r
-               Load tile textures\r
+               Preload some textures\r
        */\r
-       for(s32 i=0; i<TILES_COUNT; i++)\r
-       {\r
-               if(g_tile_texture_names[i] == NULL)\r
-                       continue;\r
-               std::string name = g_tile_texture_names[i];\r
-               std::string filename;\r
-               filename += "../data/";\r
-               filename += name;\r
-               filename += ".png";\r
-               g_texturecache.set(name, driver->getTexture(filename.c_str()));\r
-       }\r
 \r
-#endif\r
-\r
-       //tile_materials_preload(g_texturecache);\r
        tile_materials_preload(g_irrlicht);\r
-       //tile_materials_init();\r
 \r
        /*\r
                Make a scope here for the client so that it gets removed\r
@@ -1491,9 +1544,9 @@ int main(int argc, char *argv[])
        /*\r
                Add some gui stuff\r
        */\r
-       \r
-       // This is a copy of the inventory that the client's environment has\r
-       Inventory local_inventory;\r
+\r
+       // Text input system\r
+       TextInput text_input;\r
        \r
        GUIQuickInventory *quick_inventory = new GUIQuickInventory\r
                        (guienv, NULL, v2s32(10, 70), 5, &local_inventory);\r
@@ -1503,16 +1556,17 @@ int main(int argc, char *argv[])
                custom elements directly on the screen.\r
                Otherwise they won't be automatically drawn.\r
        */\r
-       gui::IGUIStaticText *root = guienv->addStaticText(L"",\r
+       guiroot = guienv->addStaticText(L"",\r
                        core::rect<s32>(0, 0, 10000, 10000));\r
        \r
        // Pause menu\r
-       pauseMenu = new GUIPauseMenu(guienv, root, -1, device);\r
+       //pauseMenu = new GUIPauseMenu(guienv, root, -1, device);\r
        \r
        // Inventory menu\r
-       inventoryMenu = new GUIInventoryMenu(guienv, root, -1, &local_inventory);\r
+       /*inventoryMenu = new GUIInventoryMenu(guienv, guiroot, -1, &local_inventory,\r
+                       &inventory_action_queue);*/\r
 \r
-       pauseMenu->launch();\r
+       //pauseMenu->launch();\r
        //inventoryMenu->launch();\r
 \r
        // First line of debug text\r
@@ -1541,40 +1595,6 @@ int main(int argc, char *argv[])
        u32 scenetime = 0;\r
        u32 endscenetime = 0;\r
 \r
-       /*\r
-               Text input system\r
-       */\r
-       \r
-       struct TextDest\r
-       {\r
-               virtual void sendText(std::string text) = 0;\r
-       };\r
-       \r
-       struct TextDestSign : public TextDest\r
-       {\r
-               TextDestSign(v3s16 blockpos, s16 id, Client *client)\r
-               {\r
-                       m_blockpos = blockpos;\r
-                       m_id = id;\r
-                       m_client = client;\r
-               }\r
-               void sendText(std::string text)\r
-               {\r
-                       dstream<<"Changing text of a sign object: "\r
-                                       <<text<<std::endl;\r
-                       m_client->sendSignText(m_blockpos, m_id, text);\r
-               }\r
-\r
-               v3s16 m_blockpos;\r
-               s16 m_id;\r
-               Client *m_client;\r
-       };\r
-\r
-       TextDest *textbuf_dest = NULL;\r
-       \r
-       //gui::IGUIWindow* input_window = NULL;\r
-       gui::IGUIStaticText* input_guitext = NULL;\r
-\r
        /*\r
                Main loop\r
        */\r
@@ -1599,8 +1619,8 @@ int main(int argc, char *argv[])
                v2u32 screensize = driver->getScreenSize();\r
                core::vector2d<s32> displaycenter(screensize.X/2,screensize.Y/2);\r
                \r
-               pauseMenu->resizeGui();\r
-               inventoryMenu->resizeGui();\r
+               /*pauseMenu->resizeGui();\r
+               inventoryMenu->resizeGui();*/\r
 \r
                // Hilight boxes collected during the loop and displayed\r
                core::list< core::aabbox3d<f32> > hilightboxes;\r
@@ -1920,32 +1940,17 @@ int main(int argc, char *argv[])
                                if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)\r
                                {\r
                                        dstream<<"Sign object right-clicked"<<std::endl;\r
-                                       \r
-                                       unFocusGame();\r
 \r
-                                       input_guitext = guienv->addStaticText(L"",\r
-                                                       core::rect<s32>(150,100,350,120),\r
-                                                       true, // border?\r
-                                                       false, // wordwrap?\r
-                                                       NULL);\r
-\r
-                                       input_guitext->setDrawBackground(true);\r
+                                       text_input.start(new TextDestSign(\r
+                                                       selected_object->getBlock()->getPos(),\r
+                                                       selected_object->getId(),\r
+                                                       &client));\r
 \r
                                        if(random_input)\r
                                        {\r
                                                g_text_buffer = L"ASD LOL 8)";\r
                                                g_text_buffer_accepted = true;\r
                                        }\r
-                                       else\r
-                                       {\r
-                                               g_text_buffer = L"";\r
-                                               g_text_buffer_accepted = false;\r
-                                       }\r
-\r
-                                       textbuf_dest = new TextDestSign(\r
-                                                       selected_object->getBlock()->getPos(),\r
-                                                       selected_object->getId(),\r
-                                                       &client);\r
                                }\r
                                /*\r
                                        Otherwise pass the event to the server as-is\r
@@ -2314,38 +2319,40 @@ int main(int argc, char *argv[])
                /*\r
                        Send actions returned by the inventory menu\r
                */\r
-               while(InventoryAction *a = inventoryMenu->getNextAction())\r
+               while(inventory_action_queue.size() != 0)\r
                {\r
+                       InventoryAction *a = inventory_action_queue.pop_front();\r
+\r
                        client.sendInventoryAction(a);\r
                        // Eat it\r
                        delete a;\r
                }\r
 \r
-               if(input_guitext != NULL)\r
+               if(text_input.guitext != NULL)\r
                {\r
                        /*wchar_t temptext[100];\r
                        swprintf(temptext, 100,\r
                                        SWPRINTF_CHARSTRING,\r
                                        g_text_buffer.substr(0,99).c_str()\r
                                        );*/\r
-                       input_guitext->setText(g_text_buffer.c_str());\r
+                       text_input.guitext->setText(g_text_buffer.c_str());\r
                }\r
 \r
                /*\r
                        Text input stuff\r
                */\r
-               if(input_guitext != NULL && g_text_buffer_accepted)\r
+               if(text_input.guitext != NULL && g_text_buffer_accepted)\r
                {\r
-                       input_guitext->remove();\r
-                       input_guitext = NULL;\r
+                       text_input.guitext->remove();\r
+                       text_input.guitext = NULL;\r
                        \r
-                       if(textbuf_dest != NULL)\r
+                       if(text_input.dest != NULL)\r
                        {\r
                                std::string text = wide_to_narrow(g_text_buffer);\r
                                dstream<<"Sending text: "<<text<<std::endl;\r
-                               textbuf_dest->sendText(text);\r
-                               delete textbuf_dest;\r
-                               textbuf_dest = NULL;\r
+                               text_input.dest->sendText(text);\r
+                               delete text_input.dest;\r
+                               text_input.dest = NULL;\r
                        }\r
 \r
                        focusGame();\r
diff --git a/src/modalMenu.h b/src/modalMenu.h
new file mode 100644 (file)
index 0000000..3706d86
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef MODALMENU_HEADER
+#define MODALMENU_HEADER
+
+#include "common_irrlicht.h"
+
+//TODO: Change GUIElement private
+class GUIModalMenu : public gui::IGUIElement
+{
+public:
+       GUIModalMenu(gui::IGUIEnvironment* env,
+                       gui::IGUIElement* parent, s32 id,
+                       int *active_menu_count):
+               IGUIElement(gui::EGUIET_ELEMENT, env, parent, id,
+                               core::rect<s32>(0,0,100,100))
+       {
+               m_active_menu_count = active_menu_count;
+               m_allow_focus_removal = false;
+               m_screensize_old = v2u32(0,0);
+
+               setVisible(true);
+               Environment->setFocus(this);
+               (*m_active_menu_count)++;
+       }
+       virtual ~GUIModalMenu()
+       {
+               (*m_active_menu_count)--;
+       }
+
+       bool canTakeFocus(gui::IGUIElement *e)
+       {
+               return (e && (e == this || isMyChild(e))) || m_allow_focus_removal;
+       }
+
+       void quitMenu()
+       {
+               m_allow_focus_removal = true;
+               // This removes Environment's grab on us
+               Environment->removeFocus(this);
+               this->remove();
+       }
+
+       virtual void regenerateGui(v2u32 screensize) = 0;
+
+       virtual void drawMenu() = 0;
+
+       void draw()
+       {
+               if(!IsVisible)
+                       return;
+                       
+               video::IVideoDriver* driver = Environment->getVideoDriver();
+               v2u32 screensize = driver->getScreenSize();
+               if(screensize != m_screensize_old)
+               {
+                       m_screensize_old = screensize;
+                       regenerateGui(screensize);
+               }
+
+               drawMenu();
+       }
+       
+       virtual bool OnEvent(const SEvent& event) { return false; };
+       
+private:
+       int *m_active_menu_count;
+       bool m_allow_focus_removal;
+       v2u32 m_screensize_old;
+};
+
+
+#endif
+