- (void)_touchBar_reloadScrubberData;
- (void)_touchBar_updateScrubberSelectedIndex:(NSUInteger)selectedIndex;
- (void)_touchBar_updateFitToView:(BOOL)fitToView;
+- (void)_touchBar_validateUserInterfaceItems;
@end
if (@available(macOS 10.12.2, *))
{
[self _touchBar_reloadScrubberData];
+ [self _touchBar_validateUserInterfaceItems];
}
}
}
}
+- (BOOL)validateUserIterfaceItemForAction:(SEL)action
+{
+ if (action == @selector(createMoviePreview:) || action == @selector(toggleScaleToScreen:))
+ {
+ return self.generator != nil;
+ }
+ return YES;
+}
+
- (IBAction)previewDurationPopUpChanged:(id)sender
{
[[NSUserDefaults standardUserDefaults] setObject:self.durationPopUp.titleOfSelectedItem forKey:@"PreviewLength"];
static NSTouchBarItemIdentifier HBTouchBarMain = @"fr.handbrake.previewWindowTouchBar";
static NSTouchBarItemIdentifier HBTouchBarRip = @"fr.handbrake.rip";
-static NSTouchBarItemIdentifier HBTouchBarScrubber = @"fr.handbrake.scrubbe";
+static NSTouchBarItemIdentifier HBTouchBarScrubber = @"fr.handbrake.scrubber";
static NSTouchBarItemIdentifier HBTouchBarFitToScreen = @"fr.handbrake.fitToScreen";
@dynamic touchBar;
}
}
+- (void)_touchBar_validateUserInterfaceItems
+{
+ for (NSTouchBarItemIdentifier identifier in self.touchBar.itemIdentifiers) {
+ NSTouchBarItem *item = [self.touchBar itemForIdentifier:identifier];
+ NSView *view = item.view;
+ if ([view isKindOfClass:[NSButton class]]) {
+ NSButton *button = (NSButton *)view;
+ BOOL enabled = [self validateUserIterfaceItemForAction:button.action];
+ button.enabled = enabled;
+ }
+ }
+}
+
@end
@property (nonatomic, readonly) NSCache<NSNumber *, id> *previewsCache;
@property (nonatomic, readonly) NSCache<NSNumber *, id> *smallPreviewsCache;
-@property (nonatomic, readonly) dispatch_semaphore_t sem;
+@property (nonatomic, readonly) dispatch_queue_t queue;
+@property (nonatomic, readonly) dispatch_group_t group;
@property (nonatomic, readonly) _Atomic bool invalidated;
@property (nonatomic, strong) HBCore *core;
_imagesCount = [_scanCore imagesCountForTitle:self.job.title];
- _sem = dispatch_semaphore_create(4);
+ _queue = dispatch_queue_create("fr.handbrake.PreviewQueue", DISPATCH_QUEUE_SERIAL);
+ _group = dispatch_group_create();
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imagesSettingsDidChange) name:HBPictureChangedNotification object:job.picture];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imagesSettingsDidChange) name:HBFiltersChangedNotification object:job.filters];
- (void)copySmallImageAtIndex:(NSUInteger)index completionHandler:(void (^)(__nullable CGImageRef result))handler
{
- dispatch_semaphore_wait(_sem, DISPATCH_TIME_FOREVER);
-
if (_invalidated || index >= self.imagesCount)
{
handler(NULL);
- dispatch_semaphore_signal(_sem);
return;
}
- CGImageRef image;
+ dispatch_group_async(_group, _queue,^{
- // First try to look in the small previews cache
- image = (__bridge CGImageRef)([_smallPreviewsCache objectForKey:@(index)]);
+ if (self->_invalidated || index >= self.imagesCount)
+ {
+ handler(NULL);
+ return;
+ }
- if (image != NULL)
- {
- handler(image);
- dispatch_semaphore_signal(_sem);
- return;
- }
+ CGImageRef image;
- // Else try the normal cache
- image = (__bridge CGImageRef)([_previewsCache objectForKey:@(index)]);
+ // First try to look in the small previews cache
+ image = (__bridge CGImageRef)([self->_smallPreviewsCache objectForKey:@(index)]);
- if (image == NULL)
- {
- image = (CGImageRef)[self.scanCore copyImageAtIndex:index
- forTitle:self.job.title
- pictureFrame:self.job.picture
- deinterlace:NO
- rotate:self.job.filters.rotate
- flipped:self.job.filters.flip];
- CFAutorelease(image);
- }
+ if (image != NULL)
+ {
+ handler(image);
+ return;
+ }
- if (image != NULL)
- {
- CGImageRef scaledImage = CreateScaledCGImageFromCGImage(image, 30);
- // The cost is the number of pixels of the image
- NSUInteger previewCost = CGImageGetWidth(scaledImage) * CGImageGetHeight(scaledImage);
- [self.smallPreviewsCache setObject:(__bridge id)(scaledImage) forKey:@(index) cost:previewCost];
- handler(scaledImage);
- dispatch_semaphore_signal(_sem);
- return;
- }
+ // Else try the normal cache
+ image = (__bridge CGImageRef)([self->_previewsCache objectForKey:@(index)]);
+
+ if (image == NULL)
+ {
+ image = (CGImageRef)[self.scanCore copyImageAtIndex:index
+ forTitle:self.job.title
+ pictureFrame:self.job.picture
+ deinterlace:NO
+ rotate:self.job.filters.rotate
+ flipped:self.job.filters.flip];
+ CFAutorelease(image);
+ }
- handler(NULL);
- dispatch_semaphore_signal(_sem);
+ if (image != NULL)
+ {
+ CGImageRef scaledImage = CreateScaledCGImageFromCGImage(image, 30);
+ // The cost is the number of pixels of the image
+ NSUInteger previewCost = CGImageGetWidth(scaledImage) * CGImageGetHeight(scaledImage);
+ [self.smallPreviewsCache setObject:(__bridge id)(scaledImage) forKey:@(index) cost:previewCost];
+ handler(scaledImage);
+ return;
+ }
+
+ handler(NULL);
+ });
}
#pragma mark -
}
}
+- (void)invalidate
+{
+ _invalidated = true;
+ dispatch_group_wait(_group, DISPATCH_TIME_FOREVER);
+}
+
@end
_imageView.hidden = YES;
- dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
- HBPreviewGenerator *generator = self.generator;
-
- [generator copySmallImageAtIndex:thumbnailIndex completionHandler:^(CGImageRef _Nullable result)
- {
- if (result != NULL)
- {
- NSSize size = NSMakeSize(CGImageGetWidth(result), CGImageGetHeight(result));
- NSImage *thumbnail = [[NSImage alloc] initWithCGImage:result size:size];
-
- dispatch_async(dispatch_get_main_queue(), ^{
- [self setThumbnail:thumbnail];
- });
- }
- else
- {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self setThumbnail:nil];
- });
- }
- }];
- });
+ [self.generator copySmallImageAtIndex:thumbnailIndex completionHandler:^(CGImageRef _Nullable result)
+ {
+ if (result != NULL)
+ {
+ NSSize size = NSMakeSize(CGImageGetWidth(result), CGImageGetHeight(result));
+ NSImage *thumbnail = [[NSImage alloc] initWithCGImage:result size:size];
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self setThumbnail:thumbnail];
+ });
+ }
+ else
+ {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self setThumbnail:nil];
+ });
+ }
+ }];
}
@end