Implemented unread badges in touchbar.

This commit is contained in:
23rd 2019-05-27 20:55:53 +03:00
parent fa245099b6
commit 26ec440a13
2 changed files with 86 additions and 25 deletions

View File

@ -63,6 +63,7 @@ enum UnreadBadgeSize {
UnreadBadgeInHistoryToDown, UnreadBadgeInHistoryToDown,
UnreadBadgeInStickersPanel, UnreadBadgeInStickersPanel,
UnreadBadgeInStickersBox, UnreadBadgeInStickersBox,
UnreadBadgeInTouchBar,
UnreadBadgeSizesCount UnreadBadgeSizesCount
}; };

View File

@ -14,6 +14,7 @@
#include "core/sandbox.h" #include "core/sandbox.h"
#include "data/data_folder.h" #include "data/data_folder.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "dialogs/dialogs_layout.h"
#include "history/history.h" #include "history/history.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "mainwindow.h" #include "mainwindow.h"
@ -22,6 +23,7 @@
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "ui/empty_userpic.h" #include "ui/empty_userpic.h"
#include "styles/style_dialogs.h"
NSImage *qt_mac_create_nsimage(const QPixmap &pm); NSImage *qt_mac_create_nsimage(const QPixmap &pm);
@ -72,6 +74,16 @@ inline bool UseEmptyUserpic(PeerData *peer) {
return (peer && (peer->useEmptyUserpic() || peer->isSelf())); return (peer && (peer->useEmptyUserpic() || peer->isSelf()));
} }
inline bool IsSelfPeer(PeerData *peer) {
return (peer && peer->id == Auth().userPeerId());
}
inline int UnreadCount(PeerData *peer) {
return (peer
&& AuthSession::Exists()
&& Auth().data().history(peer->id)->unreadCountForBadge());
}
NSString *FormatTime(int time) { NSString *FormatTime(int time) {
const auto seconds = time % 60; const auto seconds = time % 60;
const auto minutes = (time / 60) % 60; const auto minutes = (time / 60) % 60;
@ -90,6 +102,28 @@ NSString *FormatTime(int time) {
return stringTime; return stringTime;
} }
void PaintUnreadBadge(Painter &p, PeerData *peer) {
const auto history = Auth().data().history(peer->id);
const auto count = history->unreadCountForBadge();
if (!count) {
return;
}
const auto unread = history->unreadMark()
? QString()
: QString::number(count);
Dialogs::Layout::UnreadBadgeStyle unreadSt;
unreadSt.sizeId = Dialogs::Layout::UnreadBadgeInTouchBar;
unreadSt.muted = history->mute();
// Use constant values to draw badge regardless of cConfigScale().
unreadSt.size = 19;
unreadSt.padding = 5;
unreadSt.font = style::font(
12,
unreadSt.font->flags(),
unreadSt.font->family());
Dialogs::Layout::paintUnreadCount(p, unread, kIdealIconSize, kIdealIconSize - unreadSt.size, unreadSt, nullptr, 2);
}
} // namespace } // namespace
@interface PinnedDialogButton : NSCustomTouchBarItem @interface PinnedDialogButton : NSCustomTouchBarItem
@ -97,9 +131,9 @@ NSString *FormatTime(int time) {
@property(nonatomic, assign) int number; @property(nonatomic, assign) int number;
@property(nonatomic, assign) PeerData *peer; @property(nonatomic, assign) PeerData *peer;
@property(nonatomic, assign) bool isDeletedFromView; @property(nonatomic, assign) bool isDeletedFromView;
@property(nonatomic, assign) QPixmap userpic;
- (id) init:(int)num; - (id) init:(int)num;
- (NSImage *) getPinImage;
- (void)buttonActionPin:(NSButton *)sender; - (void)buttonActionPin:(NSButton *)sender;
- (void)updateUserpic; - (void)updateUserpic;
@ -107,7 +141,7 @@ NSString *FormatTime(int time) {
@implementation PinnedDialogButton { @implementation PinnedDialogButton {
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
rpl::lifetime _userpicChangedLifetime; rpl::lifetime _peerChangedLifetime;
bool isWaitingUserpicLoad; bool isWaitingUserpicLoad;
} }
@ -131,14 +165,18 @@ NSString *FormatTime(int time) {
} }
self.number = num; self.number = num;
NSButton *button = [NSButton buttonWithImage:[self getPinImage] target:self action:@selector(buttonActionPin:)]; NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameStopProgressTemplate] target:self action:@selector(buttonActionPin:)];
[button setBordered:NO]; [button setBordered:NO];
[button sizeToFit]; [button sizeToFit];
self.view = button; self.view = button;
using Update = const Window::Theme::BackgroundUpdate; using Update = const Window::Theme::BackgroundUpdate;
base::ObservableViewer( auto themeChanged = base::ObservableViewer(
*Window::Theme::Background() *Window::Theme::Background()
) | rpl::start_spawning(_lifetime);
rpl::duplicate(
themeChanged
) | rpl::filter([=](const Update &update) { ) | rpl::filter([=](const Update &update) {
return update.paletteChanged() return update.paletteChanged()
&& (_number <= kSavedMessagesId || UseEmptyUserpic(_peer)); && (_number <= kSavedMessagesId || UseEmptyUserpic(_peer));
@ -146,7 +184,17 @@ NSString *FormatTime(int time) {
[self updateUserpic]; [self updateUserpic];
}, _lifetime); }, _lifetime);
std::move(
themeChanged
) | rpl::filter([=](const Update &update) {
return update.type == Update::Type::ApplyingTheme
&& UnreadCount(_peer);
}) | rpl::start_with_next([=] {
[self updateBadge];
}, _lifetime);
if (num <= kSavedMessagesId) { if (num <= kSavedMessagesId) {
[self updateUserpic];
return self; return self;
} }
@ -167,22 +215,24 @@ NSString *FormatTime(int time) {
return; return;
} }
_peer = newPeer; _peer = newPeer;
_userpicChangedLifetime.destroy(); _peerChangedLifetime.destroy();
if (!_peer) { if (!_peer) {
return; return;
} }
Notify::PeerUpdateViewer( Notify::PeerUpdateViewer(
_peer, _peer,
Notify::PeerUpdate::Flag::PhotoChanged Notify::PeerUpdate::Flag::PhotoChanged
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
isWaitingUserpicLoad = true; isWaitingUserpicLoad = true;
[self updateUserpic]; [self updateUserpic];
}, _userpicChangedLifetime); }, _peerChangedLifetime);
}
- (void) updateUserpic { Notify::PeerUpdateViewer(
NSButton *button = self.view; _peer,
button.image = [self getPinImage]; Notify::PeerUpdate::Flag::UnreadViewChanged
) | rpl::start_with_next([=] {
[self updateBadge];
}, _peerChangedLifetime);
} }
- (void) buttonActionPin:(NSButton *)sender { - (void) buttonActionPin:(NSButton *)sender {
@ -203,16 +253,12 @@ NSString *FormatTime(int time) {
}); });
} }
- (bool) isSelfPeer { - (void) updateUserpic {
return !self.peer ? false : self.peer->id == Auth().userPeerId();
}
- (NSImage *) getPinImage {
// Don't draw self userpic if we pin Saved Messages. // Don't draw self userpic if we pin Saved Messages.
if (self.number <= kSavedMessagesId || [self isSelfPeer]) { if (self.number <= kSavedMessagesId || IsSelfPeer(_peer)) {
const int s = kIdealIconSize * cRetinaFactor(); const auto s = kIdealIconSize * cIntRetinaFactor();
auto *pix = new QPixmap(s, s); auto *pixmap = new QPixmap(s, s);
Painter paint(pix); Painter paint(pixmap);
paint.fillRect(QRectF(0, 0, s, s), QColor(0, 0, 0, 255)); paint.fillRect(QRectF(0, 0, s, s), QColor(0, 0, 0, 255));
if (self.number == kArchiveId) { if (self.number == kArchiveId) {
@ -222,17 +268,31 @@ NSString *FormatTime(int time) {
} else { } else {
Ui::EmptyUserpic::PaintSavedMessages(paint, 0, 0, s, s); Ui::EmptyUserpic::PaintSavedMessages(paint, 0, 0, s, s);
} }
pix->setDevicePixelRatio(cRetinaFactor()); pixmap->setDevicePixelRatio(cRetinaFactor());
return [qt_mac_create_nsimage(*pix) autorelease]; _userpic = *pixmap;
[self updateImage:_userpic];
return;
} }
if (!self.peer) { if (!self.peer) {
// Random picture. return;
return [NSImage imageNamed:NSImageNameTouchBarAddTemplate];
} }
isWaitingUserpicLoad = !self.peer->userpicLoaded(); isWaitingUserpicLoad = !self.peer->userpicLoaded();
auto pixmap = self.peer->genUserpic(kIdealIconSize); auto pixmap = self.peer->genUserpic(kIdealIconSize);
pixmap.setDevicePixelRatio(cRetinaFactor()); pixmap.setDevicePixelRatio(cRetinaFactor());
return [qt_mac_create_nsimage(pixmap) autorelease]; _userpic = pixmap;
[self updateBadge];
}
- (void) updateBadge {
auto pixmap = App::pixmapFromImageInPlace(_userpic.toImage());
Painter p(&pixmap);
PaintUnreadBadge(p, _peer);
[self updateImage:pixmap];
}
- (void) updateImage:(QPixmap)pixmap {
NSButton *button = self.view;
button.image = [qt_mac_create_nsimage(pixmap) autorelease];
} }
@end @end