149 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
	
		
			3.6 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
 | |
| 
 | |
| namespace Ui {
 | |
| 
 | |
| class ChatTheme;
 | |
| class ChatStyle;
 | |
| 
 | |
| enum class BubbleCornerRounding : uchar {
 | |
| 	None,
 | |
| 	Tail,
 | |
| 	Small,
 | |
| 	Large,
 | |
| };
 | |
| 
 | |
| struct BubbleRounding {
 | |
| 	BubbleCornerRounding topLeft : 2 = BubbleCornerRounding();
 | |
| 	BubbleCornerRounding topRight : 2 = BubbleCornerRounding();
 | |
| 	BubbleCornerRounding bottomLeft : 2 = BubbleCornerRounding();
 | |
| 	BubbleCornerRounding bottomRight : 2 = BubbleCornerRounding();
 | |
| 
 | |
| 	struct ConstProxy {
 | |
| 		constexpr ConstProxy(
 | |
| 			not_null<const BubbleRounding*> that,
 | |
| 			int index) noexcept
 | |
| 		: that(that)
 | |
| 		, index(index) {
 | |
| 			Expects(index >= 0 && index < 4);
 | |
| 		}
 | |
| 
 | |
| 		constexpr operator BubbleCornerRounding() const noexcept {
 | |
| 			switch (index) {
 | |
| 			case 0: return that->topLeft;
 | |
| 			case 1: return that->topRight;
 | |
| 			case 2: return that->bottomLeft;
 | |
| 			case 3: return that->bottomRight;
 | |
| 			}
 | |
| 			Unexpected("Index value in BubbleRounding::ConstProxy.");
 | |
| 		}
 | |
| 
 | |
| 		not_null<const BubbleRounding*> that;
 | |
| 		int index = 0;
 | |
| 	};
 | |
| 	struct Proxy : ConstProxy {
 | |
| 		constexpr Proxy(not_null<BubbleRounding*> that, int index) noexcept
 | |
| 		: ConstProxy(that, index) {
 | |
| 		}
 | |
| 
 | |
| 		using ConstProxy::operator BubbleCornerRounding;
 | |
| 
 | |
| 		constexpr Proxy &operator=(BubbleCornerRounding value) noexcept {
 | |
| 			const auto nonconst = const_cast<BubbleRounding*>(that.get());
 | |
| 			switch (index) {
 | |
| 			case 0: nonconst->topLeft = value; break;
 | |
| 			case 1: nonconst->topRight = value; break;
 | |
| 			case 2: nonconst->bottomLeft = value; break;
 | |
| 			case 3: nonconst->bottomRight = value; break;
 | |
| 			}
 | |
| 			return *this;
 | |
| 		}
 | |
| 	};
 | |
| 	[[nodiscard]] constexpr ConstProxy operator[](int index) const {
 | |
| 		return { this, index };
 | |
| 	}
 | |
| 	[[nodiscard]] constexpr Proxy operator[](int index) {
 | |
| 		return { this, index };
 | |
| 	}
 | |
| 
 | |
| 	[[nodiscard]] uchar key() const {
 | |
| 		static_assert(sizeof(*this) == sizeof(uchar));
 | |
| 		return uchar(*reinterpret_cast<const std::byte*>(this));
 | |
| 	}
 | |
| 
 | |
| 	inline friend constexpr auto operator<=>(
 | |
| 		BubbleRounding,
 | |
| 		BubbleRounding) = default;
 | |
| };
 | |
| 
 | |
| struct BubbleSelectionInterval {
 | |
| 	int top = 0;
 | |
| 	int height = 0;
 | |
| };
 | |
| 
 | |
| struct BubblePattern {
 | |
| 	QPixmap pixmap;
 | |
| 	std::array<QImage, 4> cornersSmall;
 | |
| 	std::array<QImage, 4> cornersLarge;
 | |
| 	QImage tailLeft;
 | |
| 	QImage tailRight;
 | |
| 	mutable QImage cornerTopSmallCache;
 | |
| 	mutable QImage cornerTopLargeCache;
 | |
| 	mutable QImage cornerBottomSmallCache;
 | |
| 	mutable QImage cornerBottomLargeCache;
 | |
| 	mutable QImage tailCache;
 | |
| };
 | |
| 
 | |
| [[nodiscard]] std::unique_ptr<BubblePattern> PrepareBubblePattern(
 | |
| 	not_null<const style::palette*> st);
 | |
| void FinishBubblePatternOnMain(not_null<BubblePattern*> pattern);
 | |
| 
 | |
| struct SimpleBubble {
 | |
| 	not_null<const ChatStyle*> st;
 | |
| 	QRect geometry;
 | |
| 	const BubblePattern *pattern = nullptr;
 | |
| 	QRect patternViewport;
 | |
| 	int outerWidth = 0;
 | |
| 	bool selected = false;
 | |
| 	bool shadowed = true;
 | |
| 	bool outbg = false;
 | |
| 	BubbleRounding rounding;
 | |
| };
 | |
| 
 | |
| struct ComplexBubble {
 | |
| 	SimpleBubble simple;
 | |
| 	const std::vector<BubbleSelectionInterval> &selection;
 | |
| };
 | |
| 
 | |
| void PaintBubble(QPainter &p, const SimpleBubble &args);
 | |
| void PaintBubble(QPainter &p, const ComplexBubble &args);
 | |
| 
 | |
| void PaintPatternBubblePart(
 | |
| 	QPainter &p,
 | |
| 	const QRect &viewport,
 | |
| 	const QPixmap &pixmap,
 | |
| 	const QRect &target);
 | |
| 
 | |
| void PaintPatternBubblePart(
 | |
| 	QPainter &p,
 | |
| 	const QRect &viewport,
 | |
| 	const QPixmap &pixmap,
 | |
| 	const QRect &target,
 | |
| 	const QImage &mask,
 | |
| 	QImage &cache);
 | |
| 
 | |
| void PaintPatternBubblePart(
 | |
| 	QPainter &p,
 | |
| 	const QRect &viewport,
 | |
| 	const QPixmap &pixmap,
 | |
| 	const QRect &target,
 | |
| 	Fn<void(QPainter&)> paintContent,
 | |
| 	QImage &cache);
 | |
| 
 | |
| } // namespace Ui
 | 
