aboutsummaryrefslogtreecommitdiff
path: root/src/Body.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-08-03 15:06:57 +0200
committerdec05eba <dec05eba@protonmail.com>2021-08-05 05:50:23 +0200
commit6c85194c3b1baef0eaa011c4f1b8e48e11860f45 (patch)
tree61f3eb4304091fd2203519702a4f4daf184c5a59 /src/Body.cpp
parentcbc6997c0a5659239d2cd971f2fa77eeda53550b (diff)
Make body items private, add accessor functions
This allows body to automatically update dirty state (and other states). Correctly format newlines in codeblocks in matrix.
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);
}