aboutsummaryrefslogtreecommitdiff
path: root/src/Body.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Body.cpp')
-rw-r--r--src/Body.cpp192
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);
}