Switched from passing pointers around to using numeric MenuIds and a factory class
[supertux.git] / src / gui / menu_manager.cpp
1 //  SuperTux
2 //  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include "gui/menu_manager.hpp"
18
19 #include <assert.h>
20
21 #include "control/input_manager.hpp"
22 #include "gui/menu.hpp"
23 #include "supertux/globals.hpp"
24 #include "supertux/menu/menu_storage.hpp"
25 #include "supertux/timer.hpp"
26
27 MenuManager* MenuManager::s_instance = 0;
28
29 MenuManager&
30 MenuManager::instance()
31 {
32   assert(s_instance);
33   return *s_instance;
34 }
35
36 MenuManager::MenuManager() :
37   m_last_menus(),
38   m_all_menus(),
39   m_previous(),
40   m_current()
41 {
42   s_instance = this;
43 }
44
45 MenuManager::~MenuManager()
46 {
47   s_instance = nullptr;
48 }
49
50 void
51 MenuManager::draw(DrawingContext& context)
52 {
53   if (m_current)
54   {
55     m_current->draw(context);
56   }
57 }
58
59 bool
60 MenuManager::check_menu()
61 {
62   if (m_current)
63   {
64     m_current->check_menu();
65     return true;
66   }
67   else
68   {
69     return false;
70   }
71 }
72
73 void
74 MenuManager::push_current(int id)
75 {
76   Menu* menu = MenuStorage::instance().create(static_cast<MenuStorage::MenuId>(id));
77   push_current_(menu);
78 }
79
80 void
81 MenuManager::push_current_(Menu* menu)
82 {
83   m_previous = m_current;
84
85   if (m_current)
86   {
87     m_last_menus.push_back(m_current);
88   }
89
90   m_current = menu;
91   m_current->effect_start_time = real_time;
92   m_current->effect_progress = 0.0f;
93 }
94
95 void
96 MenuManager::pop_current()
97 {
98   m_previous = m_current;
99
100   if (m_last_menus.size() >= 1)
101   {
102     m_current = m_last_menus.back();
103     m_current->effect_start_time = real_time;
104     m_current->effect_progress   = 0.0f;
105     m_last_menus.pop_back();
106   }
107   else
108   {
109     set_current(MenuStorage::NO_MENU);
110   }
111 }
112
113 void
114 MenuManager::set_current(int id)
115 {
116   Menu* menu = MenuStorage::instance().create(static_cast<MenuStorage::MenuId>(id));
117   set_current_ptr(menu);
118 }
119
120 void
121 MenuManager::set_current_ptr(Menu* menu)
122 {
123   if (m_current && m_current->close == true)
124   {
125     // do nothing
126   }
127   else
128   {
129     m_previous = m_current;
130
131     if (menu)
132     {
133       menu->effect_start_time = real_time;
134       menu->effect_progress = 0.0f;
135       m_current = menu;
136     }
137     else if (m_current)
138     {
139       m_last_menus.clear();                         //NULL new menu pointer => close all menus
140       m_current->effect_start_time = real_time;
141       m_current->effect_progress = 0.0f;
142       m_current->close = true;
143     }
144
145     // just to be sure...
146     g_input_manager->reset();
147   }
148 }
149
150 void
151 MenuManager::recalc_pos()
152 {
153   if (m_current)
154     m_current->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
155
156   for(auto i = m_all_menus.begin(); i != m_all_menus.end(); ++i)
157   {
158     // FIXME: This is of course not quite right, since it ignores any previous set_pos() calls
159     (*i)->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
160   }
161 }
162
163 /* EOF */