2 // Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
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.
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.
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/>.
17 #include "gui/menu_manager.hpp"
21 #include "control/input_manager.hpp"
22 #include "gui/menu.hpp"
23 #include "gui/mousecursor.hpp"
24 #include "supertux/globals.hpp"
25 #include "supertux/menu/menu_storage.hpp"
26 #include "supertux/timer.hpp"
27 #include "util/log.hpp"
28 #include "video/drawing_context.hpp"
30 MenuManager* MenuManager::s_instance = 0;
33 MenuManager::instance()
41 Rectf menu2rect(const Menu& menu)
43 return Rectf(menu.get_pos().x,
45 menu.get_pos().x + menu.get_width(),
46 menu.get_pos().y + menu.get_height());
49 Rectf pos2rect(const Menu& menu)
51 return Rectf(menu.get_pos().x,
65 bool m_closing_animation;
66 float m_effect_progress;
67 float m_effect_start_time;
75 void start(const Rectf& to_rect)
80 void start(const Rectf& from_rect,
83 m_from_rect = from_rect;
86 m_effect_start_time = real_time;
87 m_effect_progress = 0.0f;
94 m_effect_progress = (real_time - m_effect_start_time) * 6.0f;
96 if (m_effect_progress >= 1.0f) {
97 m_effect_progress = 1.0f;
101 MenuManager::instance().m_current = 0;
105 else if (m_effect_progress <= 0.0f)
107 m_effect_progress = 0.0f;
111 void draw(DrawingContext& context)
114 Vector pos = current()->get_pos();
115 float menu_width = current()->get_width();
116 float menu_height = current()->get_height();
118 float p = m_effect_progress;
123 menu_width *= 1.0f - p;
124 menu_height *= 1.0f - p;
126 else if (MenuManager::instance().m_previous)
128 menu_width = (menu_width * p) + (MenuManager::instance().m_previous->get_width() * (1.0f - p));
129 menu_height = (menu_height * p) + (MenuManager::instance().m_previous->get_height() * (1.0f - p));
130 //std::cout << p << " " << this << " " << last_menus.back() << std::endl;
139 // draw menu background rectangles
140 context.draw_filled_rect(Rectf(Vector(pos.x - menu_width/2-4, pos.y - menu_height/2 - 10-4),
141 Vector(pos.x + menu_width/2+4, pos.y - menu_height/2 + 10 + menu_height+4)),
142 Color(0.2f, 0.3f, 0.4f, 0.8f),
146 context.draw_filled_rect(Rectf(Vector(pos.x - menu_width/2, pos.y - menu_height/2 - 10),
147 Vector(pos.x + menu_width/2, pos.y - menu_height/2 + 10 + menu_height)),
148 Color(0.6f, 0.7f, 0.8f, 0.5f),
160 MenuManager::MenuManager() :
162 m_transition(new MenuTransition)
167 MenuManager::~MenuManager()
169 s_instance = nullptr;
173 MenuManager::update()
182 MenuManager::event(const SDL_Event& event)
186 current()->event(event);
191 MenuManager::draw(DrawingContext& context)
198 m_transition->update();
199 m_transition->draw(context);
202 // only pass events in non-anim states
203 if(m_effect_progress != 1.0f)
207 current()->draw(context);
209 if (MouseCursor::current())
211 MouseCursor::current()->draw(context);
216 MenuManager::check_menu()
220 current()->check_menu();
230 MenuManager::push_menu(int id)
232 push_menu(MenuStorage::instance().create(static_cast<MenuStorage::MenuId>(id)));
236 MenuManager::push_menu(std::unique_ptr<Menu> menu)
238 //start_transition_effect();
239 m_menu_stack.push_back(std::move(menu));
243 MenuManager::pop_menu()
245 if (m_menu_stack.empty())
247 log_warning << "trying to pop on an empty menu_stack" << std::endl;
251 m_menu_stack.pop_back();
252 //start_transition_effect();
257 MenuManager::clear_menu_stack()
259 m_menu_stack.clear();
263 MenuManager::set_menu(int id)
265 set_menu(MenuStorage::instance().create(static_cast<MenuStorage::MenuId>(id)));
269 MenuManager::set_menu(std::unique_ptr<Menu> menu)
273 m_transition->start(pos2rect(*menu), menu2rect(*menu));
274 m_menu_stack.push_back(std::move(menu));
278 m_menu_stack.clear();
281 // just to be sure...
282 g_input_manager->reset();
286 MenuManager::recalc_pos()
288 for(auto i = m_menu_stack.begin(); i != m_menu_stack.end(); ++i)
290 // FIXME: This is of course not quite right, since it ignores any previous set_pos() calls
291 (*i)->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
296 MenuManager::current() const
298 if (m_menu_stack.empty())
304 return m_menu_stack.back().get();