Fixed a Segmentation Fault when mr_iceblock was kicked into a brick containing coins...
[supertux.git] / src / gui / menu_manager.cpp
index 9a34c98..32b6178 100644 (file)
 #include <assert.h>
 
 #include "control/input_manager.hpp"
+#include "gui/dialog.hpp"
 #include "gui/menu.hpp"
 #include "gui/mousecursor.hpp"
 #include "math/sizef.hpp"
 #include "supertux/globals.hpp"
 #include "supertux/menu/menu_storage.hpp"
 #include "supertux/timer.hpp"
+#include "util/gettext.hpp"
 #include "util/log.hpp"
 #include "video/drawing_context.hpp"
 
@@ -134,6 +136,9 @@ public:
 };
 
 MenuManager::MenuManager() :
+  m_dialog(),
+  m_has_next_dialog(false),
+  m_next_dialog(),
   m_menu_stack(),
   m_transition(new MenuTransition)
 {
@@ -157,26 +162,43 @@ MenuManager::refresh()
 void
 MenuManager::process_input()
 {
-  if (current())
+  if (m_dialog)
   {
-    current()->process_input();
+    m_dialog->process_input(*InputManager::current()->get_controller());
+  }
+  else if (current_menu())
+  {
+    current_menu()->process_input();
   }
 }
 
 void
-MenuManager::event(const SDL_Event& event_)
+MenuManager::event(const SDL_Event& ev)
 {
-  if (current() && !m_transition->is_active())
+  if (!m_transition->is_active())
   {
-    // only pass events when the menu is fully visible and not in a
-    // transition animation
-    current()->event(event_);
+    if (m_dialog)
+    {
+      m_dialog->event(ev);
+    }
+    else if (current_menu())
+    {
+      // only pass events when the menu is fully visible and not in a
+      // transition animation
+      current_menu()->event(ev);
+    }
   }
 }
 
 void
 MenuManager::draw(DrawingContext& context)
 {
+  if (m_has_next_dialog)
+  {
+    m_dialog = std::move(m_next_dialog);
+    m_has_next_dialog = false;
+  }
+
   if (m_transition->is_active())
   {
     m_transition->update();
@@ -184,24 +206,38 @@ MenuManager::draw(DrawingContext& context)
   }
   else
   {
-    if (current())
+    if (m_dialog)
+    {
+      m_dialog->update();
+      m_dialog->draw(context);
+    }
+    else if (current_menu())
     {
       // brute force the transition into the right shape in case the
       // menu has changed sizes
-      m_transition->set(menu2rect(*current()));
+      m_transition->set(menu2rect(*current_menu()));
       m_transition->draw(context);
 
-      current()->draw(context);
+      current_menu()->draw(context);
     }
   }
 
-  if (current() && MouseCursor::current())
+  if (current_menu() && MouseCursor::current())
   {
     MouseCursor::current()->draw(context);
   }
 }
 
 void
+MenuManager::set_dialog(std::unique_ptr<Dialog> dialog)
+{
+  // delay reseting m_dialog to a later point, as otherwise the Dialog
+  // can't unset itself without ending up with "delete this" problems
+  m_next_dialog = std::move(dialog);
+  m_has_next_dialog = true;
+}
+
+void
 MenuManager::push_menu(int id)
 {
   push_menu(MenuStorage::instance().create(static_cast<MenuStorage::MenuId>(id)));
@@ -279,7 +315,7 @@ MenuManager::on_window_resize()
 }
 
 Menu*
-MenuManager::current() const
+MenuManager::current_menu() const
 {
   if (m_menu_stack.empty())
   {