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