123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- #pragma once
- #include "Text.hpp"
- #include <memory>
- #include <optional>
- #include <mglpp/graphics/Text.hpp>
- namespace mgl {
- class Window;
- }
- 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
- };
- struct ThumbnailWidget {
- mgl::vec2f position;
- mgl::vec2f size;
- };
- class BodyItem;
- struct Widgets {
- BodyItem *body_item = nullptr;
- std::optional<ThumbnailWidget> thumbnail;
- };
- // TODO: Remove and create an Userdata class instead to replace the void* userdata in BodyItem
- class BodyItemExtra {
- public:
- BodyItemExtra() = default;
- virtual ~BodyItemExtra() = default;
- virtual void draw_overlay(mgl::Window &window, const Widgets &widgets) {
- (void)window;
- (void)widgets;
- }
- };
- struct Reaction {
- std::string text_str;
- std::unique_ptr<Text> text;
- void *userdata = nullptr;
- mgl::vec2f size;
- mgl::Color text_color;
- int num_lines = 1;
- };
- class BodyItem {
- public:
- BodyItem(const BodyItem&) = delete;
- BodyItem& operator=(const BodyItem &other);
- static std::shared_ptr<BodyItem> create(std::string title, bool selectable = true);
- 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(int64_t new_timestamp) {
- if(new_timestamp == timestamp)
- return;
- timestamp = new_timestamp;
- dirty_timestamp = true;
- }
- void set_title_color(mgl::Color new_color, bool new_force_color = false) {
- if(new_color == title_color && new_force_color == force_description_color)
- return;
- title_color = new_color;
- dirty = true;
- force_title_color = new_force_color;
- }
- // Set to 0 to disable max lines
- void set_title_max_lines(int max_lines) {
- if(max_lines == title_max_lines)
- return;
- title_max_lines = max_lines;
- dirty = true;
- }
- void set_description_color(mgl::Color new_color, bool new_force_color = false) {
- if(new_color == description_color && new_force_color == force_description_color)
- return;
- description_color = new_color;
- dirty_description = true;
- force_description_color = new_force_color;
- }
- void set_description_max_lines(int max_lines) {
- if(max_lines == description_max_lines)
- return;
- description_max_lines = max_lines;
- dirty_description = true;
- }
- void set_author_color(mgl::Color new_color, bool new_force_color = false) {
- if(new_color == author_color && new_force_color == force_description_color)
- return;
- author_color = new_color;
- dirty_author = true;
- force_author_color = new_force_color;
- }
- void add_reaction(std::string text, void *userdata, mgl::Color text_color);
- 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
- int64_t get_timestamp() const { return timestamp; }
- mgl::Color get_title_color() const { return title_color; }
- mgl::Color get_description_color() const { return description_color; }
- mgl::Color get_author_color() const { return author_color; }
- bool is_selectable() const { return selectable; }
- void draw_list(Body *body, mgl::Window &render_target);
- // TODO: Bits for bools
- // TODO: Use a list of strings instead, not all plugins need all of these fields
- std::string url;
- std::string thumbnail_url;
- int title_max_lines = 0;
- int description_max_lines = 0;
- bool visible; // TODO: Make private and when set by user, set a |visible_force| variable to true or false which makes the item invisible even after filtering
- bool dirty;
- bool dirty_description;
- bool dirty_author;
- bool dirty_timestamp;
- bool dirty_reactions;
- // TODO: Remove this and instead if |thumbnail_url| starts with file://, then its a local file
- bool thumbnail_is_local;
- bool force_title_color = false;
- bool force_description_color = false;
- bool force_author_color = false;
- std::unique_ptr<Text> title_text;
- std::unique_ptr<Text> description_text;
- std::unique_ptr<Text> author_text;
- std::unique_ptr<mgl::Text> timestamp_text; // TODO: Remove
- void *userdata; // Not managed, should be deallocated by whoever sets this
- float loaded_height = 0.0f;
- float height = 0.0f;
- float prev_height = 0.0f;
- mgl::vec2f 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;
- mgl::vec2i 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:
- BodyItem(std::string _title, bool selectable);
- 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;
- int64_t timestamp;
- mgl::Color title_color;
- mgl::Color author_color;
- mgl::Color description_color;
- bool selectable;
- };
- using BodyItems = std::vector<std::shared_ptr<BodyItem>>;
- }
|