diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/Button.cpp | 31 | ||||
-rw-r--r-- | src/gui/ComboBox.cpp | 22 | ||||
-rw-r--r-- | src/gui/DropdownButton.cpp | 8 | ||||
-rw-r--r-- | src/gui/List.cpp | 53 | ||||
-rw-r--r-- | src/gui/Page.cpp | 9 | ||||
-rw-r--r-- | src/gui/Widget.cpp | 4 |
6 files changed, 108 insertions, 19 deletions
diff --git a/src/gui/Button.cpp b/src/gui/Button.cpp index eb5932b..e8137c9 100644 --- a/src/gui/Button.cpp +++ b/src/gui/Button.cpp @@ -7,15 +7,21 @@ #include <mglpp/system/FloatRect.hpp> namespace gsr { + static const float padding_top = 10.0f; + static const float padding_bottom = 10.0f; + static const float padding_left = 10.0f; + static const float padding_right = 10.0f; + Button::Button(mgl::Font *font, const char *text, mgl::vec2f size, mgl::Color bg_color) : size(size), bg_color(bg_color), text(text, *font) { } bool Button::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) { + const mgl::vec2f item_size = get_size().floor(); if(event.type == mgl::Event::MouseMoved) { - mouse_inside = mgl::FloatRect(position + offset, size).contains({ (float)event.mouse_move.x, (float)event.mouse_move.y }); + mouse_inside = mgl::FloatRect(position + offset, item_size).contains({ (float)event.mouse_move.x, (float)event.mouse_move.y }); } else if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) { - const bool clicked_inside = mouse_inside; + const bool clicked_inside = mgl::FloatRect(position + offset, item_size).contains({ (float)event.mouse_button.x, (float)event.mouse_button.y });; if(clicked_inside && on_click) on_click(); } @@ -23,18 +29,31 @@ namespace gsr { } void Button::draw(mgl::Window &window, mgl::vec2f offset) { - mgl::Rectangle background(size.floor()); - background.set_position((position + offset).floor()); + const mgl::vec2f draw_pos = position + offset; + const mgl::vec2f item_size = get_size().floor(); + mgl::Rectangle background(item_size); + background.set_position(draw_pos.floor()); background.set_color(bg_color); window.draw(background); - text.set_position((position + offset + size * 0.5f - text.get_bounds().size * 0.5f).floor()); + text.set_position((draw_pos + item_size * 0.5f - text.get_bounds().size * 0.5f).floor()); window.draw(text); + const bool mouse_inside = mgl::FloatRect(draw_pos, item_size).contains(window.get_mouse_position().to_vec2f()); if(mouse_inside) { const int border_size = 5; const mgl::Color border_color = gsr::get_theme().tint_color; - draw_rectangle_outline(window, position, size, border_color, border_size); + draw_rectangle_outline(window, position, item_size, border_color, border_size); } } + + mgl::vec2f Button::get_size() { + const mgl::vec2f text_bounds = text.get_bounds().size; + mgl::vec2f s = size; + if(s.x < 0.0001f) + s.x = padding_left + text_bounds.x + padding_right; + if(s.y < 0.0001f) + s.y = padding_top + text_bounds.y + padding_bottom; + return s; + } }
\ No newline at end of file diff --git a/src/gui/ComboBox.cpp b/src/gui/ComboBox.cpp index 3aa4439..851e3da 100644 --- a/src/gui/ComboBox.cpp +++ b/src/gui/ComboBox.cpp @@ -13,7 +13,7 @@ namespace gsr { static const float padding_left = 10.0f; static const float padding_right = 10.0f; - ComboBox::ComboBox(mgl::Font *font) : font(font) { + ComboBox::ComboBox(mgl::Font *font) : font(font), dropdown_arrow(&get_theme().combobox_arrow) { assert(font); } @@ -60,21 +60,28 @@ namespace gsr { if(items.empty()) return; - const mgl::vec2f draw_pos = position + offset; + const mgl::vec2f draw_pos = (position + offset).floor(); const mgl::vec2f item_size(max_size.x, font->get_character_size() + padding_top + padding_bottom); const mgl::vec2i mouse_pos = window.get_mouse_position(); bool inside = false; - mgl::Rectangle background(draw_pos, mgl::vec2f(max_size.x, item_size.y)); + mgl::Rectangle background(draw_pos, item_size.floor()); if(show_dropdown) { - background.set_size(max_size); + background.set_size(max_size.floor()); background.set_color(mgl::Color(0, 0, 0)); } else { background.set_color(mgl::Color(0, 0, 0, 120)); } window.draw(background); + if(!show_dropdown) { + dropdown_arrow.set_height(get_dropdown_arrow_height()); + dropdown_arrow.set_position(draw_pos + mgl::vec2f(item_size.x - dropdown_arrow.get_size().x - padding_right, item_size.y * 0.5f - dropdown_arrow.get_size().y * 0.5f).floor()); + dropdown_arrow.set_color(mgl::Color(255, 255, 255, 30)); + window.draw(dropdown_arrow); + } + mgl::vec2f pos = draw_pos + mgl::vec2f(padding_left, padding_top); Item &item = items[selected_item]; @@ -82,7 +89,7 @@ namespace gsr { if(show_dropdown) { const int border_size = 3; const mgl::Color border_color = gsr::get_theme().tint_color; - draw_rectangle_outline(window, pos - mgl::vec2f(padding_left, padding_top), item_size, border_color, border_size); + draw_rectangle_outline(window, pos - mgl::vec2f(padding_left, padding_top), item_size.floor(), border_color, border_size); } window.draw(item.text); pos.y += item.text.get_bounds().size.y + padding_top + padding_bottom; @@ -136,6 +143,7 @@ namespace gsr { max_size.x = std::max(max_size.x, bounds.x + padding_left + padding_right); max_size.y += bounds.y + padding_top + padding_bottom; } + max_size.x += padding_left + get_dropdown_arrow_height(); dirty = false; } @@ -143,4 +151,8 @@ namespace gsr { update_if_dirty(); return { max_size.x, font->get_character_size() + padding_top + padding_bottom }; } + + float ComboBox::get_dropdown_arrow_height() const { + return (font->get_character_size() + padding_top + padding_bottom) * 0.4f; + } }
\ No newline at end of file diff --git a/src/gui/DropdownButton.cpp b/src/gui/DropdownButton.cpp index fa51aac..9fb4803 100644 --- a/src/gui/DropdownButton.cpp +++ b/src/gui/DropdownButton.cpp @@ -8,10 +8,10 @@ #include <mglpp/system/FloatRect.hpp> namespace gsr { - static const float padding_top = 10.0f; - static const float padding_bottom = 10.0f; - static const float padding_left = 10.0f; - static const float padding_right = 10.0f; + static const float padding_top = 15.0f; + static const float padding_bottom = 15.0f; + static const float padding_left = 20.0f; + static const float padding_right = 20.0f; static const int border_size = 5; DropdownButton::DropdownButton(mgl::Font *title_font, mgl::Font *description_font, const char *title, const char *description_activated, const char *description_deactivated, mgl::Texture *icon_texture, mgl::vec2f size) : diff --git a/src/gui/List.cpp b/src/gui/List.cpp index 4a74f62..e8c02e0 100644 --- a/src/gui/List.cpp +++ b/src/gui/List.cpp @@ -1,13 +1,13 @@ #include "../../include/gui/List.hpp" +#include "../../include/Theme.hpp" static float floor(float f) { return (int)f; } namespace gsr { - // TODO: Make this modifiable, multiple by window size. // TODO: Add homogeneous option, using a specified max size of this list. - static const mgl::vec2f spacing(30.0f, 10.0f); + static const mgl::vec2f spacing_scale(0.009f, 0.009f); List::List(Orientation orientation, Alignment content_alignment) : orientation(orientation), content_alignment(content_alignment) {} @@ -31,7 +31,30 @@ namespace gsr { return true; } + // TODO: Maybe call this from main on all widgets instead of from draw + void List::update() { + //widgets.insert(widgets.back(), std::make_move_iterator(add_queue.begin()), std::make_move_iterator(add_queue.end())); + std::move(add_queue.begin(), add_queue.end(), std::back_inserter(widgets)); + add_queue.clear(); + + for(Widget *widget_to_remove : remove_queue) { + remove_widget_immediate(widget_to_remove); + } + remove_queue.clear(); + } + + void List::remove_widget_immediate(Widget *widget) { + for(auto it = widgets.begin(), end = widgets.end(); it != end; ++it) { + if(it->get() == widget) { + widgets.erase(it); + return; + } + } + } + void List::draw(mgl::Window &window, mgl::vec2f offset) { + update(); + mgl::vec2f draw_pos = position + offset; offset = {0.0f, 0.0f}; Widget *selected_widget = selected_child_widget; @@ -39,6 +62,7 @@ namespace gsr { // TODO: Handle start/end alignment const mgl::vec2f size = get_size(); + const mgl::vec2f spacing = (spacing_scale * get_theme().window_height).floor(); switch(orientation) { case Orientation::VERTICAL: { for(auto &widget : widgets) { @@ -68,14 +92,37 @@ namespace gsr { selected_widget->draw(window, mgl::vec2f(0.0f, 0.0f)); } + // void List::remove_child_widget(Widget *widget) { + // for(auto it = widgets.begin(), end = widgets.end(); it != end; ++it) { + // if(it->get() == widget) { + // widgets.erase(it); + // return; + // } + // } + // } + void List::add_widget(std::unique_ptr<Widget> widget) { widget->parent_widget = this; - widgets.push_back(std::move(widget)); + // TODO: Maybe only do this if this is called inside an event handler + //widgets.push_back(std::move(widget)); + add_queue.push_back(std::move(widget)); + } + + void List::remove_widget(Widget *widget) { + for(auto it = add_queue.begin(), end = add_queue.end(); it != end; ++it) { + if(it->get() == widget) { + add_queue.erase(it); + return; + } + } + // TODO: Maybe only do this if this is called inside an event handler + remove_queue.push_back(widget); } // TODO: Cache result mgl::vec2f List::get_size() { mgl::vec2f size; + const mgl::vec2f spacing = (spacing_scale * get_theme().window_height).floor(); switch(orientation) { case Orientation::VERTICAL: { for(auto &widget : widgets) { diff --git a/src/gui/Page.cpp b/src/gui/Page.cpp index 7d43c00..ae13d82 100644 --- a/src/gui/Page.cpp +++ b/src/gui/Page.cpp @@ -1,6 +1,15 @@ #include "../../include/gui/Page.hpp" namespace gsr { + // void Page::remove_child_widget(Widget *widget) { + // for(auto it = widgets.begin(), end = widgets.end(); it != end; ++it) { + // if(it->get() == widget) { + // widgets.erase(it); + // return; + // } + // } + // } + void Page::add_widget(std::unique_ptr<Widget> widget) { widget->parent_widget = this; widgets.push_back(std::move(widget)); diff --git a/src/gui/Widget.cpp b/src/gui/Widget.cpp index 3e966e5..4baeff1 100644 --- a/src/gui/Widget.cpp +++ b/src/gui/Widget.cpp @@ -6,7 +6,9 @@ namespace gsr { } Widget::~Widget() { - + remove_widget_as_selected_in_parent(); + // if(parent_widget) + // parent_widget->remove_child_widget(this); } void Widget::set_position(mgl::vec2f position) { |