mirror of https://github.com/procxx/kepka.git
Added emoji picker to touchbar.
- Added independent size of emoji for touchbar. - Added rpl::event_stream for recent emoji updates.
This commit is contained in:
parent
dcba07b9b7
commit
662d0d0764
|
@ -9,30 +9,32 @@
|
||||||
#import "mac_touchbar.h"
|
#import "mac_touchbar.h"
|
||||||
#import <QuartzCore/QuartzCore.h>
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
#include "platform/mac/mac_utilities.h"
|
#include "apiwrap.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
|
#include "chat_helpers/emoji_list_widget.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/sandbox.h"
|
#include "core/sandbox.h"
|
||||||
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_folder.h"
|
#include "data/data_folder.h"
|
||||||
#include "data/data_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "dialogs/dialogs_layout.h"
|
#include "dialogs/dialogs_layout.h"
|
||||||
|
#include "emoji_config.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
|
#include "platform/mac/mac_utilities.h"
|
||||||
|
#include "stickers.h"
|
||||||
|
#include "styles/style_dialogs.h"
|
||||||
#include "styles/style_media_player.h"
|
#include "styles/style_media_player.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "styles/style_settings.h"
|
|
||||||
#include "stickers.h"
|
|
||||||
#include "data/data_document.h"
|
|
||||||
#include "data/data_file_origin.h"
|
|
||||||
#include "chat_helpers/stickers_list_widget.h"
|
|
||||||
#include "apiwrap.h"
|
|
||||||
|
|
||||||
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
|
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
|
||||||
|
|
||||||
|
@ -55,6 +57,9 @@ constexpr auto kCommandLink = 0x014;
|
||||||
|
|
||||||
constexpr auto kCommandPopoverInput = 0x020;
|
constexpr auto kCommandPopoverInput = 0x020;
|
||||||
constexpr auto kCommandPopoverStickers = 0x021;
|
constexpr auto kCommandPopoverStickers = 0x021;
|
||||||
|
constexpr auto kCommandScrubberStickers = 0x022;
|
||||||
|
constexpr auto kCommandPopoverEmoji = 0x023;
|
||||||
|
constexpr auto kCommandScrubberEmoji = 0x024;
|
||||||
|
|
||||||
constexpr auto kMs = 1000;
|
constexpr auto kMs = 1000;
|
||||||
|
|
||||||
|
@ -96,15 +101,26 @@ const NSTouchBarItemIdentifier kLinkItemIdentifier = [NSString stringWithFormat:
|
||||||
const NSTouchBarItemIdentifier kPopoverStickersItemIdentifier = [NSString stringWithFormat:@"%@.popoverStickers", kCustomizationIdMain];
|
const NSTouchBarItemIdentifier kPopoverStickersItemIdentifier = [NSString stringWithFormat:@"%@.popoverStickers", kCustomizationIdMain];
|
||||||
const NSTouchBarItemIdentifier kScrubberStickersItemIdentifier = [NSString stringWithFormat:@"%@.scrubberStickers", kCustomizationIdMain];
|
const NSTouchBarItemIdentifier kScrubberStickersItemIdentifier = [NSString stringWithFormat:@"%@.scrubberStickers", kCustomizationIdMain];
|
||||||
const NSTouchBarItemIdentifier kStickerItemIdentifier = [NSString stringWithFormat:@"%@.stickerItem", kCustomizationIdMain];
|
const NSTouchBarItemIdentifier kStickerItemIdentifier = [NSString stringWithFormat:@"%@.stickerItem", kCustomizationIdMain];
|
||||||
const NSTouchBarItemIdentifier kStickerTitleItemIdentifier = [NSString stringWithFormat:@"%@.stickerTitleItem", kCustomizationIdMain];
|
const NSTouchBarItemIdentifier kPopoverEmojiItemIdentifier = [NSString stringWithFormat:@"%@.popoverEmoji", kCustomizationIdMain];
|
||||||
|
const NSTouchBarItemIdentifier kScrubberEmojiItemIdentifier = [NSString stringWithFormat:@"%@.scrubberEmoji", kCustomizationIdMain];
|
||||||
|
const NSTouchBarItemIdentifier kEmojiItemIdentifier = [NSString stringWithFormat:@"%@.emojiItem", kCustomizationIdMain];
|
||||||
|
const NSTouchBarItemIdentifier kPickerTitleItemIdentifier = [NSString stringWithFormat:@"%@.pickerTitleItem", kCustomizationIdMain];
|
||||||
|
|
||||||
struct StickerScrubberItem {
|
struct PickerScrubberItem {
|
||||||
StickerScrubberItem(QString title) : title(title) {
|
PickerScrubberItem(QString title) : title(title) {
|
||||||
}
|
}
|
||||||
StickerScrubberItem(DocumentData* document) : document(document) {
|
PickerScrubberItem(DocumentData* document) : document(document) {
|
||||||
|
}
|
||||||
|
PickerScrubberItem(EmojiPtr emoji) : emoji(emoji) {
|
||||||
}
|
}
|
||||||
QString title = QString();
|
QString title = QString();
|
||||||
DocumentData* document = nullptr;
|
DocumentData* document = nullptr;
|
||||||
|
EmojiPtr emoji = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ScrubberItemType {
|
||||||
|
Emoji,
|
||||||
|
Sticker,
|
||||||
};
|
};
|
||||||
|
|
||||||
using Platform::Q2NSString;
|
using Platform::Q2NSString;
|
||||||
|
@ -118,6 +134,22 @@ NSImage *CreateNSImageFromStyleIcon(const style::icon &icon, int size = kIdealIc
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSImage *CreateNSImageFromEmoji(EmojiPtr emoji) {
|
||||||
|
const auto s = kIdealIconSize * cIntRetinaFactor();
|
||||||
|
auto pixmap = QPixmap(s, s);
|
||||||
|
pixmap.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
pixmap.fill(Qt::black);
|
||||||
|
Painter paint(&pixmap);
|
||||||
|
PainterHighQualityEnabler hq(paint);
|
||||||
|
Ui::Emoji::Draw(
|
||||||
|
paint,
|
||||||
|
std::move(emoji),
|
||||||
|
Ui::Emoji::GetSizeTouchbar(),
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
return [qt_mac_create_nsimage(pixmap) autorelease];
|
||||||
|
}
|
||||||
|
|
||||||
int WidthFromString(NSString *s) {
|
int WidthFromString(NSString *s) {
|
||||||
return (int)ceil(
|
return (int)ceil(
|
||||||
[[NSTextField labelWithString:s] frame].size.width) * 1.2;
|
[[NSTextField labelWithString:s] frame].size.width) * 1.2;
|
||||||
|
@ -131,6 +163,10 @@ NSString *NSStringFromQString(QString s) {
|
||||||
return [NSString stringWithUTF8String:s.toUtf8().constData()];
|
return [NSString stringWithUTF8String:s.toUtf8().constData()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool IsSticker(ScrubberItemType type) {
|
||||||
|
return type == ScrubberItemType::Sticker;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool CurrentSongExists() {
|
inline bool CurrentSongExists() {
|
||||||
return Media::Player::instance()->current(kSongType).audio() != nullptr;
|
return Media::Player::instance()->current(kSongType).audio() != nullptr;
|
||||||
}
|
}
|
||||||
|
@ -243,7 +279,7 @@ void SendKeyEvent(int command) {
|
||||||
QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyRelease, key, modifier));
|
QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyRelease, key, modifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppendStickerSet(std::vector<StickerScrubberItem> &to, uint64 setId) {
|
void AppendStickerSet(std::vector<PickerScrubberItem> &to, uint64 setId) {
|
||||||
auto &sets = Auth().data().stickerSets();
|
auto &sets = Auth().data().stickerSets();
|
||||||
auto it = sets.constFind(setId);
|
auto it = sets.constFind(setId);
|
||||||
if (it == sets.cend() || it->stickers.isEmpty()) {
|
if (it == sets.cend() || it->stickers.isEmpty()) {
|
||||||
|
@ -256,15 +292,15 @@ void AppendStickerSet(std::vector<StickerScrubberItem> &to, uint64 setId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
to.emplace_back(StickerScrubberItem(it->title.isEmpty()
|
to.emplace_back(PickerScrubberItem(it->title.isEmpty()
|
||||||
? it->shortName
|
? it->shortName
|
||||||
: it->title));
|
: it->title));
|
||||||
for (auto sticker : it->stickers) {
|
for (const auto sticker : it->stickers) {
|
||||||
to.emplace_back(StickerScrubberItem(sticker));
|
to.emplace_back(PickerScrubberItem(sticker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppendRecentStickers(std::vector<StickerScrubberItem> &to) {
|
void AppendRecentStickers(std::vector<PickerScrubberItem> &to) {
|
||||||
const auto &sets = Auth().data().stickerSets();
|
const auto &sets = Auth().data().stickerSets();
|
||||||
const auto cloudIt = sets.constFind(Stickers::CloudRecentSetId);
|
const auto cloudIt = sets.constFind(Stickers::CloudRecentSetId);
|
||||||
const auto favedIt = sets.constFind(Stickers::FavedSetId);
|
const auto favedIt = sets.constFind(Stickers::FavedSetId);
|
||||||
|
@ -272,21 +308,21 @@ void AppendRecentStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
? cloudIt->stickers.size()
|
? cloudIt->stickers.size()
|
||||||
: 0;
|
: 0;
|
||||||
if (cloudCount > 0) {
|
if (cloudCount > 0) {
|
||||||
to.emplace_back(StickerScrubberItem(cloudIt->title));
|
to.emplace_back(PickerScrubberItem(cloudIt->title));
|
||||||
auto count = 0;
|
auto count = 0;
|
||||||
for (const auto document : cloudIt->stickers) {
|
for (const auto document : cloudIt->stickers) {
|
||||||
if (Stickers::IsFaved(document)) {
|
if (Stickers::IsFaved(document)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
to.emplace_back(StickerScrubberItem(document));
|
to.emplace_back(PickerScrubberItem(document));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto recent : Stickers::GetRecentPack()) {
|
for (const auto recent : Stickers::GetRecentPack()) {
|
||||||
to.emplace_back(StickerScrubberItem(recent.first));
|
to.emplace_back(PickerScrubberItem(recent.first));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
void AppendFavedStickers(std::vector<PickerScrubberItem> &to) {
|
||||||
const auto &sets = Auth().data().stickerSets();
|
const auto &sets = Auth().data().stickerSets();
|
||||||
const auto it = sets.constFind(Stickers::FavedSetId);
|
const auto it = sets.constFind(Stickers::FavedSetId);
|
||||||
const auto count = (it != sets.cend())
|
const auto count = (it != sets.cend())
|
||||||
|
@ -295,9 +331,27 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
if (!count) {
|
if (!count) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
to.emplace_back(StickerScrubberItem(it->title));
|
to.emplace_back(PickerScrubberItem(it->title));
|
||||||
for (const auto document : it->stickers) {
|
for (const auto document : it->stickers) {
|
||||||
to.emplace_back(StickerScrubberItem(document));
|
to.emplace_back(PickerScrubberItem(document));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
|
// Get 'Recent' string.
|
||||||
|
const auto recent = Auth().data().stickerSets()
|
||||||
|
.constFind(Stickers::CloudRecentSetId)->title;
|
||||||
|
|
||||||
|
for (auto i = 0; i != ChatHelpers::kEmojiSectionCount; ++i) {
|
||||||
|
const auto section = Ui::Emoji::GetSection(
|
||||||
|
static_cast<Ui::Emoji::Section>(i));
|
||||||
|
const auto title = i
|
||||||
|
? lang(LangKey(lng_emoji_category1 + i))
|
||||||
|
: recent;
|
||||||
|
to.emplace_back(title);
|
||||||
|
for (const auto &emoji : section) {
|
||||||
|
to.emplace_back(PickerScrubberItem(emoji));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,10 +542,10 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@interface StickerScrubberItemView : NSScrubberItemView
|
@interface PickerScrubberItemView : NSScrubberItemView
|
||||||
@property (strong) NSImageView *imageView;
|
@property (strong) NSImageView *imageView;
|
||||||
@end
|
@end
|
||||||
@implementation StickerScrubberItemView {
|
@implementation PickerScrubberItemView {
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
Data::FileOrigin _origin;
|
Data::FileOrigin _origin;
|
||||||
QSize _dimensions;
|
QSize _dimensions;
|
||||||
|
@ -552,7 +606,7 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@interface StickersCustomTouchBarItem: NSCustomTouchBarItem
|
@interface PickerCustomTouchBarItem: NSCustomTouchBarItem
|
||||||
<NSScrubberDelegate,
|
<NSScrubberDelegate,
|
||||||
NSScrubberDataSource,
|
NSScrubberDataSource,
|
||||||
NSScrubberFlowLayoutDelegate>
|
NSScrubberFlowLayoutDelegate>
|
||||||
|
@ -560,19 +614,20 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
@implementation StickersCustomTouchBarItem {
|
@implementation PickerCustomTouchBarItem {
|
||||||
Fn<void()> _stickerSent;
|
std::vector<PickerScrubberItem> _stickers;
|
||||||
std::vector<StickerScrubberItem> _stickers;
|
NSPopoverTouchBarItem *_parentPopover;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init:(Fn<void()>)stickerSent {
|
- (id) init:(ScrubberItemType)type popover:(NSPopoverTouchBarItem *)popover {
|
||||||
self = [super initWithIdentifier:kScrubberStickersItemIdentifier];
|
self = [super initWithIdentifier:IsSticker(type)
|
||||||
|
? kScrubberStickersItemIdentifier
|
||||||
|
: kScrubberEmojiItemIdentifier];
|
||||||
if (!self) {
|
if (!self) {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
_stickerSent = std::move(stickerSent);
|
_parentPopover = popover;
|
||||||
[self updateStickers];
|
IsSticker(type) ? [self updateStickers] : [self updateEmoji];
|
||||||
|
|
||||||
NSScrubber *scrubber = [[[NSScrubber alloc] initWithFrame:NSZeroRect] autorelease];
|
NSScrubber *scrubber = [[[NSScrubber alloc] initWithFrame:NSZeroRect] autorelease];
|
||||||
NSScrubberFlowLayout *layout = [[[NSScrubberFlowLayout alloc] init] autorelease];
|
NSScrubberFlowLayout *layout = [[[NSScrubberFlowLayout alloc] init] autorelease];
|
||||||
layout.itemSpacing = 10;
|
layout.itemSpacing = 10;
|
||||||
|
@ -583,8 +638,9 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
scrubber.floatsSelectionViews = true;
|
scrubber.floatsSelectionViews = true;
|
||||||
scrubber.showsAdditionalContentIndicators = true;
|
scrubber.showsAdditionalContentIndicators = true;
|
||||||
scrubber.itemAlignment = NSScrubberAlignmentCenter;
|
scrubber.itemAlignment = NSScrubberAlignmentCenter;
|
||||||
[scrubber registerClass:[StickerScrubberItemView class] forItemIdentifier:kStickerItemIdentifier];
|
[scrubber registerClass:[PickerScrubberItemView class] forItemIdentifier:kStickerItemIdentifier];
|
||||||
[scrubber registerClass:[NSScrubberTextItemView class] forItemIdentifier:kStickerTitleItemIdentifier];
|
[scrubber registerClass:[NSScrubberTextItemView class] forItemIdentifier:kPickerTitleItemIdentifier];
|
||||||
|
[scrubber registerClass:[NSScrubberImageItemView class] forItemIdentifier:kEmojiItemIdentifier];
|
||||||
|
|
||||||
self.view = scrubber;
|
self.view = scrubber;
|
||||||
return self;
|
return self;
|
||||||
|
@ -601,14 +657,18 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSScrubberItemView *)scrubber:(NSScrubber *)scrubber viewForItemAtIndex:(NSInteger)index {
|
- (NSScrubberItemView *)scrubber:(NSScrubber *)scrubber viewForItemAtIndex:(NSInteger)index {
|
||||||
const auto document = _stickers[index].document;
|
const auto item = _stickers[index];
|
||||||
if (document) {
|
if (const auto document = item.document) {
|
||||||
StickerScrubberItemView *itemView = [scrubber makeItemWithIdentifier:kStickerItemIdentifier owner:nil];
|
PickerScrubberItemView *itemView = [scrubber makeItemWithIdentifier:kStickerItemIdentifier owner:nil];
|
||||||
[itemView addDocument:document];
|
[itemView addDocument:document];
|
||||||
return itemView;
|
return itemView;
|
||||||
|
} else if (const auto emoji = item.emoji) {
|
||||||
|
NSScrubberImageItemView *itemView = [scrubber makeItemWithIdentifier:kEmojiItemIdentifier owner:nil];
|
||||||
|
itemView.imageView.image = CreateNSImageFromEmoji(emoji);
|
||||||
|
return itemView;
|
||||||
} else {
|
} else {
|
||||||
NSScrubberTextItemView *itemView = [scrubber makeItemWithIdentifier:kStickerTitleItemIdentifier owner:nil];
|
NSScrubberTextItemView *itemView = [scrubber makeItemWithIdentifier:kPickerTitleItemIdentifier owner:nil];
|
||||||
itemView.textField.stringValue = NSStringFromQString(_stickers[index].title);
|
itemView.textField.stringValue = NSStringFromQString(item.title);
|
||||||
return itemView;
|
return itemView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -616,34 +676,51 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
- (NSSize)scrubber:(NSScrubber *)scrubber layout:(NSScrubberFlowLayout *)layout sizeForItemAtIndex:(NSInteger)index {
|
- (NSSize)scrubber:(NSScrubber *)scrubber layout:(NSScrubberFlowLayout *)layout sizeForItemAtIndex:(NSInteger)index {
|
||||||
if (const auto t = _stickers[index].title; !t.isEmpty()) {
|
if (const auto t = _stickers[index].title; !t.isEmpty()) {
|
||||||
return NSMakeSize(
|
return NSMakeSize(
|
||||||
WidthFromString(NSStringFromQString(t)) + 20, kScrubberHeight);
|
WidthFromString(NSStringFromQString(t)) + 30, kScrubberHeight);
|
||||||
}
|
}
|
||||||
return NSMakeSize(kScrubberHeight, kScrubberHeight);
|
return NSMakeSize(kScrubberHeight, kScrubberHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrubber:(NSScrubber *)scrubber didSelectItemAtIndex:(NSInteger)index {
|
- (void)scrubber:(NSScrubber *)scrubber didSelectItemAtIndex:(NSInteger)index {
|
||||||
if (const auto document = _stickers[index].document) {
|
const auto controller = App::wnd()->sessionController();
|
||||||
const auto controller = App::wnd()->sessionController();
|
if (const auto history = controller->activeChatCurrent().history()) {
|
||||||
if (const auto history = controller->activeChatCurrent().history()) {
|
Fn<void()> callback;
|
||||||
Core::Sandbox::Instance().customEnterFromEventLoop([=] {
|
if (const auto document = _stickers[index].document) {
|
||||||
|
callback = [=] {
|
||||||
Auth().api().sendExistingDocument(
|
Auth().api().sendExistingDocument(
|
||||||
document,
|
document,
|
||||||
document->stickerSetOrigin(),
|
document->stickerSetOrigin(),
|
||||||
{},
|
{},
|
||||||
ApiWrap::SendOptions(history));
|
ApiWrap::SendOptions(history));
|
||||||
});
|
};
|
||||||
_stickerSent();
|
|
||||||
}
|
}
|
||||||
|
if (const auto emoji = _stickers[index].emoji) {
|
||||||
|
callback = [=] {
|
||||||
|
if (const auto inputField = qobject_cast<Ui::InputField*>(
|
||||||
|
QApplication::focusWidget()->parentWidget())) {
|
||||||
|
Ui::InsertEmojiAtCursor(inputField->textCursor(), emoji);
|
||||||
|
Ui::Emoji::AddRecent(emoji);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!callback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Core::Sandbox::Instance().customEnterFromEventLoop(
|
||||||
|
std::move(callback));
|
||||||
|
if (_parentPopover) {
|
||||||
|
[_parentPopover dismissPopover:nil];
|
||||||
|
}
|
||||||
|
scrubber.selectedIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateStickers {
|
- (void)updateStickers {
|
||||||
std::vector<StickerScrubberItem> temp;
|
std::vector<PickerScrubberItem> temp;
|
||||||
temp.reserve(Auth().data().stickerSetsOrder().size() + 3);
|
|
||||||
AppendFavedStickers(temp);
|
AppendFavedStickers(temp);
|
||||||
AppendRecentStickers(temp);
|
AppendRecentStickers(temp);
|
||||||
auto count = 0;
|
auto count = 0;
|
||||||
for (auto setId : Auth().data().stickerSetsOrder()) {
|
for (const auto setId : Auth().data().stickerSetsOrder()) {
|
||||||
AppendStickerSet(temp, setId);
|
AppendStickerSet(temp, setId);
|
||||||
if (++count == kMaxStickerSets) {
|
if (++count == kMaxStickerSets) {
|
||||||
break;
|
break;
|
||||||
|
@ -652,6 +729,12 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
_stickers = std::move(temp);
|
_stickers = std::move(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateEmoji {
|
||||||
|
std::vector<PickerScrubberItem> temp;
|
||||||
|
AppendEmojiPacks(temp);
|
||||||
|
_stickers = std::move(temp);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@ -762,8 +845,18 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
kScrubberStickersItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{
|
kScrubberStickersItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{
|
||||||
@"type": kTypeScrubber,
|
@"type": kTypeScrubber,
|
||||||
@"name": @"Stickers",
|
@"name": @"Stickers",
|
||||||
@"cmd": [NSNumber numberWithInt:kCommandPopoverStickers],
|
@"cmd": [NSNumber numberWithInt:kCommandScrubberStickers],
|
||||||
@"image": CreateNSImageFromStyleIcon(st::settingsIconStickers, iconSize),
|
}],
|
||||||
|
kPopoverEmojiItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{
|
||||||
|
@"type": kTypePopover,
|
||||||
|
@"name": @"Emoji",
|
||||||
|
@"cmd": [NSNumber numberWithInt:kCommandPopoverEmoji],
|
||||||
|
@"image": CreateNSImageFromStyleIcon(st::settingsIconEmoji, iconSize * 2),
|
||||||
|
}],
|
||||||
|
kScrubberEmojiItemIdentifier: [NSMutableDictionary dictionaryWithDictionary:@{
|
||||||
|
@"type": kTypeScrubber,
|
||||||
|
@"name": @"Emoji",
|
||||||
|
@"cmd": [NSNumber numberWithInt:kCommandScrubberEmoji],
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -824,21 +917,28 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
&& key.history()
|
&& key.history()
|
||||||
&& key.peer()->canWrite();
|
&& key.peer()->canWrite();
|
||||||
[self showItem:kPopoverStickersItemIdentifier show:show];
|
[self showItem:kPopoverStickersItemIdentifier show:show];
|
||||||
|
[self showItem:kPopoverEmojiItemIdentifier show:show];
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, _lifetimeSessionControllerChecker);
|
}, _lifetimeSessionControllerChecker);
|
||||||
|
|
||||||
Auth().data().stickersUpdated(
|
rpl::merge(
|
||||||
|
Auth().data().stickersUpdated(),
|
||||||
|
Auth().data().recentStickersUpdated()
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
[self updateStickerTouchBar:
|
[self updatePickerPopover:
|
||||||
[_touchBarMain itemForIdentifier:kPopoverStickersItemIdentifier]];
|
[_touchBarMain itemForIdentifier:kPopoverStickersItemIdentifier]
|
||||||
|
type:ScrubberItemType::Sticker];
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
Auth().data().recentStickersUpdated(
|
rpl::merge(
|
||||||
|
Ui::Emoji::UpdatedRecent(),
|
||||||
|
Ui::Emoji::Updated()
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
[self updateStickerTouchBar:
|
[self updatePickerPopover:
|
||||||
[_touchBarMain itemForIdentifier:kPopoverStickersItemIdentifier]];
|
[_touchBarMain itemForIdentifier:kPopoverEmojiItemIdentifier]
|
||||||
|
type:ScrubberItemType::Emoji];
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
[self updatePinnedButtons];
|
[self updatePinnedButtons];
|
||||||
|
@ -898,16 +998,22 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
item.pressAndHoldTouchBar = secondaryTouchBar;
|
item.pressAndHoldTouchBar = secondaryTouchBar;
|
||||||
item.popoverTouchBar = secondaryTouchBar;
|
item.popoverTouchBar = secondaryTouchBar;
|
||||||
} else if (command == kCommandPopoverStickers) {
|
} else if (command == kCommandPopoverStickers) {
|
||||||
[self updateStickerTouchBar:item];
|
[self updatePickerPopover:item type:ScrubberItemType::Sticker];
|
||||||
|
} else if (command == kCommandPopoverEmoji) {
|
||||||
|
[self updatePickerPopover:item type:ScrubberItemType::Emoji];
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
} else if (isType(kTypeScrubber)) {
|
} else if (isType(kTypeScrubber)) {
|
||||||
StickersCustomTouchBarItem *item = [[StickersCustomTouchBarItem alloc]
|
const auto isSticker = ([dictionaryItem[@"cmd"] intValue]
|
||||||
init:[=] {
|
== kCommandScrubberStickers);
|
||||||
NSPopoverTouchBarItem *item = [_touchBarMain itemForIdentifier:kPopoverStickersItemIdentifier];
|
const auto type = isSticker
|
||||||
[item dismissPopover:nil];
|
? ScrubberItemType::Sticker
|
||||||
[self updateStickerTouchBar:item];
|
: ScrubberItemType::Emoji;
|
||||||
}];
|
const auto popover = isSticker
|
||||||
|
? [_touchBarMain itemForIdentifier:kPopoverStickersItemIdentifier]
|
||||||
|
: nil;
|
||||||
|
PickerCustomTouchBarItem *item = [[PickerCustomTouchBarItem alloc]
|
||||||
|
init:type popover:popover];
|
||||||
return item;
|
return item;
|
||||||
} else if (isType(kTypePinned)) {
|
} else if (isType(kTypePinned)) {
|
||||||
NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
|
NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
|
||||||
|
@ -995,14 +1101,19 @@ void AppendFavedStickers(std::vector<StickerScrubberItem> &to) {
|
||||||
_touchBarMain.defaultItemIdentifiers = items;
|
_touchBarMain.defaultItemIdentifiers = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) updateStickerTouchBar:(NSPopoverTouchBarItem *)item {
|
- (void) updatePickerPopover:(NSPopoverTouchBarItem *)item
|
||||||
|
type:(ScrubberItemType)type {
|
||||||
|
|
||||||
NSTouchBar *secondaryTouchBar = [[NSTouchBar alloc] init];
|
NSTouchBar *secondaryTouchBar = [[NSTouchBar alloc] init];
|
||||||
secondaryTouchBar.delegate = self;
|
secondaryTouchBar.delegate = self;
|
||||||
[[StickersCustomTouchBarItem alloc] init:[=] {
|
const auto popover = IsSticker(type)
|
||||||
[item dismissPopover:nil];
|
? item
|
||||||
[self updateStickerTouchBar:item];
|
: nil;
|
||||||
}];
|
[[PickerCustomTouchBarItem alloc] init:type popover:popover];
|
||||||
secondaryTouchBar.defaultItemIdentifiers = @[kScrubberStickersItemIdentifier];
|
const auto identifier = IsSticker(type)
|
||||||
|
? kScrubberStickersItemIdentifier
|
||||||
|
: kScrubberEmojiItemIdentifier;
|
||||||
|
secondaryTouchBar.defaultItemIdentifiers = @[identifier];
|
||||||
item.popoverTouchBar = secondaryTouchBar;
|
item.popoverTouchBar = secondaryTouchBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ constexpr auto kSetVersion = uint32(1);
|
||||||
constexpr auto kCacheVersion = uint32(3);
|
constexpr auto kCacheVersion = uint32(3);
|
||||||
constexpr auto kMaxId = uint32(1 << 8);
|
constexpr auto kMaxId = uint32(1 << 8);
|
||||||
|
|
||||||
|
constexpr auto kScaleForTouchBar = 150;
|
||||||
|
|
||||||
const auto kSets = {
|
const auto kSets = {
|
||||||
Set{ 0, 0, 0, "Mac", ":/gui/emoji/set0_preview.webp" },
|
Set{ 0, 0, 0, "Mac", ":/gui/emoji/set0_preview.webp" },
|
||||||
Set{ 1, 246, 7'336'383, "Android", ":/gui/emoji/set1_preview.webp" },
|
Set{ 1, 246, 7'336'383, "Android", ":/gui/emoji/set1_preview.webp" },
|
||||||
|
@ -87,6 +89,13 @@ auto InstanceNormal = std::unique_ptr<Instance>();
|
||||||
auto InstanceLarge = std::unique_ptr<Instance>();
|
auto InstanceLarge = std::unique_ptr<Instance>();
|
||||||
auto Universal = std::shared_ptr<UniversalImages>();
|
auto Universal = std::shared_ptr<UniversalImages>();
|
||||||
auto Updates = rpl::event_stream<>();
|
auto Updates = rpl::event_stream<>();
|
||||||
|
auto UpdatesRecent = rpl::event_stream<>();
|
||||||
|
|
||||||
|
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||||
|
auto TouchbarSize = -1;
|
||||||
|
auto TouchbarInstance = std::unique_ptr<Instance>();
|
||||||
|
auto TouchbarEmoji = (Instance*)nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
auto MainEmojiMap = std::map<int, QPixmap>();
|
auto MainEmojiMap = std::map<int, QPixmap>();
|
||||||
auto OtherEmojiMap = std::map<int, std::map<int, QPixmap>>();
|
auto OtherEmojiMap = std::map<int, std::map<int, QPixmap>>();
|
||||||
|
@ -521,6 +530,17 @@ void Init() {
|
||||||
|
|
||||||
InstanceNormal = std::make_unique<Instance>(SizeNormal);
|
InstanceNormal = std::make_unique<Instance>(SizeNormal);
|
||||||
InstanceLarge = std::make_unique<Instance>(SizeLarge);
|
InstanceLarge = std::make_unique<Instance>(SizeLarge);
|
||||||
|
|
||||||
|
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||||
|
if (cScale() != kScaleForTouchBar) {
|
||||||
|
TouchbarSize = int(ConvertScale(18 * 4 / 3.,
|
||||||
|
kScaleForTouchBar * cIntRetinaFactor()));
|
||||||
|
TouchbarInstance = std::make_unique<Instance>(TouchbarSize);
|
||||||
|
TouchbarEmoji = TouchbarInstance.get();
|
||||||
|
} else {
|
||||||
|
TouchbarEmoji = InstanceLarge.get();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear() {
|
void Clear() {
|
||||||
|
@ -529,6 +549,10 @@ void Clear() {
|
||||||
|
|
||||||
InstanceNormal = nullptr;
|
InstanceNormal = nullptr;
|
||||||
InstanceLarge = nullptr;
|
InstanceLarge = nullptr;
|
||||||
|
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||||
|
TouchbarInstance = nullptr;
|
||||||
|
TouchbarEmoji = nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearIrrelevantCache() {
|
void ClearIrrelevantCache() {
|
||||||
|
@ -621,6 +645,14 @@ int GetSizeLarge() {
|
||||||
return SizeLarge;
|
return SizeLarge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||||
|
int GetSizeTouchbar() {
|
||||||
|
return (cScale() == kScaleForTouchBar)
|
||||||
|
? GetSizeLarge()
|
||||||
|
: TouchbarSize;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int One::variantsCount() const {
|
int One::variantsCount() const {
|
||||||
return hasVariants() ? 5 : 0;
|
return hasVariants() ? 5 : 0;
|
||||||
}
|
}
|
||||||
|
@ -841,6 +873,11 @@ void AddRecent(EmojiPtr emoji) {
|
||||||
qSwap(*i, *(i - 1));
|
qSwap(*i, *(i - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UpdatesRecent.fire({});
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> UpdatedRecent() {
|
||||||
|
return UpdatesRecent.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight) {
|
const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight) {
|
||||||
|
@ -857,6 +894,7 @@ const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight) {
|
||||||
image.fill(Qt::transparent);
|
image.fill(Qt::transparent);
|
||||||
{
|
{
|
||||||
QPainter p(&image);
|
QPainter p(&image);
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
Draw(
|
Draw(
|
||||||
p,
|
p,
|
||||||
emoji,
|
emoji,
|
||||||
|
@ -872,6 +910,15 @@ const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(QPainter &p, EmojiPtr emoji, int size, int x, int y) {
|
void Draw(QPainter &p, EmojiPtr emoji, int size, int x, int y) {
|
||||||
|
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||||
|
const auto s = (cScale() == kScaleForTouchBar)
|
||||||
|
? SizeLarge
|
||||||
|
: TouchbarSize;
|
||||||
|
if (size == s) {
|
||||||
|
TouchbarEmoji->draw(p, emoji, x, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (size == SizeNormal) {
|
if (size == SizeNormal) {
|
||||||
InstanceNormal->draw(p, emoji, x, y);
|
InstanceNormal->draw(p, emoji, x, y);
|
||||||
} else if (size == SizeLarge) {
|
} else if (size == SizeLarge) {
|
||||||
|
|
|
@ -44,6 +44,9 @@ rpl::producer<> Updated();
|
||||||
|
|
||||||
int GetSizeNormal();
|
int GetSizeNormal();
|
||||||
int GetSizeLarge();
|
int GetSizeLarge();
|
||||||
|
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||||
|
int GetSizeTouchbar();
|
||||||
|
#endif
|
||||||
|
|
||||||
class One {
|
class One {
|
||||||
struct CreationTag {
|
struct CreationTag {
|
||||||
|
@ -156,6 +159,7 @@ inline int ColorIndexFromOldKey(uint64 oldKey) {
|
||||||
void ReplaceInText(TextWithEntities &result);
|
void ReplaceInText(TextWithEntities &result);
|
||||||
RecentEmojiPack &GetRecent();
|
RecentEmojiPack &GetRecent();
|
||||||
void AddRecent(EmojiPtr emoji);
|
void AddRecent(EmojiPtr emoji);
|
||||||
|
rpl::producer<> UpdatedRecent();
|
||||||
|
|
||||||
const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight);
|
const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight);
|
||||||
void Draw(QPainter &p, EmojiPtr emoji, int size, int x, int y);
|
void Draw(QPainter &p, EmojiPtr emoji, int size, int x, int y);
|
||||||
|
|
Loading…
Reference in New Issue