#pragma once #include "common/FlagsEnum.hpp" #include "messages/Link.hpp" #include "messages/MessageColor.hpp" #include "singletons/Fonts.hpp" #include #include #include #include #include #include #include #include namespace chatterino { class Channel; struct MessageLayoutContainer; class Image; using ImagePtr = std::shared_ptr; struct Emote; using EmotePtr = std::shared_ptr; enum class MessageElementFlag { None = 0, Misc = (1 << 0), Text = (1 << 1), Username = (1 << 2), Timestamp = (1 << 3), TwitchEmoteImage = (1 << 4), TwitchEmoteText = (1 << 5), TwitchEmote = TwitchEmoteImage | TwitchEmoteText, BttvEmoteImage = (1 << 6), BttvEmoteText = (1 << 7), BttvEmote = BttvEmoteImage | BttvEmoteText, FfzEmoteImage = (1 << 10), FfzEmoteText = (1 << 11), FfzEmote = FfzEmoteImage | FfzEmoteText, EmoteImages = TwitchEmoteImage | BttvEmoteImage | FfzEmoteImage, BitsStatic = (1 << 12), BitsAnimated = (1 << 13), // Slot 1: Twitch // - Staff badge // - Admin badge // - Global Moderator badge BadgeGlobalAuthority = (1 << 14), // Slot 2: Twitch // - Moderator badge // - Broadcaster badge BadgeChannelAuthority = (1 << 15), // Slot 3: Twitch // - Subscription badges BadgeSubscription = (1 << 16), // Slot 4: Twitch // - Turbo badge // - Prime badge // - Bit badges // - Game badges BadgeVanity = (1 << 17), // Slot 5: Chatterino // - Chatterino developer badge // - Chatterino donator badge // - Chatterino top donator badge BadgeChatterino = (1 << 18), // Rest of slots: ffz custom badge? bttv custom badge? mywaifu (puke) // custom badge? Badges = BadgeGlobalAuthority | BadgeChannelAuthority | BadgeSubscription | BadgeVanity | BadgeChatterino, ChannelName = (1 << 19), BitsAmount = (1 << 20), ModeratorTools = (1 << 21), EmojiImage = (1 << 23), EmojiText = (1 << 24), EmojiAll = EmojiImage | EmojiText, AlwaysShow = (1 << 25), // used in the ChannelView class to make the collapse buttons visible if // needed Collapsed = (1 << 26), // used for dynamic bold usernames BoldUsername = (1 << 27), NonBoldUsername = (1 << 28), // for links LowercaseLink = (1 << 29), OriginalLink = (1 << 30), Default = Timestamp | Badges | Username | BitsStatic | FfzEmoteImage | BttvEmoteImage | TwitchEmoteImage | BitsAmount | Text | AlwaysShow, }; using MessageElementFlags = FlagsEnum; class MessageElement : boost::noncopyable { public: enum UpdateFlags : char { Update_Text = 1, Update_Emotes = 2, Update_Images = 4, Update_All = Update_Text | Update_Emotes | Update_Images }; virtual ~MessageElement(); MessageElement *setLink(const Link &link); MessageElement *setText(const QString &text); MessageElement *setTooltip(const QString &tooltip); MessageElement *setTrailingSpace(bool value); const QString &getTooltip() const; const Link &getLink() const; bool hasTrailingSpace() const; MessageElementFlags getFlags() const; MessageElement *updateLink(); virtual void addToContainer(MessageLayoutContainer &container, MessageElementFlags flags) = 0; pajlada::Signals::NoArgSignal linkChanged; protected: MessageElement(MessageElementFlags flags); bool trailingSpace = true; private: QString text_; Link link_; QString tooltip_; MessageElementFlags flags_; }; // used when layout element doesn't have a creator class EmptyElement : public MessageElement { public: EmptyElement(); void addToContainer(MessageLayoutContainer &container, MessageElementFlags flags) override; static EmptyElement &instance(); private: ImagePtr image_; }; // contains a simple image class ImageElement : public MessageElement { public: ImageElement(ImagePtr image, MessageElementFlags flags); void addToContainer(MessageLayoutContainer &container, MessageElementFlags flags) override; private: ImagePtr image_; }; // contains a text, it will split it into words class TextElement : public MessageElement { public: TextElement(const QString &text, MessageElementFlags flags, const MessageColor &color = MessageColor::Text, FontStyle style = FontStyle::ChatMedium); ~TextElement() override = default; void addToContainer(MessageLayoutContainer &container, MessageElementFlags flags) override; private: MessageColor color_; FontStyle style_; struct Word { QString text; int width = -1; }; std::vector words_; }; // contains emote data and will pick the emote based on : // a) are images for the emote type enabled // b) which size it wants class EmoteElement : public MessageElement { public: EmoteElement(const EmotePtr &data, MessageElementFlags flags_); void addToContainer(MessageLayoutContainer &container, MessageElementFlags flags_) override; EmotePtr getEmote() const; private: std::unique_ptr textElement_; EmotePtr emote_; }; // contains a text, formated depending on the preferences class TimestampElement : public MessageElement { public: TimestampElement(QTime time_ = QTime::currentTime()); ~TimestampElement() override = default; void addToContainer(MessageLayoutContainer &container, MessageElementFlags flags) override; TextElement *formatTime(const QTime &time); private: QTime time_; std::unique_ptr element_; QString format_; }; // adds all the custom moderation buttons, adds a variable amount of items // depending on settings fourtf: implement class TwitchModerationElement : public MessageElement { public: TwitchModerationElement(); void addToContainer(MessageLayoutContainer &container, MessageElementFlags flags) override; }; } // namespace chatterino