diff options
author | dec05eba <dec05eba@protonmail.com> | 2024-09-11 00:54:57 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2024-09-11 00:54:57 +0200 |
commit | dd906c6a9dde666af0b10cc016039f312733201f (patch) | |
tree | a18fea76ed728067cafba65d833234d92c2afcd3 | |
parent | 747344b858c4750e7b0b19ca10c3727148c2a161 (diff) |
Make scrollbar movable with mouse, limit filechooser content to inside of file item
m--------- | depends/mglpp | 0 | ||||
-rw-r--r-- | include/gui/ScrollablePage.hpp | 9 | ||||
-rw-r--r-- | include/gui/SettingsPage.hpp | 4 | ||||
-rw-r--r-- | src/gui/FileChooser.cpp | 13 | ||||
-rw-r--r-- | src/gui/RadioButton.cpp | 2 | ||||
-rw-r--r-- | src/gui/ScrollablePage.cpp | 53 | ||||
-rw-r--r-- | src/gui/SettingsPage.cpp | 60 | ||||
-rw-r--r-- | src/gui/Subsection.cpp | 4 |
8 files changed, 103 insertions, 42 deletions
diff --git a/depends/mglpp b/depends/mglpp -Subproject 8f6c5d220d3e4c250db4bf3022f99c38811b63f +Subproject 818092cd16431ed258e8de51fa24a5c6b074317 diff --git a/include/gui/ScrollablePage.hpp b/include/gui/ScrollablePage.hpp index 5a31b92..ade7c67 100644 --- a/include/gui/ScrollablePage.hpp +++ b/include/gui/ScrollablePage.hpp @@ -4,6 +4,8 @@ #include "../SafeVector.hpp" #include <memory> +#include <mglpp/system/FloatRect.hpp> + namespace gsr { class ScrollablePage : public Widget { public: @@ -15,15 +17,22 @@ namespace gsr { void draw(mgl::Window &window, mgl::vec2f offset) override; mgl::vec2f get_size() override; + mgl::vec2f get_inner_size() override; void set_size(mgl::vec2f size); void add_widget(std::unique_ptr<Widget> widget); void reset_scroll(); private: + float get_scrollbar_width() const; + private: mgl::vec2f size; SafeVector<std::unique_ptr<Widget>> widgets; int scroll_target_y = 0; double scroll_y = 0.0; + mgl::FloatRect scrollbar_rect; + bool moving_scrollbar_with_cursor = false; + mgl::vec2f scrollbar_move_cursor_start_pos; + double scrollbar_move_cursor_scroll_y_start = 0.0; }; }
\ No newline at end of file diff --git a/include/gui/SettingsPage.hpp b/include/gui/SettingsPage.hpp index b22506e..a9d79bc 100644 --- a/include/gui/SettingsPage.hpp +++ b/include/gui/SettingsPage.hpp @@ -57,7 +57,6 @@ namespace gsr { std::unique_ptr<List> create_video_codec(const GsrInfo &gsr_info); std::unique_ptr<ComboBox> create_audio_codec_box(); std::unique_ptr<List> create_audio_codec(); - std::unique_ptr<List> create_codec_section(const GsrInfo &gsr_info); std::unique_ptr<Entry> create_framerate_entry(); std::unique_ptr<List> create_framerate(); std::unique_ptr<ComboBox> create_framerate_mode_box(); @@ -101,7 +100,8 @@ namespace gsr { List *area_size_list_ptr = nullptr; List *restore_portal_session_list_ptr = nullptr; List *color_range_list_ptr = nullptr; - List *codec_list_ptr = nullptr; + Widget *video_codec_ptr = nullptr; + Widget *audio_codec_ptr = nullptr; List *framerate_mode_list_ptr = nullptr; ComboBox *record_area_box_ptr = nullptr; Entry *area_width_entry_ptr = nullptr; diff --git a/src/gui/FileChooser.cpp b/src/gui/FileChooser.cpp index b7321cd..994993c 100644 --- a/src/gui/FileChooser.cpp +++ b/src/gui/FileChooser.cpp @@ -26,6 +26,8 @@ namespace gsr { static const float content_padding_bottom_scale = 0.03f; static const float content_padding_left_scale = 0.03f; static const float content_padding_right_scale = 0.03f; + static const float content_margin_left_scale = 0.005f; + static const float content_margin_right_scale = 0.005f; static const float up_button_spacing_scale = 0.01f; FileChooserBody::FileChooserBody(FileChooser *file_chooser, mgl::vec2f size) : @@ -107,6 +109,8 @@ namespace gsr { window.draw(folder_sprite); // TODO: Dont allow text to go further left/right than item_pos (on the left side) and item_pos + item_size (on the right side). + folder.text.set_max_width(item_size.x); + folder.text.set_max_rows(2); folder.text.set_position(folder_sprite.get_position() + mgl::vec2f(folder_sprite.get_size().x * 0.5f - folder.text.get_bounds().size.x * 0.5f, folder_sprite.get_size().y)); window.draw(folder.text); } @@ -239,9 +243,9 @@ namespace gsr { draw_pos += mgl::vec2f(0.0f, current_directory_background_size.y + spacing_between_current_directory_and_content * get_theme().window_height); const mgl::vec2f body_size = mgl::vec2f(size.x, size.y - (draw_pos.y - draw_pos_start.y)).floor(); scrollable_page.set_size(body_size); - file_chooser_body_ptr->set_size(body_size); + file_chooser_body_ptr->set_size(scrollable_page.get_inner_size()); - mgl::Rectangle content_background(size.floor()); + mgl::Rectangle content_background(scrollable_page.get_inner_size().floor()); content_background.set_position(draw_pos.floor()); content_background.set_color(mgl::Color(0, 0, 0, 120)); window.draw(content_background); @@ -264,7 +268,10 @@ namespace gsr { void FileChooser::open_subdirectory(const char *name) { char filepath[PATH_MAX]; - snprintf(filepath, sizeof(filepath), "%s/%s", current_directory_text.get_string().c_str(), name); + if(current_directory_text.get_string() == "/") + snprintf(filepath, sizeof(filepath), "/%s", name); + else + snprintf(filepath, sizeof(filepath), "%s/%s", current_directory_text.get_string().c_str(), name); set_current_directory(filepath); } diff --git a/src/gui/RadioButton.cpp b/src/gui/RadioButton.cpp index 66f3b69..925e133 100644 --- a/src/gui/RadioButton.cpp +++ b/src/gui/RadioButton.cpp @@ -78,7 +78,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 = std::max(1.0f, border_scale * get_theme().window_height); - const mgl::Color border_color = get_theme().tint_color; + const mgl::Color border_color = i == selected_item ? mgl::Color(255, 255, 255) : get_theme().tint_color; draw_rectangle_outline(window, draw_pos.floor(), item_size.floor(), border_color, border_size); } diff --git a/src/gui/ScrollablePage.cpp b/src/gui/ScrollablePage.cpp index dc0e16f..a91367c 100644 --- a/src/gui/ScrollablePage.cpp +++ b/src/gui/ScrollablePage.cpp @@ -5,11 +5,13 @@ #include <mglpp/window/Window.hpp> #include <mglpp/window/Event.hpp> #include <mglpp/graphics/Rectangle.hpp> +#include <mglpp/system/FloatRect.hpp> namespace gsr { static const int scroll_speed = 80; static const double scroll_update_speed = 10.0; static const float scrollbar_width_scale = 0.004f; + static const float scrollbar_spacing_scale = 0.004f; ScrollablePage::ScrollablePage(mgl::vec2f size) : size(size) {} @@ -20,6 +22,12 @@ namespace gsr { offset = position + offset + mgl::vec2f(0.0f, scroll_y); Widget *selected_widget = selected_child_widget; + if(event.type == mgl::Event::MouseButtonReleased && moving_scrollbar_with_cursor) { + moving_scrollbar_with_cursor = false; + remove_widget_as_selected_in_parent(); + return false; + } + if(selected_widget) { if(!selected_widget->on_event(event, window, offset)) return false; @@ -43,16 +51,26 @@ namespace gsr { return false; } + if(event.type == mgl::Event::MouseButtonPressed && scrollbar_rect.contains(mgl::vec2f(event.mouse_button.x, event.mouse_button.y))) { + set_widget_as_selected_in_parent(); + moving_scrollbar_with_cursor = true; + scrollbar_move_cursor_start_pos = mgl::vec2f(event.mouse_button.x, event.mouse_button.y); + scrollbar_move_cursor_scroll_y_start = scroll_y; + return false; + } + return true; } void ScrollablePage::draw(mgl::Window &window, mgl::vec2f offset) { + scrollbar_rect = mgl::FloatRect(); + if(!visible || widgets.empty()) { reset_scroll(); return; } - const double scrollbar_width = std::max(5.0f, scrollbar_width_scale * get_theme().window_height); + const double scrollbar_width = get_scrollbar_width(); const mgl::vec2f scrollbar_pos = position + offset + mgl::vec2f(size.x - scrollbar_width, 0.0f); offset = position + offset; @@ -140,6 +158,9 @@ namespace gsr { if(scrollbar_height > 1.0) scrollbar_height = 1.0; + const double scrollbar_height_absolute = std::max(10.0, size.y * scrollbar_height); + const double scrollbar_empty_space = size.y - scrollbar_height_absolute; + if(scrollbar_height < 0.999) { double scroll_amount = -scroll_y / (child_height - size.y); if(scroll_amount < 0.0) @@ -147,14 +168,26 @@ namespace gsr { else if(scroll_amount > 1.0) scroll_amount = 1.0; - const double scrollbar_height_absolute = size.y * scrollbar_height; - const double scrollbar_empty_space = size.y - scrollbar_height_absolute; - mgl::Rectangle scrollbar( (scrollbar_pos + mgl::vec2f(0.0f, scroll_amount * scrollbar_empty_space)).floor(), mgl::vec2f(scrollbar_width, scrollbar_height_absolute).floor()); scrollbar.set_color(mgl::Color(200, 200, 200)); window.draw(scrollbar); + + scrollbar_rect.position = scrollbar.get_position(); + scrollbar_rect.size = scrollbar.get_size(); + } + + if(moving_scrollbar_with_cursor) { + const double scroll_bottom_limit = child_height - size.y; + const mgl::vec2f scrollbar_move_diff = window.get_mouse_position().to_vec2f() - scrollbar_move_cursor_start_pos; + const double scroll_amount = scrollbar_move_diff.y / scrollbar_empty_space; + scroll_y = scrollbar_move_cursor_scroll_y_start - scroll_amount * (child_height - size.y); + if(scroll_y > 0.0) + scroll_y = 0.0; + else if(scroll_y < -scroll_bottom_limit) + scroll_y = -scroll_bottom_limit; + scroll_target_y = scroll_y; } } @@ -165,6 +198,14 @@ namespace gsr { return size; } + mgl::vec2f ScrollablePage::get_inner_size() { + if(!visible) + return {0.0f, 0.0f}; + + const float scrollbar_spacing = std::max(2.0f, scrollbar_spacing_scale * get_theme().window_height); + return size - mgl::vec2f(get_scrollbar_width() + scrollbar_spacing, 0.0f); + } + void ScrollablePage::set_size(mgl::vec2f size) { this->size = size; } @@ -178,4 +219,8 @@ namespace gsr { scroll_y = 0; scroll_target_y = 0; } + + float ScrollablePage::get_scrollbar_width() const { + return std::max(5.0f, scrollbar_width_scale * get_theme().window_height); + } }
\ No newline at end of file diff --git a/src/gui/SettingsPage.cpp b/src/gui/SettingsPage.cpp index 12d1d99..cd5c97d 100644 --- a/src/gui/SettingsPage.cpp +++ b/src/gui/SettingsPage.cpp @@ -130,7 +130,7 @@ namespace gsr { capture_target_list->add_widget(create_select_window()); capture_target_list->add_widget(create_area_size_section()); capture_target_list->add_widget(create_restore_portal_session_section()); - return std::make_unique<Subsection>("Record area", std::move(capture_target_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f)); + return std::make_unique<Subsection>("Record area", std::move(capture_target_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)); } std::unique_ptr<ComboBox> SettingsPage::create_audio_track_selection_checkbox(const std::vector<AudioDevice> &audio_devices) { @@ -184,7 +184,8 @@ namespace gsr { audio_device_section_list->add_widget(create_add_audio_track_button(audio_devices)); audio_device_section_list->add_widget(create_audio_track_section(audio_devices)); audio_device_section_list->add_widget(create_merge_audio_tracks_checkbox()); - return std::make_unique<Subsection>("Audio", std::move(audio_device_section_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f)); + audio_device_section_list->add_widget(create_audio_codec()); + return std::make_unique<Subsection>("Audio", std::move(audio_device_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)); } std::unique_ptr<ComboBox> SettingsPage::create_video_quality_box() { @@ -230,7 +231,9 @@ namespace gsr { std::unique_ptr<ComboBox> SettingsPage::create_video_codec_box(const GsrInfo &gsr_info) { auto video_codec_box = std::make_unique<ComboBox>(&get_theme().body_font); - // TODO: Show options not supported but disable them + // TODO: Show options not supported but disable them. + // TODO: Show error if no encoders are supported. + // TODO: Show warning (once) if only software encoder is available. video_codec_box->add_item("Auto (Recommended)", "auto"); if(gsr_info.supported_video_codecs.h264) video_codec_box->add_item("H264", "h264"); @@ -260,6 +263,7 @@ namespace gsr { auto video_codec_list = std::make_unique<List>(List::Orientation::VERTICAL); video_codec_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video codec:", get_theme().text_color)); video_codec_list->add_widget(create_video_codec_box(gsr_info)); + video_codec_ptr = video_codec_list.get(); return video_codec_list; } @@ -275,17 +279,10 @@ namespace gsr { auto audio_codec_list = std::make_unique<List>(List::Orientation::VERTICAL); audio_codec_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Audio codec:", get_theme().text_color)); audio_codec_list->add_widget(create_audio_codec_box()); + audio_codec_ptr = audio_codec_list.get(); return audio_codec_list; } - std::unique_ptr<List> SettingsPage::create_codec_section(const GsrInfo &gsr_info) { - auto codec_list = std::make_unique<List>(List::Orientation::HORIZONTAL); - codec_list->add_widget(create_video_codec(gsr_info)); - codec_list->add_widget(create_audio_codec()); - codec_list_ptr = codec_list.get(); - return codec_list; - } - std::unique_ptr<Entry> SettingsPage::create_framerate_entry() { auto framerate_entry = std::make_unique<Entry>(&get_theme().body_font, "60", (int)(get_theme().body_font.get_character_size() * 2.5f)); framerate_entry->validate_handler = create_entry_validator_integer_in_range(1, 500); @@ -334,27 +331,27 @@ namespace gsr { std::unique_ptr<Widget> SettingsPage::create_video_section(const GsrInfo &gsr_info) { auto video_section_list = std::make_unique<List>(List::Orientation::VERTICAL); video_section_list->add_widget(create_video_quality_section()); - video_section_list->add_widget(create_codec_section(gsr_info)); + video_section_list->add_widget(create_video_codec(gsr_info)); video_section_list->add_widget(create_framerate_section()); video_section_list->add_widget(create_record_cursor_section()); - return std::make_unique<Subsection>("Video", std::move(video_section_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f)); + return std::make_unique<Subsection>("Video", std::move(video_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)); } std::unique_ptr<Widget> SettingsPage::create_settings(const GsrInfo &gsr_info, const std::vector<AudioDevice> &audio_devices) { - auto settings_list = std::make_unique<List>(List::Orientation::VERTICAL); - settings_list->set_spacing(0.018f); - settings_list->add_widget(create_capture_target(gsr_info)); - settings_list->add_widget(create_audio_device_section(audio_devices)); - settings_list->add_widget(create_video_section(gsr_info)); - settings_list_ptr = settings_list.get(); - auto page_list = std::make_unique<List>(List::Orientation::VERTICAL); page_list->set_spacing(0.018f); page_list->add_widget(create_view_radio_button()); auto scrollable_page = std::make_unique<ScrollablePage>(content_page_ptr->get_inner_size() - mgl::vec2f(0.0f, page_list->get_size().y + 0.018f * get_theme().window_height)); settings_scrollable_page_ptr = scrollable_page.get(); - scrollable_page->add_widget(std::move(settings_list)); page_list->add_widget(std::move(scrollable_page)); + + auto settings_list = std::make_unique<List>(List::Orientation::VERTICAL); + settings_list->set_spacing(0.018f); + settings_list->add_widget(create_capture_target(gsr_info)); + settings_list->add_widget(create_audio_device_section(audio_devices)); + settings_list->add_widget(create_video_section(gsr_info)); + settings_list_ptr = settings_list.get(); + settings_scrollable_page_ptr->add_widget(std::move(settings_list)); return page_list; } @@ -457,7 +454,7 @@ namespace gsr { replay_data_list->add_widget(create_save_directory("Directory to save replays:")); replay_data_list->add_widget(create_container_section()); replay_data_list->add_widget(create_replay_time()); - settings_list_ptr->add_widget(std::make_unique<Subsection>("File info", std::move(replay_data_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f))); + settings_list_ptr->add_widget(std::make_unique<Subsection>("File info", std::move(replay_data_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f))); auto checkboxes_list = std::make_unique<List>(List::Orientation::VERTICAL); @@ -476,7 +473,7 @@ namespace gsr { show_replay_saved_notification_checkbox_ptr = show_replay_saved_notification_checkbox.get(); checkboxes_list->add_widget(std::move(show_replay_saved_notification_checkbox)); - auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f)); + auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)); Subsection *notifications_subsection_ptr = notifications_subsection.get(); settings_list_ptr->add_widget(std::move(notifications_subsection)); @@ -484,7 +481,8 @@ namespace gsr { (void)text; const bool advanced_view = id == "advanced"; color_range_list_ptr->set_visible(advanced_view); - codec_list_ptr->set_visible(advanced_view); + audio_codec_ptr->set_visible(advanced_view); + video_codec_ptr->set_visible(advanced_view); framerate_mode_list_ptr->set_visible(advanced_view); notifications_subsection_ptr->set_visible(advanced_view); settings_scrollable_page_ptr->reset_scroll(); @@ -496,7 +494,7 @@ namespace gsr { auto file_list = std::make_unique<List>(List::Orientation::HORIZONTAL); file_list->add_widget(create_save_directory("Directory to save the video:")); file_list->add_widget(create_container_section()); - settings_list_ptr->add_widget(std::make_unique<Subsection>("File info", std::move(file_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f))); + settings_list_ptr->add_widget(std::make_unique<Subsection>("File info", std::move(file_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f))); auto checkboxes_list = std::make_unique<List>(List::Orientation::VERTICAL); @@ -510,7 +508,7 @@ namespace gsr { show_video_saved_notification_checkbox_ptr = show_video_saved_notification_checkbox.get(); checkboxes_list->add_widget(std::move(show_video_saved_notification_checkbox)); - auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f)); + auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)); Subsection *notifications_subsection_ptr = notifications_subsection.get(); settings_list_ptr->add_widget(std::move(notifications_subsection)); @@ -518,7 +516,8 @@ namespace gsr { (void)text; const bool advanced_view = id == "advanced"; color_range_list_ptr->set_visible(advanced_view); - codec_list_ptr->set_visible(advanced_view); + audio_codec_ptr->set_visible(advanced_view); + video_codec_ptr->set_visible(advanced_view); framerate_mode_list_ptr->set_visible(advanced_view); notifications_subsection_ptr->set_visible(advanced_view); settings_scrollable_page_ptr->reset_scroll(); @@ -596,7 +595,7 @@ namespace gsr { streaming_info_list->add_widget(create_stream_key_section()); streaming_info_list->add_widget(create_stream_url_section()); streaming_info_list->add_widget(create_stream_container_section()); - settings_list_ptr->add_widget(std::make_unique<Subsection>("Streaming info", std::move(streaming_info_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f))); + settings_list_ptr->add_widget(std::make_unique<Subsection>("Streaming info", std::move(streaming_info_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f))); auto checkboxes_list = std::make_unique<List>(List::Orientation::VERTICAL); @@ -610,7 +609,7 @@ namespace gsr { show_streaming_stopped_notification_checkbox_ptr = show_streaming_stopped_notification_checkbox.get(); checkboxes_list->add_widget(std::move(show_streaming_stopped_notification_checkbox)); - auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(content_page_ptr->get_inner_size().x, 0.0f)); + auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)); Subsection *notifications_subsection_ptr = notifications_subsection.get(); settings_list_ptr->add_widget(std::move(notifications_subsection)); @@ -631,7 +630,8 @@ namespace gsr { (void)text; const bool advanced_view = id == "advanced"; color_range_list_ptr->set_visible(advanced_view); - codec_list_ptr->set_visible(advanced_view); + audio_codec_ptr->set_visible(advanced_view); + video_codec_ptr->set_visible(advanced_view); framerate_mode_list_ptr->set_visible(advanced_view); notifications_subsection_ptr->set_visible(advanced_view); settings_scrollable_page_ptr->reset_scroll(); diff --git a/src/gui/Subsection.cpp b/src/gui/Subsection.cpp index 74b65e0..a03c65d 100644 --- a/src/gui/Subsection.cpp +++ b/src/gui/Subsection.cpp @@ -5,8 +5,8 @@ #include <mglpp/graphics/Rectangle.hpp> namespace gsr { - static const float margin_top_scale = 0.015f; - static const float margin_bottom_scale = 0.015f; + static const float margin_top_scale = 0.012f; + static const float margin_bottom_scale = 0.012f; static const float margin_left_scale = 0.015f; static const float margin_right_scale = 0.015f; static const float title_spacing_scale = 0.015f; |