Switched from passing pointers around to using numeric MenuIds and a factory class
[supertux.git] / src / gui / menu.cpp
index 6e48496..581414e 100644 (file)
 #include "gui/menu.hpp"
 
 #include <math.h>
+#include <stdexcept>
 
-#include "control/joystickkeyboardcontroller.hpp"
+#include "control/input_manager.hpp"
 #include "gui/menu_item.hpp"
 #include "gui/menu_manager.hpp"
 #include "gui/mousecursor.hpp"
 #include "supertux/globals.hpp"
-#include "supertux/screen_manager.hpp"
 #include "supertux/resources.hpp"
+#include "supertux/screen_manager.hpp"
 #include "supertux/timer.hpp"
 #include "util/gettext.hpp"
 #include "video/drawing_context.hpp"
 #include "video/font.hpp"
+#include "video/renderer.hpp"
 
 static const float MENU_REPEAT_INITIAL = 0.4f;
 static const float MENU_REPEAT_RATE    = 0.1f;
 
-extern SDL_Surface* g_screen;
-
 Menu::Menu() :
   hit_item(),
-  pos_x(),
-  pos_y(),
+  pos(),
   menuaction(),
   delete_character(),
   mn_input_char(),
@@ -48,64 +47,48 @@ Menu::Menu() :
   effect_progress(),
   effect_start_time(),
   arrange_left(),
-  active_item(),
-  checkbox(),
-  checkbox_checked(),
-  back(),
-  arrow_left(),
-  arrow_right()
+  active_item()
 {
-  MenuManager::all_menus.push_back(this);
+  MenuManager::instance().m_all_menus.push_back(this);
 
   hit_item = -1;
   menuaction = MENU_ACTION_NONE;
   delete_character = 0;
   mn_input_char = '\0';
 
-  pos_x        = SCREEN_WIDTH/2;
-  pos_y        = SCREEN_HEIGHT/2;
+  pos.x        = SCREEN_WIDTH/2;
+  pos.y        = SCREEN_HEIGHT/2;
   arrange_left = 0;
   active_item  = -1;
 
   effect_progress   = 0.0f;
   effect_start_time = 0.0f;
-
-  checkbox.reset(new Surface("images/engine/menu/checkbox-unchecked.png"));
-  checkbox_checked.reset(new Surface("images/engine/menu/checkbox-checked.png"));
-  back.reset(new Surface("images/engine/menu/arrow-back.png"));
-  arrow_left.reset(new Surface("images/engine/menu/arrow-left.png"));
-  arrow_right.reset(new Surface("images/engine/menu/arrow-right.png"));
 }
 
 Menu::~Menu()
 {
-  MenuManager::all_menus.remove(this);
+  MenuManager::instance().m_all_menus.remove(this);
 
-  for(std::vector<MenuItem*>::iterator i = items.begin();
-      i != items.end(); ++i) 
-  {
-    delete *i;
-  }
+  if (MenuManager::instance().m_current == this)
+    MenuManager::instance().m_current = nullptr;
 
-  if (MenuManager::current_ == this)
-    MenuManager::current_ = NULL;
-
-  if (MenuManager::previous == this)
-    MenuManager::previous = NULL;
+  if (MenuManager::instance().m_previous == this)
+    MenuManager::instance().m_previous = nullptr;
 }
 
 void
 Menu::set_pos(float x, float y, float rw, float rh)
 {
-  pos_x = x + get_width()  * rw;
-  pos_y = y + get_height() * rh;
+  pos.x = x + get_width()  * rw;
+  pos.y = y + get_height() * rh;
 }
 
 /* Add an item to a menu */
