548 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			548 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| This file is part of Telegram Desktop,
 | |
| the official desktop application for the Telegram messaging service.
 | |
| 
 | |
| For license and copyright information please follow this link:
 | |
| https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | |
| */
 | |
| #pragma once
 | |
| 
 | |
| #include "ui/cached_round_corners.h"
 | |
| #include "ui/chat/message_bubble.h"
 | |
| #include "ui/chat/chat_style_radius.h"
 | |
| #include "ui/style/style_core_palette.h"
 | |
| #include "layout/layout_selection.h"
 | |
| #include "styles/style_basic.h"
 | |
| 
 | |
| enum class ImageRoundRadius;
 | |
| 
 | |
| namespace style {
 | |
| struct TwoIconButton;
 | |
| struct ScrollArea;
 | |
| } // namespace style
 | |
| 
 | |
| namespace Ui::Text {
 | |
| class CustomEmoji;
 | |
| } // namespace Ui::Text
 | |
| 
 | |
| namespace Ui {
 | |
| 
 | |
| class ChatTheme;
 | |
| class ChatStyle;
 | |
| struct BubblePattern;
 | |
| 
 | |
| inline constexpr auto kColorPatternsCount = Text::kMaxQuoteOutlines;
 | |
| inline constexpr auto kColorIndexCount = uint8(1 << 6);
 | |
| inline constexpr auto kSimpleColorIndexCount = uint8(7);
 | |
| 
 | |
| inline constexpr auto kDefaultBgOpacity = 0.12;
 | |
| inline constexpr auto kDefaultOutline1Opacity = 0.9;
 | |
| inline constexpr auto kDefaultOutline2Opacity = 0.3;
 | |
| inline constexpr auto kDefaultOutline3Opacity = 0.6;
 | |
| inline constexpr auto kDefaultOutlineOpacitySecond = 0.5;
 | |
| 
 | |
| struct MessageStyle {
 | |
| 	CornersPixmaps msgBgCornersSmall;
 | |
| 	CornersPixmaps msgBgCornersLarge;
 | |
| 	style::color msgBg;
 | |
| 	style::color msgShadow;
 | |
| 	style::color msgServiceFg;
 | |
| 	style::color msgDateFg;
 | |
| 	style::color msgFileThumbLinkFg;
 | |
| 	style::color msgFileBg;
 | |
| 	style::color msgReplyBarColor;
 | |
| 	style::color msgWaveformActive;
 | |
| 	style::color msgWaveformInactive;
 | |
| 	style::color historyTextFg;
 | |
| 	style::color historyFileNameFg;
 | |
| 	style::color historyFileRadialFg;
 | |
| 	style::color mediaFg;
 | |
| 	style::TextPalette textPalette;
 | |
| 	style::TextPalette semiboldPalette;
 | |
| 	style::TextPalette fwdTextPalette;
 | |
| 	style::TextPalette replyTextPalette;
 | |
| 	style::icon tailLeft = { Qt::Uninitialized };
 | |
| 	style::icon tailRight = { Qt::Uninitialized };
 | |
| 	style::icon historyRepliesIcon = { Qt::Uninitialized };
 | |
| 	style::icon historyViewsIcon = { Qt::Uninitialized };
 | |
| 	style::icon historyPinIcon = { Qt::Uninitialized };
 | |
| 	style::icon historySentIcon = { Qt::Uninitialized };
 | |
| 	style::icon historyReceivedIcon = { Qt::Uninitialized };
 | |
| 	style::icon historyPsaIcon = { Qt::Uninitialized };
 | |
| 	style::icon historyCommentsOpen = { Qt::Uninitialized };
 | |
| 	style::icon historyComments = { Qt::Uninitialized };
 | |
| 	style::icon historyCallArrow = { Qt::Uninitialized };
 | |
| 	style::icon historyCallArrowMissed = { Qt::Uninitialized };
 | |
| 	style::icon historyCallIcon = { Qt::Uninitialized };
 | |
| 	style::icon historyCallCameraIcon = { Qt::Uninitialized };
 | |
| 	style::icon historyFilePlay = { Qt::Uninitialized };
 | |
| 	style::icon historyFileWaiting = { Qt::Uninitialized };
 | |
| 	style::icon historyFileDownload = { Qt::Uninitialized };
 | |
| 	style::icon historyFileCancel = { Qt::Uninitialized };
 | |
| 	style::icon historyFilePause = { Qt::Uninitialized };
 | |
| 	style::icon historyFileImage = { Qt::Uninitialized };
 | |
| 	style::icon historyFileDocument = { Qt::Uninitialized };
 | |
| 	style::icon historyAudioDownload = { Qt::Uninitialized };
 | |
| 	style::icon historyAudioCancel = { Qt::Uninitialized };
 | |
| 	style::icon historyQuizTimer = { Qt::Uninitialized };
 | |
| 	style::icon historyQuizExplain = { Qt::Uninitialized };
 | |
| 	style::icon historyPollChosen = { Qt::Uninitialized };
 | |
| 	style::icon historyPollChoiceRight = { Qt::Uninitialized };
 | |
| 	style::icon historyTranscribeIcon = { Qt::Uninitialized };
 | |
| 	style::icon historyTranscribeHide = { Qt::Uninitialized };
 | |
| 	std::array<
 | |
| 		std::unique_ptr<Text::QuotePaintCache>,
 | |
| 		kColorPatternsCount> quoteCache;
 | |
| 	std::array<
 | |
| 		std::unique_ptr<Text::QuotePaintCache>,
 | |
| 		kColorPatternsCount> replyCache;
 | |
| 	std::unique_ptr<Text::QuotePaintCache> preCache;
 | |
| };
 | |
| 
 | |
| struct MessageImageStyle {
 | |
| 	CornersPixmaps msgDateImgBgCorners;
 | |
| 	CornersPixmaps msgServiceBgCornersSmall;
 | |
| 	CornersPixmaps msgServiceBgCornersLarge;
 | |
| 	CornersPixmaps msgShadowCornersSmall;
 | |
| 	CornersPixmaps msgShadowCornersLarge;
 | |
| 	style::color msgServiceBg;
 | |
| 	style::color msgDateImgBg;
 | |
| 	style::color msgShadow;
 | |
| 	style::color historyFileThumbRadialFg;
 | |
| 	style::icon historyFileThumbPlay = { Qt::Uninitialized };
 | |
| 	style::icon historyFileThumbWaiting = { Qt::Uninitialized };
 | |
| 	style::icon historyFileThumbDownload = { Qt::Uninitialized };
 | |
| 	style::icon historyFileThumbCancel = { Qt::Uninitialized };
 | |
| 	style::icon historyFileThumbPause = { Qt::Uninitialized };
 | |
| 	style::icon historyVideoDownload = { Qt::Uninitialized };
 | |
| 	style::icon historyVideoCancel = { Qt::Uninitialized };
 | |
| 	style::icon historyVideoMessageMute = { Qt::Uninitialized };
 | |
| };
 | |
| 
 | |
| struct ReactionPaintInfo {
 | |
| 	QPoint position;
 | |
| 	QPoint effectOffset;
 | |
| 	Fn<QRect(QPainter&)> effectPaint;
 | |
| };
 | |
| 
 | |
| struct BackgroundEmojiCache {
 | |
| 	QColor color;
 | |
| 	std::array<QImage, 3> frames;
 | |
| };
 | |
| 
 | |
| struct BackgroundEmojiData {
 | |
| 	std::unique_ptr<Text::CustomEmoji> emoji;
 | |
| 	QImage firstFrameMask;
 | |
| 	std::array<BackgroundEmojiCache, 2 * (3 + kColorIndexCount)> caches;
 | |
| 
 | |
| 	[[nodiscard]] static int CacheIndex(
 | |
| 		bool selected,
 | |
| 		bool outbg,
 | |
| 		bool inbubble,
 | |
| 		uint8 colorIndexPlusOne);
 | |
| };
 | |
| 
 | |
| struct ChatPaintHighlight {
 | |
| 	float64 opacity = 0.;
 | |
| 	float64 collapsion = 0.;
 | |
| 	TextSelection range;
 | |
| };
 | |
| 
 | |
| struct ChatPaintContext {
 | |
| 	not_null<const ChatStyle*> st;
 | |
| 	const BubblePattern *bubblesPattern = nullptr;
 | |
| 	ReactionPaintInfo *reactionInfo = nullptr;
 | |
| 	QRect viewport;
 | |
| 	QRect clip;
 | |
| 	TextSelection selection;
 | |
| 	ChatPaintHighlight highlight;
 | |
| 	QPainterPath *highlightPathCache = nullptr;
 | |
| 	mutable QRect highlightInterpolateTo;
 | |
| 	crl::time now = 0;
 | |
| 
 | |
| 	void translate(int x, int y) {
 | |
| 		viewport.translate(x, y);
 | |
| 		clip.translate(x, y);
 | |
| 		highlightInterpolateTo.translate(x, y);
 | |
| 	}
 | |
| 	void translate(QPoint point) {
 | |
| 		translate(point.x(), point.y());
 | |
| 	}
 | |
| 
 | |
| 	[[nodiscard]] bool selected() const {
 | |
| 		return (selection == FullSelection);
 | |
| 	}
 | |
| 	[[nodiscard]] not_null<const MessageStyle*> messageStyle() const;
 | |
| 	[[nodiscard]] not_null<const MessageImageStyle*> imageStyle() const;
 | |
| 	[[nodiscard]] not_null<Text::QuotePaintCache*> quoteCache(
 | |
| 		uint8 colorIndex) const;
 | |
| 
 | |
| 	[[nodiscard]] ChatPaintContext translated(int x, int y) const {
 | |
| 		auto result = *this;
 | |
| 		result.translate(x, y);
 | |
| 		return result;
 | |
| 	}
 | |
| 	[[nodiscard]] ChatPaintContext translated(QPoint point) const {
 | |
| 		return translated(point.x(), point.y());
 | |
| 	}
 | |
| 	[[nodiscard]] ChatPaintContext withSelection(
 | |
| 			TextSelection selection) const {
 | |
| 		auto result = *this;
 | |
| 		result.selection = selection;
 | |
| 		return result;
 | |
| 	}
 | |
| 	[[nodiscard]] auto computeHighlightCache() const
 | |
| 	-> std::optional<Ui::Text::HighlightInfoRequest> {
 | |
| 		if (highlight.range.empty() || highlight.collapsion <= 0.) {
 | |
| 			return {};
 | |
| 		}
 | |
| 		return Ui::Text::HighlightInfoRequest{
 | |
| 			.range = highlight.range,
 | |
| 			.interpolateTo = highlightInterpolateTo,
 | |
| 			.interpolateProgress = (1. - highlight.collapsion),
 | |
| 			.outPath = highlightPathCache,
 | |
| 		};
 | |
| 	};
 | |
| 
 | |
| 
 | |
| 	// This is supported only in unwrapped media for now.
 | |
| 	enum class SkipDrawingParts {
 | |
| 		None,
 | |
| 		Content,
 | |
| 		Surrounding,
 | |
| 	};
 | |
| 	SkipDrawingParts skipDrawingParts = SkipDrawingParts::None;
 | |
| 
 | |
| 	bool outbg = false;
 | |
| 	bool paused = false;
 | |
| 
 | |
| };
 | |
| 
 | |
| [[nodiscard]] int HistoryServiceMsgRadius();
 | |
| [[nodiscard]] int HistoryServiceMsgInvertedRadius();
 | |
| [[nodiscard]] int HistoryServiceMsgInvertedShrink();
 | |
| 
 | |
| struct ColorIndexData {
 | |
| 	std::array<uint32, kColorPatternsCount> light = {};
 | |
| 	std::array<uint32, kColorPatternsCount> dark = {};
 | |
| 
 | |
| 	friend inline bool operator==(
 | |
| 		const ColorIndexData&,
 | |
| 		const ColorIndexData&) = default;
 | |
| };
 | |
| 
 | |
| struct ColorIndicesCompressed {
 | |
| 	std::shared_ptr<std::array<ColorIndexData, kColorIndexCount>> colors;
 | |
| };
 | |
| 
 | |
| struct ColorIndexValues {
 | |
| 	std::array<QColor, kColorPatternsCount> outlines;
 | |
| 	QColor name;
 | |
| 	QColor bg;
 | |
| };
 | |
| 
 | |
| class ChatStyle final : public style::palette {
 | |
| public:
 | |
| 	explicit ChatStyle(rpl::producer<ColorIndicesCompressed> colorIndices);
 | |
| 	explicit ChatStyle(not_null<const style::palette*> isolated);
 | |
| 	ChatStyle(const ChatStyle &other) = delete;
 | |
| 	ChatStyle &operator=(const ChatStyle &other) = delete;
 | |
| 	~ChatStyle();
 | |
| 
 | |
| 	void apply(not_null<ChatTheme*> theme);
 | |
| 	void applyCustomPalette(const style::palette *palette);
 | |
| 	void applyAdjustedServiceBg(QColor serviceBg);
 | |
| 
 | |
| 	[[nodiscard]] bool dark() const {
 | |
| 		return _dark;
 | |
| 	}
 | |
| 
 | |
| 	[[nodiscard]] std::span<Text::SpecialColor> highlightColors() const;
 | |
| 
 | |
| 	[[nodiscard]] rpl::producer<> paletteChanged() const {
 | |
| 		return _paletteChanged.events();
 | |
| 	}
 | |
| 
 | |
| 	template <typename Type>
 | |
| 	[[nodiscard]] Type value(const Type &original) const {
 | |
| 		auto my = Type();
 | |
| 		make(my, original);
 | |
| 		return my;
 | |
| 	}
 | |
| 
 | |
| 	template <typename Type>
 | |
| 	[[nodiscard]] const Type &value(
 | |
| 			rpl::lifetime &parentLifetime,
 | |
| 			const Type &original) const {
 | |
| 		const auto my = parentLifetime.make_state<Type>();
 | |
| 		make(*my, original);
 | |
| 		return *my;
 | |
| 	}
 | |
| 
 | |
| 	[[nodiscard]] const CornersPixmaps &serviceBgCornersNormal() const;
 | |
| 	[[nodiscard]] const CornersPixmaps &serviceBgCornersInverted() const;
 | |
| 
 | |
| 	[[nodiscard]] const MessageStyle &messageStyle(
 | |
| 		bool outbg,
 | |
| 		bool selected) const;
 | |
| 	[[nodiscard]] const MessageImageStyle &imageStyle(bool selected) const;
 | |
| 
 | |
| 	[[nodiscard]] int colorPatternIndex(uint8 colorIndex) const;
 | |
| 	[[nodiscard]] ColorIndexValues computeColorIndexValues(
 | |
| 		bool selected,
 | |
| 		uint8 colorIndex) const;
 | |
| 
 | |
| 	[[nodiscard]] auto serviceQuoteCache(bool twoColored) const
 | |
| 		-> not_null<Text::QuotePaintCache*>;
 | |
| 	[[nodiscard]] auto serviceReplyCache(bool twoColored) const
 | |
| 		-> not_null<Text::QuotePaintCache*>;
 | |
| 	[[nodiscard]] const ColorIndexValues &coloredValues(
 | |
| 		bool selected,
 | |
| 		uint8 colorIndex) const;
 | |
| 	[[nodiscard]] not_null<Text::QuotePaintCache*> coloredQuoteCache(
 | |
| 		bool selected,
 | |
| 		uint8 colorIndex) const;
 | |
| 	[[nodiscard]] not_null<Text::QuotePaintCache*> coloredReplyCache(
 | |
| 		bool selected,
 | |
| 		uint8 colorIndex) const;
 | |
| 
 | |
| 	[[nodiscard]] const style::TextPalette &coloredTextPalette(
 | |
| 		bool selected,
 | |
| 		uint8 colorIndex) const;
 | |
| 
 | |
| 	[[nodiscard]] not_null<BackgroundEmojiData*> backgroundEmojiData(
 | |
| 		uint64 id) const;
 | |
| 
 | |
| 	[[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCornersSmall() const;
 | |
| 	[[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCornersLarge() const;
 | |
| 	[[nodiscard]] const CornersPixmaps &msgSelectOverlayCorners(
 | |
| 		CachedCornerRadius radius) const;
 | |
| 
 | |
| 	[[nodiscard]] const style::TextPalette &historyPsaForwardPalette() const {
 | |
| 		return _historyPsaForwardPalette;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::TextPalette &imgReplyTextPalette() const {
 | |
| 		return _imgReplyTextPalette;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::TextPalette &serviceTextPalette() const {
 | |
| 		return _serviceTextPalette;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyRepliesInvertedIcon() const {
 | |
| 		return _historyRepliesInvertedIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyViewsInvertedIcon() const {
 | |
| 		return _historyViewsInvertedIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyViewsSendingIcon() const {
 | |
| 		return _historyViewsSendingIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyViewsSendingInvertedIcon() const {
 | |
| 		return _historyViewsSendingInvertedIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyPinInvertedIcon() const {
 | |
| 		return _historyPinInvertedIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historySendingIcon() const {
 | |
| 		return _historySendingIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historySendingInvertedIcon() const {
 | |
| 		return _historySendingInvertedIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historySentInvertedIcon() const {
 | |
| 		return _historySentInvertedIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyReceivedInvertedIcon() const {
 | |
| 		return _historyReceivedInvertedIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &msgBotKbUrlIcon() const {
 | |
| 		return _msgBotKbUrlIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &msgBotKbPaymentIcon() const {
 | |
| 		return _msgBotKbPaymentIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &msgBotKbSwitchPmIcon() const {
 | |
| 		return _msgBotKbSwitchPmIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &msgBotKbWebviewIcon() const {
 | |
| 		return _msgBotKbWebviewIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyFastCommentsIcon() const {
 | |
| 		return _historyFastCommentsIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyFastShareIcon() const {
 | |
| 		return _historyFastShareIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyFastTranscribeIcon() const {
 | |
| 		return _historyFastTranscribeIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyGoToOriginalIcon() const {
 | |
| 		return _historyGoToOriginalIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyMapPoint() const {
 | |
| 		return _historyMapPoint;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyMapPointInner() const {
 | |
| 		return _historyMapPointInner;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &youtubeIcon() const {
 | |
| 		return _youtubeIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &videoIcon() const {
 | |
| 		return _videoIcon;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyPollChoiceRight() const {
 | |
| 		return _historyPollChoiceRight;
 | |
| 	}
 | |
| 	[[nodiscard]] const style::icon &historyPollChoiceWrong() const {
 | |
| 		return _historyPollChoiceWrong;
 | |
| 	}
 | |
| 
 | |
| private:
 | |
| 	using ColoredQuotePaintCaches = std::array<
 | |
| 		std::unique_ptr<Text::QuotePaintCache>,
 | |
| 		kColorIndexCount * 2>;
 | |
| 
 | |
| 	struct ColoredPalette {
 | |
| 		std::optional<style::owned_color> linkFg;
 | |
| 		style::TextPalette data;
 | |
| 	};
 | |
| 
 | |
| 	void assignPalette(not_null<const style::palette*> palette);
 | |
| 	void clearColorIndexCaches();
 | |
| 	void updateDarkValue();
 | |
| 
 | |
| 	[[nodiscard]] not_null<Text::QuotePaintCache*> coloredCache(
 | |
| 		ColoredQuotePaintCaches &caches,
 | |
| 		bool selected,
 | |
| 		uint8 colorIndex) const;
 | |
| 
 | |
| 	void make(style::color &my, const style::color &original) const;
 | |
| 	void make(style::icon &my, const style::icon &original) const;
 | |
| 	void make(
 | |
| 		style::TextPalette &my,
 | |
| 		const style::TextPalette &original) const;
 | |
| 	void make(
 | |
| 		style::TwoIconButton &my,
 | |
| 		const style::TwoIconButton &original) const;
 | |
| 	void make(
 | |
| 		style::ScrollArea &my,
 | |
| 		const style::ScrollArea &original) const;
 | |
| 
 | |
| 	[[nodiscard]] MessageStyle &messageStyleRaw(
 | |
| 		bool outbg,
 | |
| 		bool selected) const;
 | |
| 	[[nodiscard]] MessageStyle &messageIn();
 | |
| 	[[nodiscard]] MessageStyle &messageInSelected();
 | |
| 	[[nodiscard]] MessageStyle &messageOut();
 | |
| 	[[nodiscard]] MessageStyle &messageOutSelected();
 | |
| 
 | |
| 	[[nodiscard]] MessageImageStyle &imageStyleRaw(bool selected) const;
 | |
| 	[[nodiscard]] MessageImageStyle &image();
 | |
| 	[[nodiscard]] MessageImageStyle &imageSelected();
 | |
| 
 | |
| 	template <typename Type>
 | |
| 	void make(
 | |
| 		Type MessageStyle::*my,
 | |
| 		const Type &originalIn,
 | |
| 		const Type &originalInSelected,
 | |
| 		const Type &originalOut,
 | |
| 		const Type &originalOutSelected);
 | |
| 
 | |
| 	template <typename Type>
 | |
| 	void make(
 | |
| 		Type MessageImageStyle::*my,
 | |
| 		const Type &original,
 | |
| 		const Type &originalSelected);
 | |
| 
 | |
| 	mutable CornersPixmaps _serviceBgCornersNormal;
 | |
| 	mutable CornersPixmaps _serviceBgCornersInverted;
 | |
| 
 | |
| 	mutable std::array<MessageStyle, 4> _messageStyles;
 | |
| 	mutable std::array<MessageImageStyle, 2> _imageStyles;
 | |
| 
 | |
| 	mutable CornersPixmaps _msgBotKbOverBgAddCornersSmall;
 | |
| 	mutable CornersPixmaps _msgBotKbOverBgAddCornersLarge;
 | |
| 	mutable CornersPixmaps _msgSelectOverlayCorners[
 | |
| 		int(CachedCornerRadius::kCount)];
 | |
| 
 | |
| 	mutable std::vector<Text::SpecialColor> _highlightColors;
 | |
| 	mutable std::array<
 | |
| 		std::unique_ptr<Text::QuotePaintCache>,
 | |
| 		2> _serviceQuoteCache;
 | |
| 	mutable std::array<
 | |
| 		std::unique_ptr<Text::QuotePaintCache>,
 | |
| 		2> _serviceReplyCache;
 | |
| 	mutable std::array<
 | |
| 		std::optional<ColorIndexValues>,
 | |
| 		2 * kColorIndexCount> _coloredValues;
 | |
| 	mutable ColoredQuotePaintCaches _coloredQuoteCaches;
 | |
| 	mutable ColoredQuotePaintCaches _coloredReplyCaches;
 | |
| 	mutable std::array<
 | |
| 		ColoredPalette,
 | |
| 		2 * kColorIndexCount> _coloredTextPalettes;
 | |
| 	mutable base::flat_map<uint64, BackgroundEmojiData> _backgroundEmojis;
 | |
| 
 | |
| 	style::TextPalette _historyPsaForwardPalette;
 | |
| 	style::TextPalette _imgReplyTextPalette;
 | |
| 	style::TextPalette _serviceTextPalette;
 | |
| 	style::icon _historyRepliesInvertedIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyViewsInvertedIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyViewsSendingIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyViewsSendingInvertedIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyPinInvertedIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historySendingIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historySendingInvertedIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historySentInvertedIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyReceivedInvertedIcon = { Qt::Uninitialized };
 | |
| 	style::icon _msgBotKbUrlIcon = { Qt::Uninitialized };
 | |
| 	style::icon _msgBotKbPaymentIcon = { Qt::Uninitialized };
 | |
| 	style::icon _msgBotKbSwitchPmIcon = { Qt::Uninitialized };
 | |
| 	style::icon _msgBotKbWebviewIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyFastCommentsIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyFastShareIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyFastTranscribeIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyGoToOriginalIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyMapPoint = { Qt::Uninitialized };
 | |
| 	style::icon _historyMapPointInner = { Qt::Uninitialized };
 | |
| 	style::icon _youtubeIcon = { Qt::Uninitialized };
 | |
| 	style::icon _videoIcon = { Qt::Uninitialized };
 | |
| 	style::icon _historyPollChoiceRight = { Qt::Uninitialized };
 | |
| 	style::icon _historyPollChoiceWrong = { Qt::Uninitialized };
 | |
| 
 | |
| 	ColorIndicesCompressed _colorIndices;
 | |
| 
 | |
| 	bool _dark = false;
 | |
| 
 | |
| 	rpl::event_stream<> _paletteChanged;
 | |
| 
 | |
| 	rpl::lifetime _defaultPaletteChangeLifetime;
 | |
| 	rpl::lifetime _colorIndicesLifetime;
 | |
| 
 | |
| };
 | |
| 
 | |
| [[nodiscard]] uint8 DecideColorIndex(uint64 id);
 | |
| [[nodiscard]] uint8 ColorIndexToPaletteIndex(uint8 colorIndex);
 | |
| 
 | |
| [[nodiscard]] QColor FromNameFg(
 | |
| 	not_null<const ChatStyle*> st,
 | |
| 	bool selected,
 | |
| 	uint8 colorIndex);
 | |
| 
 | |
| [[nodiscard]] inline QColor FromNameFg(
 | |
| 		const ChatPaintContext &context,
 | |
| 		uint8 colorIndex) {
 | |
| 	return FromNameFg(context.st, context.selected(), colorIndex);
 | |
| }
 | |
| 
 | |
| void FillComplexOverlayRect(
 | |
| 	QPainter &p,
 | |
| 	QRect rect,
 | |
| 	const style::color &color,
 | |
| 	const CornersPixmaps &corners);
 | |
| 
 | |
| void FillComplexEllipse(
 | |
| 	QPainter &p,
 | |
| 	not_null<const ChatStyle*> st,
 | |
| 	QRect rect);
 | |
| 
 | |
| } // namespace Ui
 | 
