From 5dd0248e16522a3672c58a7892d549840257e8dd Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 22 Nov 2020 10:29:58 +0100 Subject: Matrix: add reactions --- src/Body.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 28 deletions(-) (limited to 'src/Body.cpp') diff --git a/src/Body.cpp b/src/Body.cpp index 430c28f..0b4ec0f 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -17,6 +17,11 @@ static const float padding_y = 5.0f; static const float embedded_item_padding_y = 0.0f; static const double thumbnail_fade_duration_sec = 0.1; +const float reaction_background_padding_x = 7.0f; +const float reaction_background_padding_y = 3.0f; +const float reaction_spacing_x = 5.0f; +static const float reaction_padding_y = 7.0f; + namespace QuickMedia { BodyItem::BodyItem(std::string _title) : visible(true), @@ -75,6 +80,13 @@ namespace QuickMedia { } thumbnail_mask_type = other.thumbnail_mask_type; thumbnail_size = other.thumbnail_size; + reactions.clear(); + for(auto &reaction : other.reactions) { + Reaction reaction_copy; + reaction_copy.text = std::make_unique(*reaction.text); + reaction_copy.userdata = reaction.userdata; + reactions.push_back(std::move(reaction_copy)); + } title = other.title; description = other.description; author = other.author; @@ -549,7 +561,7 @@ namespace QuickMedia { if(body_item->title_text) body_item->title_text->setString(std::move(str)); else - body_item->title_text = std::make_unique(std::move(str), false, 16, width - 50 - image_padding_x * 2.0f); + body_item->title_text = std::make_unique(std::move(str), false, 16, width); body_item->title_text->setFillColor(body_item->get_title_color()); body_item->title_text->updateGeometry(); } @@ -560,7 +572,7 @@ namespace QuickMedia { if(body_item->description_text) body_item->description_text->setString(std::move(str)); else - body_item->description_text = std::make_unique(std::move(str), false, 14, width - 50 - image_padding_x * 2.0f); + body_item->description_text = std::make_unique(std::move(str), false, 14, width); body_item->description_text->setFillColor(body_item->get_description_color()); body_item->description_text->updateGeometry(); } @@ -571,7 +583,7 @@ namespace QuickMedia { if(body_item->author_text) body_item->author_text->setString(std::move(str)); else - body_item->author_text = std::make_unique(std::move(str), true, 14, width - 50 - image_padding_x * 2.0f); + body_item->author_text = std::make_unique(std::move(str), true, 14, width); body_item->author_text->setFillColor(body_item->get_author_color()); body_item->author_text->updateGeometry(); } @@ -706,7 +718,6 @@ namespace QuickMedia { only_show_thumbnail = true; } - bool has_thumbnail_texture = false; // TODO: Verify if this is safe. The thumbnail is being modified in another thread if(item_thumbnail->loading_state == LoadingState::APPLIED_TO_TEXTURE && item_thumbnail->texture.getNativeHandle() != 0) { image.setTexture(item_thumbnail->texture, true); @@ -723,7 +734,6 @@ namespace QuickMedia { else window.draw(image); text_offset_x += image_padding_x + new_image_size.x; - has_thumbnail_texture = true; // We want the next image fallback to have the same size as the successful image rendering, because its likely the image fallback will have the same size (for example thumbnails on youtube) //image_fallback.setSize(sf::Vector2f(width_ratio * image_size.x, height_ratio * image_size.y)); } else if(!item->thumbnail_url.empty() && !only_show_thumbnail) { @@ -753,9 +763,7 @@ namespace QuickMedia { loading_icon.setRotation(elapsed_time_sec * 400.0); loading_icon.setColor(sf::Color(255, 255, 255, fallback_fade_alpha)); window.draw(loading_icon); - - if(!has_thumbnail_texture) - text_offset_x += image_padding_x + content_size.x; + text_offset_x += image_padding_x + content_size.x; } } @@ -820,6 +828,31 @@ namespace QuickMedia { item_pos.y += item->description_text->getHeight() - 2.0f; } + if(!item->reactions.empty()) { + sf::RoundedRectangleShape reaction_background(sf::Vector2f(1.0f, 1.0f), 10.0f, 10); + reaction_background.setFillColor(sf::Color(33, 38, 44)); + float reaction_offset_x = 0.0f; + item_pos.y += reaction_padding_y; + float reaction_max_height = 0.0f; + for(auto &reaction : item->reactions) { + reaction.text->setMaxWidth(size.x - text_offset_x - image_padding_x); + reaction.text->updateGeometry(); + reaction_max_height = std::max(reaction_max_height, reaction.text->getHeight()); + if(text_offset_x + reaction_offset_x + reaction.text->getWidth() + reaction_background_padding_x * 2.0f > size.x) { + reaction_offset_x = 0.0f; + item_pos.y += reaction.text->getHeight() + reaction_padding_y + 6.0f; + reaction_max_height = reaction.text->getHeight(); + } + reaction.text->setPosition(std::floor(item_pos.x + text_offset_x + reaction_offset_x + reaction_background_padding_x), std::floor(item_pos.y + padding_y - 4.0f + reaction_background_padding_y)); + reaction_background.setPosition(std::floor(item_pos.x + text_offset_x + reaction_offset_x), std::floor(item_pos.y + padding_y)); + reaction_background.setSize(sf::Vector2f(reaction.text->getWidth() + reaction_background_padding_x * 2.0f, reaction.text->getHeight() + reaction_background_padding_y * 2.0f)); + window.draw(reaction_background); + reaction_offset_x += reaction.text->getWidth() + reaction_background_padding_x * 2.0f + reaction_spacing_x; + reaction.text->draw(window); + } + item_pos.y += reaction_max_height + reaction_padding_y; + } + if(item->timestamp_text) { item->timestamp_text->setPosition(std::floor(item_pos.x + size.x - item->timestamp_text->getLocalBounds().width - padding_x), timestamp_text_y + 8.0f); window.draw(*item->timestamp_text); @@ -844,27 +877,11 @@ namespace QuickMedia { } float Body::get_item_height(BodyItem *item, float width, bool load_texture, bool include_embedded_item) { - if(load_texture) - update_dirty_state(item, width); - float item_height = 0.0f; - if(item->title_text) { - item_height += item->title_text->getHeight() - 2.0f; - } - if(item->author_text) { - item_height += item->author_text->getHeight() - 2.0f; - } - if(include_embedded_item && item->embedded_item_status != FetchStatus::NONE) { - if(item->embedded_item) - item_height += (get_item_height(item->embedded_item.get(), width, load_texture, false) + 4.0f + embedded_item_padding_y * 2.0f); - else - item_height += (embedded_item_load_text.getLocalBounds().height + 4.0f + embedded_item_padding_y * 2.0f); - } - if(item->description_text) { - item_height += item->description_text->getHeight() - 2.0f; - } + float image_height = 0.0f; + float text_offset_x = padding_x; if(draw_thumbnails && !item->thumbnail_url.empty()) { sf::Vector2i content_size = get_item_thumbnail_size(item); - float image_height = content_size.y; + image_height = content_size.y; std::shared_ptr item_thumbnail; auto item_thumbnail_it = item_thumbnail_textures.find(item->thumbnail_url); @@ -899,10 +916,51 @@ namespace QuickMedia { sf::Vector2f image_size_f(image_size.x, image_size.y); auto new_image_size = clamp_to_size(image_size_f, to_vec2f(content_size)); image_height = new_image_size.y; + text_offset_x += image_padding_x + new_image_size.x; + } else { + text_offset_x += image_padding_x + content_size.x; } + } - item_height = std::max(item_height, image_height); + if(load_texture) + update_dirty_state(item, width - text_offset_x - image_padding_x); + + float item_height = 0.0f; + if(item->title_text) { + item_height += item->title_text->getHeight() - 2.0f; + } + if(item->author_text) { + item_height += item->author_text->getHeight() - 2.0f; } + if(include_embedded_item && item->embedded_item_status != FetchStatus::NONE) { + if(item->embedded_item) + item_height += (get_item_height(item->embedded_item.get(), width, load_texture, false) + 4.0f + embedded_item_padding_y * 2.0f); + else + item_height += (embedded_item_load_text.getLocalBounds().height + 4.0f + embedded_item_padding_y * 2.0f); + } + if(item->description_text) { + item_height += item->description_text->getHeight() - 2.0f; + } + + if(!item->reactions.empty()) { + float reaction_offset_x = 0.0f; + item_height += reaction_padding_y; + float reaction_max_height = 0.0f; + for(auto &reaction : item->reactions) { + reaction.text->setMaxWidth(width - text_offset_x - image_padding_x); + reaction.text->updateGeometry(); + reaction_max_height = std::max(reaction_max_height, reaction.text->getHeight()); + if(text_offset_x + reaction_offset_x + reaction.text->getWidth() + reaction_background_padding_x * 2.0f > width) { + reaction_offset_x = 0.0f; + item_height += reaction.text->getHeight() + reaction_padding_y + 6.0f; + reaction_max_height = reaction.text->getHeight(); + } + reaction_offset_x += reaction.text->getWidth() + reaction_background_padding_x * 2.0f + reaction_spacing_x; + } + item_height += reaction_max_height + reaction_padding_y; + } + + item_height = std::max(item_height, image_height); return item_height + padding_y * 2.0f; } -- cgit v1.2.3