-void
-Menu::additem(MenuItem* item)
+MenuItem*
+Menu::add_item(std::unique_ptr<MenuItem> new_item)
 {
-  items.push_back(item);
+  items.push_back(std::move(new_item));
+  MenuItem* item = items.back().get();
 
   /* If a new menu is being built, the active item shouldn't be set to
    * something that isn't selectable. Set the active_item to the first
@@ -114,102 +97,92 @@ Menu::additem(MenuItem* item)
   if (active_item == -1
       && item->kind != MN_HL
       && item->kind != MN_LABEL
-      && item->kind != MN_INACTIVE) {
+      && item->kind != MN_INACTIVE)
+  {
     active_item = items.size() - 1;
   }
+
+  return item;
 }
 
 MenuItem*
 Menu::add_hl()
 {
-  MenuItem* item = new MenuItem(MN_HL);
-  additem(item);
-  return item;
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_HL));
+  return add_item(std::move(item));
 }
 
 MenuItem*
 Menu::add_label(const std::string& text)
 {
-  MenuItem* item = new MenuItem(MN_LABEL);
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_LABEL));
   item->text = text;
-  additem(item);
-  return item;
+  return add_item(std::move(item));
 }
 
 MenuItem*
 Menu::add_controlfield(int id, const std::string& text,
                        const std::string& mapping)
 {
-  MenuItem* item = new MenuItem(MN_CONTROLFIELD, id);
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_CONTROLFIELD, id));
   item->change_text(text);
   item->change_input(mapping);
-  additem(item);
-  return item;
+  return add_item(std::move(item));
 }
 
 MenuItem*
 Menu::add_entry(int id, const std::string& text)
 {
-  MenuItem* item = new MenuItem(MN_ACTION, id);
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_ACTION, id));
   item->text = text;
-  additem(item);
-  return item;
+  return add_item(std::move(item));
 }
 
 MenuItem*
 Menu::add_inactive(int id, const std::string& text)
 {
-  MenuItem* item = new MenuItem(MN_INACTIVE, id);
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_INACTIVE, id));
   item->text = text;
-  additem(item);
-  return item;
+  return add_item(std::move(item));
 }
 
 MenuItem*
 Menu::add_toggle(int id, const std::string& text, bool toogled)
 {
-  MenuItem* item = new MenuItem(MN_TOGGLE, id);
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_TOGGLE, id));
   item->text = text;
   item->toggled = toogled;
-  additem(item);
-  return item;
+  return add_item(std::move(item));
 }
 
 MenuItem*
 Menu::add_string_select(int id, const std::string& text)
 {
-  MenuItem* item = new MenuItem(MN_STRINGSELECT, id);
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_STRINGSELECT, id));
   item->text = text;
-  additem(item);
-  return item;
+  return add_item(std::move(item));
 }
 
 MenuItem*
 Menu::add_back(const std::string& text)
 {
-  MenuItem* item = new MenuItem(MN_BACK);
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_BACK));
   item->text = text;
-  additem(item);
-  return item;
+  return add_item(std::move(item));
 }
 
 MenuItem*
-Menu::add_submenu(const std::string& text, Menu* submenu, int id)
+Menu::add_submenu(const std::string& text, int submenu, int id)
 {
-  MenuItem* item = new MenuItem(MN_GOTO, id);
+  std::unique_ptr<MenuItem> item(new MenuItem(MN_GOTO, id));
   item->text = text;
   item->target_menu = submenu;
-  additem(item);
-  return item;
+  return add_item(std::move(item));
 }
 
 void
 Menu::clear()
 {
-  for(std::vector<MenuItem*>::iterator i = items.begin();
-      i != items.end(); ++i) {
-    delete *i;
-  }
   items.clear();
   active_item = -1;
 }
@@ -222,7 +195,7 @@ Menu::update()
   if (menu_height > SCREEN_HEIGHT)
   { // Scrolling
     int scroll_offset = (menu_height - SCREEN_HEIGHT) / 2 + 32;
-    pos_y = SCREEN_HEIGHT/2 - scroll_offset * ((float(active_item) / (items.size()-1)) - 0.5f) * 2.0f;
+    pos.y = SCREEN_HEIGHT/2 - scroll_offset * ((float(active_item) / (items.size()-1)) - 0.5f) * 2.0f;
   }
 
   effect_progress = (real_time - effect_start_time) * 6.0f;
@@ -231,7 +204,7 @@ Menu::update()
     effect_progress = 1.0f;
 
     if (close) {
-      MenuManager::current_ = 0;
+      MenuManager::instance().m_current = 0;
       close = false;
     }
   }
@@ -239,52 +212,54 @@ Menu::update()
     effect_progress = 0.0f;
   }
 
+  Controller* controller = g_input_manager->get_controller();
   /** check main input controller... */
-  if(g_main_controller->pressed(Controller::UP)) {
+  if(controller->pressed(Controller::UP)) {
     menuaction = MENU_ACTION_UP;
     menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
   }
-  if(g_main_controller->hold(Controller::UP) &&
+  if(controller->hold(Controller::UP) &&
      menu_repeat_time != 0 && real_time > menu_repeat_time) {
     menuaction = MENU_ACTION_UP;
     menu_repeat_time = real_time + MENU_REPEAT_RATE;
   }
 
-  if(g_main_controller->pressed(Controller::DOWN)) {
+  if(controller->pressed(Controller::DOWN)) {
     menuaction = MENU_ACTION_DOWN;
     menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
   }
-  if(g_main_controller->hold(Controller::DOWN) &&
+  if(controller->hold(Controller::DOWN) &&
      menu_repeat_time != 0 && real_time > menu_repeat_time) {
     menuaction = MENU_ACTION_DOWN;
     menu_repeat_time = real_time + MENU_REPEAT_RATE;
   }
 
-  if(g_main_controller->pressed(Controller::LEFT)) {
+  if(controller->pressed(Controller::LEFT)) {
     menuaction = MENU_ACTION_LEFT;
     menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
   }
-  if(g_main_controller->hold(Controller::LEFT) &&
+  if(controller->hold(Controller::LEFT) &&
      menu_repeat_time != 0 && real_time > menu_repeat_time) {
     menuaction = MENU_ACTION_LEFT;
     menu_repeat_time = real_time + MENU_REPEAT_RATE;
   }
 
-  if(g_main_controller->pressed(Controller::RIGHT)) {
+  if(controller->pressed(Controller::RIGHT)) {
     menuaction = MENU_ACTION_RIGHT;
     menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
   }
-  if(g_main_controller->hold(Controller::RIGHT) &&
+  if(controller->hold(Controller::RIGHT) &&
      menu_repeat_time != 0 && real_time > menu_repeat_time) {
     menuaction = MENU_ACTION_RIGHT;
     menu_repeat_time = real_time + MENU_REPEAT_RATE;
   }
 
-  if(g_main_controller->pressed(Controller::ACTION)
-     || g_main_controller->pressed(Controller::MENU_SELECT)) {
+  if(controller->pressed(Controller::ACTION)
+     || controller->pressed(Controller::MENU_SELECT)) {
     menuaction = MENU_ACTION_HIT;
   }
-  if(g_main_controller->pressed(Controller::PAUSE_MENU)) {
+  if(controller->pressed(Controller::PAUSE_MENU)
+    || controller->pressed(Controller::MENU_BACK)) {
     menuaction = MENU_ACTION_BACK;
   }
 
@@ -326,8 +301,8 @@ Menu::update()
           items[active_item]->selected--;
         else
           items[active_item]->selected = items[active_item]->list.size()-1;
-        
-        menu_action(items[active_item]);
+
+        menu_action(items[active_item].get());
       }
       break;
 
@@ -337,8 +312,8 @@ Menu::update()
           items[active_item]->selected++;
         else
           items[active_item]->selected = 0;
-        
-        menu_action(items[active_item]);
+
+        menu_action(items[active_item].get());
       }
       break;
 
@@ -347,20 +322,20 @@ Menu::update()
       switch (items[active_item]->kind) {
         case MN_GOTO:
           assert(items[active_item]->target_menu != 0);
-          MenuManager::push_current(items[active_item]->target_menu);
+          MenuManager::instance().push_current(items[active_item]->target_menu);
           break;
 
         case MN_TOGGLE:
           items[active_item]->toggled = !items[active_item]->toggled;
-          menu_action(items[active_item]);
+          menu_action(items[active_item].get());
           break;
 
         case MN_CONTROLFIELD:
-          menu_action(items[active_item]);
+          menu_action(items[active_item].get());
           break;
 
         case MN_ACTION:
-          menu_action(items[active_item]);
+          menu_action(items[active_item].get());
           break;
 
         case MN_STRINGSELECT:
@@ -369,7 +344,7 @@ Menu::update()
           else
             items[active_item]->selected = 0;
 
-          menu_action(items[active_item]);
+          menu_action(items[active_item].get());
           break;
 
         case MN_TEXTFIELD:
@@ -379,7 +354,7 @@ Menu::update()
           break;
 
         case MN_BACK:
-          MenuManager::pop_current();
+          MenuManager::instance().pop_current();
           break;
         default:
           break;
@@ -414,7 +389,7 @@ Menu::update()
       break;
 
     case MENU_ACTION_BACK:
-      MenuManager::pop_current();
+      MenuManager::instance().pop_current();
       break;
 
     case MENU_ACTION_NONE:
@@ -428,11 +403,11 @@ Menu::update()
 int
 Menu::check()
 {
-  if (hit_item != -1) 
+  if (hit_item != -1)
   {
     int id = items[hit_item]->id;
     // Clear event when checked out.. (we would end up in a loop when we try to leave "fake" submenu like Addons or Contrib)
-    hit_item = -1;                      
+    hit_item = -1;
     return id;
   }
   else
@@ -452,15 +427,14 @@ Menu::draw_item(DrawingContext& context, int index)
   MenuItem& pitem = *(items[index]);
 
   Color text_color = default_color;
-  float x_pos       = pos_x;
-  float y_pos       = pos_y + 24*index - menu_height/2 + 12;
-  int shadow_size = 2;
+  float x_pos       = pos.x;
+  float y_pos       = pos.y + 24*index - menu_height/2 + 12;
   int text_width  = int(Resources::normal_font->get_text_width(pitem.text));
   int input_width = int(Resources::normal_font->get_text_width(pitem.input) + 10);
   int list_width = 0;
 
-  float left  = pos_x - menu_width/2 + 16;
-  float right = pos_x + menu_width/2 - 16;
+  float left  = pos.x - menu_width/2 + 16;
+  float right = pos.x + menu_width/2 - 16;
 
   if(pitem.list.size() > 0) {
     list_width = (int) Resources::normal_font->get_text_width(pitem.list[pitem.selected]);
@@ -471,20 +445,19 @@ Menu::draw_item(DrawingContext& context, int index)
 
   if(index == active_item)
   {
-    shadow_size = 3;
     text_color = active_color;
   }
 
   if(active_item == index)
   {
     float blink = (sinf(real_time * M_PI * 1.0f)/2.0f + 0.5f) * 0.5f + 0.25f;
-    context.draw_filled_rect(Rect(Vector(pos_x - menu_width/2 + 10 - 2, y_pos - 12 - 2),
-                                  Vector(pos_x + menu_width/2 - 10 + 2, y_pos + 12 + 2)),
+    context.draw_filled_rect(Rectf(Vector(pos.x - menu_width/2 + 10 - 2, y_pos - 12 - 2),
+                                   Vector(pos.x + menu_width/2 - 10 + 2, y_pos + 12 + 2)),
                              Color(1.0f, 1.0f, 1.0f, blink),
                              14.0f,
                              LAYER_GUI-10);
-    context.draw_filled_rect(Rect(Vector(pos_x - menu_width/2 + 10, y_pos - 12),
-                                  Vector(pos_x + menu_width/2 - 10, y_pos + 12)),
+    context.draw_filled_rect(Rectf(Vector(pos.x - menu_width/2 + 10, y_pos - 12),
+                                   Vector(pos.x + menu_width/2 - 10, y_pos + 12)),
                              Color(1.0f, 1.0f, 1.0f, 0.5f),
                              12.0f,
                              LAYER_GUI-10);
@@ -495,7 +468,7 @@ Menu::draw_item(DrawingContext& context, int index)
     case MN_INACTIVE:
     {
       context.draw_text(Resources::normal_font, pitem.text,
-                        Vector(pos_x, y_pos - int(Resources::normal_font->get_height()/2)),
+                        Vector(pos.x, y_pos - int(Resources::normal_font->get_height()/2)),
                         ALIGN_CENTER, LAYER_GUI, inactive_color);
       break;
     }
@@ -503,7 +476,7 @@ Menu::draw_item(DrawingContext& context, int index)
     case MN_HL:
     {
       // TODO
-      float x = pos_x - menu_width/2;
+      float x = pos.x - menu_width/2;
       float y = y_pos - 12;
       /* Draw a horizontal line with a little 3d effect */
       context.draw_filled_rect(Vector(x, y + 6),
@@ -517,7 +490,7 @@ Menu::draw_item(DrawingContext& context, int index)
     case MN_LABEL:
     {
       context.draw_text(Resources::big_font, pitem.text,
-                        Vector(pos_x, y_pos - int(Resources::big_font->get_height()/2)),
+                        Vector(pos.x, y_pos - int(Resources::big_font->get_height()/2)),
                         ALIGN_CENTER, LAYER_GUI, label_color);
       break;
     }
@@ -550,17 +523,17 @@ Menu::draw_item(DrawingContext& context, int index)
     }
     case MN_STRINGSELECT:
     {
-      float roff = arrow_left->get_width();
+      float roff = Resources::arrow_left->get_width();
       // Draw left side
       context.draw_text(Resources::normal_font, pitem.text,
                         Vector(left, y_pos - int(Resources::normal_font->get_height()/2)),
                         ALIGN_LEFT, LAYER_GUI, text_color);
 
       // Draw right side
-      context.draw_surface(arrow_left.get(),
+      context.draw_surface(Resources::arrow_left,
                            Vector(right - list_width - roff - roff, y_pos - 8),
                            LAYER_GUI);
-      context.draw_surface(arrow_right.get(),
+      context.draw_surface(Resources::arrow_right,
                            Vector(right - roff, y_pos - 8),
                            LAYER_GUI);
       context.draw_text(Resources::normal_font, pitem.list[pitem.selected],
@@ -571,9 +544,9 @@ Menu::draw_item(DrawingContext& context, int index)
     case MN_BACK:
     {
       context.draw_text(Resources::Resources::normal_font, pitem.text,
-                        Vector(pos_x, y_pos - int(Resources::normal_font->get_height()/2)),
+                        Vector(pos.x, y_pos - int(Resources::normal_font->get_height()/2)),
                         ALIGN_CENTER, LAYER_GUI, text_color);
-      context.draw_surface(back.get(),
+      context.draw_surface(Resources::back,
                            Vector(x_pos + text_width/2  + 16, y_pos - 8),
                            LAYER_GUI);
       break;
@@ -582,28 +555,28 @@ Menu::draw_item(DrawingContext& context, int index)
     case MN_TOGGLE:
     {
       context.draw_text(Resources::normal_font, pitem.text,
-                        Vector(pos_x - menu_width/2 + 16, y_pos - (Resources::normal_font->get_height()/2)),
+                        Vector(pos.x - menu_width/2 + 16, y_pos - (Resources::normal_font->get_height()/2)),
                         ALIGN_LEFT, LAYER_GUI, text_color);
 
       if(pitem.toggled)
-        context.draw_surface(checkbox_checked.get(),
-                             Vector(x_pos + (menu_width/2-16) - checkbox->get_width(), y_pos - 8),
+        context.draw_surface(Resources::checkbox_checked,
+                             Vector(x_pos + (menu_width/2-16) - Resources::checkbox->get_width(), y_pos - 8),
                              LAYER_GUI + 1);
       else
-        context.draw_surface(checkbox.get(),
-                             Vector(x_pos + (menu_width/2-16) - checkbox->get_width(), y_pos - 8),
+        context.draw_surface(Resources::checkbox,
+                             Vector(x_pos + (menu_width/2-16) - Resources::checkbox->get_width(), y_pos - 8),
                              LAYER_GUI + 1);
       break;
     }
     case MN_ACTION:
       context.draw_text(Resources::normal_font, pitem.text,
-                        Vector(pos_x, y_pos - int(Resources::normal_font->get_height()/2)),
+                        Vector(pos.x, y_pos - int(Resources::normal_font->get_height()/2)),
                         ALIGN_CENTER, LAYER_GUI, text_color);
       break;
 
     case MN_GOTO:
       context.draw_text(Resources::normal_font, pitem.text,
-                        Vector(pos_x, y_pos - int(Resources::normal_font->get_height()/2)),
+                        Vector(pos.x, y_pos - int(Resources::normal_font->get_height()/2)),
                         ALIGN_CENTER, LAYER_GUI, text_color);
       break;
   }
@@ -617,7 +590,7 @@ Menu::get_width() const
   float menu_width = 0;
   for(unsigned int i = 0; i < items.size(); ++i)
   {
-    Font* font = Resources::Resources::normal_font;
+    FontPtr font = Resources::Resources::normal_font;
     if(items[i]->kind == MN_LABEL)
       font = Resources::big_font;
 
@@ -625,6 +598,9 @@ Menu::get_width() const
       Resources::big_font->get_text_width(items[i]->input) + 16;
     if(items[i]->kind == MN_TOGGLE)
       w += 32;
+    if (items[i]->kind == MN_STRINGSELECT)
+      w += font->get_text_width(items[i]->list[items[i]->selected]) + 32;
+
 
     if(w > menu_width)
       menu_width = w;
@@ -654,13 +630,13 @@ Menu::draw(DrawingContext& context)
   {
     if (close)
     {
-      menu_width  = (MenuManager::current_->get_width()  * (1.0f - effect_progress));
-      menu_height = (MenuManager::current_->get_height() * (1.0f - effect_progress));
+      menu_width *= 1.0f - effect_progress;
+      menu_height *= 1.0f - effect_progress;
     }
-    else if (MenuManager::previous)
+    else if (MenuManager::instance().m_previous)
     {
-      menu_width  = (menu_width  * effect_progress) + (MenuManager::previous->get_width()  * (1.0f - effect_progress));
-      menu_height = (menu_height * effect_progress) + (MenuManager::previous->get_height() * (1.0f - effect_progress));
+      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
@@ -671,15 +647,15 @@ Menu::draw(DrawingContext& context)
   }
 
   /* Draw a transparent background */
-  context.draw_filled_rect(Rect(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.2f, 0.3f, 0.4f, 0.8f), 
+  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.2f, 0.3f, 0.4f, 0.8f),
                            20.0f,
                            LAYER_GUI-10);
 
-  context.draw_filled_rect(Rect(Vector(pos_x - menu_width/2, pos_y - menu_height/2 - 10),
-                                Vector(pos_x + menu_width/2, pos_y - menu_height/2 + 10 + menu_height)),
-                           Color(0.6f, 0.7f, 0.8f, 0.5f), 
+  context.draw_filled_rect(Rectf(Vector(pos.x - menu_width/2, pos.y - menu_height/2 - 10),
+                                 Vector(pos.x + menu_width/2, pos.y - menu_height/2 + 10 + menu_height)),
+                           Color(0.6f, 0.7f, 0.8f, 0.5f),
                            16.0f,
                            LAYER_GUI-10);
 
@@ -687,25 +663,25 @@ Menu::draw(DrawingContext& context)
   {
     int text_width  = (int) Resources::normal_font->get_text_width(items[active_item]->help);
     int text_height = (int) Resources::normal_font->get_text_height(items[active_item]->help);
-      
-    Rect text_rect(pos_x - text_width/2 - 8, 
+
+    Rectf text_rect(pos.x - text_width/2 - 8,
                    SCREEN_HEIGHT - 48 - text_height/2 - 4,
-                   pos_x + text_width/2 + 8, 
+                   pos.x + text_width/2 + 8,
                    SCREEN_HEIGHT - 48 + text_height/2 + 4);
-        
-    context.draw_filled_rect(Rect(text_rect.p1 - Vector(4,4),
-                                  text_rect.p2 + Vector(4,4)),
-                             Color(0.2f, 0.3f, 0.4f, 0.8f), 
+
+    context.draw_filled_rect(Rectf(text_rect.p1 - Vector(4,4),
+                                   text_rect.p2 + Vector(4,4)),
+                             Color(0.2f, 0.3f, 0.4f, 0.8f),
                              16.0f,
                              LAYER_GUI-10);
-      
+
     context.draw_filled_rect(text_rect,
-                             Color(0.6f, 0.7f, 0.8f, 0.5f), 
+                             Color(0.6f, 0.7f, 0.8f, 0.5f),
                              16.0f,
                              LAYER_GUI-10);
 
     context.draw_text(Resources::normal_font, items[active_item]->help,
-                      Vector(pos_x, SCREEN_HEIGHT - 48 - text_height/2),
+                      Vector(pos.x, SCREEN_HEIGHT - 48 - text_height/2),
                       ALIGN_CENTER, LAYER_GUI);
   }
 
@@ -719,12 +695,12 @@ Menu::draw(DrawingContext& context)
 MenuItem&
 Menu::get_item_by_id(int id)
 {
-  for(std::vector<MenuItem*>::iterator i = items.begin();
-      i != items.end(); ++i) {
-    MenuItem& item = **i;
-
-    if(item.id == id)
-      return item;
+  for (const auto& item : items)
+  {
+    if (item->id == id)
+    {
+      return *item;
+    }
   }
 
   throw std::runtime_error("MenuItem not found");
@@ -733,12 +709,12 @@ Menu::get_item_by_id(int id)
 const MenuItem&
 Menu::get_item_by_id(int id) const
 {
-  for(std::vector<MenuItem*>::const_iterator i = items.begin();
-      i != items.end(); ++i) {
-    const MenuItem& item = **i;
-
-    if(item.id == id)
-      return item;
+  for (const auto& item : items)
+  {
+    if (item->id == id)
+    {
+      return *item;
+    }
   }
 
   throw std::runtime_error("MenuItem not found");
@@ -761,15 +737,6 @@ Menu::set_toggled(int id, bool toggled)
   get_item_by_id(id).toggled = toggled;
 }
 
-Menu*
-Menu::get_parent() const
-{
-  if (MenuManager::last_menus.empty())
-    return 0;
-  else
-    return MenuManager::last_menus.back();
-}
-
 /* Check for menu event */
 void
 Menu::event(const SDL_Event& event)
@@ -779,14 +746,16 @@ Menu::event(const SDL_Event& event)
 
   switch(event.type) {
     case SDL_MOUSEBUTTONDOWN:
+    if(event.button.button == SDL_BUTTON_LEFT)
     {
-      int x = int(event.motion.x * float(SCREEN_WIDTH)/g_screen->w);
-      int y = int(event.motion.y * float(SCREEN_HEIGHT)/g_screen->h);
-
-      if(x > pos_x - get_width()/2 &&
-         x < pos_x + get_width()/2 &&
-         y > pos_y - get_height()/2 &&
-         y < pos_y + get_height()/2)
+      Vector mouse_pos = Renderer::instance()->to_logical(event.motion.x, event.motion.y);
+      int x = int(mouse_pos.x);
+      int y = int(mouse_pos.y);
+
+      if(x > pos.x - get_width()/2 &&
+         x < pos.x + get_width()/2 &&
+         y > pos.y - get_height()/2 &&
+         y < pos.y + get_height()/2)
       {
         menuaction = MENU_ACTION_HIT;
       }
@@ -795,16 +764,17 @@ Menu::event(const SDL_Event& event)
 
     case SDL_MOUSEMOTION:
     {
-      float x = event.motion.x * SCREEN_WIDTH/g_screen->w;
-      float y = event.motion.y * SCREEN_HEIGHT/g_screen->h;
-
-      if(x > pos_x - get_width()/2 &&
-         x < pos_x + get_width()/2 &&
-         y > pos_y - get_height()/2 &&
-         y < pos_y + get_height()/2)
+      Vector mouse_pos = Renderer::instance()->to_logical(event.motion.x, event.motion.y);
+      float x = mouse_pos.x;
+      float y = mouse_pos.y;
+
+      if(x > pos.x - get_width()/2 &&
+         x < pos.x + get_width()/2 &&
+         y > pos.y - get_height()/2 &&
+         y < pos.y + get_height()/2)
       {
         int new_active_item
-          = static_cast<int> ((y - (pos_y - get_height()/2)) / 24);
+          = static_cast<int> ((y - (pos.y - get_height()/2)) / 24);
 
         /* only change the mouse focus to a selectable item */
         if ((items[new_active_item]->kind != MN_HL)
@@ -832,8 +802,7 @@ void
 Menu::set_active_item(int id)
 {
   for(size_t i = 0; i < items.size(); ++i) {
-    MenuItem* item = items[i];
-    if(item->id == id) {
+    if(items[i]->id == id) {
       active_item = i;
       break;
     }