diff options
Diffstat (limited to 'src/Body.cpp')
-rw-r--r-- | src/Body.cpp | 192 |
1 files changed, 104 insertions, 88 deletions
diff --git a/src/Body.cpp b/src/Body.cpp index 0804399..6e01266 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -92,79 +92,6 @@ namespace QuickMedia { return sf::Vector2f(vec.x, vec.y); } - BodyItem::BodyItem(std::string _title) : - visible(true), - dirty(false), - dirty_description(false), - dirty_author(false), - dirty_timestamp(false), - thumbnail_is_local(false), - userdata(nullptr), - timestamp(0), - title_color(get_current_theme().text_color), - author_color(get_current_theme().text_color), - description_color(get_current_theme().text_color) - { - if(!_title.empty()) - set_title(std::move(_title)); - } - - BodyItem& BodyItem::operator=(const BodyItem &other) { - url = other.url; - thumbnail_url = other.thumbnail_url; - visible = other.visible; - dirty = !other.title.empty(); - dirty_description = !other.description.empty(); - dirty_author = !other.author.empty(); - dirty_timestamp = other.timestamp != 0; - thumbnail_is_local = other.thumbnail_is_local; - title_text.reset(); - description_text.reset(); - author_text.reset(); - timestamp_text.reset(); - replies_to = other.replies_to; - replies = other.replies; - post_number = other.post_number; - userdata = other.userdata; - loaded_height = 0.0f; - loaded_image_size = sf::Vector2f(0.0f, 0.0f); - loaded_content_height = 0.0f; - embedded_item_status = other.embedded_item_status; - if(other.embedded_item) { - embedded_item.reset(new BodyItem("")); - *embedded_item = *other.embedded_item; - } else { - embedded_item.reset(); - } - 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<Text>(*reaction.text); - reaction_copy.userdata = reaction.userdata; - reactions.push_back(std::move(reaction_copy)); - } - title = other.title; - description = other.description; - author = other.author; - timestamp = other.timestamp; - title_color = other.title_color; - author_color = other.author_color; - description_color = other.description_color; - extra = other.extra; - keep_alive_frames = other.keep_alive_frames; - return *this; - } - - void BodyItem::add_reaction(std::string text, void *userdata) { - sf::String str = sf::String::fromUtf8(text.begin(), text.end()); - Reaction reaction; - reaction.text = std::make_unique<Text>(std::move(str), false, std::floor(14 * get_ui_scale()), 0.0f); - reaction.userdata = userdata; - reactions.push_back(std::move(reaction)); - } - Body::Body(BodyTheme body_theme, sf::Texture &loading_icon_texture, sf::Shader *rounded_rectangle_shader, sf::Shader *rounded_rectangle_mask_shader) : draw_thumbnails(true), body_item_render_callback(nullptr), @@ -329,6 +256,13 @@ namespace QuickMedia { clamp_selection(); } + void Body::set_items(BodyItems items) { + for(auto &item : items) { + filter_search_fuzzy_item(current_filter, item.get()); + } + this->items = std::move(items); + } + void Body::clear_items() { items.clear(); selected_item = 0; @@ -336,18 +270,53 @@ namespace QuickMedia { page_scroll = 0.0f; } + void Body::prepend_item(std::shared_ptr<BodyItem> body_item) { + apply_search_filter_for_item(body_item.get()); + items.insert(items.begin(), std::move(body_item)); + } + void Body::prepend_items_reverse(BodyItems new_items) { + for(auto &item : new_items) { + filter_search_fuzzy_item(current_filter, item.get()); + } items.insert(items.begin(), std::make_move_iterator(new_items.rbegin()), std::make_move_iterator(new_items.rend())); - items_set_dirty(); + } + + void Body::append_item(std::shared_ptr<BodyItem> body_item) { + apply_search_filter_for_item(body_item.get()); + items.push_back(std::move(body_item)); } void Body::append_items(BodyItems new_items) { + for(auto &item : new_items) { + filter_search_fuzzy_item(current_filter, item.get()); + } items.insert(items.end(), std::make_move_iterator(new_items.begin()), std::make_move_iterator(new_items.end())); - items_set_dirty(); + } + + void Body::insert_item(std::shared_ptr<BodyItem> body_item, int index) { + apply_search_filter_for_item(body_item.get()); + items.insert(items.begin() + index, std::move(body_item)); + } + + void Body::move_items_to(Body *other_body) { + other_body->set_items(std::move(items)); + } + + void Body::move_item(size_t src_index, size_t dst_index) { + assert(src_index < items.size()); + assert(dst_index < items.size()); + auto item_to_move = std::move(items[src_index]); + items.erase(items.begin() + src_index); + if(dst_index <= src_index) + items.insert(items.begin() + dst_index, std::move(item_to_move)); + else + items.insert(items.begin() + dst_index - 1, std::move(item_to_move)); } // TODO: Binary search and use hint to start search from start or end (for example when adding "previous" items or "next" items) size_t Body::insert_item_by_timestamp(std::shared_ptr<BodyItem> body_item) { + apply_search_filter_for_item(body_item.get()); for(size_t i = 0; i < items.size(); ++i) { if(body_item->get_timestamp() < items[i]->get_timestamp()) { items.insert(items.begin() + i, std::move(body_item)); @@ -369,7 +338,6 @@ namespace QuickMedia { } clamp_selection(); - items_set_dirty(); // TODO: Apply this now, otherwise the below code wont work if(!selected_body_item) return; @@ -382,6 +350,66 @@ namespace QuickMedia { } } + void Body::for_each_item(std::function<void(std::shared_ptr<BodyItem>&)> callback) { + for(std::shared_ptr<BodyItem> &body_item : items) { + callback(body_item); + } + } + + std::shared_ptr<BodyItem> Body::find_item(std::function<bool(std::shared_ptr<BodyItem>&)> callback) { + for(std::shared_ptr<BodyItem> &body_item : items) { + if(callback(body_item)) + return body_item; + } + return nullptr; + } + + int Body::find_item_index(std::function<bool(std::shared_ptr<BodyItem>&)> callback) { + for(int i = 0; i != (int)items.size(); ++i) { + std::shared_ptr<BodyItem> &body_item = items[i]; + if(callback(body_item)) + return i; + } + return -1; + } + + bool Body::erase_item(std::function<bool(std::shared_ptr<BodyItem>&)> callback) { + for(auto it = items.begin(), end = items.end(); it != end; ++it) { + if(callback(*it)) { + items.erase(it); + return true; + } + } + return false; + } + + std::shared_ptr<BodyItem> Body::get_item_by_index(size_t index) { + assert(index < items.size()); + return items[index]; + } + + BodyItemList Body::get_items() { + return BodyItemList(&items); + } + + BodyItems Body::get_items_copy() { + return items; + } + + void Body::copy_range(size_t start_index, size_t end_index, BodyItems &target) { + assert(end_index == (size_t)-1 || end_index >= start_index); + assert(start_index < items.size() && (end_index == (size_t)-1 || end_index < items.size())); + target.insert(target.end(), items.begin() + start_index, end_index == (size_t)-1 ? items.end() : (items.begin() + end_index)); + } + + size_t Body::get_num_items() const { + return items.size(); + } + + void Body::reverse_items() { + std::reverse(items.begin(), items.end()); + } + void Body::clear_cache() { clear_text_cache(); malloc_trim(0); @@ -554,12 +582,6 @@ namespace QuickMedia { // 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) { - if(items_dirty != DirtyState::FALSE) { - if(using_filter || items_dirty == DirtyState::FORCE_TRUE) - filter_search_fuzzy(current_filter); - items_dirty = DirtyState::FALSE; - } - 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; @@ -1599,7 +1621,6 @@ namespace QuickMedia { // TODO: Support utf-8 case insensitive find static bool string_find_fuzzy_case_insensitive(const std::string &str, const std::string &substr) { - if(str.empty()) return false; if(substr.empty()) return true; size_t str_index = 0; @@ -1623,7 +1644,6 @@ namespace QuickMedia { void Body::filter_search_fuzzy(const std::string &text) { current_filter = text; - items_dirty = DirtyState::FALSE; if(text.empty()) { for(auto &item : items) { @@ -1670,10 +1690,6 @@ namespace QuickMedia { page_scroll = scroll; } - void Body::items_set_dirty(bool force) { - items_dirty = force ? DirtyState::FORCE_TRUE : DirtyState::TRUE; - } - void Body::apply_search_filter_for_item(BodyItem *body_item) { filter_search_fuzzy_item(current_filter, body_item); } |