From f0f6d45cd3aa39f1eea4e8fd1518edeee50689ef Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 24 Sep 2021 03:33:13 +0200 Subject: Add scrollbar --- src/Body.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 13 deletions(-) (limited to 'src/Body.cpp') diff --git a/src/Body.cpp b/src/Body.cpp index d5395fd..3f24e7d 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -110,6 +110,7 @@ namespace QuickMedia { bottom_cut_off(false), item_background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_theme().selected_color, rounded_rectangle_shader), reaction_background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_theme().shade_color, rounded_rectangle_shader), + rounded_rectangle_shader(rounded_rectangle_shader), rounded_rectangle_mask_shader(rounded_rectangle_mask_shader) { assert(rounded_rectangle_shader); @@ -592,13 +593,13 @@ namespace QuickMedia { window.draw(gradient_points, 4, sf::Quads); } - void Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size) { - draw(window, pos, size, Json::Value::nullSingleton()); + double Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size) { + return draw(window, pos, size, Json::Value::nullSingleton()); } // TODO: Use a render target for the whole body so all images can be put into one. // TODO: Load thumbnails with more than one thread. - void Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, const Json::Value &content_progress) { + double Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, const Json::Value &content_progress) { const bool rendering_card_view = card_view && card_view_enabled; body_size_changed = std::abs(size.x - body_size.x) > 0.1f || std::abs(size.y - body_size.y) > 0.1f; @@ -609,6 +610,7 @@ namespace QuickMedia { const float scissor_y = pos.y; pos.y = 0.0f; + size.x = std::max(0.0f, size.x - 10.0f); if(!rendering_card_view) { pos.x += body_spacing[body_theme].body_padding_horizontal; size.x = std::max(0.0f, size.x - body_spacing[body_theme].body_padding_horizontal * 2.0f); @@ -665,7 +667,7 @@ namespace QuickMedia { clicked_body_item = nullptr; draw_drop_shadow(window); - return; + return 0.0f; } if(is_touch_enabled()) { @@ -774,9 +776,9 @@ namespace QuickMedia { } item_background_prev_pos = item_background_new_pos; - float body_total_height = 0.0f; + double body_total_height = 0.0; if(rendering_card_view) { - draw_card_view(window, pos, size, window_size, scissor_y); + body_total_height = draw_card_view(window, pos, size, window_size, scissor_y); } else { body_total_height = draw_list_view(window, pos, size, content_progress); } @@ -784,6 +786,31 @@ namespace QuickMedia { window.setView(prev_view); draw_drop_shadow(window); + const double scrolling_bar_height_ratio = body_total_height == 0.0 ? 0.0 : (size.y / body_total_height); + if(scrolling_bar_height_ratio <= 1.0) { + const double scrollbar_max_height = size.y - body_spacing[body_theme].body_padding_vertical * 2.0f; + double scrollbar_offset_y = body_total_height == 0.0 ? 0.0 : (std::abs(page_scroll) / body_total_height); + + RoundedRectangle scrollbar( + sf::Vector2f(std::floor(5.0f * get_config().scale), std::floor(scrollbar_max_height * scrolling_bar_height_ratio)), std::floor(3.0f * get_config().scale), + get_theme().selected_color, + rounded_rectangle_shader); + + float scrollbar_offset_x = size.x + 10.0f; + if(rendering_card_view) + scrollbar_offset_x = std::floor(size.x - scrollbar.get_size().x); + + double scrollbar_y; + if(attach_side == AttachSide::TOP) + scrollbar_y = std::floor(scissor_y + body_spacing[body_theme].body_padding_vertical + scrollbar_offset_y * scrollbar_max_height); + else + scrollbar_y = std::floor(scissor_y + body_spacing[body_theme].body_padding_vertical + scrollbar_max_height - scrollbar.get_size().y - scrollbar_offset_y * scrollbar_max_height); + + scrollbar.set_position( + sf::Vector2f(pos.x + scrollbar_offset_x, scrollbar_y)); + scrollbar.draw(window); + } + // TODO: Move up where scroll is limited? then we wont delay this by 1 frame creating a small scroll overflow only in the opposite direction of attach side. // Also take |selected_scrolled| into consideration // Limit scroll in the opposide direction of attach side, since the scroll is already limited for the attach side above (with a simple check) @@ -792,7 +819,6 @@ namespace QuickMedia { if(top_cut_off && !bottom_cut_off && body_total_height > (size.y - body_spacing[body_theme].body_padding_vertical)) page_scroll = -(body_total_height - (size.y - body_spacing[body_theme].body_padding_vertical)); } else { - body_total_height = -body_total_height; if(bottom_cut_off && !top_cut_off && body_total_height > size.y) page_scroll = (body_total_height - size.y); } @@ -807,7 +833,7 @@ namespace QuickMedia { } if(is_touch_enabled()) - return; + return body_total_height; const float item_target_top_diff = item_background_target_pos.y - selected_scrolled - (attach_side == AttachSide::TOP ? body_spacing[body_theme].body_padding_vertical : 0.0f); const float item_target_bottom_diff = (item_background_target_pos.y - selected_scrolled + item_background_target_size.y + body_spacing[body_theme].spacing_y) - size.y; @@ -839,6 +865,8 @@ namespace QuickMedia { else page_scroll -= item_target_bottom_diff*page_scroll_speed; } + + return body_total_height; } void Body::update_dirty_state(BodyItem *body_item, float width) { @@ -1007,7 +1035,7 @@ namespace QuickMedia { return { std::floor(vec.x), std::floor(vec.y) }; } - float Body::draw_list_view(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, const Json::Value &content_progress) { + double Body::draw_list_view(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, const Json::Value &content_progress) { const int num_items = items.size(); const float pos_y_before_scroll = pos.y; @@ -1183,10 +1211,10 @@ namespace QuickMedia { } render_items.clear(); - return pos.y - pos_y_start; + return std::abs(pos.y - pos_y_start); } - void Body::draw_card_view(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, sf::Vector2u window_size, float scissor_y) { + double Body::draw_card_view(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, sf::Vector2u window_size, float scissor_y) { num_columns = size.x / card_width; int space_left_column = size.x - (num_columns * card_width); @@ -1205,9 +1233,9 @@ namespace QuickMedia { if(num_columns <= num_columns_switch_to_list) { num_columns = 1; card_view_enabled = false; - draw(window, body_pos, body_size); + const float body_total_height = draw(window, body_pos, body_size); card_view_enabled = true; - return; + return body_total_height; } const int space_left_row_each = space_left_column_each; @@ -1221,6 +1249,7 @@ namespace QuickMedia { int num_visible_rows = 1; int row_max_height = 0; const int num_items = items.size(); + const float pos_y_start = page_scroll; sf::Vector2f pos_offset(space_left_column_each, page_scroll); while(item_index < num_items) { @@ -1348,6 +1377,8 @@ namespace QuickMedia { if(row_has_selected_item) item_background_target_size = sf::Vector2f(card_width, row_max_height); + + return std::abs(pos_offset.y - pos_y_start); } void Body::draw_item(sf::RenderWindow &window, std::shared_ptr &item, const sf::Vector2f &pos, const sf::Vector2f &size, const float item_height, const int item_index, const Json::Value &content_progress, bool include_embedded_item, bool merge_with_previous) { -- cgit v1.2.3