aboutsummaryrefslogtreecommitdiff
path: root/include/BodyItem.hpp
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 /include/BodyItem.hpp
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 'include/BodyItem.hpp')
-rw-r--r--include/BodyItem.hpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/include/BodyItem.hpp b/include/BodyItem.hpp
new file mode 100644
index 0000000..ed53908
--- /dev/null
+++ b/include/BodyItem.hpp
@@ -0,0 +1,175 @@
+#pragma once
+
+#include "Text.hpp"
+#include <memory>
+#include <SFML/Graphics/Text.hpp>
+
+namespace sf {
+ class RenderTarget;
+}
+
+namespace QuickMedia {
+ class Body;
+
+ enum class FetchStatus {
+ NONE,
+ QUEUED_LOADING,
+ LOADING,
+ FINISHED_LOADING,
+ FAILED_TO_LOAD
+ };
+
+ enum class ThumbnailMaskType {
+ NONE,
+ CIRCLE,
+ ROUNDED_RECTANGLE
+ };
+
+ enum BodyTheme : int {
+ BODY_THEME_MINIMAL,
+ BODY_THEME_MODERN_SPACIOUS
+ };
+
+ // TODO: Remove and create an Userdata class instead to replace the void* userdata in BodyItem
+ class BodyItemExtra {
+ public:
+ virtual ~BodyItemExtra() = default;
+ };
+
+ struct Reaction {
+ std::unique_ptr<Text> text;
+ void *userdata = nullptr;
+ };
+
+ class BodyItem {
+ public:
+ BodyItem(std::string _title);
+ BodyItem(const BodyItem&) = delete;
+ BodyItem& operator=(const BodyItem &other);
+
+ static std::shared_ptr<BodyItem> create(std::string title) { return std::make_shared<BodyItem>(std::move(title)); }
+
+ void set_title(std::string new_title) {
+ if(title == new_title)
+ return;
+ title = std::move(new_title);
+ dirty = true;
+ }
+
+ void set_description(std::string new_description) {
+ if(description == new_description)
+ return;
+ description = std::move(new_description);
+ dirty_description = true;
+ }
+
+ void set_author(std::string new_author) {
+ if(author == new_author)
+ return;
+ author = std::move(new_author);
+ dirty_author = true;
+ }
+
+ // |new_timestamp| is in milliseconds
+ void set_timestamp(time_t new_timestamp) {
+ if(new_timestamp == timestamp)
+ return;
+ timestamp = new_timestamp;
+ dirty_timestamp = true;
+ }
+
+ void set_title_color(sf::Color new_color) {
+ if(new_color == title_color)
+ return;
+ title_color = new_color;
+ dirty = true;
+ }
+
+ void set_description_color(sf::Color new_color) {
+ if(new_color == description_color)
+ return;
+ description_color = new_color;
+ dirty_description = true;
+ }
+
+ void set_author_color(sf::Color new_color) {
+ if(new_color == author_color)
+ return;
+ author_color = new_color;
+ dirty_author = true;
+ }
+
+ void add_reaction(std::string text, void *userdata);
+
+ // Returns true if reaction is found
+ bool remove_reaction_by_userdata(void *userdata) {
+ for(auto it = reactions.begin(); it != reactions.end(); ++it) {
+ if(it->userdata == userdata) {
+ reactions.erase(it);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ const std::string& get_title() const { return title; }
+ const std::string& get_description() const { return description; }
+ const std::string& get_author() const { return author; }
+ // In milliseconds
+ time_t get_timestamp() const { return timestamp; }
+
+ sf::Color get_title_color() const { return title_color; }
+ sf::Color get_description_color() const { return description_color; }
+ sf::Color get_author_color() const { return author_color; }
+
+ void draw_list(Body *body, sf::RenderTarget &render_target);
+
+ // TODO: Use a list of strings instead, not all plugins need all of these fields
+ std::string url;
+ std::string thumbnail_url;
+ bool visible;
+ bool dirty;
+ bool dirty_description;
+ bool dirty_author;
+ bool dirty_timestamp;
+ // TODO: Remove this and instead if |thumbnail_url| starts with file://, then its a local file
+ bool thumbnail_is_local;
+ std::unique_ptr<Text> title_text;
+ std::unique_ptr<Text> description_text;
+ std::unique_ptr<Text> author_text;
+ std::unique_ptr<sf::Text> timestamp_text; // TODO: Remove
+ // Used by image boards for example. The elements are indices to other body items
+ std::vector<size_t> replies_to;
+ // Used by image boards for example. The elements are indices to other body items
+ std::vector<size_t> replies;
+ std::string post_number;
+ void *userdata; // Not managed, should be deallocated by whoever sets this
+ float loaded_height = 0.0f;
+ sf::Vector2f loaded_image_size;
+ float loaded_content_height = 0.0f;
+ FetchStatus embedded_item_status = FetchStatus::NONE;
+ // Important! Should refer to a new BodyItem, not one that already exists in the body.
+ // TODO: Allow referring to an existing body item. This doesn't work properly at the moment because max width of text and line count calculation getting messed up
+ // if an embedded item wraps but not the original body item.
+ std::shared_ptr<BodyItem> embedded_item; // Used by matrix for example to display reply message body. Note: only the first level of embedded items is rendered (not recursive, this is done on purpose)
+ ThumbnailMaskType thumbnail_mask_type = ThumbnailMaskType::NONE;
+ sf::Vector2i thumbnail_size;
+ std::vector<Reaction> reactions; // TODO: Move to a different body item type
+ std::shared_ptr<BodyItemExtra> extra; // TODO: Remove
+
+ // Internal use only
+ int keep_alive_frames = 0;
+ private:
+ // TODO: Clean up these strings when set in text, and get_title for example should return |title_text.getString()|
+ // TODO: Use sf::String instead, removes the need to convert to utf32 every time the text is dirty (for example when resizing window)
+ std::string title;
+ std::string description;
+ std::string author;
+ time_t timestamp;
+ sf::Color title_color;
+ sf::Color author_color;
+ sf::Color description_color;
+ };
+
+ using BodyItems = std::vector<std::shared_ptr<BodyItem>>;
+} \ No newline at end of file