From dd3da1832c0103a2da35df8ac2483461311bdf25 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 10 Nov 2020 21:13:02 +0100 Subject: Scroll body automatically to reveal more items when making the window larger, even after resizing to smaller size before --- src/Body.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 14 deletions(-) (limited to 'src/Body.cpp') diff --git a/src/Body.cpp b/src/Body.cpp index 01aabea..74646fd 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -111,8 +111,11 @@ namespace QuickMedia { // TODO: Make this work with wraparound enabled? // TODO: For plugins with different sized body items this can be weird, because after scrolling down thumbnails could load and they could move items up/down until we see items we haven't seen bool Body::select_previous_page() { + if(!selected_line_top_visible) + return select_previous_item(false); + for(int i = 0; i < num_visible_items - 1; ++i) { - if(!select_previous_item()) + if(!select_previous_item(false)) return false; } return true; @@ -121,19 +124,22 @@ namespace QuickMedia { // TODO: Make this work with wraparound enabled? // TODO: For plugins with different sized body items this can be weird, because after scrolling down thumbnails could load and they could move items up/down until we see items we haven't seen bool Body::select_next_page() { + if(!selected_line_bottom_visible) + return select_next_item(false); + for(int i = 0; i < num_visible_items - 1; ++i) { - if(!select_next_item()) + if(!select_next_item(false)) return false; } return true; } - bool Body::select_previous_item() { + bool Body::select_previous_item(bool scroll_page_if_large_item) { if(items.empty()) return false; - if(!selected_line_top_visible) { - page_scroll += 32.0f; + if(scroll_page_if_large_item && !selected_line_top_visible) { + page_scroll += 128.0f; return true; } @@ -161,12 +167,12 @@ namespace QuickMedia { return true; } - bool Body::select_next_item() { + bool Body::select_next_item(bool scroll_page_if_large_item) { if(items.empty()) return false; - if(!selected_line_bottom_visible) { - page_scroll -= 32.0f; + if(scroll_page_if_large_item && !selected_line_bottom_visible) { + page_scroll -= 128.0f; return true; } @@ -336,7 +342,6 @@ namespace QuickMedia { //item_background.setOutlineColor(sf::Color(13, 15, 17)); item_separator.setFillColor(line_separator_color); num_visible_items = 0; - last_item_fully_visible = true; last_fully_visible_item = -1; selected_line_top_visible = true; selected_line_bottom_visible = true; @@ -349,6 +354,10 @@ namespace QuickMedia { if(body_item->embedded_item) clear_body_item_cache(body_item->embedded_item.get()); } + last_item_fully_visible = true; + items_cut_off = false; + offset_to_top = 0.0f; + offset_to_bottom = 0.0f; return; } @@ -400,7 +409,7 @@ namespace QuickMedia { if(pos.y - start_y + page_scroll >= size.y && !selected_item_fits_on_screen) page_scroll = 0.0f; else if(pos.y - start_y + page_scroll + selected_item_height <= 0.0f && !selected_item_fits_on_screen) - page_scroll = -selected_item_height + size.y; + page_scroll = size.y - selected_item_height; selected_line_top_visible |= selected_item_fits_on_screen; selected_line_bottom_visible |= selected_item_fits_on_screen; @@ -412,12 +421,28 @@ namespace QuickMedia { page_scroll = 0.0f; } + if(items_cut_off) { + if(offset_to_top > 0.0f) + page_scroll -= offset_to_top; + else if(offset_to_bottom > 0.0f) + page_scroll += offset_to_bottom; + } else { + if(attach_side == AttachSide::TOP) + page_scroll -= offset_to_top; + else if(attach_side == AttachSide::BOTTOM) + page_scroll += offset_to_bottom; + } + pos.y += page_scroll; + last_item_fully_visible = true; + items_cut_off = false; + sf::Vector2u window_size = window.getSize(); sf::Vector2f prev_pos = pos; - for(int i = selected_item - 1; i >= 0; --i) { + int i; + for(i = selected_item - 1; i >= 0; --i) { auto &item = items[i]; // TODO: Find a better solution? @@ -428,8 +453,10 @@ namespace QuickMedia { float item_height = get_item_height(item.get(), size.x); prev_pos.y -= (item_height + spacing_y); - if(prev_pos.y + item_height + spacing_y <= start_y) + if(prev_pos.y + item_height + spacing_y <= start_y) { + items_cut_off = true; break; + } // This is needed here rather than above the loop, since update_dirty_text cant be called inside scissor because it corrupts the text for some reason glEnable(GL_SCISSOR_TEST); @@ -439,6 +466,8 @@ namespace QuickMedia { ++num_visible_items; } + offset_to_top = prev_pos.y - start_y; + sf::Vector2f after_pos = pos; for(int i = selected_item; i < num_items; ++i) { auto &item = items[i]; @@ -449,6 +478,7 @@ namespace QuickMedia { if(after_pos.y - start_y >= size.y) { last_item_fully_visible = false; + items_cut_off = true; break; } @@ -463,15 +493,18 @@ namespace QuickMedia { after_pos.y += item_height + spacing_y; ++num_visible_items; - if(after_pos.y - start_y > size.y) + if(after_pos.y - start_y > size.y) { last_item_fully_visible = false; - else + } else { last_fully_visible_item = i; + } } if(last_fully_visible_item == -1) last_fully_visible_item = selected_item; + offset_to_bottom = size.y - (after_pos.y - start_y); + for(auto it = item_thumbnail_textures.begin(); it != item_thumbnail_textures.end();) { if(!it->second->referenced) it = item_thumbnail_textures.erase(it); -- cgit v1.2.3