mirror-chatterino2/src/messages/MessageElement.hpp

249 lines
6.2 KiB
C++

#pragma once
#include "common/FlagsEnum.hpp"
#include "messages/Link.hpp"
#include "messages/MessageColor.hpp"
#include "singletons/Fonts.hpp"
#include <QRect>
#include <QString>
#include <QTime>
#include <boost/noncopyable.hpp>
#include <cstdint>
#include <memory>
#include <pajlada/signals/signalholder.hpp>
#include <vector>
namespace chatterino {
class Channel;
struct MessageLayoutContainer;
class Image;
using ImagePtr = std::shared_ptr<Image>;
struct Emote;
using EmotePtr = std::shared_ptr<const Emote>;
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<MessageElementFlag>;
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<Word> 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> 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<TextElement> 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