From 1a49f86e9841035fe670f6b42a3c988f737267d2 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 7 Aug 2024 21:27:36 +0200 Subject: Add settings icon, close window when pressing the close button --- images/settings.png | Bin 0 -> 6713 bytes include/Theme.hpp | 3 +- include/gui/CheckBox.hpp | 2 + include/gui/CustomRendererWidget.hpp | 25 ++++++++++++ meson.build | 1 + src/SettingsPage.cpp | 73 ++++++++++++++++++++++++++++++----- src/Theme.cpp | 5 ++- src/gui/Button.cpp | 2 +- src/gui/CheckBox.cpp | 4 ++ src/gui/ComboBox.cpp | 4 +- src/gui/CustomRendererWidget.cpp | 41 ++++++++++++++++++++ src/gui/Entry.cpp | 2 +- src/gui/RadioButton.cpp | 2 +- src/main.cpp | 34 ++++++++++++++-- 14 files changed, 177 insertions(+), 21 deletions(-) create mode 100644 images/settings.png create mode 100644 include/gui/CustomRendererWidget.hpp create mode 100644 src/gui/CustomRendererWidget.cpp diff --git a/images/settings.png b/images/settings.png new file mode 100644 index 0000000..5f8d203 Binary files /dev/null and b/images/settings.png differ diff --git a/include/Theme.hpp b/include/Theme.hpp index ced85bd..cc321bd 100644 --- a/include/Theme.hpp +++ b/include/Theme.hpp @@ -28,7 +28,8 @@ namespace gsr { mgl::Font title_font; mgl::Font top_bar_font; - mgl::Texture combobox_arrow; + mgl::Texture combobox_arrow_texture; + mgl::Texture settings_texture; }; bool init_theme(const gsr::GsrInfo &gsr_info, mgl::vec2i window_size, const std::string &resources_path); diff --git a/include/gui/CheckBox.hpp b/include/gui/CheckBox.hpp index c91b947..19ffaf6 100644 --- a/include/gui/CheckBox.hpp +++ b/include/gui/CheckBox.hpp @@ -16,6 +16,8 @@ namespace gsr { void draw(mgl::Window &window, mgl::vec2f offset) override; mgl::vec2f get_size() override; + + void set_checked(bool checked); bool is_checked() const; private: mgl::vec2f get_checkbox_size(); diff --git a/include/gui/CustomRendererWidget.hpp b/include/gui/CustomRendererWidget.hpp new file mode 100644 index 0000000..e16e532 --- /dev/null +++ b/include/gui/CustomRendererWidget.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "Widget.hpp" + +#include + +namespace gsr { + class CustomRendererWidget : public Widget { + public: + CustomRendererWidget(mgl::vec2f size); + CustomRendererWidget(const CustomRendererWidget&) = delete; + CustomRendererWidget& operator=(const CustomRendererWidget&) = delete; + + bool on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) override; + void draw(mgl::Window &window, mgl::vec2f offset) override; + + mgl::vec2f get_size() override; + + std::function draw_handler; + // Return true to allow other widgets to handle events + std::function event_handler; + private: + mgl::vec2f size; + }; +} \ No newline at end of file diff --git a/meson.build b/meson.build index f04ec23..6447534 100644 --- a/meson.build +++ b/meson.build @@ -21,6 +21,7 @@ src = [ 'src/gui/Utils.cpp', 'src/gui/DropdownButton.cpp', 'src/gui/Label.cpp', + 'src/gui/CustomRendererWidget.cpp', 'src/SettingsPage.cpp', 'src/Utils.cpp', 'src/Config.cpp', diff --git a/src/SettingsPage.cpp b/src/SettingsPage.cpp index 187d414..e4c41c8 100644 --- a/src/SettingsPage.cpp +++ b/src/SettingsPage.cpp @@ -8,8 +8,14 @@ #include "../include/gui/Entry.hpp" #include "../include/gui/CheckBox.hpp" #include "../include/gui/ScrollablePage.hpp" +#include "../include/gui/CustomRendererWidget.hpp" #include "../include/GsrInfo.hpp" +#include +#include +#include +#include + namespace gsr { SettingsPage::SettingsPage(Type type, const GsrInfo &gsr_info, const std::vector &audio_devices, std::function back_button_callback) : page(mgl::vec2f(get_theme().window_width, get_theme().window_height).floor()), @@ -51,6 +57,26 @@ namespace gsr { back_button->on_click = back_button_callback; page.add_widget(std::move(back_button)); + auto settings_icon_widget = std::make_unique(mgl::vec2f(window_size.x / 10, window_size.x / 10).floor()); + settings_icon_widget->set_position(content_page_ptr->get_position().floor() - mgl::vec2f(settings_icon_widget->get_size().x + window_size.x / 50, 0.0f).floor()); + settings_icon_widget->draw_handler = [&](mgl::Window &window, mgl::vec2f pos, mgl::vec2f size) { + mgl::Rectangle background(size); + background.set_position(pos); + background.set_color(mgl::Color(0, 0, 0, 255)); + window.draw(background); + + const int text_margin = size.y * 0.085; + mgl::Text title("Settings", get_theme().title_font); + title.set_position((pos + mgl::vec2f(size.x * 0.5f - title.get_bounds().size.x * 0.5f, text_margin)).floor()); + window.draw(title); + + mgl::Sprite icon(&get_theme().settings_texture); + icon.set_height((int)(size.y * 0.5f)); + icon.set_position((pos + size * 0.5f - icon.get_size() * 0.5f).floor()); + window.draw(icon); + }; + page.add_widget(std::move(settings_icon_widget)); + auto settings_list = std::make_unique(List::Orientation::VERTICAL); { auto view_radio_button = std::make_unique(&get_theme().body_font); @@ -306,10 +332,21 @@ namespace gsr { } settings_list_ptr->add_widget(std::move(file_list)); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Record cursor")); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Show replay started notification")); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Show replay stopped notification")); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Show replay saved notification")); + auto record_cursor_checkbox = std::make_unique(&get_theme().body_font, "Record cursor"); + record_cursor_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(record_cursor_checkbox)); + + auto show_replay_started_notification_checkbox = std::make_unique(&get_theme().body_font, "Show replay started notification"); + show_replay_started_notification_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(show_replay_started_notification_checkbox)); + + auto show_replay_stopped_notification_checkbox = std::make_unique(&get_theme().body_font, "Show replay stopped notification"); + show_replay_stopped_notification_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(show_replay_stopped_notification_checkbox)); + + auto show_replay_saved_notification_checkbox = std::make_unique(&get_theme().body_font, "Show replay saved notification"); + show_replay_saved_notification_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(show_replay_saved_notification_checkbox)); } void SettingsPage::add_record_widgets() { @@ -337,9 +374,17 @@ namespace gsr { } settings_list_ptr->add_widget(std::move(file_list)); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Record cursor")); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Show recording started notification")); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Show video saved notification")); + auto record_cursor_checkbox = std::make_unique(&get_theme().body_font, "Record cursor"); + record_cursor_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(record_cursor_checkbox)); + + auto show_recording_started_notification_checkbox = std::make_unique(&get_theme().body_font, "Show recording started notification"); + show_recording_started_notification_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(show_recording_started_notification_checkbox)); + + auto show_video_saved_notification_checkbox = std::make_unique(&get_theme().body_font, "Show video saved notification"); + show_video_saved_notification_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(show_video_saved_notification_checkbox)); } void SettingsPage::add_stream_widgets() { @@ -395,9 +440,17 @@ namespace gsr { } settings_list_ptr->add_widget(std::move(streaming_info_list)); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Record cursor")); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Show streaming started notification")); - settings_list_ptr->add_widget(std::make_unique(&get_theme().body_font, "Show streaming stopped notification")); + auto record_cursor_checkbox = std::make_unique(&get_theme().body_font, "Record cursor"); + record_cursor_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(record_cursor_checkbox)); + + auto show_streaming_started_notification_checkbox = std::make_unique(&get_theme().body_font, "Show streaming started notification"); + show_streaming_started_notification_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(show_streaming_started_notification_checkbox)); + + auto show_streaming_stopped_notification_checkbox = std::make_unique(&get_theme().body_font, "Show streaming stopped notification"); + show_streaming_stopped_notification_checkbox->set_checked(true); + settings_list_ptr->add_widget(std::move(show_streaming_stopped_notification_checkbox)); streaming_service_box_ptr->on_selection_changed = [=](const std::string &text, const std::string &id) { (void)text; diff --git a/src/Theme.cpp b/src/Theme.cpp index 0849eed..946b4b2 100644 --- a/src/Theme.cpp +++ b/src/Theme.cpp @@ -47,7 +47,10 @@ namespace gsr { if(!theme->body_font.load_from_file(theme->body_font_file, std::max(13.0f, window_size.y * 0.015f))) goto error; - if(!theme->combobox_arrow.load_from_file((resources_path + "images/combobox_arrow.png").c_str(), {false, false, false})) + if(!theme->combobox_arrow_texture.load_from_file((resources_path + "images/combobox_arrow.png").c_str(), {false, false, false})) + goto error; + + if(!theme->settings_texture.load_from_file((resources_path + "images/settings.png").c_str(), {false, false, false})) goto error; return true; diff --git a/src/gui/Button.cpp b/src/gui/Button.cpp index d2c4a2c..e36d07b 100644 --- a/src/gui/Button.cpp +++ b/src/gui/Button.cpp @@ -46,7 +46,7 @@ namespace gsr { const bool mouse_inside = mgl::FloatRect(draw_pos, item_size).contains(window.get_mouse_position().to_vec2f()) && !has_parent_with_selected_child_widget(); if(mouse_inside) - draw_rectangle_outline(window, draw_pos, item_size, get_theme().tint_color, border_scale * get_theme().window_height); + draw_rectangle_outline(window, draw_pos, item_size, get_theme().tint_color, std::max(1.0f, border_scale * get_theme().window_height)); } mgl::vec2f Button::get_size() { diff --git a/src/gui/CheckBox.cpp b/src/gui/CheckBox.cpp index 94e5f9e..e0904ba 100644 --- a/src/gui/CheckBox.cpp +++ b/src/gui/CheckBox.cpp @@ -75,6 +75,10 @@ namespace gsr { return mgl::vec2f(text_bounds.y, text_bounds.y).floor(); } + void CheckBox::set_checked(bool checked) { + this->checked = checked; + } + bool CheckBox::is_checked() const { return checked; } diff --git a/src/gui/ComboBox.cpp b/src/gui/ComboBox.cpp index 6aff979..373b06b 100644 --- a/src/gui/ComboBox.cpp +++ b/src/gui/ComboBox.cpp @@ -14,7 +14,7 @@ namespace gsr { static const float padding_right_scale = 0.007f; static const float border_scale = 0.0015f; - ComboBox::ComboBox(mgl::Font *font) : font(font), dropdown_arrow(&get_theme().combobox_arrow) { + ComboBox::ComboBox(mgl::Font *font) : font(font), dropdown_arrow(&get_theme().combobox_arrow_texture) { assert(font); } @@ -109,7 +109,7 @@ namespace gsr { Item &item = items[selected_item]; item.text.set_position(pos.floor()); if(show_dropdown || mouse_inside) { - const int border_size = border_scale * get_theme().window_height; + const int border_size = std::max(1.0f, border_scale * get_theme().window_height); const mgl::Color border_color = get_theme().tint_color; draw_rectangle_outline(window, pos - mgl::vec2f(padding_left, padding_top), item_size.floor(), border_color, border_size); } diff --git a/src/gui/CustomRendererWidget.cpp b/src/gui/CustomRendererWidget.cpp new file mode 100644 index 0000000..98b7caf --- /dev/null +++ b/src/gui/CustomRendererWidget.cpp @@ -0,0 +1,41 @@ +#include "../../include/gui/CustomRendererWidget.hpp" + +#include + +namespace gsr { + CustomRendererWidget::CustomRendererWidget(mgl::vec2f size) : size(size) {} + + bool CustomRendererWidget::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) { + if(!visible || !event_handler) + return true; + return event_handler(event, window, position + offset, size); + } + + void CustomRendererWidget::draw(mgl::Window &window, mgl::vec2f offset) { + if(!visible) + return; + + const mgl::vec2f draw_pos = position + offset; + + mgl_scissor prev_scissor; + mgl_window_get_scissor(window.internal_window(), &prev_scissor); + + mgl_scissor new_scissor = { + mgl_vec2i{(int)draw_pos.x, (int)draw_pos.y}, + mgl_vec2i{(int)size.x, (int)size.y} + }; + mgl_window_set_scissor(window.internal_window(), &new_scissor); + + if(draw_handler) + draw_handler(window, draw_pos, size); + + mgl_window_set_scissor(window.internal_window(), &prev_scissor); + } + + mgl::vec2f CustomRendererWidget::get_size() { + if(!visible) + return {0.0f, 0.0f}; + + return size; + } +} \ No newline at end of file diff --git a/src/gui/Entry.cpp b/src/gui/Entry.cpp index e74e41e..f337bcf 100644 --- a/src/gui/Entry.cpp +++ b/src/gui/Entry.cpp @@ -57,7 +57,7 @@ namespace gsr { window.draw(background); if(selected) { - const int border_size = border_scale * get_theme().window_height; + const int border_size = std::max(1.0f, border_scale * get_theme().window_height); draw_rectangle_outline(window, draw_pos.floor(), get_size().floor(), get_theme().tint_color, border_size); const int caret_width = std::max(1.0f, caret_width_scale * get_theme().window_height); diff --git a/src/gui/RadioButton.cpp b/src/gui/RadioButton.cpp index 15b0989..eb1f900 100644 --- a/src/gui/RadioButton.cpp +++ b/src/gui/RadioButton.cpp @@ -77,7 +77,7 @@ namespace gsr { const bool mouse_inside = mgl::FloatRect(draw_pos, item_size).contains(window.get_mouse_position().to_vec2f()); if(can_select_item && mouse_inside) { - const int border_size = border_scale * get_theme().window_height; + const int border_size = std::max(1.0f, border_scale * get_theme().window_height); const mgl::Color border_color = get_theme().tint_color; draw_rectangle_outline(window, draw_pos.floor(), item_size.floor(), border_color, border_size); } diff --git a/src/main.cpp b/src/main.cpp index 0649c09..196f7e1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,8 @@ #include "../include/gui/StaticPage.hpp" #include "../include/gui/DropdownButton.hpp" +#include "../include/gui/CustomRendererWidget.hpp" +#include "../include/gui/Utils.hpp" #include "../include/Process.hpp" #include "../include/Theme.hpp" #include "../include/GsrInfo.hpp" @@ -620,9 +622,32 @@ int main(int argc, char **argv) { if(!close_texture.load_from_file((resources_path + "images/cross.png").c_str())) startup_error("failed to load texture: images/cross.png"); - mgl::Sprite close_sprite(&close_texture); - close_sprite.set_height(int(top_bar_background.get_size().y * 0.3f)); - close_sprite.set_position(mgl::vec2f(window_size.x - close_sprite.get_size().x - 50.0f, top_bar_background.get_size().y * 0.5f - close_sprite.get_size().y * 0.5f).floor()); + gsr::CustomRendererWidget close_button_widget(mgl::vec2f(top_bar_background.get_size().y * 0.3f, top_bar_background.get_size().y * 0.3f).floor()); + close_button_widget.set_position(mgl::vec2f(window_size.x - close_button_widget.get_size().x - 50.0f, top_bar_background.get_size().y * 0.5f - close_button_widget.get_size().y * 0.5f).floor()); + close_button_widget.draw_handler = [&](mgl::Window &window, mgl::vec2f pos, mgl::vec2f size) { + if(mgl::FloatRect(pos, size).contains(window.get_mouse_position().to_vec2f())) { + const float border_scale = 0.0015f; + const int border_size = std::max(1.0f, border_scale * gsr::get_theme().window_height); + gsr::draw_rectangle_outline(window, pos, size, gsr::get_theme().tint_color, border_size); + } + + mgl::Sprite close_sprite(&close_texture); + close_sprite.set_position(pos); + close_sprite.set_size(size); + window.draw(close_sprite); + }; + bool close_button_pressed_inside = false; + close_button_widget.event_handler = [&](mgl::Event &event, mgl::Window&, mgl::vec2f pos, mgl::vec2f size) { + if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) { + close_button_pressed_inside = mgl::FloatRect(pos, size).contains(mgl::vec2f(event.mouse_button.x, event.mouse_button.y)); + } else if(event.type == mgl::Event::MouseButtonReleased && event.mouse_button.button == mgl::Mouse::Left && close_button_pressed_inside) { + if(mgl::FloatRect(pos, size).contains(mgl::vec2f(event.mouse_button.x, event.mouse_button.y))) { + running = false; + return false; + } + } + return true; + }; mgl::Texture logo_texture; if(!logo_texture.load_from_file((resources_path + "images/gpu_screen_recorder_logo.png").c_str())) @@ -655,7 +680,7 @@ int main(int argc, char **argv) { window.draw(top_bar_background); window.draw(top_bar_text); window.draw(logo_sprite); - window.draw(close_sprite); + close_button_widget.draw(window, mgl::vec2f(0.0f, 0.0f)); page_stack.top()->draw(window, mgl::vec2f(0.0f, 0.0f)); window.display(); }; @@ -668,6 +693,7 @@ int main(int argc, char **argv) { while(window.poll_event(event)) { page_stack.top()->on_event(event, window, mgl::vec2f(0.0f, 0.0f)); + close_button_widget.on_event(event, window, mgl::vec2f(0.0f, 0.0f)); if(event.type == mgl::Event::KeyReleased) { if(event.key.code == mgl::Keyboard::Escape && !page_stack.empty()) page_stack.pop(); -- cgit v1.2.3