diff options
author | Damiano Galassi <[email protected]> | 2017-11-24 11:27:06 +0100 |
---|---|---|
committer | Damiano Galassi <[email protected]> | 2017-11-24 11:27:06 +0100 |
commit | 13c8582eff580913d290b98bc0a58970121ee088 (patch) | |
tree | eb4fa7ab1263664d65ed3ca53f5e807d88180cd7 /macosx/HBSummaryViewController.m | |
parent | 47d7b716b2c1f99c9d6a0ba6d2e834012d0a4d68 (diff) |
MacGui: use KVO to get a good part of the change notification in the summary view.
Diffstat (limited to 'macosx/HBSummaryViewController.m')
-rw-r--r-- | macosx/HBSummaryViewController.m | 195 |
1 files changed, 173 insertions, 22 deletions
diff --git a/macosx/HBSummaryViewController.m b/macosx/HBSummaryViewController.m index 63fb45957..7a4d84284 100644 --- a/macosx/HBSummaryViewController.m +++ b/macosx/HBSummaryViewController.m @@ -10,32 +10,53 @@ @import HandBrakeKit; +static void *HBSummaryViewControllerContext = &HBSummaryViewControllerContext; + @interface HBSummaryViewController () @property (strong) IBOutlet HBPreviewView *previewView; @property (strong) IBOutlet NSTextField *tracksLabel; @property (strong) IBOutlet NSTextField *filtersLabel; +@property (strong) IBOutlet NSTextField *dimensionLabel; + +@property (nonatomic) BOOL tracksReloadInQueue; +@property (nonatomic) BOOL filtersReloadInQueue; +@property (nonatomic) BOOL pictureReloadInQueue; + +@property (nonatomic) BOOL visible; @end @implementation HBSummaryViewController -- (void)loadView { +- (void)loadView +{ [super loadView]; self.previewView.showShadow = NO; [self resetLabels]; } +- (void)viewDidAppear +{ + self.visible = YES; + if (self.pictureReloadInQueue || self.previewView.image == NULL) + { + [self updatePicture]; + } +} + +- (void)viewDidDisappear +{ + self.visible = NO; +} + - (void)setGenerator:(HBPreviewGenerator *)generator { _generator = generator; if (generator) { - NSUInteger index = generator.imagesCount > 1 ? 1 : 0; - CGImageRef fPreviewImage = [generator copyImageAtIndex:index shouldCache:NO]; - self.previewView.image = fPreviewImage; - CFRelease(fPreviewImage); + [self updatePicture]; } else { @@ -47,9 +68,11 @@ { if (job) { + [self removeJobObservers]; _job = job; [self addJobObservers]; - [self updateLabels]; + [self updateTracksLabel]; + [self updateFiltersLabel]; } else { @@ -59,51 +82,179 @@ } } +#pragma mark - KVO + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context == HBSummaryViewControllerContext) + { + if ([keyPath isEqualToString:@"audio.tracks"]) + { + if ([change[@"kind"] integerValue] == NSKeyValueChangeInsertion) + { + [self addAudioTracksObservers:change[@"new"]]; + } + else if ([change[@"kind"] integerValue]== NSKeyValueChangeRemoval) + { + [self removeAudioTracksObservers:change[@"old"]]; + } + } + else if ([keyPath isEqualToString:@"subtitles.tracks"]) + { + if ([change[@"kind"] integerValue] == NSKeyValueChangeInsertion) + { + [self addSubtitlesTracksObservers:change[@"new"]]; + } + else if ([change[@"kind"] integerValue]== NSKeyValueChangeRemoval) + { + [self removeSubtitlesTracksObservers:change[@"old"]]; + } + } + + [self updateTracks:nil]; + } + else + { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +- (void)addAudioTracksObservers:(NSArray<HBAudioTrack *> *)tracks +{ + for (HBAudioTrack *track in tracks) + { + [track addObserver:self forKeyPath:@"encoder" options:0 context:HBSummaryViewControllerContext]; + [track addObserver:self forKeyPath:@"mixdown" options:0 context:HBSummaryViewControllerContext]; + } +} + +- (void)removeAudioTracksObservers:(NSArray<HBAudioTrack *> *)tracks +{ + for (HBAudioTrack *track in tracks) + { + [track removeObserver:self forKeyPath:@"encoder"]; + [track removeObserver:self forKeyPath:@"mixdown"]; + } +} + +- (void)addSubtitlesTracksObservers:(NSArray<HBSubtitlesTrack *> *)tracks +{ + for (HBSubtitlesTrack *track in tracks) + { + [track addObserver:self forKeyPath:@"burnedIn" options:0 context:HBSummaryViewControllerContext]; + } +} + +- (void)removeSubtitlesTracksObservers:(NSArray<HBSubtitlesTrack *> *)tracks +{ + for (HBSubtitlesTrack *track in tracks) + { + [track removeObserver:self forKeyPath:@"burnedIn"]; + } +} + +- (void)addJobObservers +{ + if (_job) + { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePicture:) name:HBPictureChangedNotification object:_job.picture]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateFilters:) name:HBFiltersChangedNotification object:_job.filters]; + + [_job addObserver:self forKeyPath:@"video.encoder" options:0 context:HBSummaryViewControllerContext]; + [_job addObserver:self forKeyPath:@"video.frameRate" options:0 context:HBSummaryViewControllerContext]; + [_job addObserver:self forKeyPath:@"video.frameRateMode" options:0 context:HBSummaryViewControllerContext]; + [_job addObserver:self forKeyPath:@"container" options:0 context:HBSummaryViewControllerContext]; + [_job addObserver:self forKeyPath:@"chaptersEnabled" options:0 context:HBSummaryViewControllerContext]; + [_job addObserver:self forKeyPath:@"audio.tracks" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:HBSummaryViewControllerContext]; + [_job addObserver:self forKeyPath:@"subtitles.tracks" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:HBSummaryViewControllerContext]; + + [self addAudioTracksObservers:_job.audio.tracks]; + [self addSubtitlesTracksObservers:_job.subtitles.tracks]; + } +} + - (void)removeJobObservers { - if (self.job) + if (_job) { - [[NSNotificationCenter defaultCenter] removeObserver:self name:HBContainerChangedNotification object:_job]; [[NSNotificationCenter defaultCenter] removeObserver:self name:HBPictureChangedNotification object:_job.picture]; [[NSNotificationCenter defaultCenter] removeObserver:self name:HBFiltersChangedNotification object:_job.filters]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:HBVideoChangedNotification object:_job.video]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:HBAudioChangedNotification object:_job.audio]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:HBChaptersChangedNotification object:_job]; + + [_job removeObserver:self forKeyPath:@"video.encoder"]; + [_job removeObserver:self forKeyPath:@"video.frameRate"]; + [_job removeObserver:self forKeyPath:@"video.frameRateMode"]; + [_job removeObserver:self forKeyPath:@"container"]; + [_job removeObserver:self forKeyPath:@"chaptersEnabled"]; + [_job removeObserver:self forKeyPath:@"audio.tracks"]; + [_job removeObserver:self forKeyPath:@"subtitles.tracks"]; + + [self removeAudioTracksObservers:_job.audio.tracks]; + [self removeSubtitlesTracksObservers:_job.subtitles.tracks]; } } - (void)updateTracks:(NSNotification *)notification { - self.tracksLabel.stringValue = self.job.shortDescription; + if (self.tracksReloadInQueue == NO) + { + [[NSRunLoop mainRunLoop] performSelector:@selector(updateTracksLabel) target:self argument:nil order:0 modes:@[NSDefaultRunLoopMode]]; + self.tracksReloadInQueue = YES; + } } - (void)updateFilters:(NSNotification *)notification { - self.filtersLabel.stringValue = self.job.filtersShortDescription; + if (self.filtersReloadInQueue == NO) + { + [[NSRunLoop mainRunLoop] performSelector:@selector(updateFiltersLabel) target:self argument:nil order:0 modes:@[NSDefaultRunLoopMode]]; + self.filtersReloadInQueue = YES; + } +} + +- (void)updatePicture:(NSNotification *)notification +{ + // Enquee the reload call on the main runloop + // to avoid reloading the same image multiple times. + if (self.pictureReloadInQueue == NO) + { + [[NSRunLoop mainRunLoop] performSelector:@selector(updatePicture) target:self argument:nil order:0 modes:@[NSDefaultRunLoopMode]]; + self.pictureReloadInQueue = YES; + } } - (void)resetLabels { self.tracksLabel.stringValue = NSLocalizedString(@"None", nil); self.filtersLabel.stringValue = NSLocalizedString(@"None", nil); + self.dimensionLabel.stringValue = NSLocalizedString(@"None", nil); + self.tracksReloadInQueue = NO; + self.filtersReloadInQueue = NO; + self.pictureReloadInQueue = NO; } -- (void)updateLabels +- (void)updateTracksLabel { self.tracksLabel.stringValue = self.job.shortDescription; + self.tracksReloadInQueue = NO; +} + +- (void)updateFiltersLabel +{ self.filtersLabel.stringValue = self.job.filtersShortDescription; + self.filtersReloadInQueue = NO; } -- (void)addJobObservers +- (void)updatePicture { - if (self.job) + if (self.visible && self.generator) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTracks:) name:HBContainerChangedNotification object:_job]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTracks:) name:HBPictureChangedNotification object:_job.picture]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateFilters:) name:HBFiltersChangedNotification object:_job.filters]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTracks:) name:HBVideoChangedNotification object:_job.video]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTracks:) name:HBAudioChangedNotification object:_job.audio]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTracks:) name:HBChaptersChangedNotification object:_job]; + NSUInteger index = self.generator.imagesCount > 1 ? 1 : 0; + CGImageRef fPreviewImage = [self.generator copyImageAtIndex:index shouldCache:NO]; + self.previewView.image = fPreviewImage; + CFRelease(fPreviewImage); + self.pictureReloadInQueue = NO; + + self.dimensionLabel.stringValue = self.job.picture.shortInfo; } } |