#include "control/controller.hpp"
#include "gui/menu_manager.hpp"
+#include "gui/menu.hpp"
+#include "gui/mousecursor.hpp"
#include "supertux/resources.hpp"
+#include "supertux/colorscheme.hpp"
#include "video/drawing_context.hpp"
+#include "video/renderer.hpp"
+#include "video/video_system.hpp"
Dialog::Dialog() :
m_text(),
m_buttons(),
- m_selected_button()
+ m_selected_button(),
+ m_cancel_button(-1),
+ m_text_size()
{
}
Dialog::set_text(const std::string& text)
{
m_text = text;
+
+ m_text_size = Sizef(Resources::normal_font->get_text_width(m_text),
+ Resources::normal_font->get_text_height(m_text));
+
+}
+
+void
+Dialog::clear_buttons()
+{
+ m_buttons.clear();
+ m_selected_button = 0;
+ m_cancel_button = -1;
+}
+
+void
+Dialog::add_default_button(const std::string& text, const std::function<void ()>& callback)
+{
+ add_button(text, callback);
+ m_selected_button = m_buttons.size() - 1;
+}
+
+void
+Dialog::add_cancel_button(const std::string& text, const std::function<void ()>& callback)
+{
+ add_button(text, callback);
+ m_cancel_button = m_buttons.size() - 1;
+}
+
+void
+Dialog::add_button(const std::string& text, const std::function<void ()>& callback)
+{
+ m_buttons.push_back({text, callback});
+}
+
+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<int>(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::add_button(const std::string& text)
+Dialog::event(const SDL_Event& ev)
{
- m_buttons.push_back(text);
+ 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);
+ }
+ }
+ 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
if (controller.pressed(Controller::ACTION) ||
controller.pressed(Controller::MENU_SELECT))
{
- on_select(m_selected_button);
+ on_button_click(m_selected_button);
+ }
- // warning: this will "delete this"
- MenuManager::instance().set_dialog({});
+ if (m_cancel_button != -1 &&
+ (controller.pressed(Controller::ESCAPE) ||
+ controller.pressed(Controller::MENU_BACK)))
+ {
+ on_button_click(m_cancel_button);
}
}
void
Dialog::draw(DrawingContext& ctx)
{
- Vector center(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
-
- Sizef text_size(Resources::normal_font->get_text_width(m_text),
- Resources::normal_font->get_text_height(m_text));
-
- Rectf text_rect(Vector(center.x - text_size.width/2,
- center.y - text_size.height/2),
- text_size);
-
- Rectf bg_rect = text_rect;
- bg_rect.p2.y += 44;
+ 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));
// draw background rect
ctx.draw_filled_rect(bg_rect.grown(12.0f),
// draw HL line
ctx.draw_filled_rect(Vector(bg_rect.p1.x, bg_rect.p2.y - 35),
- Vector(bg_rect.get_width(), 4),
- Color(0.6f, 0.7f, 1.0f, 1.0f), LAYER_GUI);
+ Vector(bg_rect.get_width(), 4),
+ Color(0.6f, 0.7f, 1.0f, 1.0f), LAYER_GUI);
ctx.draw_filled_rect(Vector(bg_rect.p1.x, bg_rect.p2.y - 35),
- Vector(bg_rect.get_width(), 2),
- Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI);
+ Vector(bg_rect.get_width(), 2),
+ Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI);
// draw buttons
for(int i = 0; i < static_cast<int>(m_buttons.size()); ++i)
{
float segment_width = bg_rect.get_width() / m_buttons.size();
- float button_width = segment_width * 0.95;
- float button_height = 24.0f;
+ float button_width = segment_width;
Vector pos(bg_rect.p1.x + segment_width/2.0f + i * segment_width,
bg_rect.p2.y - 12);
if (i == m_selected_button)
{
+ float button_height = 24.0f;
float blink = (sinf(real_time * M_PI * 1.0f)/2.0f + 0.5f) * 0.5f + 0.25f;
ctx.draw_filled_rect(Rectf(Vector(pos.x - button_width/2, pos.y - button_height/2),
Vector(pos.x + button_width/2, pos.y + button_height/2)).grown(2.0f),
LAYER_GUI-10);
}
- ctx.draw_text(Resources::normal_font, m_buttons[i],
+ ctx.draw_text(Resources::normal_font, m_buttons[i].text,
Vector(pos.x, pos.y - int(Resources::normal_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI);
+ ALIGN_CENTER, LAYER_GUI,
+ i == m_selected_button ? ColorScheme::Menu::active_color : ColorScheme::Menu::default_color);
}
}
void
-Dialog::on_select(int id)
+Dialog::on_button_click(int button) const
{
+ if (m_buttons[button].callback)
+ {
+ m_buttons[button].callback();
+ }
+ MenuManager::instance().set_dialog({});
}
/* EOF */