diff options
-rw-r--r-- | macosx/English.lproj/HBPreviewViewController.xib | 77 | ||||
-rw-r--r-- | macosx/English.lproj/HBSummaryViewController.xib | 7 | ||||
-rw-r--r-- | macosx/HBPreviewViewController.h | 19 | ||||
-rw-r--r-- | macosx/HBPreviewViewController.m | 209 | ||||
-rw-r--r-- | macosx/HBSummaryViewController.m | 60 |
5 files changed, 326 insertions, 46 deletions
diff --git a/macosx/English.lproj/HBPreviewViewController.xib b/macosx/English.lproj/HBPreviewViewController.xib new file mode 100644 index 000000000..94364a9a5 --- /dev/null +++ b/macosx/English.lproj/HBPreviewViewController.xib @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> + <dependencies> + <deployment identifier="macosx"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="HBPreviewViewController"> + <connections> + <outlet property="hud" destination="Fn2-om-hEi" id="Fck-vd-r8e"/> + <outlet property="previewView" destination="wh8-oO-lCN" id="dCK-4h-Ho2"/> + <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/> + </connections> + </customObject> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> + <customView id="Hz6-mo-xeY"> + <rect key="frame" x="0.0" y="0.0" width="640" height="480"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <customView wantsLayer="YES" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wh8-oO-lCN" customClass="HBPreviewView" propertyAccessControl="all"> + <rect key="frame" x="0.0" y="0.0" width="640" height="480"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + </customView> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="Fn2-om-hEi" customClass="HBHUDView"> + <rect key="frame" x="280" y="40" width="80" height="26"/> + <subviews> + <button toolTip="Toggle Play/Pause" translatesAutoresizingMaskIntoConstraints="NO" id="5po-M6-Hqa"> + <rect key="frame" x="44" y="5" width="24" height="18"/> + <constraints> + <constraint firstAttribute="width" constant="24" id="8M6-qp-Hbs"/> + <constraint firstAttribute="height" constant="18" id="pHH-yR-lLG"/> + </constraints> + <buttonCell key="cell" type="square" title="›" bezelStyle="shadowlessSquare" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" id="Izx-9B-XA3"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system" size="18"/> + </buttonCell> + <accessibility description="Play/Pause"/> + <connections> + <action selector="next:" target="-2" id="IlJ-w9-A9q"/> + </connections> + </button> + <button toolTip="Toggle Play/Pause" translatesAutoresizingMaskIntoConstraints="NO" id="1o6-MG-Jbu"> + <rect key="frame" x="12" y="6" width="24" height="16"/> + <constraints> + <constraint firstAttribute="height" constant="16" id="efr-28-vaL"/> + <constraint firstAttribute="width" constant="24" id="tBw-VV-Jdp"/> + </constraints> + <buttonCell key="cell" type="square" title="‹" bezelStyle="shadowlessSquare" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" id="EWx-of-C7c"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system" size="18"/> + </buttonCell> + <accessibility description="Play/Pause"/> + <connections> + <action selector="previous:" target="-2" id="UxL-j8-GeJ"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstItem="1o6-MG-Jbu" firstAttribute="centerY" secondItem="5po-M6-Hqa" secondAttribute="centerY" id="aSW-vr-iFV"/> + <constraint firstAttribute="trailing" secondItem="5po-M6-Hqa" secondAttribute="trailing" constant="12" id="esD-wC-uht"/> + <constraint firstItem="5po-M6-Hqa" firstAttribute="leading" secondItem="1o6-MG-Jbu" secondAttribute="trailing" constant="8" id="gSU-gO-hbY"/> + <constraint firstAttribute="height" constant="26" id="sJO-EZ-FmV"/> + <constraint firstItem="1o6-MG-Jbu" firstAttribute="leading" secondItem="Fn2-om-hEi" secondAttribute="leading" constant="12" id="tO0-TJ-Bm0"/> + <constraint firstItem="1o6-MG-Jbu" firstAttribute="top" secondItem="Fn2-om-hEi" secondAttribute="top" constant="4" id="ysh-ll-QCP"/> + </constraints> + </customView> + </subviews> + <constraints> + <constraint firstItem="Fn2-om-hEi" firstAttribute="centerX" secondItem="Hz6-mo-xeY" secondAttribute="centerX" id="1DU-Zn-HTj"/> + <constraint firstAttribute="bottom" secondItem="Fn2-om-hEi" secondAttribute="bottom" constant="40" id="M3h-dq-YzY"/> + </constraints> + <point key="canvasLocation" x="-376" y="-8"/> + </customView> + </objects> +</document> diff --git a/macosx/English.lproj/HBSummaryViewController.xib b/macosx/English.lproj/HBSummaryViewController.xib index 942816e26..e7df77063 100644 --- a/macosx/English.lproj/HBSummaryViewController.xib +++ b/macosx/English.lproj/HBSummaryViewController.xib @@ -1,9 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <dependencies> <deployment identifier="macosx"/> - <development version="8000" identifier="xcode"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13529"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <objects> @@ -95,7 +94,7 @@ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> </textFieldCell> </textField> - <customView wantsLayer="YES" translatesAutoresizingMaskIntoConstraints="NO" id="m5a-0z-QQ4" customClass="HBPreviewView"> + <customView wantsLayer="YES" translatesAutoresizingMaskIntoConstraints="NO" id="m5a-0z-QQ4"> <rect key="frame" x="295" y="16" width="556" height="334"/> </customView> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="100" translatesAutoresizingMaskIntoConstraints="NO" id="Jgq-K8-z3W"> diff --git a/macosx/HBPreviewViewController.h b/macosx/HBPreviewViewController.h new file mode 100644 index 000000000..d3101a540 --- /dev/null +++ b/macosx/HBPreviewViewController.h @@ -0,0 +1,19 @@ +// +// HBPreviewViewController.h +// HandBrake +// +// Created by Damiano Galassi on 14/12/2017. +// + +#import <Cocoa/Cocoa.h> + +@class HBPreviewGenerator; +@class HBPreviewController; + +@interface HBPreviewViewController : NSViewController + +@property (nonatomic, readwrite, weak, nullable) HBPreviewGenerator *generator; + +- (void)update; + +@end diff --git a/macosx/HBPreviewViewController.m b/macosx/HBPreviewViewController.m new file mode 100644 index 000000000..a9e275e28 --- /dev/null +++ b/macosx/HBPreviewViewController.m @@ -0,0 +1,209 @@ +// +// HBPreviewViewController.m +// HandBrake +// +// Created by Damiano Galassi on 14/12/2017. +// + +#import <QuartzCore/QuartzCore.h> +#import "HBPreviewViewController.h" + +#import "HBPreviewView.h" +#import "HBPreviewGenerator.h" +#import "HBPreviewController.h" + +@interface HBPreviewViewController () + +@property (nonatomic, strong) IBOutlet HBPreviewView *previewView; + +@property (nonatomic, strong) IBOutlet NSView *hud; + +@property (nonatomic) NSInteger selectedIndex; +@property (nonatomic) BOOL visible; + +@property (nonatomic) NSTimer *hudTimer; +@property (nonatomic) BOOL mouseInView; + +@end + +@implementation HBPreviewViewController + +- (instancetype)init +{ + self = [super initWithNibName:@"HBPreviewViewController" bundle:nil]; + if (self) + { + _selectedIndex = 1; + } + return self; +} + +- (void)loadView +{ + [super loadView]; + self.visible = YES; + self.previewView.showShadow = NO; + + NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.view.frame + options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways + owner:self + userInfo:nil]; + [self.view addTrackingArea:trackingArea]; + self.hud.hidden = YES; + self.hud.layer.opacity = 0; +} + +- (void)viewWillAppear +{ + self.visible = YES; + [self updatePicture]; +} + +- (void)viewDidDisappear +{ + self.visible = NO; +} + +- (void)setGenerator:(HBPreviewGenerator *)generator +{ + _generator = generator; + if (generator) + { + self.selectedIndex = self.selectedIndex; + [self updatePicture]; + } + else + { + self.previewView.image = nil; + } +} + +- (void)update +{ + [self updatePicture]; +} + +#pragma MARK: - HUD + +- (void)mouseEntered:(NSEvent *)theEvent +{ + if (self.generator) + { + [self showHudWithAnimation:self.hud]; + } + self.mouseInView = YES; +} + +- (void)mouseMoved:(NSEvent *)theEvent +{ + [super mouseMoved:theEvent]; + + // Test for mouse location to show/hide hud controls + if (self.generator && self.mouseInView) + { + [self showHudWithAnimation:self.hud]; + } +} + +- (void)mouseExited:(NSEvent *)theEvent +{ + [self hideHudWithAnimation:self.hud]; + self.mouseInView = NO; +} + +#define ANIMATION_DUR 0.15 + +- (void)showHudWithAnimation:(NSView *)hud +{ + // The standard view animator doesn't play + // nicely with the Yosemite visual effects yet. + // So let's do the fade ourself. + if (hud.layer.opacity == 0 || hud.isHidden) + { + hud.hidden = NO; + + [CATransaction begin]; + CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; + fadeInAnimation.fromValue = @(hud.layer.presentationLayer.opacity); + fadeInAnimation.toValue = @(1.0); + fadeInAnimation.beginTime = 0.0; + fadeInAnimation.duration = ANIMATION_DUR; + + [hud.layer addAnimation:fadeInAnimation forKey:nil]; + [hud.layer setOpacity:1]; + + [CATransaction commit]; + } +} + +- (void)hideHudWithAnimation:(NSView *)hud +{ + if (hud.layer.opacity != 0) + { + [CATransaction begin]; + CABasicAnimation *fadeOutAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; + fadeOutAnimation.fromValue = @(hud.layer.presentationLayer.opacity); + fadeOutAnimation.toValue = @(0.0); + fadeOutAnimation.beginTime = 0.0; + fadeOutAnimation.duration = ANIMATION_DUR; + + [hud.layer addAnimation:fadeOutAnimation forKey:nil]; + [hud.layer setOpacity:0]; + + [CATransaction commit]; + } +} + +#pragma MARK: - Preview index + +- (void)setSelectedIndex:(NSInteger)selectedIndex +{ + NSInteger count = self.generator.imagesCount; + if (selectedIndex >= count) + { + selectedIndex = count -1; + } + else if (selectedIndex < 0) + { + selectedIndex = 0; + } + _selectedIndex = selectedIndex; +} + +- (IBAction)next:(id)sender +{ + self.selectedIndex += 1; + [self updatePicture]; +} + +- (IBAction)previous:(id)sender +{ + self.selectedIndex -= 1; + [self updatePicture]; +} + +- (void)updatePicture +{ + if (self.generator && self.visible) + { + CGImageRef fPreviewImage = [self.generator copyImageAtIndex:self.selectedIndex shouldCache:YES]; + self.previewView.image = fPreviewImage; + CFRelease(fPreviewImage); + } +} + +- (void)scrollWheel:(NSEvent *)theEvent +{ + if (theEvent.deltaY < 0) + { + self.selectedIndex += 1; + [self updatePicture]; + } + else if (theEvent.deltaY > 0) + { + self.selectedIndex -= 1; + [self updatePicture]; + } +} + +@end diff --git a/macosx/HBSummaryViewController.m b/macosx/HBSummaryViewController.m index e16f26e87..52c192172 100644 --- a/macosx/HBSummaryViewController.m +++ b/macosx/HBSummaryViewController.m @@ -5,7 +5,8 @@ It may be used under the terms of the GNU General Public License. */ #import "HBSummaryViewController.h" -#import "HBPreviewView.h" + +#import "HBPreviewViewController.h" #import "HBPreviewGenerator.h" @import HandBrakeKit; @@ -25,14 +26,14 @@ static void *HBSummaryViewControllerSubsContext = &HBSummaryViewControllerSubsCo @property (nonatomic, strong) IBOutlet NSTextField *filtersLabel; @property (nonatomic, strong) IBOutlet NSTextField *dimensionLabel; -@property (nonatomic, strong) IBOutlet HBPreviewView *previewView; +@property (nonatomic, strong) IBOutlet NSView *previewView; + +@property (nonatomic, strong) HBPreviewViewController *previewViewController; @property (nonatomic) BOOL tracksReloadInQueue; @property (nonatomic) BOOL filtersReloadInQueue; @property (nonatomic) BOOL pictureReloadInQueue; -@property (nonatomic) BOOL visible; - @end @implementation HBSummaryViewController @@ -40,43 +41,25 @@ static void *HBSummaryViewControllerSubsContext = &HBSummaryViewControllerSubsCo - (instancetype)init { self = [super initWithNibName:@"HBSummaryViewController" bundle:nil]; + if (self) + { + _previewViewController = [[HBPreviewViewController alloc] init]; + } return self; } - (void)loadView { [super loadView]; - self.previewView.showShadow = NO; - self.visible = YES; + self.previewViewController.view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + self.previewViewController.view.frame = NSMakeRect(0, 0, self.previewView.frame.size.width, self.previewView.frame.size.height); + [self.previewView addSubview:self.previewViewController.view]; [self resetLabels]; } -- (void)viewWillAppear -{ - 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) - { - [self updatePicture]; - } - else - { - self.previewView.image = nil; - } + self.previewViewController.generator = generator; } - (void)setJob:(HBJob *)job @@ -258,7 +241,7 @@ static void *HBSummaryViewControllerSubsContext = &HBSummaryViewControllerSubsCo // 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]]; + [[NSRunLoop mainRunLoop] performSelector:@selector(updatePictureLabel) target:self argument:nil order:0 modes:@[NSDefaultRunLoopMode]]; self.pictureReloadInQueue = YES; } } @@ -285,18 +268,11 @@ static void *HBSummaryViewControllerSubsContext = &HBSummaryViewControllerSubsCo self.filtersReloadInQueue = NO; } -- (void)updatePicture +- (void)updatePictureLabel { - if (self.visible && self.generator) - { - 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; - } + self.pictureReloadInQueue = NO; + self.dimensionLabel.stringValue = self.job.picture.shortInfo; + [self.previewViewController update]; } @end |