mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Refactored ability to display media preview from touchbar.
This commit is contained in:
parent
664162982c
commit
9bf8b619fe
1 changed files with 74 additions and 62 deletions
|
@ -74,6 +74,17 @@ constexpr auto kArchiveId = -1;
|
||||||
|
|
||||||
constexpr auto kMaxStickerSets = 5;
|
constexpr auto kMaxStickerSets = 5;
|
||||||
|
|
||||||
|
constexpr auto kGestureStateProcessed = {
|
||||||
|
NSGestureRecognizerStateChanged,
|
||||||
|
NSGestureRecognizerStateBegan,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr auto kGestureStateFinished = {
|
||||||
|
NSGestureRecognizerStateEnded,
|
||||||
|
NSGestureRecognizerStateCancelled,
|
||||||
|
NSGestureRecognizerStateFailed,
|
||||||
|
};
|
||||||
|
|
||||||
NSString *const kTypePinned = @"pinned";
|
NSString *const kTypePinned = @"pinned";
|
||||||
NSString *const kTypeSlider = @"slider";
|
NSString *const kTypeSlider = @"slider";
|
||||||
NSString *const kTypeButton = @"button";
|
NSString *const kTypeButton = @"button";
|
||||||
|
@ -641,9 +652,11 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
@end // @interface PickerScrubberItemView
|
@end // @interface PickerScrubberItemView
|
||||||
@implementation PickerScrubberItemView {
|
@implementation PickerScrubberItemView {
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
Data::FileOrigin _origin;
|
|
||||||
QSize _dimensions;
|
QSize _dimensions;
|
||||||
Image *_image;
|
Image *_image;
|
||||||
|
@public
|
||||||
|
Data::FileOrigin fileOrigin;
|
||||||
|
DocumentData *documentData;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(NSRect)frameRect {
|
- (instancetype)initWithFrame:(NSRect)frameRect {
|
||||||
|
@ -667,9 +680,10 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
if (!_image) {
|
if (!_image) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
fileOrigin = document->stickerSetOrigin();
|
||||||
|
documentData = std::move(document);
|
||||||
_dimensions = document->dimensions;
|
_dimensions = document->dimensions;
|
||||||
_origin = document->stickerSetOrigin();
|
_image->load(fileOrigin);
|
||||||
_image->load(_origin);
|
|
||||||
if (_image->loaded()) {
|
if (_image->loaded()) {
|
||||||
[self updateImage];
|
[self updateImage];
|
||||||
return;
|
return;
|
||||||
|
@ -689,7 +703,7 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
.scaled(kCircleDiameter, kCircleDiameter, Qt::KeepAspectRatio);
|
.scaled(kCircleDiameter, kCircleDiameter, Qt::KeepAspectRatio);
|
||||||
_imageView.image = [qt_mac_create_nsimage(
|
_imageView.image = [qt_mac_create_nsimage(
|
||||||
_image->pixSingle(
|
_image->pixSingle(
|
||||||
_origin,
|
fileOrigin,
|
||||||
size.width(),
|
size.width(),
|
||||||
size.height(),
|
size.height(),
|
||||||
kCircleDiameter,
|
kCircleDiameter,
|
||||||
|
@ -711,9 +725,7 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
@implementation PickerCustomTouchBarItem {
|
@implementation PickerCustomTouchBarItem {
|
||||||
std::vector<PickerScrubberItem> _stickers;
|
std::vector<PickerScrubberItem> _stickers;
|
||||||
NSPopoverTouchBarItem *_parentPopover;
|
NSPopoverTouchBarItem *_parentPopover;
|
||||||
std::unique_ptr<base::Timer> _previewTimer;
|
DocumentId _lastPreviewedSticker;
|
||||||
int _highlightedIndex;
|
|
||||||
bool _previewShown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init:(ScrubberItemType)type popover:(NSPopoverTouchBarItem *)popover {
|
- (id) init:(ScrubberItemType)type popover:(NSPopoverTouchBarItem *)popover {
|
||||||
|
@ -739,18 +751,65 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
[scrubber registerClass:[NSScrubberTextItemView class] forItemIdentifier:kPickerTitleItemIdentifier];
|
[scrubber registerClass:[NSScrubberTextItemView class] forItemIdentifier:kPickerTitleItemIdentifier];
|
||||||
[scrubber registerClass:[NSScrubberImageItemView class] forItemIdentifier:kEmojiItemIdentifier];
|
[scrubber registerClass:[NSScrubberImageItemView class] forItemIdentifier:kEmojiItemIdentifier];
|
||||||
|
|
||||||
_previewShown = false;
|
if (IsSticker(type)) {
|
||||||
_highlightedIndex = 0;
|
auto *gesture = [[NSPressGestureRecognizer alloc]
|
||||||
_previewTimer = !IsSticker(type)
|
initWithTarget:self
|
||||||
? nullptr
|
action:@selector(gesturePreviewHandler:)];
|
||||||
: std::make_unique<base::Timer>([=] {
|
gesture.allowedTouchTypes = NSTouchTypeMaskDirect;
|
||||||
[self showPreview];
|
gesture.minimumPressDuration = QApplication::startDragTime() / 1000.;
|
||||||
});
|
gesture.allowableMovement = 0;
|
||||||
|
[scrubber addGestureRecognizer:gesture];
|
||||||
|
}
|
||||||
|
_lastPreviewedSticker = 0;
|
||||||
|
|
||||||
self.view = scrubber;
|
self.view = scrubber;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)gesturePreviewHandler:(NSPressGestureRecognizer *)gesture {
|
||||||
|
const auto customEnter = [](const auto callback) {
|
||||||
|
Core::Sandbox::Instance().customEnterFromEventLoop([=] {
|
||||||
|
if (App::wnd()) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto checkState = [&](const auto &states) {
|
||||||
|
return ranges::find(states, gesture.state) != end(states);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (checkState(kGestureStateProcessed)) {
|
||||||
|
NSScrollView *scrollView = self.view;
|
||||||
|
auto *container = scrollView.documentView.subviews.firstObject;
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto point = [gesture locationInView:(std::move(container))];
|
||||||
|
|
||||||
|
for (PickerScrubberItemView *item in container.subviews) {
|
||||||
|
const auto &doc = item->documentData;
|
||||||
|
const auto &origin = item->fileOrigin
|
||||||
|
? item->fileOrigin
|
||||||
|
: Data::FileOrigin();
|
||||||
|
if (![item isMemberOfClass:[PickerScrubberItemView class]]
|
||||||
|
|| !doc
|
||||||
|
|| (doc->id == _lastPreviewedSticker)
|
||||||
|
|| !NSPointInRect(point, item.frame)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_lastPreviewedSticker = doc->id;
|
||||||
|
customEnter([origin = std::move(origin), doc = std::move(doc)] {
|
||||||
|
App::wnd()->showMediaPreview(origin, doc);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (checkState(kGestureStateFinished)) {
|
||||||
|
customEnter([] { App::wnd()->hideMediaPreview(); });
|
||||||
|
_lastPreviewedSticker = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
|
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
|
||||||
// Has not been implemented.
|
// Has not been implemented.
|
||||||
}
|
}
|
||||||
|
@ -765,7 +824,7 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
const auto item = _stickers[index];
|
const auto item = _stickers[index];
|
||||||
if (const auto document = item.document) {
|
if (const auto document = item.document) {
|
||||||
PickerScrubberItemView *itemView = [scrubber makeItemWithIdentifier:kStickerItemIdentifier owner:nil];
|
PickerScrubberItemView *itemView = [scrubber makeItemWithIdentifier:kStickerItemIdentifier owner:nil];
|
||||||
[itemView addDocument:document];
|
[itemView addDocument:(std::move(document))];
|
||||||
return itemView;
|
return itemView;
|
||||||
} else if (const auto emoji = item.emoji) {
|
} else if (const auto emoji = item.emoji) {
|
||||||
NSScrubberImageItemView *itemView = [scrubber makeItemWithIdentifier:kEmojiItemIdentifier owner:nil];
|
NSScrubberImageItemView *itemView = [scrubber makeItemWithIdentifier:kEmojiItemIdentifier owner:nil];
|
||||||
|
@ -791,12 +850,6 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scrubber.selectedIndex = -1;
|
scrubber.selectedIndex = -1;
|
||||||
if (_previewShown && [self hidePreview]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_previewTimer) {
|
|
||||||
_previewTimer->cancel();
|
|
||||||
}
|
|
||||||
const auto chat = GetActiveChat();
|
const auto chat = GetActiveChat();
|
||||||
|
|
||||||
const auto callback = [&]() -> bool {
|
const auto callback = [&]() -> bool {
|
||||||
|
@ -828,47 +881,6 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrubber:(NSScrubber *)scrubber didHighlightItemAtIndex:(NSInteger)index {
|
|
||||||
if (_previewTimer) {
|
|
||||||
_previewTimer->callOnce(QApplication::startDragTime());
|
|
||||||
_highlightedIndex = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)scrubber:(NSScrubber *)scrubber didChangeVisibleRange:(NSRange)visibleRange {
|
|
||||||
[self didCancelInteractingWithScrubber:scrubber];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)didCancelInteractingWithScrubber:(NSScrubber *)scrubber {
|
|
||||||
if (_previewTimer) {
|
|
||||||
_previewTimer->cancel();
|
|
||||||
}
|
|
||||||
if (_previewShown) {
|
|
||||||
[self hidePreview];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)showPreview {
|
|
||||||
if (const auto document = _stickers[_highlightedIndex].document) {
|
|
||||||
if (const auto w = App::wnd()) {
|
|
||||||
w->showMediaPreview(document->stickerSetOrigin(), document);
|
|
||||||
_previewShown = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (bool)hidePreview {
|
|
||||||
if (const auto w = App::wnd()) {
|
|
||||||
Core::Sandbox::Instance().customEnterFromEventLoop([=] {
|
|
||||||
w->hideMediaPreview();
|
|
||||||
});
|
|
||||||
_previewShown = false;
|
|
||||||
_highlightedIndex = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateStickers {
|
- (void)updateStickers {
|
||||||
std::vector<PickerScrubberItem> temp;
|
std::vector<PickerScrubberItem> temp;
|
||||||
if (const auto error = RestrictionToSendStickers()) {
|
if (const auto error = RestrictionToSendStickers()) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue