From 518a7685c411b5f3f75091298e6afe6fab8e0303 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 10 Jun 2021 00:46:59 +0200 Subject: Smoother body movement with unknown image size --- src/Body.cpp | 74 +++++++++++++++++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 41 deletions(-) (limited to 'src/Body.cpp') diff --git a/src/Body.cpp b/src/Body.cpp index 37a67ee..c25b75f 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -124,9 +124,9 @@ namespace QuickMedia { replies = other.replies; post_number = other.post_number; userdata = other.userdata; - prev_last_loaded_height = other.prev_last_loaded_height; - last_loaded_height = other.last_loaded_height; - current_loaded_height = other.current_loaded_height; + loaded_height = other.loaded_height; + loaded_image_height = other.loaded_image_height; + loaded_content_height = other.loaded_content_height; embedded_item_status = other.embedded_item_status; if(other.embedded_item) { embedded_item.reset(new BodyItem("")); @@ -686,7 +686,7 @@ namespace QuickMedia { const int selected_prev_item = get_previous_visible_item(selected_item); const bool selected_merge_with_previous = selected_prev_item != -1 && body_item_merge_handler && body_item_merge_handler(items[selected_prev_item].get(), items[selected_item].get()); get_item_height(items[selected_item].get(), size.x, true, true, selected_merge_with_previous, selected_item); - selected_item_fits_in_body = items[selected_item]->last_loaded_height < size.y; + selected_item_fits_in_body = items[selected_item]->loaded_height < size.y; if(selected_item_fits_in_body) selected_scrolled = 0.0f; } @@ -1001,13 +1001,12 @@ namespace QuickMedia { pos.y -= body_spacing[body_theme].spacing_y; get_item_height(item, size.x, false, true, merge_with_previous, index); - item->current_loaded_height = item->last_loaded_height; float top_y; if(attach_side == AttachSide::TOP) top_y = pos.y; else - top_y = pos.y - (item->current_loaded_height + body_spacing[body_theme].spacing_y); + top_y = pos.y - (item->loaded_height + body_spacing[body_theme].spacing_y); if(top_y < 0.0f) { top_cut_off = true; @@ -1015,18 +1014,17 @@ namespace QuickMedia { selected_line_top_visible = false; } - if(top_y + item->current_loaded_height > size.y) { + if(top_y + item->loaded_height > size.y) { bottom_cut_off = true; if(index == selected_item) selected_line_bottom_visible = false; } - const bool is_item_visible_in_body = top_y + item->current_loaded_height >= 0.0f && top_y <= size.y; + const bool is_item_visible_in_body = top_y + item->loaded_height >= 0.0f && top_y <= size.y; if(is_item_visible_in_body || index == selected_item) { get_item_height(item, size.x, true, true, merge_with_previous, index); - item->current_loaded_height = item->last_loaded_height; if(attach_side == AttachSide::BOTTOM) - pos.y -= (item->current_loaded_height + body_spacing[body_theme].spacing_y); + pos.y -= (item->loaded_height + body_spacing[body_theme].spacing_y); //page_scroll += add_height; //const float top_y_clamped = clamp(pos.y, 0.0f, size.y); @@ -1042,8 +1040,8 @@ namespace QuickMedia { //new_view.setViewport(sf::FloatRect(0.0f, (scissor_y + top_y_clamped) / (float)window_size.y, 1.0f, (scissor_y + bottom_y_clamped) / (float)window_size.y)); //window.setView(new_view); - draw_item(window, item, pos/*sf::Vector2f(pos.x, offset_y)*/, size, item->current_loaded_height, index, content_progress, true, merge_with_previous); - handle_item_render(pos, size.x, item->current_loaded_height, index); + draw_item(window, item, pos/*sf::Vector2f(pos.x, offset_y)*/, size, item->loaded_height, index, content_progress, true, merge_with_previous); + handle_item_render(pos, size.x, item->loaded_height, index); ++num_visible_items; if(first_visible_item == -1 || index < first_visible_item) @@ -1052,12 +1050,12 @@ namespace QuickMedia { last_visible_item = index; if(attach_side == AttachSide::TOP) - pos.y += (item->current_loaded_height + body_spacing[body_theme].spacing_y); + pos.y += (item->loaded_height + body_spacing[body_theme].spacing_y); } else { if(attach_side == AttachSide::TOP) - pos.y += (item->current_loaded_height + body_spacing[body_theme].spacing_y); + pos.y += (item->loaded_height + body_spacing[body_theme].spacing_y); else - pos.y -= (item->current_loaded_height + body_spacing[body_theme].spacing_y); + pos.y -= (item->loaded_height + body_spacing[body_theme].spacing_y); if(item->keep_alive_frames == 0) { clear_body_item_cache(item); @@ -1123,8 +1121,7 @@ namespace QuickMedia { BodyItem *item = items[item_index].get(); get_item_height(item, card_max_image_size.x, false, false, false, item_index); - item->current_loaded_height = item->last_loaded_height; - int item_height = item->current_loaded_height; + int item_height = item->loaded_height; item_height = std::min(card_height, item_height + ((draw_thumbnails && !item->thumbnail_url.empty()) ? card_image_text_padding : 0) + card_padding_y * 2 + 5); column_max_height = std::max(column_max_height, item_height); @@ -1150,8 +1147,7 @@ namespace QuickMedia { item_thumbnail = AsyncImageLoader::get_instance().get_thumbnail(item->thumbnail_url, item->thumbnail_is_local, thumbnail_size); get_item_height(item, card_max_image_size.x, true, false, false, item_index); - item->current_loaded_height = item->last_loaded_height; - int item_height = item->current_loaded_height; + item_height = item->loaded_height; item_height = std::min(card_height, item_height + (item_thumbnail ? card_image_text_padding : 0) + card_padding_y * 2 + 5); column_max_height = std::max(column_max_height, item_height); @@ -1483,9 +1479,7 @@ namespace QuickMedia { float image_height = 0.0f; float text_offset_x = body_spacing[body_theme].padding_x; - bool has_thumbnail = false; if(draw_thumbnails && load_texture && !item->thumbnail_url.empty() && !merge_with_previous) { - has_thumbnail = true; std::shared_ptr item_thumbnail = AsyncImageLoader::get_instance().get_thumbnail(item->thumbnail_url, item->thumbnail_is_local, content_size); content_size = clamp_to_size_x(content_size, sf::Vector2i(width, content_size.y)); image_height = content_size.y; @@ -1508,6 +1502,9 @@ namespace QuickMedia { } else { text_offset_x += body_spacing[body_theme].image_padding_x + content_size.x; } + + // TODO: This wont work if the image has changed to a different image (for example if the image is a local image and it has been overwritten). + item->loaded_image_height = std::max(item->loaded_image_height, image_height); } else if(item->thumbnail_size.x > 0) { text_offset_x += body_spacing[body_theme].image_padding_x + content_size.x; // TODO: Fix. This makes the body item have incorrect position when loading and if the item is merge_with_previous? and has an embedded item @@ -1521,11 +1518,14 @@ namespace QuickMedia { update_dirty_state(item, text_max_width); float item_height = 0.0f; + bool has_loaded_text = false; if(item->title_text) { item_height += item->title_text->getHeight() - 2.0f + std::floor(3.0f * get_ui_scale()); + has_loaded_text = true; } if(item->author_text && !merge_with_previous) { item_height += item->author_text->getHeight() - 2.0f + std::floor(3.0f * get_ui_scale()); + has_loaded_text = true; } if(include_embedded_item && item->embedded_item_status != FetchStatus::NONE) { if(item->embedded_item) @@ -1535,6 +1535,7 @@ namespace QuickMedia { } if(item->description_text) { item_height += item->description_text->getHeight() - 2.0f; + has_loaded_text = true; } if(!item->reactions.empty() && include_embedded_item) { @@ -1554,34 +1555,25 @@ namespace QuickMedia { } } item_height += reaction_max_height + body_spacing[body_theme].reaction_padding_y; + has_loaded_text = true; } + // Text can unload. Do not update height if that happens. TODO: Do not unload text, instead clear the internal buffer + if(has_loaded_text) + item->loaded_content_height = item_height; + else + item_height = item->loaded_content_height; + if(card_view && card_view_enabled) { - item_height += image_height; + item_height += item->loaded_image_height; } else { + const bool has_thumbnail = draw_thumbnails && !item->thumbnail_url.empty() && !merge_with_previous; const float padding_y = has_thumbnail ? body_spacing[body_theme].padding_y : body_spacing[body_theme].padding_y_text_only; - item_height = std::max(item_height, image_height); + item_height = std::max(item_height, item->loaded_image_height); item_height += (padding_y * 2.0f); } - const bool first_height_set = item->last_loaded_height > 0.01f; - if(item_index != -1 && (!first_height_set || load_texture)) { - const float height_diff = item_height - item->prev_last_loaded_height; - /* - if(attach_side == AttachSide::TOP) { - if(item_index < selected_item) - page_scroll -= height_diff; - } else if(attach_side == AttachSide::BOTTOM) { - if(item_index > selected_item) - page_scroll += height_diff; - } - */ - item->last_loaded_height = item_height; - item->prev_last_loaded_height = item_height; - if(!first_height_set) - item->current_loaded_height = item_height; - } - + item->loaded_height = item_height; return item_height; } -- cgit v1.2.3