Further cleanup in the MenuManager
authorIngo Ruhnke <grumbel@gmail.com>
Sat, 9 Aug 2014 05:53:39 +0000 (07:53 +0200)
committerIngo Ruhnke <grumbel@gmail.com>
Sat, 9 Aug 2014 05:53:39 +0000 (07:53 +0200)
src/gui/menu_manager.cpp
src/gui/menu_manager.hpp
src/supertux/screen_manager.cpp
src/supertux/title_screen.cpp

index c96fe7f..b029e0f 100644 (file)
@@ -24,6 +24,7 @@
 #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;
@@ -35,26 +36,106 @@ MenuManager::instance()
   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)),
@@ -67,56 +148,68 @@ MenuManager::draw(DrawingContext& context)
                              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
@@ -142,31 +235,28 @@ MenuManager::push_menu(int id)
 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
@@ -180,16 +270,12 @@ MenuManager::set_menu(std::unique_ptr<Menu> menu)
 {
   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...
@@ -206,4 +292,17 @@ MenuManager::recalc_pos()
   }
 }
 
+Menu*
+MenuManager::current() const
+{
+  if (m_menu_stack.empty())
+  {
+    return nullptr;
+  }
+  else
+  {
+    return m_menu_stack.back().get();
+  }
+}
+
 /* EOF */
index 85ba2ec..3baf4ec 100644 (file)
 #include <list>
 #include <memory>
 
-class Menu;
+#include "SDL.h"
+
 class DrawingContext;
+class Menu;
+class MenuTransition;
 
 class MenuManager
 {
@@ -33,10 +36,7 @@ public:
 
 public:
   std::vector<std::unique_ptr<Menu> > m_menu_stack;
-
-  bool close;
-  float effect_progress;
-  float effect_start_time;
+  std::unique_ptr<MenuTransition> m_transition;
 
   friend class Menu;
 
@@ -44,39 +44,26 @@ public:
   MenuManager();
   ~MenuManager();
 
+  void event(const SDL_Event& event);
+  void update();
   void draw(DrawingContext& context);
   bool check_menu();
 
   void set_menu(int id);
-  void clear_menu_stack();
-
-  void push_menu(std::unique_ptr<Menu> menu);
+  void set_menu(std::unique_ptr<Menu> menu);
   void push_menu(int id);
+  void push_menu(std::unique_ptr<Menu> menu);
   void pop_menu();
+  void clear_menu_stack();
 
   void recalc_pos();
-
-  /** Return the current active menu or NULL if none is active */
-  Menu* current() const
-  {
-    if (m_menu_stack.empty())
-    {
-      return nullptr;
-    }
-    else
-    {
-      return m_menu_stack.back().get();
-    }
-  }
-
   bool is_active() const
   {
     return !m_menu_stack.empty();
   }
 
 private:
-  /** Set the current menu, if pmenu is NULL, hide the current menu */
-  void set_menu(std::unique_ptr<Menu> menu);
+  Menu* current() const;
 
 private:
   MenuManager(const MenuManager&);
index a19f914..17e2ba2 100644 (file)
@@ -174,8 +174,7 @@ ScreenManager::update_gamelogic(float elapsed_time)
   scripting::update_debugger();
   scripting::TimeScheduler::instance->update(game_time);
   current_screen->update(elapsed_time);
-  if (m_menu_manager->current() != NULL)
-    m_menu_manager->current()->update();
+  m_menu_manager->update();
   if(screen_fade.get() != NULL)
     screen_fade->update(elapsed_time);
   Console::instance->update(elapsed_time);
@@ -190,8 +189,7 @@ ScreenManager::process_events()
   {
     g_input_manager->process_event(event);
 
-    if(m_menu_manager->current() != NULL)
-      m_menu_manager->current()->event(event);
+    m_menu_manager->event(event);
 
     switch(event.type)
     {
index ae5cd23..681e3e3 100644 (file)
@@ -157,10 +157,7 @@ TitleScreen::update(float elapsed_time)
 
   make_tux_jump();
 
-  if (Menu* menu = MenuManager::instance().current())
-  {
-    menu->check_menu();
-  }
+  MenuManager::instance().check_menu();
 
   // reopen menu if user closed it (so that the app doesn't close when user
   // accidently hit ESC)