]> git.lizzy.rs Git - minetest.git/blob - src/modalMenu.h
FormSpec : Add an auto vertical scrollbar to the textarea
[minetest.git] / src / modalMenu.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #pragma once
21
22 #include "irrlichttypes_extrabloated.h"
23 #ifdef HAVE_TOUCHSCREENGUI
24 #include "touchscreengui.h"
25 #endif
26
27 class GUIModalMenu;
28
29 class IMenuManager
30 {
31 public:
32         // A GUIModalMenu calls these when this class is passed as a parameter
33         virtual void createdMenu(gui::IGUIElement *menu) = 0;
34         virtual void deletingMenu(gui::IGUIElement *menu) = 0;
35 };
36
37 /*
38         Remember to drop() the menu after creating, so that it can
39         remove itself when it wants to.
40 */
41
42 class GUIModalMenu : public gui::IGUIElement
43 {
44 public:
45         GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id,
46                         IMenuManager *menumgr):
47                 IGUIElement(gui::EGUIET_ELEMENT, env, parent, id,
48                                 core::rect<s32>(0,0,100,100))
49         {
50                 m_menumgr = menumgr;
51
52                 setVisible(true);
53                 Environment->setFocus(this);
54                 m_menumgr->createdMenu(this);
55         }
56
57         virtual ~GUIModalMenu()
58         {
59                 m_menumgr->deletingMenu(this);
60         }
61
62         void allowFocusRemoval(bool allow)
63         {
64                 m_allow_focus_removal = allow;
65         }
66
67         bool canTakeFocus(gui::IGUIElement *e)
68         {
69                 return (e && (e == this || isMyChild(e))) || m_allow_focus_removal;
70         }
71
72         void draw()
73         {
74                 if(!IsVisible)
75                         return;
76
77                 video::IVideoDriver* driver = Environment->getVideoDriver();
78                 v2u32 screensize = driver->getScreenSize();
79                 if(screensize != m_screensize_old /*|| m_force_regenerate_gui*/)
80                 {
81                         m_screensize_old = screensize;
82                         regenerateGui(screensize);
83                         //m_force_regenerate_gui = false;
84                 }
85
86                 drawMenu();
87         }
88
89         /*
90                 This should be called when the menu wants to quit.
91
92                 WARNING: THIS DEALLOCATES THE MENU FROM MEMORY. Return
93                 immediately if you call this from the menu itself.
94
95                 (More precisely, this decrements the reference count.)
96         */
97         void quitMenu()
98         {
99                 allowFocusRemoval(true);
100                 // This removes Environment's grab on us
101                 Environment->removeFocus(this);
102                 m_menumgr->deletingMenu(this);
103                 this->remove();
104 #ifdef HAVE_TOUCHSCREENGUI
105                 if (g_touchscreengui)
106                         g_touchscreengui->show();
107 #endif
108         }
109
110         void removeChildren()
111         {
112                 const core::list<gui::IGUIElement*> &children = getChildren();
113                 core::list<gui::IGUIElement*> children_copy;
114                 for (gui::IGUIElement *i : children) {
115                         children_copy.push_back(i);
116                 }
117
118                 for (gui::IGUIElement *i : children_copy) {
119                         i->remove();
120                 }
121         }
122
123         virtual void regenerateGui(v2u32 screensize) = 0;
124         virtual void drawMenu() = 0;
125         virtual bool preprocessEvent(const SEvent& event) { return false; };
126         virtual bool OnEvent(const SEvent& event) { return false; };
127         virtual bool pausesGame(){ return false; } // Used for pause menu
128
129 protected:
130         //bool m_force_regenerate_gui;
131         v2u32 m_screensize_old;
132 private:
133         IMenuManager *m_menumgr;
134         // This might be necessary to expose to the implementation if it
135         // wants to launch other menus
136         bool m_allow_focus_removal = false;
137 };