Refactor icon unread counter painting.
This commit is contained in:
		
							parent
							
								
									87af865604
								
							
						
					
					
						commit
						aef45b3a1d
					
				
					 15 changed files with 300 additions and 258 deletions
				
			
		| 
						 | 
					@ -141,12 +141,7 @@ Application::Application(not_null<Launcher*> launcher)
 | 
				
			||||||
, _langpack(std::make_unique<Lang::Instance>())
 | 
					, _langpack(std::make_unique<Lang::Instance>())
 | 
				
			||||||
, _langCloudManager(std::make_unique<Lang::CloudManager>(langpack()))
 | 
					, _langCloudManager(std::make_unique<Lang::CloudManager>(langpack()))
 | 
				
			||||||
, _emojiKeywords(std::make_unique<ChatHelpers::EmojiKeywords>())
 | 
					, _emojiKeywords(std::make_unique<ChatHelpers::EmojiKeywords>())
 | 
				
			||||||
, _logo(Window::LoadLogo())
 | 
					 | 
				
			||||||
, _logoNoMargin(Window::LoadLogoNoMargin())
 | 
					 | 
				
			||||||
, _autoLockTimer([=] { checkAutoLock(); }) {
 | 
					, _autoLockTimer([=] { checkAutoLock(); }) {
 | 
				
			||||||
	Expects(!_logo.isNull());
 | 
					 | 
				
			||||||
	Expects(!_logoNoMargin.isNull());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Ui::Integration::Set(&_private->uiIntegration);
 | 
						Ui::Integration::Set(&_private->uiIntegration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	passcodeLockChanges(
 | 
						passcodeLockChanges(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,12 +145,6 @@ public:
 | 
				
			||||||
	bool hideMediaView();
 | 
						bool hideMediaView();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] QPoint getPointForCallPanelCenter() const;
 | 
						[[nodiscard]] QPoint getPointForCallPanelCenter() const;
 | 
				
			||||||
	[[nodiscard]] QImage logo() const {
 | 
					 | 
				
			||||||
		return _logo;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	[[nodiscard]] QImage logoNoMargin() const {
 | 
					 | 
				
			||||||
		return _logoNoMargin;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void startSettingsAndBackground();
 | 
						void startSettingsAndBackground();
 | 
				
			||||||
	[[nodiscard]] Settings &settings() {
 | 
						[[nodiscard]] Settings &settings() {
 | 
				
			||||||
| 
						 | 
					@ -354,9 +348,6 @@ private:
 | 
				
			||||||
	Media::Player::FloatDelegate *_defaultFloatPlayerDelegate = nullptr;
 | 
						Media::Player::FloatDelegate *_defaultFloatPlayerDelegate = nullptr;
 | 
				
			||||||
	Media::Player::FloatDelegate *_replacementFloatPlayerDelegate = nullptr;
 | 
						Media::Player::FloatDelegate *_replacementFloatPlayerDelegate = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const QImage _logo;
 | 
					 | 
				
			||||||
	const QImage _logoNoMargin;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rpl::variable<bool> _passcodeLock;
 | 
						rpl::variable<bool> _passcodeLock;
 | 
				
			||||||
	bool _screenIsLocked = false;
 | 
						bool _screenIsLocked = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "core/application.h"
 | 
					#include "core/application.h"
 | 
				
			||||||
#include "core/click_handler_types.h"
 | 
					#include "core/click_handler_types.h"
 | 
				
			||||||
#include "window/window_session_controller.h"
 | 
					#include "window/window_session_controller.h"
 | 
				
			||||||
 | 
					#include "window/main_window.h" // Window::LogoNoMargin.
 | 
				
			||||||
#include "ui/image/image.h"
 | 
					#include "ui/image/image.h"
 | 
				
			||||||
#include "ui/empty_userpic.h"
 | 
					#include "ui/empty_userpic.h"
 | 
				
			||||||
#include "ui/text/text_options.h"
 | 
					#include "ui/text/text_options.h"
 | 
				
			||||||
| 
						 | 
					@ -302,7 +303,7 @@ Image *PeerData::currentUserpic(
 | 
				
			||||||
		_userpicEmpty = nullptr;
 | 
							_userpicEmpty = nullptr;
 | 
				
			||||||
	} else if (isNotificationsUser()) {
 | 
						} else if (isNotificationsUser()) {
 | 
				
			||||||
		static auto result = Image(
 | 
							static auto result = Image(
 | 
				
			||||||
			Core::App().logoNoMargin().scaledToWidth(
 | 
								Window::LogoNoMargin().scaledToWidth(
 | 
				
			||||||
				kUserpicSize,
 | 
									kUserpicSize,
 | 
				
			||||||
				Qt::SmoothTransformation));
 | 
									Qt::SmoothTransformation));
 | 
				
			||||||
		return &result;
 | 
							return &result;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,17 +81,6 @@ void FeedLangTestingKey(int key) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MainWindow::MainWindow(not_null<Window::Controller*> controller)
 | 
					MainWindow::MainWindow(not_null<Window::Controller*> controller)
 | 
				
			||||||
: Platform::MainWindow(controller) {
 | 
					: Platform::MainWindow(controller) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto logo = Core::App().logo();
 | 
					 | 
				
			||||||
	icon16 = logo.scaledToWidth(16, Qt::SmoothTransformation);
 | 
					 | 
				
			||||||
	icon32 = logo.scaledToWidth(32, Qt::SmoothTransformation);
 | 
					 | 
				
			||||||
	icon64 = logo.scaledToWidth(64, Qt::SmoothTransformation);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto logoNoMargin = Core::App().logoNoMargin();
 | 
					 | 
				
			||||||
	iconbig16 = logoNoMargin.scaledToWidth(16, Qt::SmoothTransformation);
 | 
					 | 
				
			||||||
	iconbig32 = logoNoMargin.scaledToWidth(32, Qt::SmoothTransformation);
 | 
					 | 
				
			||||||
	iconbig64 = logoNoMargin.scaledToWidth(64, Qt::SmoothTransformation);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	resize(st::windowDefaultWidth, st::windowDefaultHeight);
 | 
						resize(st::windowDefaultWidth, st::windowDefaultHeight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
 | 
						setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
 | 
				
			||||||
| 
						 | 
					@ -842,122 +831,6 @@ void MainWindow::updateControlsGeometry() {
 | 
				
			||||||
	if (_main) _main->checkMainSectionToLayer();
 | 
						if (_main) _main->checkMainSectionToLayer();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) {
 | 
					 | 
				
			||||||
	QPainter p(&img);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 10, 1, 10, QChar('0'));
 | 
					 | 
				
			||||||
	int32 cntSize = cnt.size();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p.setBrush(bg->b);
 | 
					 | 
				
			||||||
	p.setPen(Qt::NoPen);
 | 
					 | 
				
			||||||
	p.setRenderHint(QPainter::Antialiasing);
 | 
					 | 
				
			||||||
	int32 fontSize;
 | 
					 | 
				
			||||||
	if (size == 16) {
 | 
					 | 
				
			||||||
		fontSize = 8;
 | 
					 | 
				
			||||||
	} else if (size == 32) {
 | 
					 | 
				
			||||||
		fontSize = (cntSize < 2) ? 12 : 12;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		fontSize = (cntSize < 2) ? 22 : 22;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	style::font f = { fontSize, 0, 0 };
 | 
					 | 
				
			||||||
	int32 w = f->width(cnt), d, r;
 | 
					 | 
				
			||||||
	if (size == 16) {
 | 
					 | 
				
			||||||
		d = (cntSize < 2) ? 2 : 1;
 | 
					 | 
				
			||||||
		r = (cntSize < 2) ? 4 : 3;
 | 
					 | 
				
			||||||
	} else if (size == 32) {
 | 
					 | 
				
			||||||
		d = (cntSize < 2) ? 5 : 2;
 | 
					 | 
				
			||||||
		r = (cntSize < 2) ? 8 : 7;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		d = (cntSize < 2) ? 9 : 4;
 | 
					 | 
				
			||||||
		r = (cntSize < 2) ? 16 : 14;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	p.drawRoundedRect(QRect(shift.x() + size - w - d * 2, shift.y() + size - f->height, w + d * 2, f->height), r, r);
 | 
					 | 
				
			||||||
	p.setFont(f->f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p.setPen(color->p);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p.drawText(shift.x() + size - w - d, shift.y() + size - f->height + f->ascent, cnt);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QImage MainWindow::iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) {
 | 
					 | 
				
			||||||
	bool layer = false;
 | 
					 | 
				
			||||||
	if (size < 0) {
 | 
					 | 
				
			||||||
		size = -size;
 | 
					 | 
				
			||||||
		layer = true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (layer) {
 | 
					 | 
				
			||||||
		if (size != 16 && size != 20 && size != 24) size = 32;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// platform/linux/main_window_linux depends on count used the same
 | 
					 | 
				
			||||||
		// way for all the same (count % 1000) values.
 | 
					 | 
				
			||||||
		QString cnt = (count < 1000) ? QString("%1").arg(count) : QString("..%1").arg(count % 100, 2, 10, QChar('0'));
 | 
					 | 
				
			||||||
		QImage result(size, size, QImage::Format_ARGB32);
 | 
					 | 
				
			||||||
		int32 cntSize = cnt.size();
 | 
					 | 
				
			||||||
		result.fill(Qt::transparent);
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			QPainter p(&result);
 | 
					 | 
				
			||||||
			p.setBrush(bg);
 | 
					 | 
				
			||||||
			p.setPen(Qt::NoPen);
 | 
					 | 
				
			||||||
			p.setRenderHint(QPainter::Antialiasing);
 | 
					 | 
				
			||||||
			int32 fontSize;
 | 
					 | 
				
			||||||
			if (size == 16) {
 | 
					 | 
				
			||||||
				fontSize = (cntSize < 2) ? 11 : ((cntSize < 3) ? 11 : 8);
 | 
					 | 
				
			||||||
			} else if (size == 20) {
 | 
					 | 
				
			||||||
				fontSize = (cntSize < 2) ? 14 : ((cntSize < 3) ? 13 : 10);
 | 
					 | 
				
			||||||
			} else if (size == 24) {
 | 
					 | 
				
			||||||
				fontSize = (cntSize < 2) ? 17 : ((cntSize < 3) ? 16 : 12);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				fontSize = (cntSize < 2) ? 22 : ((cntSize < 3) ? 20 : 16);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			style::font f = { fontSize, 0, 0 };
 | 
					 | 
				
			||||||
			int32 w = f->width(cnt), d, r;
 | 
					 | 
				
			||||||
			if (size == 16) {
 | 
					 | 
				
			||||||
				d = (cntSize < 2) ? 5 : ((cntSize < 3) ? 2 : 1);
 | 
					 | 
				
			||||||
				r = (cntSize < 2) ? 8 : ((cntSize < 3) ? 7 : 3);
 | 
					 | 
				
			||||||
			} else if (size == 20) {
 | 
					 | 
				
			||||||
				d = (cntSize < 2) ? 6 : ((cntSize < 3) ? 2 : 1);
 | 
					 | 
				
			||||||
				r = (cntSize < 2) ? 10 : ((cntSize < 3) ? 9 : 5);
 | 
					 | 
				
			||||||
			} else if (size == 24) {
 | 
					 | 
				
			||||||
				d = (cntSize < 2) ? 7 : ((cntSize < 3) ? 3 : 1);
 | 
					 | 
				
			||||||
				r = (cntSize < 2) ? 12 : ((cntSize < 3) ? 11 : 6);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				d = (cntSize < 2) ? 9 : ((cntSize < 3) ? 4 : 2);
 | 
					 | 
				
			||||||
				r = (cntSize < 2) ? 16 : ((cntSize < 3) ? 14 : 8);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			p.drawRoundedRect(QRect(size - w - d * 2, size - f->height, w + d * 2, f->height), r, r);
 | 
					 | 
				
			||||||
			p.setFont(f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			p.setPen(fg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			p.drawText(size - w - d, size - f->height + f->ascent, cnt);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return result;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if (size != 16 && size != 32) size = 64;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QImage img(smallIcon ? ((size == 16) ? iconbig16 : (size == 32 ? iconbig32 : iconbig64)) : ((size == 16) ? icon16 : (size == 32 ? icon32 : icon64)));
 | 
					 | 
				
			||||||
	if (const auto controller = sessionController()) {
 | 
					 | 
				
			||||||
		if (controller->session().supportMode()) {
 | 
					 | 
				
			||||||
			Window::ConvertIconToBlack(img);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!count) return img;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (smallIcon) {
 | 
					 | 
				
			||||||
		placeSmallCounter(img, size, count, bg, QPoint(), fg);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		QPainter p(&img);
 | 
					 | 
				
			||||||
		p.drawPixmap(
 | 
					 | 
				
			||||||
			size / 2,
 | 
					 | 
				
			||||||
			size / 2,
 | 
					 | 
				
			||||||
			Ui::PixmapFromImage(
 | 
					 | 
				
			||||||
				iconWithCounter(-size / 2, count, bg, fg, false)));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return img;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MainWindow::sendPaths() {
 | 
					void MainWindow::sendPaths() {
 | 
				
			||||||
	if (controller().locked()) {
 | 
						if (controller().locked()) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,9 +71,6 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void sendPaths();
 | 
						void sendPaths();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
 | 
					 | 
				
			||||||
	void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool contentOverlapped(const QRect &globalRect);
 | 
						bool contentOverlapped(const QRect &globalRect);
 | 
				
			||||||
	bool contentOverlapped(QWidget *w, QPaintEvent *e) {
 | 
						bool contentOverlapped(QWidget *w, QPaintEvent *e) {
 | 
				
			||||||
		return contentOverlapped(QRect(w->mapToGlobal(e->rect().topLeft()), e->rect().size()));
 | 
							return contentOverlapped(QRect(w->mapToGlobal(e->rect().topLeft()), e->rect().size()));
 | 
				
			||||||
| 
						 | 
					@ -148,8 +145,6 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::unique_ptr<Media::SystemMediaControlsManager> _mediaControlsManager;
 | 
						std::unique_ptr<Media::SystemMediaControlsManager> _mediaControlsManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	crl::time _lastTrayClickTime = 0;
 | 
						crl::time _lastTrayClickTime = 0;
 | 
				
			||||||
	QPoint _lastMousePosition;
 | 
						QPoint _lastMousePosition;
 | 
				
			||||||
	bool _activeForTrayIconAction = true;
 | 
						bool _activeForTrayIconAction = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -305,7 +305,7 @@ QIcon TrayIconGen(int counter, bool muted) {
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				currentImageBack = Core::App().logo();
 | 
									currentImageBack = Window::Logo();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (dprSize(currentImageBack) != desiredSize) {
 | 
								if (dprSize(currentImageBack) != desiredSize) {
 | 
				
			||||||
| 
						 | 
					@ -324,20 +324,19 @@ QIcon TrayIconGen(int counter, bool muted) {
 | 
				
			||||||
				: st::trayCounterBg;
 | 
									: st::trayCounterBg;
 | 
				
			||||||
			const auto &fg = st::trayCounterFg;
 | 
								const auto &fg = st::trayCounterFg;
 | 
				
			||||||
			if (iconSize >= 22) {
 | 
								if (iconSize >= 22) {
 | 
				
			||||||
				auto layerSize = -16;
 | 
									const auto layerSize = (iconSize >= 48)
 | 
				
			||||||
				if (iconSize >= 48) {
 | 
										? 32
 | 
				
			||||||
					layerSize = -32;
 | 
										: (iconSize >= 36)
 | 
				
			||||||
				} else if (iconSize >= 36) {
 | 
										? 24
 | 
				
			||||||
					layerSize = -24;
 | 
										: (iconSize >= 32)
 | 
				
			||||||
				} else if (iconSize >= 32) {
 | 
										? 20
 | 
				
			||||||
					layerSize = -20;
 | 
										: 16;
 | 
				
			||||||
				}
 | 
									const auto layer = Window::GenerateCounterLayer({
 | 
				
			||||||
				const auto layer = App::wnd()->iconWithCounter(
 | 
										.size = layerSize,
 | 
				
			||||||
					layerSize,
 | 
										.count = counter,
 | 
				
			||||||
					counter,
 | 
										.bg = bg,
 | 
				
			||||||
					bg,
 | 
										.fg = fg,
 | 
				
			||||||
					fg,
 | 
									});
 | 
				
			||||||
					false);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				QPainter p(&iconImage);
 | 
									QPainter p(&iconImage);
 | 
				
			||||||
				p.drawImage(
 | 
									p.drawImage(
 | 
				
			||||||
| 
						 | 
					@ -345,13 +344,12 @@ QIcon TrayIconGen(int counter, bool muted) {
 | 
				
			||||||
					iconImage.height() - layer.height() - 1,
 | 
										iconImage.height() - layer.height() - 1,
 | 
				
			||||||
					layer);
 | 
										layer);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				App::wnd()->placeSmallCounter(
 | 
									iconImage = Window::WithSmallCounter(std::move(iconImage), {
 | 
				
			||||||
					iconImage,
 | 
										.size = 16,
 | 
				
			||||||
					16,
 | 
										.count = counter,
 | 
				
			||||||
					counter,
 | 
										.bg = bg,
 | 
				
			||||||
					bg,
 | 
										.fg = fg,
 | 
				
			||||||
					QPoint(),
 | 
									});
 | 
				
			||||||
					fg);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,13 +20,6 @@ class MainWindow : public Window::MainWindow {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	explicit MainWindow(not_null<Window::Controller*> controller);
 | 
						explicit MainWindow(not_null<Window::Controller*> controller);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual QImage iconWithCounter(
 | 
					 | 
				
			||||||
		int size,
 | 
					 | 
				
			||||||
		int count,
 | 
					 | 
				
			||||||
		style::color bg,
 | 
					 | 
				
			||||||
		style::color fg,
 | 
					 | 
				
			||||||
		bool smallIcon) = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void psShowTrayMenu();
 | 
						void psShowTrayMenu();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool trayAvailable() {
 | 
						bool trayAvailable() {
 | 
				
			||||||
| 
						 | 
					@ -54,14 +47,6 @@ protected:
 | 
				
			||||||
	void psTrayMenuUpdated();
 | 
						void psTrayMenuUpdated();
 | 
				
			||||||
	void psSetupTrayIcon();
 | 
						void psSetupTrayIcon();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual void placeSmallCounter(
 | 
					 | 
				
			||||||
		QImage &img,
 | 
					 | 
				
			||||||
		int size,
 | 
					 | 
				
			||||||
		int count,
 | 
					 | 
				
			||||||
		style::color bg,
 | 
					 | 
				
			||||||
		const QPoint &shift,
 | 
					 | 
				
			||||||
		style::color color) = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	class Private;
 | 
						class Private;
 | 
				
			||||||
	friend class Private;
 | 
						friend class Private;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,8 +25,6 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool psFilterNativeEvent(void *event);
 | 
						bool psFilterNativeEvent(void *event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int getCustomTitleHeight() const {
 | 
						int getCustomTitleHeight() const {
 | 
				
			||||||
		return _customTitleHeight;
 | 
							return _customTitleHeight;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -77,7 +75,6 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void psTrayMenuUpdated();
 | 
						void psTrayMenuUpdated();
 | 
				
			||||||
	void psSetupTrayIcon();
 | 
						void psSetupTrayIcon();
 | 
				
			||||||
	virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void closeWithoutDestroy() override;
 | 
						void closeWithoutDestroy() override;
 | 
				
			||||||
	void createGlobalMenu() override;
 | 
						void createGlobalMenu() override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "platform/win/windows_dlls.h"
 | 
					#include "platform/win/windows_dlls.h"
 | 
				
			||||||
#include "platform/win/windows_event_filter.h"
 | 
					#include "platform/win/windows_event_filter.h"
 | 
				
			||||||
#include "window/notifications_manager.h"
 | 
					#include "window/notifications_manager.h"
 | 
				
			||||||
 | 
					#include "window/window_session_controller.h"
 | 
				
			||||||
#include "mainwindow.h"
 | 
					#include "mainwindow.h"
 | 
				
			||||||
 | 
					#include "main/main_session.h"
 | 
				
			||||||
#include "base/crc32hash.h"
 | 
					#include "base/crc32hash.h"
 | 
				
			||||||
#include "base/platform/win/base_windows_wrl.h"
 | 
					#include "base/platform/win/base_windows_wrl.h"
 | 
				
			||||||
#include "base/platform/base_platform_info.h"
 | 
					#include "base/platform/base_platform_info.h"
 | 
				
			||||||
| 
						 | 
					@ -59,47 +61,77 @@ constexpr auto kKeepActiveForTrayIcon = crl::time(500);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace Microsoft::WRL;
 | 
					using namespace Microsoft::WRL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HICON createHIconFromQIcon(const QIcon &icon, int xSize, int ySize) {
 | 
					[[nodiscard]] HICON NativeIcon(const QIcon &icon, QSize size) {
 | 
				
			||||||
	if (!icon.isNull()) {
 | 
						if (!icon.isNull()) {
 | 
				
			||||||
		const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize)));
 | 
							const auto pixmap = icon.pixmap(icon.actualSize(size));
 | 
				
			||||||
		if (!pm.isNull()) {
 | 
							if (!pixmap.isNull()) {
 | 
				
			||||||
			return qt_pixmapToWinHICON(pm);
 | 
								return qt_pixmapToWinHICON(pixmap);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nullptr;
 | 
						return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HWND createTaskbarHider() {
 | 
					[[nodiscard]] QImage IconWithCounter(
 | 
				
			||||||
	HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
 | 
							Window::CounterLayerArgs &&args,
 | 
				
			||||||
	HWND hWnd = 0;
 | 
							Main::Session *session,
 | 
				
			||||||
 | 
							bool smallIcon) {
 | 
				
			||||||
 | 
						static constexpr auto kCount = 3;
 | 
				
			||||||
 | 
						static auto ScaledLogo = std::array<QImage, kCount>();
 | 
				
			||||||
 | 
						static auto ScaledLogoNoMargin = std::array<QImage, kCount>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QString cn = QString("TelegramTaskbarHider");
 | 
						struct Dimensions {
 | 
				
			||||||
	LPCWSTR _cn = (LPCWSTR)cn.utf16();
 | 
							int index = 0;
 | 
				
			||||||
	WNDCLASSEX wc;
 | 
							int size = 0;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
	wc.cbSize = sizeof(wc);
 | 
						const auto d = [&]() -> Dimensions {
 | 
				
			||||||
	wc.style = 0;
 | 
							switch (args.size) {
 | 
				
			||||||
	wc.lpfnWndProc = DefWindowProc;
 | 
							case 16:
 | 
				
			||||||
	wc.cbClsExtra = 0;
 | 
								return {
 | 
				
			||||||
	wc.cbWndExtra = 0;
 | 
									.index = 0,
 | 
				
			||||||
	wc.hInstance = appinst;
 | 
									.size = 16,
 | 
				
			||||||
	wc.hIcon = 0;
 | 
								};
 | 
				
			||||||
	wc.hCursor = 0;
 | 
							case 32:
 | 
				
			||||||
	wc.hbrBackground = 0;
 | 
								return {
 | 
				
			||||||
	wc.lpszMenuName = NULL;
 | 
									.index = 1,
 | 
				
			||||||
	wc.lpszClassName = _cn;
 | 
									.size = 32,
 | 
				
			||||||
	wc.hIconSm = 0;
 | 
								};
 | 
				
			||||||
	if (!RegisterClassEx(&wc)) {
 | 
							default:
 | 
				
			||||||
		DEBUG_LOG(("Application Error: could not register taskbar hider window class, error: %1").arg(GetLastError()));
 | 
								return {
 | 
				
			||||||
		return hWnd;
 | 
									.index = 2,
 | 
				
			||||||
 | 
									.size = 64,
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}();
 | 
				
			||||||
 | 
						Assert(d.index < kCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, _cn, 0, WS_POPUP, 0, 0, 0, 0, 0, 0, appinst, 0);
 | 
						auto &scaled = smallIcon ? ScaledLogoNoMargin : ScaledLogo;
 | 
				
			||||||
	if (!hWnd) {
 | 
						auto result = [&] {
 | 
				
			||||||
		DEBUG_LOG(("Application Error: could not create taskbar hider window class, error: %1").arg(GetLastError()));
 | 
							auto &image = scaled[d.index];
 | 
				
			||||||
		return hWnd;
 | 
							if (image.isNull()) {
 | 
				
			||||||
 | 
								image = (smallIcon
 | 
				
			||||||
 | 
									? Window::LogoNoMargin()
 | 
				
			||||||
 | 
									: Window::Logo()).scaledToWidth(
 | 
				
			||||||
 | 
										d.size,
 | 
				
			||||||
 | 
										Qt::SmoothTransformation);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	return hWnd;
 | 
							return image;
 | 
				
			||||||
 | 
						}();
 | 
				
			||||||
 | 
						if (session && session->supportMode()) {
 | 
				
			||||||
 | 
							Window::ConvertIconToBlack(result);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!args.count) {
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
 | 
						} else if (smallIcon) {
 | 
				
			||||||
 | 
							return Window::WithSmallCounter(std::move(result), std::move(args));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						QPainter p(&result);
 | 
				
			||||||
 | 
						const auto half = d.size / 2;
 | 
				
			||||||
 | 
						args.size = half;
 | 
				
			||||||
 | 
						p.drawPixmap(
 | 
				
			||||||
 | 
							half,
 | 
				
			||||||
 | 
							half,
 | 
				
			||||||
 | 
							Ui::PixmapFromImage(Window::GenerateCounterLayer(std::move(args))));
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ComPtr<ITaskbarList3> taskbarList;
 | 
					ComPtr<ITaskbarList3> taskbarList;
 | 
				
			||||||
| 
						 | 
					@ -202,7 +234,8 @@ void MainWindow::psSetupTrayIcon() {
 | 
				
			||||||
	if (!trayIcon) {
 | 
						if (!trayIcon) {
 | 
				
			||||||
		trayIcon = new QSystemTrayIcon(this);
 | 
							trayIcon = new QSystemTrayIcon(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto icon = QIcon(Ui::PixmapFromImage(Core::App().logoNoMargin()));
 | 
							const auto icon = QIcon(Ui::PixmapFromImage(
 | 
				
			||||||
 | 
								QImage(Window::LogoNoMargin())));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		trayIcon->setIcon(icon);
 | 
							trayIcon->setIcon(icon);
 | 
				
			||||||
		connect(
 | 
							connect(
 | 
				
			||||||
| 
						 | 
					@ -327,47 +360,72 @@ void MainWindow::unreadCounterChangedHook() {
 | 
				
			||||||
void MainWindow::updateIconCounters() {
 | 
					void MainWindow::updateIconCounters() {
 | 
				
			||||||
	const auto counter = Core::App().unreadBadge();
 | 
						const auto counter = Core::App().unreadBadge();
 | 
				
			||||||
	const auto muted = Core::App().unreadBadgeMuted();
 | 
						const auto muted = Core::App().unreadBadgeMuted();
 | 
				
			||||||
 | 
						const auto controller = sessionController();
 | 
				
			||||||
 | 
						const auto session = controller ? &controller->session() : nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto iconSizeSmall = QSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
 | 
						const auto iconSizeSmall = QSize(
 | 
				
			||||||
	auto iconSizeBig = QSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
 | 
							GetSystemMetrics(SM_CXSMICON),
 | 
				
			||||||
 | 
							GetSystemMetrics(SM_CYSMICON));
 | 
				
			||||||
 | 
						const auto iconSizeBig = QSize(
 | 
				
			||||||
 | 
							GetSystemMetrics(SM_CXICON),
 | 
				
			||||||
 | 
							GetSystemMetrics(SM_CYICON));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto &bg = (muted ? st::trayCounterBgMute : st::trayCounterBg);
 | 
						const auto &bg = muted ? st::trayCounterBgMute : st::trayCounterBg;
 | 
				
			||||||
	auto &fg = st::trayCounterFg;
 | 
						const auto &fg = st::trayCounterFg;
 | 
				
			||||||
	auto iconSmallPixmap16 = Ui::PixmapFromImage(
 | 
						const auto counterArgs = [&](int size, int counter) {
 | 
				
			||||||
		iconWithCounter(16, counter, bg, fg, true));
 | 
							return Window::CounterLayerArgs{
 | 
				
			||||||
	auto iconSmallPixmap32 = Ui::PixmapFromImage(
 | 
								.size = size,
 | 
				
			||||||
		iconWithCounter(32, counter, bg, fg, true));
 | 
								.count = counter,
 | 
				
			||||||
 | 
								.bg = bg,
 | 
				
			||||||
 | 
								.fg = fg,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						const auto iconWithCounter = [&](int size, int counter, bool smallIcon) {
 | 
				
			||||||
 | 
							return Ui::PixmapFromImage(IconWithCounter(
 | 
				
			||||||
 | 
								counterArgs(size, counter),
 | 
				
			||||||
 | 
								session,
 | 
				
			||||||
 | 
								smallIcon));
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto iconSmallPixmap16 = iconWithCounter(16, counter, true);
 | 
				
			||||||
 | 
						auto iconSmallPixmap32 = iconWithCounter(32, counter, true);
 | 
				
			||||||
	QIcon iconSmall, iconBig;
 | 
						QIcon iconSmall, iconBig;
 | 
				
			||||||
	iconSmall.addPixmap(iconSmallPixmap16);
 | 
						iconSmall.addPixmap(iconSmallPixmap16);
 | 
				
			||||||
	iconSmall.addPixmap(iconSmallPixmap32);
 | 
						iconSmall.addPixmap(iconSmallPixmap32);
 | 
				
			||||||
	iconBig.addPixmap(Ui::PixmapFromImage(
 | 
						const auto bigCounter = taskbarList.Get() ? 0 : counter;
 | 
				
			||||||
		iconWithCounter(32, taskbarList.Get() ? 0 : counter, bg, fg, false)));
 | 
						iconBig.addPixmap(iconWithCounter(32, bigCounter, false));
 | 
				
			||||||
	iconBig.addPixmap(Ui::PixmapFromImage(
 | 
						iconBig.addPixmap(iconWithCounter(64, bigCounter, false));
 | 
				
			||||||
		iconWithCounter(64, taskbarList.Get() ? 0 : counter, bg, fg, false)));
 | 
					 | 
				
			||||||
	if (trayIcon) {
 | 
						if (trayIcon) {
 | 
				
			||||||
		// Force Qt to use right icon size, not the larger one.
 | 
							// Force Qt to use right icon size, not the larger one.
 | 
				
			||||||
		QIcon forTrayIcon;
 | 
							QIcon forTrayIcon;
 | 
				
			||||||
		forTrayIcon.addPixmap(iconSizeSmall.width() >= 20 ? iconSmallPixmap32 : iconSmallPixmap16);
 | 
							forTrayIcon.addPixmap(iconSizeSmall.width() >= 20
 | 
				
			||||||
 | 
								? iconSmallPixmap32
 | 
				
			||||||
 | 
								: iconSmallPixmap16);
 | 
				
			||||||
		trayIcon->setIcon(forTrayIcon);
 | 
							trayIcon->setIcon(forTrayIcon);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	psDestroyIcons();
 | 
						psDestroyIcons();
 | 
				
			||||||
	ps_iconSmall = createHIconFromQIcon(iconSmall, iconSizeSmall.width(), iconSizeSmall.height());
 | 
						ps_iconSmall = NativeIcon(iconSmall, iconSizeSmall);
 | 
				
			||||||
	ps_iconBig = createHIconFromQIcon(iconBig, iconSizeBig.width(), iconSizeBig.height());
 | 
						ps_iconBig = NativeIcon(iconBig, iconSizeBig);
 | 
				
			||||||
	SendMessage(ps_hWnd, WM_SETICON, 0, (LPARAM)ps_iconSmall);
 | 
						SendMessage(ps_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)ps_iconSmall);
 | 
				
			||||||
	SendMessage(ps_hWnd, WM_SETICON, 1, (LPARAM)(ps_iconBig ? ps_iconBig : ps_iconSmall));
 | 
						SendMessage(ps_hWnd, WM_SETICON, ICON_BIG, (LPARAM)(ps_iconBig ? ps_iconBig : ps_iconSmall));
 | 
				
			||||||
	if (taskbarList.Get()) {
 | 
						if (taskbarList) {
 | 
				
			||||||
		if (counter > 0) {
 | 
							if (counter > 0) {
 | 
				
			||||||
 | 
								const auto pixmap = [&](int size) {
 | 
				
			||||||
 | 
									return Ui::PixmapFromImage(Window::GenerateCounterLayer(
 | 
				
			||||||
 | 
										counterArgs(size, counter)));
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
			QIcon iconOverlay;
 | 
								QIcon iconOverlay;
 | 
				
			||||||
			iconOverlay.addPixmap(Ui::PixmapFromImage(
 | 
								iconOverlay.addPixmap(pixmap(16));
 | 
				
			||||||
				iconWithCounter(-16, counter, bg, fg, false)));
 | 
								iconOverlay.addPixmap(pixmap(32));
 | 
				
			||||||
			iconOverlay.addPixmap(Ui::PixmapFromImage(
 | 
								ps_iconOverlay = NativeIcon(iconOverlay, iconSizeSmall);
 | 
				
			||||||
				iconWithCounter(-32, counter, bg, fg, false)));
 | 
					 | 
				
			||||||
			ps_iconOverlay = createHIconFromQIcon(iconOverlay, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		auto description = (counter > 0) ? tr::lng_unread_bar(tr::now, lt_count, counter) : QString();
 | 
							const auto description = (counter > 0)
 | 
				
			||||||
		taskbarList->SetOverlayIcon(ps_hWnd, ps_iconOverlay, description.toStdWString().c_str());
 | 
								? tr::lng_unread_bar(tr::now, lt_count, counter).toStdWString()
 | 
				
			||||||
 | 
								: std::wstring();
 | 
				
			||||||
 | 
							taskbarList->SetOverlayIcon(ps_hWnd, ps_iconOverlay, description.c_str());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						psDestroyIcons();
 | 
				
			||||||
	SetWindowPos(ps_hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
 | 
						SetWindowPos(ps_hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,8 +30,6 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void psRefreshTaskbarIcon();
 | 
						void psRefreshTaskbarIcon();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] static uint32 TaskbarCreatedMsgId();
 | 
						[[nodiscard]] static uint32 TaskbarCreatedMsgId();
 | 
				
			||||||
	static void TaskbarCreated();
 | 
						static void TaskbarCreated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +57,6 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void psTrayMenuUpdated();
 | 
						void psTrayMenuUpdated();
 | 
				
			||||||
	void psSetupTrayIcon();
 | 
						void psSetupTrayIcon();
 | 
				
			||||||
	virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void showTrayTooltip() override;
 | 
						void showTrayTooltip() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -258,7 +258,7 @@ void NotificationsCount::prepareNotificationSampleSmall() {
 | 
				
			||||||
void NotificationsCount::prepareNotificationSampleUserpic() {
 | 
					void NotificationsCount::prepareNotificationSampleUserpic() {
 | 
				
			||||||
	if (_notificationSampleUserpic.isNull()) {
 | 
						if (_notificationSampleUserpic.isNull()) {
 | 
				
			||||||
		_notificationSampleUserpic = Ui::PixmapFromImage(
 | 
							_notificationSampleUserpic = Ui::PixmapFromImage(
 | 
				
			||||||
			Core::App().logoNoMargin().scaled(
 | 
								Window::LogoNoMargin().scaled(
 | 
				
			||||||
				st::notifyPhotoSize * cIntRetinaFactor(),
 | 
									st::notifyPhotoSize * cIntRetinaFactor(),
 | 
				
			||||||
				st::notifyPhotoSize * cIntRetinaFactor(),
 | 
									st::notifyPhotoSize * cIntRetinaFactor(),
 | 
				
			||||||
				Qt::IgnoreAspectRatio,
 | 
									Qt::IgnoreAspectRatio,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,12 +49,14 @@ constexpr auto kSaveWindowPositionTimeout = crl::time(1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QImage LoadLogo() {
 | 
					const QImage &Logo() {
 | 
				
			||||||
	return QImage(qsl(":/gui/art/logo_256.png"));
 | 
						static const auto result = QImage(u":/gui/art/logo_256.png"_q);
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QImage LoadLogoNoMargin() {
 | 
					const QImage &LogoNoMargin() {
 | 
				
			||||||
	return QImage(qsl(":/gui/art/logo_256_no_margin.png"));
 | 
						static const auto result = QImage(u":/gui/art/logo_256_no_margin.png"_q);
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ConvertIconToBlack(QImage &image) {
 | 
					void ConvertIconToBlack(QImage &image) {
 | 
				
			||||||
| 
						 | 
					@ -105,7 +107,7 @@ void ConvertIconToBlack(QImage &image) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QIcon CreateOfficialIcon(Main::Session *session) {
 | 
					QIcon CreateOfficialIcon(Main::Session *session) {
 | 
				
			||||||
	auto image = Core::IsAppLaunched() ? Core::App().logo() : LoadLogo();
 | 
						auto image = Logo();
 | 
				
			||||||
	if (session && session->supportMode()) {
 | 
						if (session && session->supportMode()) {
 | 
				
			||||||
		ConvertIconToBlack(image);
 | 
							ConvertIconToBlack(image);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -156,6 +158,144 @@ QIcon CreateIcon(Main::Session *session) {
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QImage GenerateCounterLayer(CounterLayerArgs &&args) {
 | 
				
			||||||
 | 
						// platform/linux/main_window_linux depends on count used the same
 | 
				
			||||||
 | 
						// way for all the same (count % 1000) values.
 | 
				
			||||||
 | 
						const auto count = args.count.value();
 | 
				
			||||||
 | 
						const auto text = (count < 1000)
 | 
				
			||||||
 | 
							? QString::number(count)
 | 
				
			||||||
 | 
							: u"..%1"_q.arg(count % 100, 2, 10, QChar('0'));
 | 
				
			||||||
 | 
						const auto textSize = text.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct Dimensions {
 | 
				
			||||||
 | 
							int size = 0;
 | 
				
			||||||
 | 
							int font = 0;
 | 
				
			||||||
 | 
							int delta = 0;
 | 
				
			||||||
 | 
							int radius = 0;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						const auto d = [&]() -> Dimensions {
 | 
				
			||||||
 | 
							switch (args.size.value()) {
 | 
				
			||||||
 | 
							case 16:
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									.size = 16,
 | 
				
			||||||
 | 
									.font = ((textSize < 2) ? 11 : (textSize < 3) ? 11 : 8),
 | 
				
			||||||
 | 
									.delta = ((textSize < 2) ? 5 : (textSize < 3) ? 2 : 1),
 | 
				
			||||||
 | 
									.radius = ((textSize < 2) ? 8 : (textSize < 3) ? 7 : 3),
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							case 20:
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									.size = 20,
 | 
				
			||||||
 | 
									.font = ((textSize < 2) ? 14 : (textSize < 3) ? 13 : 10),
 | 
				
			||||||
 | 
									.delta = ((textSize < 2) ? 6 : (textSize < 3) ? 2 : 1),
 | 
				
			||||||
 | 
									.radius = ((textSize < 2) ? 10 : (textSize < 3) ? 9 : 5),
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							case 24:
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									.size = 24,
 | 
				
			||||||
 | 
									.font = ((textSize < 2) ? 17 : (textSize < 3) ? 16 : 12),
 | 
				
			||||||
 | 
									.delta = ((textSize < 2) ? 7 : (textSize < 3) ? 3 : 1),
 | 
				
			||||||
 | 
									.radius = ((textSize < 2) ? 12 : (textSize < 3) ? 11 : 6),
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									.size = 32,
 | 
				
			||||||
 | 
									.font = ((textSize < 2) ? 22 : (textSize < 3) ? 20 : 16),
 | 
				
			||||||
 | 
									.delta = ((textSize < 2) ? 9 : (textSize < 3) ? 4 : 2),
 | 
				
			||||||
 | 
									.radius = ((textSize < 2) ? 16 : (textSize < 3) ? 14 : 8),
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto result = QImage(d.size, d.size, QImage::Format_ARGB32);
 | 
				
			||||||
 | 
						result.fill(Qt::transparent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto p = QPainter(&result);
 | 
				
			||||||
 | 
						auto hq = PainterHighQualityEnabler(p);
 | 
				
			||||||
 | 
						const auto f = style::font{ d.font, 0, 0 };
 | 
				
			||||||
 | 
						const auto w = f->width(text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.setBrush(args.bg.value());
 | 
				
			||||||
 | 
						p.setPen(Qt::NoPen);
 | 
				
			||||||
 | 
						p.drawRoundedRect(
 | 
				
			||||||
 | 
							QRect(
 | 
				
			||||||
 | 
								d.size - w - d.delta * 2,
 | 
				
			||||||
 | 
								d.size - f->height,
 | 
				
			||||||
 | 
								w + d.delta * 2,
 | 
				
			||||||
 | 
								f->height),
 | 
				
			||||||
 | 
							d.radius,
 | 
				
			||||||
 | 
							d.radius);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.setFont(f);
 | 
				
			||||||
 | 
						p.setPen(args.fg.value());
 | 
				
			||||||
 | 
						p.drawText(d.size - w - d.delta, d.size - f->height + f->ascent, text);
 | 
				
			||||||
 | 
						p.end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QImage WithSmallCounter(QImage image, CounterLayerArgs &&args) {
 | 
				
			||||||
 | 
						const auto count = args.count.value();
 | 
				
			||||||
 | 
						const auto text = (count < 100)
 | 
				
			||||||
 | 
							? QString::number(count)
 | 
				
			||||||
 | 
							: QString("..%1").arg(count % 10, 1, 10, QChar('0'));
 | 
				
			||||||
 | 
						const auto textSize = text.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct Dimensions {
 | 
				
			||||||
 | 
							int size = 0;
 | 
				
			||||||
 | 
							int font = 0;
 | 
				
			||||||
 | 
							int delta = 0;
 | 
				
			||||||
 | 
							int radius = 0;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						const auto d = [&]() -> Dimensions {
 | 
				
			||||||
 | 
							switch (args.size.value()) {
 | 
				
			||||||
 | 
							case 16:
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									.size = 16,
 | 
				
			||||||
 | 
									.font = 8,
 | 
				
			||||||
 | 
									.delta = ((textSize < 2) ? 2 : 1),
 | 
				
			||||||
 | 
									.radius = ((textSize < 2) ? 4 : 3),
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							case 32:
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									.size = 32,
 | 
				
			||||||
 | 
									.font = 12,
 | 
				
			||||||
 | 
									.delta = ((textSize < 2) ? 5 : 2),
 | 
				
			||||||
 | 
									.radius = ((textSize < 2) ? 8 : 7),
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return {
 | 
				
			||||||
 | 
									.size = 64,
 | 
				
			||||||
 | 
									.font = 22,
 | 
				
			||||||
 | 
									.delta = ((textSize < 2) ? 9 : 4),
 | 
				
			||||||
 | 
									.radius = ((textSize < 2) ? 16 : 14),
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto p = QPainter(&image);
 | 
				
			||||||
 | 
						auto hq = PainterHighQualityEnabler(p);
 | 
				
			||||||
 | 
						const auto f = style::font{ d.font, 0, 0 };
 | 
				
			||||||
 | 
						const auto w = f->width(text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.setBrush(args.bg.value());
 | 
				
			||||||
 | 
						p.setPen(Qt::NoPen);
 | 
				
			||||||
 | 
						p.drawRoundedRect(
 | 
				
			||||||
 | 
							QRect(
 | 
				
			||||||
 | 
								d.size - w - d.delta * 2,
 | 
				
			||||||
 | 
								d.size - f->height,
 | 
				
			||||||
 | 
								w + d.delta * 2,
 | 
				
			||||||
 | 
								f->height),
 | 
				
			||||||
 | 
							d.radius,
 | 
				
			||||||
 | 
							d.radius);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.setFont(f);
 | 
				
			||||||
 | 
						p.setPen(args.fg.value());
 | 
				
			||||||
 | 
						p.drawText(d.size - w - d.delta, d.size - f->height + f->ascent, text);
 | 
				
			||||||
 | 
						p.end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return image;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MainWindow::MainWindow(not_null<Controller*> controller)
 | 
					MainWindow::MainWindow(not_null<Controller*> controller)
 | 
				
			||||||
: _controller(controller)
 | 
					: _controller(controller)
 | 
				
			||||||
, _positionUpdatedTimer([=] { savePosition(); })
 | 
					, _positionUpdatedTimer([=] { savePosition(); })
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "base/timer.h"
 | 
					#include "base/timer.h"
 | 
				
			||||||
#include "base/object_ptr.h"
 | 
					#include "base/object_ptr.h"
 | 
				
			||||||
#include "core/core_settings.h"
 | 
					#include "core/core_settings.h"
 | 
				
			||||||
 | 
					#include "base/required.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <QtWidgets/QSystemTrayIcon>
 | 
					#include <QtWidgets/QSystemTrayIcon>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,11 +36,21 @@ class SessionController;
 | 
				
			||||||
class TitleWidget;
 | 
					class TitleWidget;
 | 
				
			||||||
struct TermsLock;
 | 
					struct TermsLock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QImage LoadLogo();
 | 
					[[nodiscard]] const QImage &Logo();
 | 
				
			||||||
QImage LoadLogoNoMargin();
 | 
					[[nodiscard]] const QImage &LogoNoMargin();
 | 
				
			||||||
QIcon CreateIcon(Main::Session *session = nullptr);
 | 
					[[nodiscard]] QIcon CreateIcon(Main::Session *session = nullptr);
 | 
				
			||||||
void ConvertIconToBlack(QImage &image);
 | 
					void ConvertIconToBlack(QImage &image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct CounterLayerArgs {
 | 
				
			||||||
 | 
						base::required<int> size = 16;
 | 
				
			||||||
 | 
						base::required<int> count = 1;
 | 
				
			||||||
 | 
						base::required<style::color> bg;
 | 
				
			||||||
 | 
						base::required<style::color> fg;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]] QImage GenerateCounterLayer(CounterLayerArgs &&args);
 | 
				
			||||||
 | 
					[[nodiscard]] QImage WithSmallCounter(QImage image, CounterLayerArgs &&args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MainWindow : public Ui::RpWindow {
 | 
					class MainWindow : public Ui::RpWindow {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	explicit MainWindow(not_null<Controller*> controller);
 | 
						explicit MainWindow(not_null<Controller*> controller);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ Manager::QueuedNotification::QueuedNotification(
 | 
				
			||||||
QPixmap Manager::hiddenUserpicPlaceholder() const {
 | 
					QPixmap Manager::hiddenUserpicPlaceholder() const {
 | 
				
			||||||
	if (_hiddenUserpicPlaceholder.isNull()) {
 | 
						if (_hiddenUserpicPlaceholder.isNull()) {
 | 
				
			||||||
		_hiddenUserpicPlaceholder = Ui::PixmapFromImage(
 | 
							_hiddenUserpicPlaceholder = Ui::PixmapFromImage(
 | 
				
			||||||
			Core::App().logoNoMargin().scaled(
 | 
								LogoNoMargin().scaled(
 | 
				
			||||||
				st::notifyPhotoSize,
 | 
									st::notifyPhotoSize,
 | 
				
			||||||
				st::notifyPhotoSize,
 | 
									st::notifyPhotoSize,
 | 
				
			||||||
				Qt::IgnoreAspectRatio,
 | 
									Qt::IgnoreAspectRatio,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "window/notifications_utilities.h"
 | 
					#include "window/notifications_utilities.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "window/main_window.h"
 | 
				
			||||||
#include "base/platform/base_platform_file_utilities.h"
 | 
					#include "base/platform/base_platform_file_utilities.h"
 | 
				
			||||||
#include "base/random.h"
 | 
					#include "base/random.h"
 | 
				
			||||||
#include "core/application.h"
 | 
					#include "core/application.h"
 | 
				
			||||||
| 
						 | 
					@ -79,7 +80,7 @@ QString CachedUserpics::get(
 | 
				
			||||||
				peer->saveUserpic(view, v.path, st::notifyMacPhotoSize);
 | 
									peer->saveUserpic(view, v.path, st::notifyMacPhotoSize);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			Core::App().logoNoMargin().save(v.path, "PNG");
 | 
								LogoNoMargin().save(v.path, "PNG");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		i = _images.insert(key, v);
 | 
							i = _images.insert(key, v);
 | 
				
			||||||
		_someSavedFlag = true;
 | 
							_someSavedFlag = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue