Chatterino
MessageElement.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "common/FlagsEnum.hpp"
4 #include "messages/ImageSet.hpp"
5 #include "messages/Link.hpp"
7 #include "singletons/Fonts.hpp"
8 
9 #include <QRect>
10 #include <QString>
11 #include <QTime>
12 #include <boost/noncopyable.hpp>
13 #include <cstdint>
14 #include <memory>
15 #include <pajlada/signals/signalholder.hpp>
16 #include <vector>
17 
18 namespace chatterino {
19 class Channel;
20 struct MessageLayoutContainer;
21 class MessageLayoutElement;
22 
23 class Image;
24 using ImagePtr = std::shared_ptr<Image>;
25 
26 struct Emote;
27 using EmotePtr = std::shared_ptr<const Emote>;
28 
29 enum class MessageElementFlag : int64_t {
30  None = 0LL,
31  Misc = (1LL << 0),
32  Text = (1LL << 1),
33 
34  Username = (1LL << 2),
35  Timestamp = (1LL << 3),
36 
37  TwitchEmoteImage = (1LL << 4),
38  TwitchEmoteText = (1LL << 5),
40 
41  BttvEmoteImage = (1LL << 6),
42  BttvEmoteText = (1LL << 7),
43  BttvEmote = BttvEmoteImage | BttvEmoteText,
44 
45  ChannelPointReward = (1LL << 8),
46  ChannelPointRewardImage = ChannelPointReward | TwitchEmoteImage,
47 
48  FfzEmoteImage = (1LL << 9),
49  FfzEmoteText = (1LL << 10),
51 
52  SevenTVEmoteImage = (1LL << 34),
53  SevenTVEmoteText = (1LL << 35),
55 
56  EmoteImages =
58  EmoteText =
60 
61  BitsStatic = (1LL << 11),
62  BitsAnimated = (1LL << 12),
63 
64  // Slot 1: Twitch
65  // - Staff badge
66  // - Admin badge
67  // - Global Moderator badge
68  BadgeGlobalAuthority = (1LL << 13),
69 
70  // Slot 2: Twitch
71  // - Predictions badge
72  BadgePredictions = (1LL << 14),
73 
74  // Slot 3: Twitch
75  // - VIP badge
76  // - Moderator badge
77  // - Broadcaster badge
78  BadgeChannelAuthority = (1LL << 15),
79 
80  // Slot 4: Twitch
81  // - Subscription badges
82  BadgeSubscription = (1LL << 16),
83 
84  // Slot 5: Twitch
85  // - Turbo badge
86  // - Prime badge
87  // - Bit badges
88  // - Game badges
89  BadgeVanity = (1LL << 17),
90 
91  // Slot 6: Chatterino
92  // - Chatterino developer badge
93  // - Chatterino contributor badge
94  // - Chatterino donator badge
95  // - Chatterino top donator badge
96  // - Chatterino special pepe badge
97  // - Chatterino gnome badge
98  BadgeChatterino = (1LL << 18),
99 
100  // Slot 7: 7TV
101  // - 7TV Admin
102  // - 7TV Dungeon Mistress
103  // - 7TV Moderator
104  // - 7TV Subscriber
105  // - 7TV Translator
106  // - 7TV Contributor
107  BadgeSevenTV = (1LL << 36),
108 
109  // Slot 7: FrankerFaceZ
110  // - FFZ developer badge
111  // - FFZ bot badge
112  // - FFZ donator badge
113  BadgeFfz = (1LL << 19),
114 
117  BadgeFfz,
118 
119  ChannelName = (1LL << 20),
120 
121  BitsAmount = (1LL << 21),
122 
123  ModeratorTools = (1LL << 22),
124 
125  EmojiImage = (1LL << 23),
126  EmojiText = (1LL << 24),
128 
129  AlwaysShow = (1LL << 25),
130 
131  // used in the ChannelView class to make the collapse buttons visible if
132  // needed
133  Collapsed = (1LL << 26),
134 
135  // used for dynamic bold usernames
136  BoldUsername = (1LL << 27),
137  NonBoldUsername = (1LL << 28),
138 
139  // for links
140  LowercaseLink = (1LL << 29),
141  OriginalLink = (1LL << 30),
142 
143  // ZeroWidthEmotes are emotes that are supposed to overlay over any pre-existing emotes
144  // e.g. BTTV's SoSnowy during christmas season or 7TV's RainTime
145  ZeroWidthEmote = (1LL << 31),
146 
147  // for elements of the message reply
148  RepliedMessage = (1LL << 32),
149 
150  // for the reply button element
151  ReplyButton = (1LL << 33),
152 
153  // (1LL << 34) through (1LL << 36) are occupied by
154  // SevenTVEmoteImage, SevenTVEmoteText, and BadgeSevenTV,
155 
157  BttvEmoteImage | SevenTVEmoteImage | TwitchEmoteImage |
158  BitsAmount | Text | AlwaysShow,
159 };
161 
162 class MessageElement : boost::noncopyable
163 {
164 public:
165  enum UpdateFlags : char {
166  Update_Text = 1,
167  Update_Emotes = 2,
168  Update_Images = 4,
169  Update_All = Update_Text | Update_Emotes | Update_Images
170  };
171  enum ThumbnailType : char {
172  Link_Thumbnail = 1,
173  };
174 
175  virtual ~MessageElement();
176 
177  MessageElement *setLink(const Link &link);
178  MessageElement *setText(const QString &text);
179  MessageElement *setTooltip(const QString &tooltip);
180  MessageElement *setThumbnailType(const ThumbnailType type);
181  MessageElement *setThumbnail(const ImagePtr &thumbnail);
182 
183  MessageElement *setTrailingSpace(bool value);
184  const QString &getTooltip() const;
185  const ImagePtr &getThumbnail() const;
186  const ThumbnailType &getThumbnailType() const;
187 
188  const Link &getLink() const;
189  bool hasTrailingSpace() const;
190  MessageElementFlags getFlags() const;
191  MessageElement *updateLink();
192 
193  virtual void addToContainer(MessageLayoutContainer &container,
194  MessageElementFlags flags) = 0;
195 
196  pajlada::Signals::NoArgSignal linkChanged;
197 
198 protected:
200  bool trailingSpace = true;
201 
202 private:
203  QString text_;
204  Link link_;
205  QString tooltip_;
206  ImagePtr thumbnail_;
207  ThumbnailType thumbnailType_;
208  MessageElementFlags flags_;
209 };
210 
211 // used when layout element doesn't have a creator
213 {
214 public:
215  EmptyElement();
216 
217  void addToContainer(MessageLayoutContainer &container,
218  MessageElementFlags flags) override;
219 
220  static EmptyElement &instance();
221 
222 private:
223  ImagePtr image_;
224 };
225 
226 // contains a simple image
228 {
229 public:
231 
232  void addToContainer(MessageLayoutContainer &container,
233  MessageElementFlags flags) override;
234 
235 private:
236  ImagePtr image_;
237 };
238 
239 // contains a image with a circular background color
241 {
242 public:
243  CircularImageElement(ImagePtr image, int padding, QColor background,
244  MessageElementFlags flags);
245 
246  void addToContainer(MessageLayoutContainer &container,
247  MessageElementFlags flags) override;
248 
249 private:
250  ImagePtr image_;
251  int padding_;
252  QColor background_;
253 };
254 
255 // contains a text, it will split it into words
257 {
258 public:
259  TextElement(const QString &text, MessageElementFlags flags,
260  const MessageColor &color = MessageColor::Text,
262  ~TextElement() override = default;
263 
264  void addToContainer(MessageLayoutContainer &container,
265  MessageElementFlags flags) override;
266 
267 private:
268  MessageColor color_;
269  FontStyle style_;
270 
271  struct Word {
272  QString text;
273  int width = -1;
274  };
275  std::vector<Word> words_;
276 };
277 
278 // contains a text that will be truncated to one line
280 {
281 public:
282  SingleLineTextElement(const QString &text, MessageElementFlags flags,
283  const MessageColor &color = MessageColor::Text,
285  ~SingleLineTextElement() override = default;
286 
287  void addToContainer(MessageLayoutContainer &container,
288  MessageElementFlags flags) override;
289 
290 private:
291  MessageColor color_;
292  FontStyle style_;
293 
294  struct Word {
295  QString text;
296  int width = -1;
297  };
298  std::vector<Word> words_;
299 };
300 
301 // contains emote data and will pick the emote based on :
302 // a) are images for the emote type enabled
303 // b) which size it wants
305 {
306 public:
307  EmoteElement(const EmotePtr &data, MessageElementFlags flags_,
308  const MessageColor &textElementColor = MessageColor::Text);
309 
310  void addToContainer(MessageLayoutContainer &container,
311  MessageElementFlags flags_) override;
312  EmotePtr getEmote() const;
313 
314 protected:
315  virtual MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
316  const QSize &size);
317 
318 private:
319  std::unique_ptr<TextElement> textElement_;
320  EmotePtr emote_;
321 };
322 
324 {
325 public:
326  BadgeElement(const EmotePtr &data, MessageElementFlags flags_);
327 
328  void addToContainer(MessageLayoutContainer &container,
329  MessageElementFlags flags_) override;
330 
331  EmotePtr getEmote() const;
332 
333 protected:
334  virtual MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
335  const QSize &size);
336 
337 private:
338  EmotePtr emote_;
339 };
340 
342 {
343 public:
344  ModBadgeElement(const EmotePtr &data, MessageElementFlags flags_);
345 
346 protected:
347  MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
348  const QSize &size) override;
349 };
350 
352 {
353 public:
354  VipBadgeElement(const EmotePtr &data, MessageElementFlags flags_);
355 
356 protected:
357  MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
358  const QSize &size) override;
359 };
360 
362 {
363 public:
364  FfzBadgeElement(const EmotePtr &data, MessageElementFlags flags_,
365  QColor color_);
366 
367 protected:
368  MessageLayoutElement *makeImageLayoutElement(const ImagePtr &image,
369  const QSize &size) override;
370  const QColor color;
371 };
372 
373 // contains a text, formated depending on the preferences
375 {
376 public:
377  TimestampElement(QTime time_ = QTime::currentTime());
378  ~TimestampElement() override = default;
379 
380  void addToContainer(MessageLayoutContainer &container,
381  MessageElementFlags flags) override;
382 
383  TextElement *formatTime(const QTime &time);
384 
385 private:
386  QTime time_;
387  std::unique_ptr<TextElement> element_;
388  QString format_;
389 };
390 
391 // adds all the custom moderation buttons, adds a variable amount of items
392 // depending on settings fourtf: implement
394 {
395 public:
397 
398  void addToContainer(MessageLayoutContainer &container,
399  MessageElementFlags flags) override;
400 };
401 
402 // Forces a linebreak
404 {
405 public:
407 
408  void addToContainer(MessageLayoutContainer &container,
409  MessageElementFlags flags) override;
410 };
411 
412 // Image element which will pick the quality of the image based on ui scale
414 {
415 public:
417 
418  void addToContainer(MessageLayoutContainer &container,
419  MessageElementFlags flags) override;
420 
421 private:
422  ImageSet images_;
423 };
424 
426 {
427 public:
429 
430  void addToContainer(MessageLayoutContainer &container,
431  MessageElementFlags flags) override;
432 };
433 
434 } // namespace chatterino
Definition: MessageElement.hpp:374
Definition: MessageElement.hpp:323
int64_t FlagsEnum< MessageElementFlag > MessageElementFlags
Definition: MessageLayout.hpp:21
Definition: MessageColor.hpp:8
const QColor color
Definition: MessageElement.hpp:370
Definition: MessageElement.hpp:425
Definition: MessageLayoutElement.hpp:26
UpdateFlags
Definition: MessageElement.hpp:165
Definition: MessageElement.hpp:256
Definition: Badges.hpp:9
Definition: MessageElement.hpp:413
Definition: MessageElement.hpp:227
Definition: Application.cpp:48
Definition: MessageElement.hpp:361
Definition: MessageElement.hpp:341
Definition: ImageSet.hpp:7
Definition: MessageColor.hpp:9
MessageElementFlag
Definition: MessageElement.hpp:29
std::shared_ptr< const Emote > EmotePtr
Definition: Emote.hpp:38
pajlada::Signals::NoArgSignal linkChanged
Definition: MessageElement.hpp:196
Definition: MessageElement.hpp:240
Definition: MessageElement.hpp:162
Definition: MessageElement.hpp:279
Definition: MessageElement.hpp:304
QString formatTime(int totalSeconds)
Definition: FormatTime.cpp:19
Definition: MessageLayoutContainer.hpp:46
ThumbnailType
Definition: MessageElement.hpp:171
Definition: ChannelPointReward.hpp:14
Definition: MessageElement.hpp:403
FontStyle
Definition: Fonts.hpp:20
Definition: MessageElement.hpp:393
Definition: MessageElement.hpp:212
std::shared_ptr< Image > ImagePtr
Definition: ModerationAction.hpp:14
Definition: MessageElement.hpp:351