1 #pragma once
2 
3 #include <QPoint>
4 #include <QRect>
5 #include <QString>
6 #include <boost/noncopyable.hpp>
7 #include <climits>
8 
9 #include "common/FlagsEnum.hpp"
10 #include "messages/Link.hpp"
11 #include "messages/MessageColor.hpp"
12 #include "messages/MessageElement.hpp"
13 
14 class QPainter;
15 
16 namespace chatterino {
17 class MessageElement;
18 class Image;
19 using ImagePtr = std::shared_ptr<Image>;
20 enum class FontStyle : uint8_t;
21 
22 class MessageLayoutElement : boost::noncopyable
23 {
24 public:
25     MessageLayoutElement(MessageElement &creator_, const QSize &size);
26     virtual ~MessageLayoutElement();
27 
28     const QRect &getRect() const;
29     MessageElement &getCreator() const;
30     void setPosition(QPoint point);
31     bool hasTrailingSpace() const;
32     int getLine() const;
33     void setLine(int line);
34 
35     MessageLayoutElement *setTrailingSpace(bool value);
36     MessageLayoutElement *setLink(const Link &link_);
37     MessageLayoutElement *setText(const QString &text_);
38 
39     virtual void addCopyTextToString(QString &str, int from = 0,
40                                      int to = INT_MAX) const = 0;
41     virtual int getSelectionIndexCount() const = 0;
42     virtual void paint(QPainter &painter) = 0;
43     virtual void paintAnimated(QPainter &painter, int yOffset) = 0;
44     virtual int getMouseOverIndex(const QPoint &abs) const = 0;
45     virtual int getXFromIndex(int index) = 0;
46 
47     const Link &getLink() const;
48     const QString &getText() const;
49     FlagsEnum<MessageElementFlag> getFlags() const;
50 
51 protected:
52     bool trailingSpace = true;
53 
54 private:
55     QString text_;
56     QRect rect_;
57     Link link_;
58     MessageElement &creator_;
59     int line_{};
60 };
61 
62 // IMAGE
63 class ImageLayoutElement : public MessageLayoutElement
64 {
65 public:
66     ImageLayoutElement(MessageElement &creator, ImagePtr image,
67                        const QSize &size);
68 
69 protected:
70     void addCopyTextToString(QString &str, int from = 0,
71                              int to = INT_MAX) const override;
72     int getSelectionIndexCount() const override;
73     void paint(QPainter &painter) override;
74     void paintAnimated(QPainter &painter, int yOffset) override;
75     int getMouseOverIndex(const QPoint &abs) const override;
76     int getXFromIndex(int index) override;
77 
78     ImagePtr image_;
79 };
80 
81 class ImageWithBackgroundLayoutElement : public ImageLayoutElement
82 {
83 public:
84     ImageWithBackgroundLayoutElement(MessageElement &creator, ImagePtr image,
85                                      const QSize &size, QColor color);
86 
87 protected:
88     void paint(QPainter &painter) override;
89 
90 private:
91     QColor color_;
92 };
93 
94 // TEXT
95 class TextLayoutElement : public MessageLayoutElement
96 {
97 public:
98     TextLayoutElement(MessageElement &creator_, QString &text,
99                       const QSize &size, QColor color_, FontStyle style_,
100                       float scale_);
101 
102     void listenToLinkChanges();
103 
104 protected:
105     void addCopyTextToString(QString &str, int from = 0,
106                              int to = INT_MAX) const override;
107     int getSelectionIndexCount() const override;
108     void paint(QPainter &painter) override;
109     void paintAnimated(QPainter &painter, int yOffset) override;
110     int getMouseOverIndex(const QPoint &abs) const override;
111     int getXFromIndex(int index) override;
112 
113     QColor color_;
114     FontStyle style_;
115     float scale_;
116 
117     std::vector<pajlada::Signals::ScopedConnection> managedConnections_;
118 };
119 
120 // TEXT ICON
121 // two lines of text (characters) in the size of a normal chat badge
122 class TextIconLayoutElement : public MessageLayoutElement
123 {
124 public:
125     TextIconLayoutElement(MessageElement &creator_, const QString &line1,
126                           const QString &line2, float scale, const QSize &size);
127 
128 protected:
129     void addCopyTextToString(QString &str, int from = 0,
130                              int to = INT_MAX) const override;
131     int getSelectionIndexCount() const override;
132     void paint(QPainter &painter) override;
133     void paintAnimated(QPainter &painter, int yOffset) override;
134     int getMouseOverIndex(const QPoint &abs) const override;
135     int getXFromIndex(int index) override;
136 
137 private:
138     float scale;
139     QString line1;
140     QString line2;
141 };
142 
143 struct PajSegment {
144     QString text;
145     QColor color;
146 };
147 
148 // TEXT
149 class MultiColorTextLayoutElement : public TextLayoutElement
150 {
151 public:
152     MultiColorTextLayoutElement(MessageElement &creator_, QString &text,
153                                 const QSize &size,
154                                 std::vector<PajSegment> segments,
155                                 FontStyle style_, float scale_);
156 
157 protected:
158     void paint(QPainter &painter) override;
159 
160 private:
161     std::vector<PajSegment> segments_;
162 };
163 
164 }  // namespace chatterino
165