#include "supertux/globals.hpp"
#include "supertux/menu/menu_storage.hpp"
#include "supertux/timer.hpp"
+#include "util/log.hpp"
#include "video/drawing_context.hpp"
MenuManager* MenuManager::s_instance = 0;
return *s_instance;
}
-MenuManager::MenuManager() :
- m_menu_stack()
+namespace {
+
+Rectf menu2rect(const Menu& menu)
{
- s_instance = this;
+ return Rectf(menu.get_pos().x,
+ menu.get_pos().y,
+ menu.get_pos().x + menu.get_width(),
+ menu.get_pos().y + menu.get_height());
}
-MenuManager::~MenuManager()
+Rectf pos2rect(const Menu& menu)
{
- s_instance = nullptr;
+ return Rectf(menu.get_pos().x,
+ menu.get_pos().y,
+ menu.get_pos().x,
+ menu.get_pos().y);
}
-void
-MenuManager::draw(DrawingContext& context)
+} // namespace
+
+class MenuTransition
{
- if (current())
+private:
+ Rectf m_from_rect;
+ Rectf m_to_rect;
+
+ bool m_closing_animation;
+ float m_effect_progress;
+ float m_effect_start_time;
+ bool m_is_active;
+public:
+ MenuTransition() :
+ m_is_active(false)
{
+ }
+
+ void start(const Rectf& to_rect)
+ {
+ m_to_rect = to_rect;
+ }
+
+ void start(const Rectf& from_rect,
+ const Rectf& to_rect)
+ {
+ m_from_rect = from_rect;
+ m_to_rect = to_rect;
+
+ m_effect_start_time = real_time;
+ m_effect_progress = 0.0f;
+
+ m_is_active = true;
+ }
+
+ void update()
+ {
+ m_effect_progress = (real_time - m_effect_start_time) * 6.0f;
+
+ if (m_effect_progress >= 1.0f) {
+ m_effect_progress = 1.0f;
+
+ /* if (close)
+ {
+ MenuManager::instance().m_current = 0;
+ close = false;
+ }*/
+ }
+ else if (m_effect_progress <= 0.0f)
+ {
+ m_effect_progress = 0.0f;
+ }
+ }
+
+ void draw(DrawingContext& context)
+ {
+#ifdef GRUMBEL
Vector pos = current()->get_pos();
float menu_width = current()->get_width();
float menu_height = current()->get_height();
+ float p = m_effect_progress;
+ if (p != 1.0f)
+ {
+ if (close)
+ {
+ menu_width *= 1.0f - p;
+ menu_height *= 1.0f - p;
+ }
+ else if (MenuManager::instance().m_previous)
+ {
+ menu_width = (menu_width * p) + (MenuManager::instance().m_previous->get_width() * (1.0f - p));
+ menu_height = (menu_height * p) + (MenuManager::instance().m_previous->get_height() * (1.0f - p));
+ //std::cout << p << " " << this << " " << last_menus.back() << std::endl;
+ }
+ else
+ {
+ menu_width *= p;
+ menu_height *= p;
+ }
+ }
+
// draw menu background rectangles
context.draw_filled_rect(Rectf(Vector(pos.x - menu_width/2-4, pos.y - menu_height/2 - 10-4),
Vector(pos.x + menu_width/2+4, pos.y - menu_height/2 + 10 + menu_height+4)),
Color(0.6f, 0.7f, 0.8f, 0.5f),
16.0f,
LAYER_GUI-10);
-
- current()->draw(context);
-
- if (MouseCursor::current())
- {
- MouseCursor::current()->draw(context);
- }
+#endif
}
-#ifdef GRUMBEL
- if (effect_progress != 1.0f)
+ bool is_active()
{
- if (close)
- {
- menu_width *= 1.0f - effect_progress;
- menu_height *= 1.0f - effect_progress;
- }
- else if (MenuManager::instance().m_previous)
- {
- menu_width = (menu_width * effect_progress) + (MenuManager::instance().m_previous->get_width() * (1.0f - effect_progress));
- menu_height = (menu_height * effect_progress) + (MenuManager::instance().m_previous->get_height() * (1.0f - effect_progress));
- //std::cout << effect_progress << " " << this << " " << last_menus.back() << std::endl;
- }
- else
- {
- menu_width *= effect_progress;
- menu_height *= effect_progress;
- }
+ return m_is_active;
}
+};
- //update
- effect_progress = (real_time - effect_start_time) * 6.0f;
+MenuManager::MenuManager() :
+ m_menu_stack(),
+ m_transition(new MenuTransition)
+{
+ s_instance = this;
+}
- if(effect_progress >= 1.0f) {
- effect_progress = 1.0f;
+MenuManager::~MenuManager()
+{
+ s_instance = nullptr;
+}
- if (close) {
- MenuManager::instance().m_current = 0;
- close = false;
- }
+void
+MenuManager::update()
+{
+ if (current())
+ {
+ current()->update();
+ }
+}
+
+void
+MenuManager::event(const SDL_Event& event)
+{
+ if (current())
+ {
+ current()->event(event);
}
- else if (effect_progress <= 0.0f) {
- effect_progress = 0.0f;
+}
+
+void
+MenuManager::draw(DrawingContext& context)
+{
+ if (!current())
+ {
+ return;
}
+ m_transition->update();
+ m_transition->draw(context);
+
+#ifdef GRUMBEL
// only pass events in non-anim states
- if(effect_progress != 1.0f)
+ if(m_effect_progress != 1.0f)
return;
-
#endif
+
+ current()->draw(context);
+
+ if (MouseCursor::current())
+ {
+ MouseCursor::current()->draw(context);
+ }
}
bool
void
MenuManager::push_menu(std::unique_ptr<Menu> menu)
{
+ //start_transition_effect();
m_menu_stack.push_back(std::move(menu));
-
- //current()->effect_start_time = real_time;
- //current()->effect_progress = 0.0f;
}
void
MenuManager::pop_menu()
{
- if (!m_menu_stack.empty())
+ if (m_menu_stack.empty())
{
- m_menu_stack.pop_back();
- //current()->effect_start_time = real_time;
- //current()->effect_progress = 0.0f;
+ log_warning << "trying to pop on an empty menu_stack" << std::endl;
}
else
{
- set_menu(MenuStorage::NO_MENU);
+ m_menu_stack.pop_back();
+ //start_transition_effect();
}
}
void
MenuManager::clear_menu_stack()
{
- set_menu(MenuStorage::NO_MENU);
+ m_menu_stack.clear();
}
void
{
if (menu)
{
+ m_transition->start(pos2rect(*menu), menu2rect(*menu));
m_menu_stack.push_back(std::move(menu));
- //current()->effect_start_time = real_time;
- //current()->effect_progress = 0.0f;
}
else
{
m_menu_stack.clear();
- //current()->effect_start_time = real_time;
- //current()->effect_progress = 0.0f;
- //current()->close = true;
}
// just to be sure...
}
}
+Menu*
+MenuManager::current() const
+{
+ if (m_menu_stack.empty())
+ {
+ return nullptr;
+ }
+ else
+ {
+ return m_menu_stack.back().get();
+ }
+}
+
/* EOF */