From 96a81e3ea484f4e38117f2aa2eafdcfb4ca1cbba Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Mon, 25 Aug 2014 06:46:34 +0200 Subject: [PATCH] Added mouse support to the Dialog class --- src/gui/dialog.cpp | 73 +++++++++++++++++++++++++++++++++++++++- src/gui/dialog.hpp | 5 ++- src/gui/menu_manager.cpp | 17 +++++++--- 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/src/gui/dialog.cpp b/src/gui/dialog.cpp index c3b200075c3..cd56c40a8de 100644 --- a/src/gui/dialog.cpp +++ b/src/gui/dialog.cpp @@ -18,8 +18,11 @@ #include "control/controller.hpp" #include "gui/menu_manager.hpp" +#include "gui/mousecursor.hpp" #include "supertux/resources.hpp" #include "video/drawing_context.hpp" +#include "video/renderer.hpp" +#include "video/video_system.hpp" Dialog::Dialog() : m_text(), @@ -54,6 +57,74 @@ Dialog::add_button(const std::string& text, const std::function& callba } } +int +Dialog::get_button_at(const Vector& mouse_pos) const +{ + Rectf bg_rect(Vector(SCREEN_WIDTH/2 - m_text_size.width/2, + SCREEN_HEIGHT/2 - m_text_size.height/2), + Sizef(m_text_size.width, + m_text_size.height + 44)); + + for(int i = 0; i < static_cast(m_buttons.size()); ++i) + { + float segment_width = bg_rect.get_width() / m_buttons.size(); + float button_width = segment_width; + float button_height = 24.0f; + Vector pos(bg_rect.p1.x + segment_width/2.0f + i * segment_width, + bg_rect.p2.y - 12); + Rectf button_rect(Vector(pos.x - button_width/2, pos.y - button_height/2), + Vector(pos.x + button_width/2, pos.y + button_height/2)); + if (button_rect.contains(mouse_pos)) + { + return i; + } + } + return -1; +} + +void +Dialog::event(const SDL_Event& ev) +{ + switch(ev.type) { + case SDL_MOUSEBUTTONDOWN: + if(ev.button.button == SDL_BUTTON_LEFT) + { + Vector mouse_pos = VideoSystem::current()->get_renderer().to_logical(ev.motion.x, ev.motion.y); + int new_button = get_button_at(mouse_pos); + if (new_button != -1) + { + m_selected_button = new_button; + on_button_click(m_selected_button); + + // warning: this will "delete this" + MenuManager::instance().set_dialog({}); + } + } + break; + + case SDL_MOUSEMOTION: + { + Vector mouse_pos = VideoSystem::current()->get_renderer().to_logical(ev.motion.x, ev.motion.y); + int new_button = get_button_at(mouse_pos); + if (new_button != -1) + { + m_selected_button = new_button; + if(MouseCursor::current()) + MouseCursor::current()->set_state(MC_LINK); + } + else + { + if(MouseCursor::current()) + MouseCursor::current()->set_state(MC_NORMAL); + } + } + break; + + default: + break; + } +} + void Dialog::process_input(const Controller& controller) { @@ -143,7 +214,7 @@ Dialog::draw(DrawingContext& ctx) } void -Dialog::on_button_click(int button) +Dialog::on_button_click(int button) const { if (m_buttons[button].callback) { diff --git a/src/gui/dialog.hpp b/src/gui/dialog.hpp index e7965555258..736614188de 100644 --- a/src/gui/dialog.hpp +++ b/src/gui/dialog.hpp @@ -17,6 +17,7 @@ #ifndef HEADER_SUPERTUX_GUI_DIALOG_HPP #define HEADER_SUPERTUX_GUI_DIALOG_HPP +#include #include #include #include @@ -49,11 +50,13 @@ class Dialog void add_button(const std::string& text, const std::function& callback = {}, bool focus = false); + void event(const SDL_Event& event); void process_input(const Controller& controller); void draw(DrawingContext& context); private: - void on_button_click(int button); + void on_button_click(int button) const; + int get_button_at(const Vector& pos) const; private: Dialog(const Dialog&) = delete; diff --git a/src/gui/menu_manager.cpp b/src/gui/menu_manager.cpp index e69aa5941d4..1bd6330aae3 100644 --- a/src/gui/menu_manager.cpp +++ b/src/gui/menu_manager.cpp @@ -170,13 +170,20 @@ MenuManager::process_input() } void -MenuManager::event(const SDL_Event& event_) +MenuManager::event(const SDL_Event& ev) { - if (current_menu() && !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_menu()->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); + } } }