1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4 
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #pragma once
9 
10 #include "ui/cached_round_corners.h"
11 #include "ui/style/style_core_palette.h"
12 #include "layout/layout_selection.h"
13 
14 enum class ImageRoundRadius;
15 
16 namespace style {
17 struct TwoIconButton;
18 struct ScrollArea;
19 } // namespace style
20 
21 namespace Ui {
22 
23 class ChatTheme;
24 class ChatStyle;
25 struct BubblePattern;
26 
27 struct MessageStyle {
28 	CornersPixmaps msgBgCorners;
29 	style::color msgBg;
30 	style::color msgShadow;
31 	style::color msgServiceFg;
32 	style::color msgDateFg;
33 	style::color msgFileThumbLinkFg;
34 	style::color msgFileBg;
35 	style::color msgReplyBarColor;
36 	style::color msgWaveformActive;
37 	style::color msgWaveformInactive;
38 	style::color historyTextFg;
39 	style::color historyFileNameFg;
40 	style::color historyFileRadialFg;
41 	style::color mediaFg;
42 	style::TextPalette textPalette;
43 	style::TextPalette semiboldPalette;
44 	style::TextPalette fwdTextPalette;
45 	style::TextPalette replyTextPalette;
46 	style::icon tailLeft = { Qt::Uninitialized };
47 	style::icon tailRight = { Qt::Uninitialized };
48 	style::icon historyRepliesIcon = { Qt::Uninitialized };
49 	style::icon historyViewsIcon = { Qt::Uninitialized };
50 	style::icon historyPinIcon = { Qt::Uninitialized };
51 	style::icon historySentIcon = { Qt::Uninitialized };
52 	style::icon historyReceivedIcon = { Qt::Uninitialized };
53 	style::icon historyPsaIcon = { Qt::Uninitialized };
54 	style::icon historyCommentsOpen = { Qt::Uninitialized };
55 	style::icon historyComments = { Qt::Uninitialized };
56 	style::icon historyCallArrow = { Qt::Uninitialized };
57 	style::icon historyCallArrowMissed = { Qt::Uninitialized };
58 	style::icon historyCallIcon = { Qt::Uninitialized };
59 	style::icon historyCallCameraIcon = { Qt::Uninitialized };
60 	style::icon historyFilePlay = { Qt::Uninitialized };
61 	style::icon historyFileWaiting = { Qt::Uninitialized };
62 	style::icon historyFileDownload = { Qt::Uninitialized };
63 	style::icon historyFileCancel = { Qt::Uninitialized };
64 	style::icon historyFilePause = { Qt::Uninitialized };
65 	style::icon historyFileImage = { Qt::Uninitialized };
66 	style::icon historyFileDocument = { Qt::Uninitialized };
67 	style::icon historyAudioDownload = { Qt::Uninitialized };
68 	style::icon historyAudioCancel = { Qt::Uninitialized };
69 	style::icon historyQuizTimer = { Qt::Uninitialized };
70 	style::icon historyQuizExplain = { Qt::Uninitialized };
71 	style::icon historyPollChosen = { Qt::Uninitialized };
72 	style::icon historyPollChoiceRight = { Qt::Uninitialized };
73 };
74 
75 struct MessageImageStyle {
76 	CornersPixmaps msgDateImgBgCorners;
77 	CornersPixmaps msgServiceBgCorners;
78 	CornersPixmaps msgShadowCorners;
79 	style::color msgServiceBg;
80 	style::color msgDateImgBg;
81 	style::color msgShadow;
82 	style::color historyFileThumbRadialFg;
83 	style::icon historyFileThumbPlay = { Qt::Uninitialized };
84 	style::icon historyFileThumbWaiting = { Qt::Uninitialized };
85 	style::icon historyFileThumbDownload = { Qt::Uninitialized };
86 	style::icon historyFileThumbCancel = { Qt::Uninitialized };
87 	style::icon historyFileThumbPause = { Qt::Uninitialized };
88 	style::icon historyVideoDownload = { Qt::Uninitialized };
89 	style::icon historyVideoCancel = { Qt::Uninitialized };
90 	style::icon historyVideoMessageMute = { Qt::Uninitialized };
91 };
92 
93 struct ChatPaintContext {
94 	not_null<const ChatStyle*> st;
95 	const BubblePattern *bubblesPattern = nullptr;
96 	QRect viewport;
97 	QRect clip;
98 	TextSelection selection;
99 	bool outbg = false;
100 	crl::time now = 0;
101 
translateChatPaintContext102 	void translate(int x, int y) {
103 		viewport.translate(x, y);
104 		clip.translate(x, y);
105 	}
translateChatPaintContext106 	void translate(QPoint point) {
107 		translate(point.x(), point.y());
108 	}
109 
selectedChatPaintContext110 	[[nodiscard]] bool selected() const {
111 		return (selection == FullSelection);
112 	}
113 	[[nodiscard]] not_null<const MessageStyle*> messageStyle() const;
114 	[[nodiscard]] not_null<const MessageImageStyle*> imageStyle() const;
115 
translatedChatPaintContext116 	[[nodiscard]] ChatPaintContext translated(int x, int y) const {
117 		auto result = *this;
118 		result.translate(x, y);
119 		return result;
120 	}
translatedChatPaintContext121 	[[nodiscard]] ChatPaintContext translated(QPoint point) const {
122 		return translated(point.x(), point.y());
123 	}
withSelectionChatPaintContext124 	[[nodiscard]] ChatPaintContext withSelection(
125 		TextSelection selection) const {
126 		auto result = *this;
127 		result.selection = selection;
128 		return result;
129 	}
130 
131 };
132 
133 [[nodiscard]] int HistoryServiceMsgRadius();
134 [[nodiscard]] int HistoryServiceMsgInvertedRadius();
135 [[nodiscard]] int HistoryServiceMsgInvertedShrink();
136 
137 class ChatStyle final : public style::palette {
138 public:
139 	ChatStyle();
140 
141 	void apply(not_null<ChatTheme*> theme);
142 
paletteChanged()143 	[[nodiscard]] rpl::producer<> paletteChanged() const {
144 		return _paletteChanged.events();
145 	}
146 
147 	template <typename Type>
value(const Type & original)148 	[[nodiscard]] Type value(const Type &original) const {
149 		auto my = Type();
150 		make(my, original);
151 		return my;
152 	}
153 
154 	template <typename Type>
value(rpl::lifetime & parentLifetime,const Type & original)155 	[[nodiscard]] const Type &value(
156 			rpl::lifetime &parentLifetime,
157 			const Type &original) const {
158 		const auto my = parentLifetime.make_state<Type>();
159 		make(*my, original);
160 		return *my;
161 	}
162 
163 	[[nodiscard]] const CornersPixmaps &serviceBgCornersNormal() const;
164 	[[nodiscard]] const CornersPixmaps &serviceBgCornersInverted() const;
165 
166 	[[nodiscard]] const MessageStyle &messageStyle(
167 		bool outbg,
168 		bool selected) const;
169 	[[nodiscard]] const MessageImageStyle &imageStyle(bool selected) const;
170 
171 	[[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCorners() const;
172 	[[nodiscard]] const CornersPixmaps &msgSelectOverlayCornersSmall() const;
173 	[[nodiscard]] const CornersPixmaps &msgSelectOverlayCornersLarge() const;
174 
historyPsaForwardPalette()175 	[[nodiscard]] const style::TextPalette &historyPsaForwardPalette() const {
176 		return _historyPsaForwardPalette;
177 	}
imgReplyTextPalette()178 	[[nodiscard]] const style::TextPalette &imgReplyTextPalette() const {
179 		return _imgReplyTextPalette;
180 	}
serviceTextPalette()181 	[[nodiscard]] const style::TextPalette &serviceTextPalette() const {
182 		return _serviceTextPalette;
183 	}
historyRepliesInvertedIcon()184 	[[nodiscard]] const style::icon &historyRepliesInvertedIcon() const {
185 		return _historyRepliesInvertedIcon;
186 	}
historyViewsInvertedIcon()187 	[[nodiscard]] const style::icon &historyViewsInvertedIcon() const {
188 		return _historyViewsInvertedIcon;
189 	}
historyViewsSendingIcon()190 	[[nodiscard]] const style::icon &historyViewsSendingIcon() const {
191 		return _historyViewsSendingIcon;
192 	}
historyViewsSendingInvertedIcon()193 	[[nodiscard]] const style::icon &historyViewsSendingInvertedIcon() const {
194 		return _historyViewsSendingInvertedIcon;
195 	}
historyPinInvertedIcon()196 	[[nodiscard]] const style::icon &historyPinInvertedIcon() const {
197 		return _historyPinInvertedIcon;
198 	}
historySendingIcon()199 	[[nodiscard]] const style::icon &historySendingIcon() const {
200 		return _historySendingIcon;
201 	}
historySendingInvertedIcon()202 	[[nodiscard]] const style::icon &historySendingInvertedIcon() const {
203 		return _historySendingInvertedIcon;
204 	}
historySentInvertedIcon()205 	[[nodiscard]] const style::icon &historySentInvertedIcon() const {
206 		return _historySentInvertedIcon;
207 	}
historyReceivedInvertedIcon()208 	[[nodiscard]] const style::icon &historyReceivedInvertedIcon() const {
209 		return _historyReceivedInvertedIcon;
210 	}
msgBotKbUrlIcon()211 	[[nodiscard]] const style::icon &msgBotKbUrlIcon() const {
212 		return _msgBotKbUrlIcon;
213 	}
msgBotKbPaymentIcon()214 	[[nodiscard]] const style::icon &msgBotKbPaymentIcon() const {
215 		return _msgBotKbPaymentIcon;
216 	}
msgBotKbSwitchPmIcon()217 	[[nodiscard]] const style::icon &msgBotKbSwitchPmIcon() const {
218 		return _msgBotKbSwitchPmIcon;
219 	}
historyFastCommentsIcon()220 	[[nodiscard]] const style::icon &historyFastCommentsIcon() const {
221 		return _historyFastCommentsIcon;
222 	}
historyFastShareIcon()223 	[[nodiscard]] const style::icon &historyFastShareIcon() const {
224 		return _historyFastShareIcon;
225 	}
historyGoToOriginalIcon()226 	[[nodiscard]] const style::icon &historyGoToOriginalIcon() const {
227 		return _historyGoToOriginalIcon;
228 	}
historyMapPoint()229 	[[nodiscard]] const style::icon &historyMapPoint() const {
230 		return _historyMapPoint;
231 	}
historyMapPointInner()232 	[[nodiscard]] const style::icon &historyMapPointInner() const {
233 		return _historyMapPointInner;
234 	}
youtubeIcon()235 	[[nodiscard]] const style::icon &youtubeIcon() const {
236 		return _youtubeIcon;
237 	}
videoIcon()238 	[[nodiscard]] const style::icon &videoIcon() const {
239 		return _videoIcon;
240 	}
historyPollChoiceRight()241 	[[nodiscard]] const style::icon &historyPollChoiceRight() const {
242 		return _historyPollChoiceRight;
243 	}
historyPollChoiceWrong()244 	[[nodiscard]] const style::icon &historyPollChoiceWrong() const {
245 		return _historyPollChoiceWrong;
246 	}
247 
248 private:
249 	void assignPalette(not_null<const style::palette*> palette);
250 
251 	void make(style::color &my, const style::color &original) const;
252 	void make(style::icon &my, const style::icon &original) const;
253 	void make(
254 		style::TextPalette &my,
255 		const style::TextPalette &original) const;
256 	void make(
257 		style::TwoIconButton &my,
258 		const style::TwoIconButton &original) const;
259 	void make(
260 		style::ScrollArea &my,
261 		const style::ScrollArea &original) const;
262 
263 	[[nodiscard]] MessageStyle &messageStyleRaw(
264 		bool outbg,
265 		bool selected) const;
266 	[[nodiscard]] MessageStyle &messageIn();
267 	[[nodiscard]] MessageStyle &messageInSelected();
268 	[[nodiscard]] MessageStyle &messageOut();
269 	[[nodiscard]] MessageStyle &messageOutSelected();
270 
271 	[[nodiscard]] MessageImageStyle &imageStyleRaw(bool selected) const;
272 	[[nodiscard]] MessageImageStyle &image();
273 	[[nodiscard]] MessageImageStyle &imageSelected();
274 
275 	template <typename Type>
276 	void make(
277 		Type MessageStyle::*my,
278 		const Type &originalIn,
279 		const Type &originalInSelected,
280 		const Type &originalOut,
281 		const Type &originalOutSelected);
282 
283 	template <typename Type>
284 	void make(
285 		Type MessageImageStyle::*my,
286 		const Type &original,
287 		const Type &originalSelected);
288 
289 	mutable CornersPixmaps _serviceBgCornersNormal;
290 	mutable CornersPixmaps _serviceBgCornersInverted;
291 
292 	mutable std::array<MessageStyle, 4> _messageStyles;
293 	mutable std::array<MessageImageStyle, 2> _imageStyles;
294 
295 	mutable CornersPixmaps _msgBotKbOverBgAddCorners;
296 	mutable CornersPixmaps _msgSelectOverlayCornersSmall;
297 	mutable CornersPixmaps _msgSelectOverlayCornersLarge;
298 
299 	style::TextPalette _historyPsaForwardPalette;
300 	style::TextPalette _imgReplyTextPalette;
301 	style::TextPalette _serviceTextPalette;
302 	style::icon _historyRepliesInvertedIcon = { Qt::Uninitialized };
303 	style::icon _historyViewsInvertedIcon = { Qt::Uninitialized };
304 	style::icon _historyViewsSendingIcon = { Qt::Uninitialized };
305 	style::icon _historyViewsSendingInvertedIcon = { Qt::Uninitialized };
306 	style::icon _historyPinInvertedIcon = { Qt::Uninitialized };
307 	style::icon _historySendingIcon = { Qt::Uninitialized };
308 	style::icon _historySendingInvertedIcon = { Qt::Uninitialized };
309 	style::icon _historySentInvertedIcon = { Qt::Uninitialized };
310 	style::icon _historyReceivedInvertedIcon = { Qt::Uninitialized };
311 	style::icon _msgBotKbUrlIcon = { Qt::Uninitialized };
312 	style::icon _msgBotKbPaymentIcon = { Qt::Uninitialized };
313 	style::icon _msgBotKbSwitchPmIcon = { Qt::Uninitialized };
314 	style::icon _historyFastCommentsIcon = { Qt::Uninitialized };
315 	style::icon _historyFastShareIcon = { Qt::Uninitialized };
316 	style::icon _historyGoToOriginalIcon = { Qt::Uninitialized };
317 	style::icon _historyMapPoint = { Qt::Uninitialized };
318 	style::icon _historyMapPointInner = { Qt::Uninitialized };
319 	style::icon _youtubeIcon = { Qt::Uninitialized };
320 	style::icon _videoIcon = { Qt::Uninitialized };
321 	style::icon _historyPollChoiceRight = { Qt::Uninitialized };
322 	style::icon _historyPollChoiceWrong = { Qt::Uninitialized };
323 
324 	rpl::event_stream<> _paletteChanged;
325 
326 	rpl::lifetime _defaultPaletteChangeLifetime;
327 
328 };
329 
330 void FillComplexOverlayRect(
331 	Painter &p,
332 	not_null<const ChatStyle*> st,
333 	QRect rect,
334 	ImageRoundRadius radius,
335 	RectParts roundCorners);
336 void FillComplexLocationRect(
337 	Painter &p,
338 	not_null<const ChatStyle*> st,
339 	QRect rect,
340 	ImageRoundRadius radius,
341 	RectParts roundCorners);
342 
343 } // namespace Ui
344