From 2816d8f638de2f7f06ca1086d1c8846e8971f421 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Thu, 23 Dec 2010 15:31:50 +0200 Subject: [PATCH] redoing gui stuff --- Makefile | 4 +- src/guiInventoryMenu.cpp | 38 ++----- src/guiInventoryMenu.h | 30 ++---- src/guiPauseMenu.cpp | 146 ++++--------------------- src/guiPauseMenu.h | 49 ++------- src/main.cpp | 223 ++++++++++++++++++++------------------- src/modalMenu.h | 91 ++++++++++++++++ 7 files changed, 252 insertions(+), 329 deletions(-) create mode 100644 src/modalMenu.h diff --git a/Makefile b/Makefile index 5dcee0d9a..25e58a99a 100644 --- a/Makefile +++ b/Makefile @@ -22,9 +22,9 @@ IRRLICHTPATH = ../irrlicht/irrlicht-1.7.1 JTHREADPATH = ../jthread/jthread-1.2.1 #CXXFLAGS = -O2 -ffast-math -Wall -fomit-frame-pointer -pipe -CXXFLAGS = -O2 -ffast-math -Wall -g -pipe +#CXXFLAGS = -O2 -ffast-math -Wall -g -pipe #CXXFLAGS = -O1 -ffast-math -Wall -g -#CXXFLAGS = -Wall -g -O0 +CXXFLAGS = -Wall -g -O0 all: fast_linux diff --git a/src/guiInventoryMenu.cpp b/src/guiInventoryMenu.cpp index 88cb8c830..bba23e719 100644 --- a/src/guiInventoryMenu.cpp +++ b/src/guiInventoryMenu.cpp @@ -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(0,0,100,100)) + Inventory *inventory, + Queue *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(); -} diff --git a/src/guiInventoryMenu.h b/src/guiInventoryMenu.h index 0032ce66a..b6766484e 100644 --- a/src/guiInventoryMenu.h +++ b/src/guiInventoryMenu.h @@ -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 rect, const core::rect *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 *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 m_draw_positions; Inventory *m_inventory; - v2u32 m_screensize_old; ItemSpec *m_selected_item; - - Queue m_actions; + Queue *m_actions; }; #endif diff --git a/src/guiPauseMenu.cpp b/src/guiPauseMenu.cpp index b8f0473e8..ed4f0cd6f 100644 --- a/src/guiPauseMenu.cpp +++ b/src/guiPauseMenu.cpp @@ -1,8 +1,6 @@ /* Minetest-c55 Copyright (C) 2010 celeron55, Perttu Ahola -Original author Kabak Dmitry , contributed under -the minetest contributor agreement. 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 @@ -26,33 +24,20 @@ with this program; if not, write to the Free Software Foundation, Inc., GUIPauseMenu::GUIPauseMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, - IrrlichtDevice *dev): - IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, - core::rect(0,0,100,100)) + IrrlichtDevice *dev, + int *active_menu_count): + GUIModalMenu(env, parent, id, active_menu_count) { m_dev = dev; - m_screensize_old = v2u32(0,0); - - resizeGui(); - - setVisible(false); } GUIPauseMenu::~GUIPauseMenu() { + removeChildren(); } -void GUIPauseMenu::resizeGui() +void GUIPauseMenu::removeChildren() { - video::IVideoDriver* driver = Environment->getVideoDriver(); - v2u32 screensize = driver->getScreenSize(); - if(screensize == m_screensize_old) - return; - m_screensize_old = screensize; - - /* - Remove stuff - */ { gui::IGUIElement *e = getElementFromId(256); if(e != NULL) @@ -73,7 +58,18 @@ void GUIPauseMenu::resizeGui() if(e != NULL) e->remove(); } +} +void GUIPauseMenu::regenerateGui(v2u32 screensize) +{ + /* + Remove stuff + */ + removeChildren(); + + /* + Calculate new sizes and positions + */ core::rect rect( screensize.X/2 - 580/2, screensize.Y/2 - 300/2, @@ -129,11 +125,8 @@ void GUIPauseMenu::resizeGui() } } -void GUIPauseMenu::draw() +void GUIPauseMenu::drawMenu() { - if(!IsVisible) - return; - gui::IGUISkin* skin = Environment->getSkin(); if (!skin) return; @@ -151,7 +144,7 @@ bool GUIPauseMenu::OnEvent(const SEvent& event) { if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown) { - setVisible(false); + quitMenu(); return true; } } @@ -173,7 +166,7 @@ bool GUIPauseMenu::OnEvent(const SEvent& event) switch(event.GUIEvent.Caller->getID()) { case 256: // continue - setVisible(false); + quitMenu(); break; case 257: // exit m_dev->closeDevice(); @@ -185,104 +178,3 @@ bool GUIPauseMenu::OnEvent(const SEvent& event) return Parent ? Parent->OnEvent(event) : false; } -#if 0 -GUIPauseMenu::GUIPauseMenu(IrrlichtDevice *device, IEventReceiver *recv): - dev(device), - oldRecv(recv) -{ - if(!dev) - return; - guienv=dev->getGUIEnvironment(); - - if (!loadMenu()) - return; - - device->setEventReceiver(this); // now WE are the input receiver! ahhaha! -} - -GUIPauseMenu::~GUIPauseMenu(void) -{ -} - -void GUIPauseMenu::scaleGui() // this function scales gui from the size stored in file to screen size -{ - core::dimension2du screen=dev->getVideoDriver()->getScreenSize(); - core::vector2di real=root->getAbsolutePosition().LowerRightCorner; // determine gui size stored in file (which is size of my menu root node) - float factorX=(float)screen.Width/(float)real.X; - float factorY=(float)screen.Height/(float)real.Y; - scaleGui(guienv->getRootGUIElement(),factorX,factorY); -} -void GUIPauseMenu::scaleGui(gui::IGUIElement *node,float factorX,float factorY) // recursive set scale -{ - if((node->getParent() && node->getParent()->getID()==255) || node->getID()==255) // modify only menu's elements - { - int lx,rx,ly,ry; - lx=(float)node->getRelativePosition().UpperLeftCorner.X*factorX; - ly=(float)node->getRelativePosition().UpperLeftCorner.Y*factorY; - rx=(float)node->getRelativePosition().LowerRightCorner.X*factorX; - ry=(float)node->getRelativePosition().LowerRightCorner.Y*factorY; - node->setRelativePosition(core::recti(lx,ly,rx,ry)); - } - - core::list::ConstIterator it = node->getChildren().begin(); - for(; it != node->getChildren().end(); ++it) - scaleGui((*it),factorX,factorY); -} - -bool GUIPauseMenu::loadMenu() -{ - guienv->loadGUI("../data/pauseMenu.gui"); - - root=(gui::IGUIStaticText*)guienv->getRootGUIElement()->getElementFromId(255,true); - if(!root) // if there is no my root node then menu file not found or corrupted - return false; - - scaleGui(); // scale gui to our screen size - - root->setVisible(false); // hide our menu - // make it transparent - //root->setBackgroundColor(video::SColor(100,128,100,128)); - root->setBackgroundColor(video::SColor(140,0,0,0)); - - return true; -} - -bool GUIPauseMenu::OnEvent(const SEvent& event) -{ - if(!dev->isWindowFocused()) - setVisible(true); - - bool ret=false; - if(oldRecv && !isVisible()) // call master if we have it and if we are inactive - ret=oldRecv->OnEvent(event); - - if(ret==true) - return true; // if the master receiver does the work - - if(event.EventType==EET_KEY_INPUT_EVENT) - { - if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown) - { - setVisible(!isVisible()); - } - } - if(event.EventType==EET_GUI_EVENT) - { - if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED) - { - switch(event.GUIEvent.Caller->getID()) - { - case 256: // continue - setVisible(false); - break; - case 257: // exit - dev->closeDevice(); - break; - } - } - } - - return false; -} -#endif - diff --git a/src/guiPauseMenu.h b/src/guiPauseMenu.h index f26a26149..7c37af8ef 100644 --- a/src/guiPauseMenu.h +++ b/src/guiPauseMenu.h @@ -1,8 +1,6 @@ /* Minetest-c55 Copyright (C) 2010 celeron55, Perttu Ahola -Original author Kabak Dmitry , contributed under -the minetest contributor agreement. 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 @@ -24,63 +22,30 @@ with this program; if not, write to the Free Software Foundation, Inc., #define GUIPAUSEMENU_HEADER #include "common_irrlicht.h" +#include "modalMenu.h" -class GUIPauseMenu : public gui::IGUIElement +class GUIPauseMenu : public GUIModalMenu { public: GUIPauseMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, - IrrlichtDevice *dev); + IrrlichtDevice *dev, + int *active_menu_count); ~GUIPauseMenu(); + void removeChildren(); /* Remove and re-add (or reposition) stuff */ - void resizeGui(); + void regenerateGui(v2u32 screensize); - 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); private: IrrlichtDevice *m_dev; - v2u32 m_screensize_old; }; -/*class GUIPauseMenu : public IEventReceiver -{ -public: - void scaleGui(); - - GUIPauseMenu(IrrlichtDevice *device,IEventReceiver *recv); - ~GUIPauseMenu(void); - - void setVisible(bool visible){root->setVisible(visible);}; - bool isVisible(){return root->isVisible();}; - - bool OnEvent(const SEvent& event); - -private: - bool loadMenu(); - void scaleGui(gui::IGUIElement *node,float factorX,float factorY); - - IrrlichtDevice *dev; - gui::IGUIEnvironment *guienv; - IEventReceiver *oldRecv; - - gui::IGUIStaticText *root; -};*/ - #endif diff --git a/src/main.cpp b/src/main.cpp index aacf4d775..4d8a952ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -268,22 +268,25 @@ extern void set_default_settings(); //u16 g_selected_material = 0; u16 g_selected_item = 0; +IrrlichtDevice *g_device = NULL; + /* GUI Stuff */ gui::IGUIEnvironment* guienv = NULL; -GUIPauseMenu *pauseMenu = NULL; -GUIInventoryMenu *inventoryMenu = NULL; +gui::IGUIStaticText *guiroot = NULL; +int g_active_menu_count = 0; bool noMenuActive() { - if(pauseMenu && pauseMenu->isVisible()) - return false; - if(inventoryMenu && inventoryMenu->isVisible()) - return false; - return true; + return (g_active_menu_count == 0); } +// Inventory actions from the menu are buffered here before sending +Queue inventory_action_queue; +// This is a copy of the inventory that the client's environment has +Inventory local_inventory; + std::wstring g_text_buffer; bool g_text_buffer_accepted = false; @@ -360,7 +363,8 @@ public: } } - if(pauseMenu != NULL) + //if(pauseMenu != NULL) + if(guienv != NULL && guiroot != NULL && g_device != NULL) { if(event.KeyInput.Key == irr::KEY_ESCAPE) { @@ -368,13 +372,18 @@ public: { dstream<launch(); + // It will delete itself by itself + GUIPauseMenu *menu = new + GUIPauseMenu(guienv, guiroot, -1, g_device, + &g_active_menu_count); + menu->drop(); return true; } } } - if(inventoryMenu != NULL) + //if(inventoryMenu != NULL) + if(guienv != NULL && guiroot != NULL && g_device != NULL) { if(event.KeyInput.Key == irr::KEY_KEY_I) { @@ -382,7 +391,11 @@ public: { dstream<launch(); + GUIInventoryMenu *inventoryMenu = new + GUIInventoryMenu(guienv, guiroot, -1, + &local_inventory, &inventory_action_queue, + &g_active_menu_count); + inventoryMenu->drop(); return true; } } @@ -523,6 +536,7 @@ private: bool keyIsDown[KEY_KEY_CODES_COUNT]; //s32 mouseX; //s32 mouseY; + IrrlichtDevice *m_device; }; class InputHandler @@ -997,6 +1011,68 @@ private: s32 m_selection; }; +/* + Text input system +*/ + +struct TextDest +{ + virtual void sendText(std::string text) = 0; +}; + +struct TextDestSign : public TextDest +{ + TextDestSign(v3s16 blockpos, s16 id, Client *client) + { + m_blockpos = blockpos; + m_id = id; + m_client = client; + } + void sendText(std::string text) + { + dstream<<"Changing text of a sign object: " + <sendSignText(m_blockpos, m_id, text); + } + + v3s16 m_blockpos; + s16 m_id; + Client *m_client; +}; + +struct TextInput +{ + TextDest *dest; + gui::IGUIStaticText* guitext; + /*std::wstring buffer; + bool buffer_accepted;*/ + + TextInput() + { + dest = NULL; + guitext = NULL; + //buffer_accepted = false; + } + + void start(TextDest *a_dest) + { + unFocusGame(); + + guitext = guienv->addStaticText(L"", + core::rect(150,100,550,120), + true, // border? + false, // wordwrap? + NULL); + + guitext->setDrawBackground(true); + + g_text_buffer = L""; + g_text_buffer_accepted = false; + + dest = a_dest; + } +}; + int main(int argc, char *argv[]) { /* @@ -1306,6 +1382,7 @@ int main(int argc, char *argv[]) if (device == 0) return 1; // could not create selected driver. + g_device = device; g_irrlicht = new IrrlichtWrapper(device); //g_device = device; @@ -1362,34 +1439,10 @@ int main(int argc, char *argv[]) driver->endScene(); /* - Preload some random textures that are used in threads + Preload some textures */ -#if 0 - g_texturecache.set("torch", driver->getTexture("../data/torch.png")); - g_texturecache.set("torch_on_floor", driver->getTexture("../data/torch_on_floor.png")); - g_texturecache.set("torch_on_ceiling", driver->getTexture("../data/torch_on_ceiling.png")); - g_texturecache.set("crack", driver->getTexture("../data/crack.png")); - - /* - Load tile textures - */ - for(s32 i=0; igetTexture(filename.c_str())); - } -#endif - - //tile_materials_preload(g_texturecache); tile_materials_preload(g_irrlicht); - //tile_materials_init(); /* Make a scope here for the client so that it gets removed @@ -1491,9 +1544,9 @@ int main(int argc, char *argv[]) /* Add some gui stuff */ - - // This is a copy of the inventory that the client's environment has - Inventory local_inventory; + + // Text input system + TextInput text_input; GUIQuickInventory *quick_inventory = new GUIQuickInventory (guienv, NULL, v2s32(10, 70), 5, &local_inventory); @@ -1503,16 +1556,17 @@ int main(int argc, char *argv[]) custom elements directly on the screen. Otherwise they won't be automatically drawn. */ - gui::IGUIStaticText *root = guienv->addStaticText(L"", + guiroot = guienv->addStaticText(L"", core::rect(0, 0, 10000, 10000)); // Pause menu - pauseMenu = new GUIPauseMenu(guienv, root, -1, device); + //pauseMenu = new GUIPauseMenu(guienv, root, -1, device); // Inventory menu - inventoryMenu = new GUIInventoryMenu(guienv, root, -1, &local_inventory); + /*inventoryMenu = new GUIInventoryMenu(guienv, guiroot, -1, &local_inventory, + &inventory_action_queue);*/ - pauseMenu->launch(); + //pauseMenu->launch(); //inventoryMenu->launch(); // First line of debug text @@ -1541,40 +1595,6 @@ int main(int argc, char *argv[]) u32 scenetime = 0; u32 endscenetime = 0; - /* - Text input system - */ - - struct TextDest - { - virtual void sendText(std::string text) = 0; - }; - - struct TextDestSign : public TextDest - { - TextDestSign(v3s16 blockpos, s16 id, Client *client) - { - m_blockpos = blockpos; - m_id = id; - m_client = client; - } - void sendText(std::string text) - { - dstream<<"Changing text of a sign object: " - <sendSignText(m_blockpos, m_id, text); - } - - v3s16 m_blockpos; - s16 m_id; - Client *m_client; - }; - - TextDest *textbuf_dest = NULL; - - //gui::IGUIWindow* input_window = NULL; - gui::IGUIStaticText* input_guitext = NULL; - /* Main loop */ @@ -1599,8 +1619,8 @@ int main(int argc, char *argv[]) v2u32 screensize = driver->getScreenSize(); core::vector2d displaycenter(screensize.X/2,screensize.Y/2); - pauseMenu->resizeGui(); - inventoryMenu->resizeGui(); + /*pauseMenu->resizeGui(); + inventoryMenu->resizeGui();*/ // Hilight boxes collected during the loop and displayed core::list< core::aabbox3d > hilightboxes; @@ -1920,32 +1940,17 @@ int main(int argc, char *argv[]) if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN) { dstream<<"Sign object right-clicked"<addStaticText(L"", - core::rect(150,100,350,120), - true, // border? - false, // wordwrap? - NULL); - - input_guitext->setDrawBackground(true); + text_input.start(new TextDestSign( + selected_object->getBlock()->getPos(), + selected_object->getId(), + &client)); if(random_input) { g_text_buffer = L"ASD LOL 8)"; g_text_buffer_accepted = true; } - else - { - g_text_buffer = L""; - g_text_buffer_accepted = false; - } - - textbuf_dest = new TextDestSign( - selected_object->getBlock()->getPos(), - selected_object->getId(), - &client); } /* Otherwise pass the event to the server as-is @@ -2314,38 +2319,40 @@ int main(int argc, char *argv[]) /* Send actions returned by the inventory menu */ - while(InventoryAction *a = inventoryMenu->getNextAction()) + while(inventory_action_queue.size() != 0) { + InventoryAction *a = inventory_action_queue.pop_front(); + client.sendInventoryAction(a); // Eat it delete a; } - if(input_guitext != NULL) + if(text_input.guitext != NULL) { /*wchar_t temptext[100]; swprintf(temptext, 100, SWPRINTF_CHARSTRING, g_text_buffer.substr(0,99).c_str() );*/ - input_guitext->setText(g_text_buffer.c_str()); + text_input.guitext->setText(g_text_buffer.c_str()); } /* Text input stuff */ - if(input_guitext != NULL && g_text_buffer_accepted) + if(text_input.guitext != NULL && g_text_buffer_accepted) { - input_guitext->remove(); - input_guitext = NULL; + text_input.guitext->remove(); + text_input.guitext = NULL; - if(textbuf_dest != NULL) + if(text_input.dest != NULL) { std::string text = wide_to_narrow(g_text_buffer); dstream<<"Sending text: "<sendText(text); - delete textbuf_dest; - textbuf_dest = NULL; + text_input.dest->sendText(text); + delete text_input.dest; + text_input.dest = NULL; } focusGame(); diff --git a/src/modalMenu.h b/src/modalMenu.h new file mode 100644 index 000000000..3706d86dc --- /dev/null +++ b/src/modalMenu.h @@ -0,0 +1,91 @@ +/* +Minetest-c55 +Copyright (C) 2010 celeron55, Perttu Ahola + +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(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 +