summaryrefslogtreecommitdiffstats
path: root/macosx/HBPreviewController.m
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/HBPreviewController.m')
-rw-r--r--macosx/HBPreviewController.m777
1 files changed, 215 insertions, 562 deletions
diff --git a/macosx/HBPreviewController.m b/macosx/HBPreviewController.m
index 4e7d259e2..1db48cdcd 100644
--- a/macosx/HBPreviewController.m
+++ b/macosx/HBPreviewController.m
@@ -1,4 +1,4 @@
-/* $Id: HBPreviewController.mm,v 1.11 2005/08/01 15:10:44 titer Exp $
+/* $Id: HBPreviewController.m $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.fr/>.
@@ -8,65 +8,42 @@
#import "HBPreviewGenerator.h"
#import "HBPictureController.h"
+#import "HBController.h"
#import "HBPreviewView.h"
-#import "HBController.h"
+#import "HBPlayer.h"
+#import "HBQTKitPlayer.h"
+#import "HBAVPlayer.h"
-#import <QTKit/QTKit.h>
-#import "QTKit+HBQTMovieExtensions.h"
+#import "HBPictureHUDController.h"
+#import "HBEncodingProgressHUDController.h"
+#import "HBPlayerHUDController.h"
+
+#import "NSWindow+HBAdditions.h"
#define ANIMATION_DUR 0.15
+#define HUD_FADEOUT_TIME 4.0
-// make min width and height of preview window large enough for hud
+// Make min width and height of preview window large enough for hud.
#define MIN_WIDTH 480.0
#define MIN_HEIGHT 360.0
-typedef enum ViewMode : NSUInteger {
- ViewModePicturePreview,
- ViewModeEncoding,
- ViewModeMoviePreview
-} ViewMode;
+@interface HBPreviewController () <HBPreviewGeneratorDelegate, HBPictureHUDControllerDelegate, HBEncodingProgressHUDControllerDelegate, HBPlayerHUDControllerDelegate>
-@interface HBPreviewController () <HBPreviewGeneratorDelegate>
-{
- /* HUD boxes */
- IBOutlet NSView * fPictureControlBox;
- IBOutlet NSView * fEncodingControlBox;
- IBOutlet NSView * fMoviePlaybackControlBox;
+@property (nonatomic, readonly) HBPictureHUDController *pictureHUD;
+@property (nonatomic, readonly) HBEncodingProgressHUDController *encodingHUD;
+@property (nonatomic, readonly) HBPlayerHUDController *playerHUD;
- IBOutlet NSSlider * fPictureSlider;
- IBOutlet NSTextField * fInfoField;
- IBOutlet NSTextField * fscaleInfoField;
+@property (nonatomic, readwrite) NSViewController<HBHUD> *currentHUD;
- /* Full Screen Mode Toggle */
- IBOutlet NSButton * fScaleToScreenToggleButton;
+@property (nonatomic) NSTimer *hudTimer;
+@property (nonatomic) BOOL mouseInWindow;
- /* Movie Previews */
- IBOutlet QTMovieView * fMovieView;
- /* Playback Panel Controls */
- IBOutlet NSButton * fPlayPauseButton;
- IBOutlet NSSlider * fMovieScrubberSlider;
- IBOutlet NSTextField * fMovieInfoField;
-
- IBOutlet NSProgressIndicator * fMovieCreationProgressIndicator;
- IBOutlet NSTextField * fPreviewMovieStatusField;
-
- /* Popup of choices for length of preview in seconds */
- IBOutlet NSPopUpButton * fPreviewMovieLengthPopUp;
-}
+@property (nonatomic) id<HBPlayer> player;
-@property (nonatomic, readwrite) HBPictureController *pictureSettingsWindow;
+@property (nonatomic) HBPictureController *pictureSettingsWindow;
-@property (nonatomic) ViewMode currentViewMode;
@property (nonatomic) NSPoint windowCenterPoint;
-
-@property (nonatomic, strong) NSTimer *hudTimer;
-
-@property (nonatomic) NSUInteger pictureIndex;
-
-@property (nonatomic, strong) QTMovie *movie;
-@property (nonatomic, strong) NSTimer *movieTimer;
-
@property (weak) IBOutlet HBPreviewView *previewView;
@end
@@ -92,51 +69,48 @@ typedef enum ViewMode : NSUInteger {
{
NSPoint center = NSPointFromString(centerString);
self.windowCenterPoint = center;
- [self resizeWindowForViewSize:NSMakeSize(MIN_WIDTH, MIN_HEIGHT) animate:NO];
+ [self.window HB_resizeToBestSizeForViewSize:NSMakeSize(MIN_WIDTH, MIN_HEIGHT) center:self.windowCenterPoint animate:NO];
}
else
{
- self.windowCenterPoint = [self centerPoint];
+ self.windowCenterPoint = [self.window HB_centerPoint];
}
self.window.excludedFromWindowsMenu = YES;
self.window.acceptsMouseMovedEvents = YES;
- // we set the preview length popup in seconds
- [fPreviewMovieLengthPopUp removeAllItems];
- [fPreviewMovieLengthPopUp addItemsWithTitles:@[@"15", @"30", @"45", @"60", @"90",
- @"120", @"150", @"180", @"210", @"240"]];
+ _pictureHUD = [[HBPictureHUDController alloc] init];
+ self.pictureHUD.delegate = self;
+ _encodingHUD = [[HBEncodingProgressHUDController alloc] init];
+ self.encodingHUD.delegate = self;
+ _playerHUD = [[HBPlayerHUDController alloc] init];
+ self.playerHUD.delegate = self;
- if ([[NSUserDefaults standardUserDefaults] objectForKey:@"PreviewLength"])
- {
- [fPreviewMovieLengthPopUp selectItemWithTitle:[[NSUserDefaults standardUserDefaults]
- objectForKey:@"PreviewLength"]];
- }
- if (!fPreviewMovieLengthPopUp.selectedItem)
- {
- // currently hard set default to 15 seconds
- [fPreviewMovieLengthPopUp selectItemAtIndex: 0];
- }
+ [self.window.contentView addSubview:self.pictureHUD.view];
+ [self.window.contentView addSubview:self.encodingHUD.view];
+ [self.window.contentView addSubview:self.playerHUD.view];
// Relocate our hud origins.
- NSPoint hudControlBoxOrigin = fMoviePlaybackControlBox.frame.origin;
- fPictureControlBox.frameOrigin = hudControlBoxOrigin;
- fEncodingControlBox.frameOrigin = hudControlBoxOrigin;
- fMoviePlaybackControlBox.frameOrigin = hudControlBoxOrigin;
+ CGPoint origin = CGPointMake(floor((MIN_WIDTH - _pictureHUD.view.bounds.size.width) / 2), MIN_HEIGHT / 10);
+
+ [self.pictureHUD.view setFrameOrigin:origin];
+ [self.encodingHUD.view setFrameOrigin:origin];
+ [self.playerHUD.view setFrameOrigin:origin];
- [self hideHud];
+ self.currentHUD = self.pictureHUD;
+ self.currentHUD.view.hidden = YES;
- fMovieView.hidden = YES;
- fMovieView.delegate = self;
- [fMovieView setControllerVisible:NO];
+ NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.window.contentView.frame
+ options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
+ owner:self
+ userInfo:nil];
+ [self.window.contentView addTrackingArea:trackingArea];
}
- (void)dealloc
{
- [self removeMovieObservers];
-
[_hudTimer invalidate];
- [_movieTimer invalidate];
+ _generator.delegate = nil;
[_generator cancel];
}
@@ -188,21 +162,13 @@ typedef enum ViewMode : NSUInteger {
generator.delegate = self;
// adjust the preview slider length
- [fPictureSlider setMaxValue: generator.imagesCount - 1.0];
- [fPictureSlider setNumberOfTickMarks: generator.imagesCount];
-
- if (self.pictureIndex > generator.imagesCount)
- {
- self.pictureIndex = generator.imagesCount - 1;
- }
-
- [self switchViewToMode:ViewModePicturePreview];
- [self displayPreviewAtIndex:self.pictureIndex];
+ self.pictureHUD.pictureCount = generator.imagesCount;
+ [self switchStateToHUD:self.pictureHUD];
}
else
{
self.previewView.image = nil;
- [self hideHud];
+ self.currentHUD.view.hidden = YES;
self.window.title = NSLocalizedString(@"Preview", nil);
}
}
@@ -212,8 +178,7 @@ typedef enum ViewMode : NSUInteger {
if (self.generator)
{
[self.generator cancel];
- [self switchViewToMode:ViewModePicturePreview];
- [self displayPreviewAtIndex:self.pictureIndex];
+ [self switchStateToHUD:self.pictureHUD];
}
}
@@ -221,11 +186,7 @@ typedef enum ViewMode : NSUInteger {
{
[super showWindow:sender];
- if (self.currentViewMode == ViewModeMoviePreview)
- {
- [self startMovieTimer];
- }
- else if (self.currentViewMode == ViewModePicturePreview)
+ if (self.currentHUD == self.pictureHUD)
{
[self reloadPreviews];
}
@@ -233,14 +194,13 @@ typedef enum ViewMode : NSUInteger {
- (void)windowWillClose:(NSNotification *)aNotification
{
- if (self.currentViewMode == ViewModeEncoding)
+ if (self.currentHUD == self.encodingHUD)
{
- [self cancelCreateMoviePreview:self];
+ [self cancelEncoding];
}
- else if (self.currentViewMode == ViewModeMoviePreview)
+ else if (self.currentHUD == self.playerHUD)
{
- [fMovieView pause:self];
- [self stopMovieTimer];
+ [self.player pause];
}
[self.pictureSettingsWindow close];
@@ -249,11 +209,10 @@ typedef enum ViewMode : NSUInteger {
- (void)windowDidChangeBackingProperties:(NSNotification *)notification
{
- NSWindow *theWindow = (NSWindow *)[notification object];
+ NSWindow *theWindow = (NSWindow *)notification.object;
- CGFloat newBackingScaleFactor = [theWindow backingScaleFactor];
- CGFloat oldBackingScaleFactor = [[notification userInfo][@"NSBackingPropertyOldScaleFactorKey"]
- doubleValue];
+ CGFloat newBackingScaleFactor = theWindow.backingScaleFactor;
+ CGFloat oldBackingScaleFactor = [notification.userInfo[@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
if (newBackingScaleFactor != oldBackingScaleFactor)
{
@@ -268,20 +227,11 @@ typedef enum ViewMode : NSUInteger {
#pragma mark - Window sizing
-/**
- * Calculates and returns the center point of the window
- */
-- (NSPoint)centerPoint {
- NSPoint center = NSMakePoint(floor(self.window.frame.origin.x + self.window.frame.size.width / 2),
- floor(self.window.frame.origin.y + self.window.frame.size.height / 2));
- return center;
-}
-
- (void)windowDidMove:(NSNotification *)notification
{
if (self.previewView.fitToView == NO)
{
- self.windowCenterPoint = [self centerPoint];
+ self.windowCenterPoint = [self.window HB_centerPoint];
[[NSUserDefaults standardUserDefaults] setObject:NSStringFromPoint(self.windowCenterPoint) forKey:@"HBPreviewWindowCenter"];
}
}
@@ -291,68 +241,6 @@ typedef enum ViewMode : NSUInteger {
[self updateSizeLabels];
}
-/**
- * Resizes the entire window to accomodate a view of a particular size.
- */
-- (void)resizeWindowForViewSize:(NSSize)viewSize animate:(BOOL)performAnimation
-{
- NSWindow *window = self.window;
- NSSize currentSize = [window.contentView frame].size;
- NSRect frame = window.frame;
-
- // Calculate border around content region of the frame
- int borderX = (int)(frame.size.width - currentSize.width);
- int borderY = (int)(frame.size.height - currentSize.height);
-
- // Make sure the frame is smaller than the screen
- NSSize maxSize = window.screen.visibleFrame.size;
-
- // if we are not Scale To Screen, put an 10% of visible screen on the window
- maxSize.width = maxSize.width * 0.90;
- maxSize.height = maxSize.height * 0.90;
-
- // Set the new frame size
- // Add the border to the new frame size so that the content region
- // of the frame is large enough to accomodate the preview image
- frame.size.width = viewSize.width + borderX;
- frame.size.height = viewSize.height + borderY;
-
- // compare frame to max size of screen
- if (frame.size.width > maxSize.width)
- {
- frame.size.width = maxSize.width;
- }
- if (frame.size.height > maxSize.height)
- {
- frame.size.height = maxSize.height;
- }
-
- // Since upon launch we can open up the preview window if it was open
- // the last time we quit (and at the size it was) we want to make
- // sure that upon resize we do not have the window off the screen
- // So check the origin against the screen origin and adjust if
- // necessary.
- NSSize screenSize = window.screen.visibleFrame.size;
- NSPoint screenOrigin = window.screen.visibleFrame.origin;
-
- frame.origin.x = self.windowCenterPoint.x - floor(frame.size.width / 2);
- frame.origin.y = self.windowCenterPoint.y - floor(frame.size.height / 2);
-
- // our origin is off the screen to the left
- if (frame.origin.x < screenOrigin.x)
- {
- // so shift our origin to the right
- frame.origin.x = screenOrigin.x;
- }
- else if ((frame.origin.x + frame.size.width) > (screenOrigin.x + screenSize.width))
- {
- // the right side of the preview is off the screen, so shift to the left
- frame.origin.x = (screenOrigin.x + screenSize.width) - frame.size.width;
- }
-
- [window setFrame:frame display:YES animate:performAnimation];
-}
-
- (void)updateSizeLabels
{
if (self.generator)
@@ -375,8 +263,8 @@ typedef enum ViewMode : NSUInteger {
}
// Set the info fields in the hud controller
- fInfoField.stringValue = self.generator.info;
- fscaleInfoField.stringValue = scaleString;
+ self.pictureHUD.info = self.generator.info;
+ self.pictureHUD.scale = scaleString;
// Set the info field in the window title bar
self.window.title = [NSString stringWithFormat:NSLocalizedString(@"Preview - %@ %@", nil),
@@ -384,138 +272,86 @@ typedef enum ViewMode : NSUInteger {
}
}
-#pragma mark - Hud mode
+#pragma mark - Hud State
/**
- * Enable/Disable an arbitrary number of UI elements.
- * @param boxes an array of UI elements
- * @param indexes a set of indexes of the elements in boxes to be enabled
- */
-- (void) toggleBoxes: (NSArray *) boxes usingIndexes: (NSIndexSet *) indexes
-{
- [NSAnimationContext beginGrouping];
- [[NSAnimationContext currentContext] setDuration:ANIMATION_DUR];
-
- [boxes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
- BOOL hide = [indexes containsIndex:idx] ? NO : YES;
- if (hide)
- {
- [self hideHudWithAnimation:obj];
- }
- else
- {
- [self showHudWithAnimation:obj];
- }
- }];
-
- [NSAnimationContext endGrouping];
-}
-
-/**
- * Switch the preview controller to one of his view mode:
- * ViewModePicturePreview, ViewModeEncoding, ViewModeMoviePreview
+ * Switch the preview controller to one of his hud mode:
* This methods is the only way to change the mode, do not try otherwise.
- * @param mode ViewMode mode
+ * @param hud NSViewController<HBHUD> the hud to show
*/
-- (void) switchViewToMode: (ViewMode) mode
+- (void)switchStateToHUD:(NSViewController<HBHUD> *)hud
{
- switch (mode) {
- case ViewModePicturePreview:
- {
- if (self.currentViewMode == ViewModeEncoding)
- {
- [self toggleBoxes:@[fPictureControlBox, fEncodingControlBox]
- usingIndexes:[NSIndexSet indexSetWithIndex:0]];
- [fMovieCreationProgressIndicator stopAnimation:self];
- }
- else if (self.currentViewMode == ViewModeMoviePreview)
- {
- // Stop playback and remove the observers
- [fMovieView pause:self];
- [self stopMovieTimer];
- [self removeMovieObservers];
-
- [self toggleBoxes:@[fPictureControlBox, fMoviePlaybackControlBox, fMovieView]
- usingIndexes:[NSIndexSet indexSetWithIndex:0]];
-
- /* Release the movie */
- [fMovieView setMovie:nil];
- self.movie = nil;
- }
-
- break;
- }
+ if (self.currentHUD == self.playerHUD)
+ {
+ [self exitPlayerState];
+ }
- case ViewModeEncoding:
- {
- [fMovieCreationProgressIndicator setDoubleValue:0];
- [fMovieCreationProgressIndicator startAnimation:self];
- [self toggleBoxes:@[fEncodingControlBox, fPictureControlBox, fMoviePlaybackControlBox]
- usingIndexes:[NSIndexSet indexSetWithIndex:0]];
+ if (hud == self.pictureHUD)
+ {
+ [self enterPictureState];
+ }
+ else if (hud == self.encodingHUD)
+ {
+ [self enterEncodingState];
+ }
+ else if (hud == self.playerHUD)
+ {
+ [self enterPlayerState];
+ }
- break;
- }
+ // Show the current hud
+ NSMutableArray *huds = [@[self.pictureHUD, self.encodingHUD, self.playerHUD] mutableCopy];
+ [huds removeObject:hud];
+ for (NSViewController *controller in huds) {
+ controller.view.hidden = YES;
+ }
+ hud.view.hidden = NO;
+ hud.view.layer.opacity = 1.0;
- case ViewModeMoviePreview:
- {
- [self toggleBoxes:@[fMovieView, fMoviePlaybackControlBox, fEncodingControlBox, fPictureControlBox]
- usingIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)]];
+ [self.window makeFirstResponder:hud.view];
+ [self startHudTimer];
+ self.currentHUD = hud;
+}
- [fMovieCreationProgressIndicator stopAnimation:self];
- [self initPreviewScrubberForMovie];
- [self startMovieTimer];
+#pragma mark - HUD Control Overlay
- // Install movie notifications
- [self addMovieObservers];
- }
- break;
+- (void)mouseEntered:(NSEvent *)theEvent
+{
+ if (self.generator)
+ {
+ NSView *hud = self.currentHUD.view;
- default:
- break;
+ [self showHudWithAnimation:hud];
+ [self startHudTimer];
}
-
- self.currentViewMode = mode;
+ self.mouseInWindow = YES;
}
-#pragma mark -
-#pragma mark Hud Control Overlay
+- (void)mouseExited:(NSEvent *)theEvent
+{
+ [self hudTimerFired:nil];
+ self.mouseInWindow = NO;
+}
- (void)mouseMoved:(NSEvent *)theEvent
{
[super mouseMoved:theEvent];
- NSPoint mouseLoc = [theEvent locationInWindow];
- /* Test for mouse location to show/hide hud controls */
- if (self.currentViewMode != ViewModeEncoding && self.generator)
+ // Test for mouse location to show/hide hud controls
+ if (self.generator && self.mouseInWindow)
{
- /* Since we are not encoding, verify which control hud to show
- * or hide based on aMovie ( aMovie indicates we need movie controls )
- */
- NSView *hud;
- if (self.currentViewMode == !ViewModeMoviePreview) // No movie loaded up
- {
- hud = fPictureControlBox;
- }
- else // We have a movie
- {
- hud = fMoviePlaybackControlBox;
- }
+ NSView *hud = self.currentHUD.view;
+ NSPoint mouseLoc = theEvent.locationInWindow;
- if (NSPointInRect(mouseLoc, [hud frame]))
+ if (NSPointInRect(mouseLoc, hud.frame))
{
- [self showHudWithAnimation:hud];
[self stopHudTimer];
}
- else if (NSPointInRect(mouseLoc, [[[self window] contentView] frame]))
+ else
{
[self showHudWithAnimation:hud];
[self startHudTimer];
}
- else
- {
- [self hideHudWithAnimation:hud];
- [self stopHudTimer];
- }
}
}
@@ -524,13 +360,13 @@ typedef enum ViewMode : NSUInteger {
// 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])
+ if (hud.layer.opacity == 0 || hud.isHidden)
{
[hud setHidden:NO];
[CATransaction begin];
CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
- fadeInAnimation.fromValue = @(0.0);
+ fadeInAnimation.fromValue = @([hud.layer.presentationLayer opacity]);
fadeInAnimation.toValue = @(1.0);
fadeInAnimation.beginTime = 0.0;
fadeInAnimation.duration = ANIMATION_DUR;
@@ -547,41 +383,28 @@ typedef enum ViewMode : NSUInteger {
if (hud.layer.opacity != 0)
{
[CATransaction begin];
- [CATransaction setCompletionBlock:^{
- if (hud.layer.opacity == 0)
- {
- [hud setHidden:YES];
- }
- }];
- CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
- fadeInAnimation.fromValue = @([hud.layer.presentationLayer opacity]);
- fadeInAnimation.toValue = @(0.0);
- fadeInAnimation.beginTime = 0.0;
- fadeInAnimation.duration = ANIMATION_DUR;
+ 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:fadeInAnimation forKey:nil];
+ [hud.layer addAnimation:fadeOutAnimation forKey:nil];
[hud.layer setOpacity:0];
[CATransaction commit];
}
}
-- (void)hideHud
-{
- [fPictureControlBox setHidden:YES];
- [fMoviePlaybackControlBox setHidden:YES];
- [fEncodingControlBox setHidden:YES];
-}
-
- (void)startHudTimer
{
if (self.hudTimer)
{
- [self.hudTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:8.0]];
+ [self.hudTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:HUD_FADEOUT_TIME]];
}
else
{
- self.hudTimer = [NSTimer scheduledTimerWithTimeInterval:8.0 target:self selector:@selector(hudTimerFired:)
+ self.hudTimer = [NSTimer scheduledTimerWithTimeInterval:HUD_FADEOUT_TIME target:self selector:@selector(hudTimerFired:)
userInfo:nil repeats:YES];
}
}
@@ -592,18 +415,21 @@ typedef enum ViewMode : NSUInteger {
self.hudTimer = nil;
}
-- (void)hudTimerFired: (NSTimer *)theTimer
+- (void)hudTimerFired:(NSTimer *)theTimer
{
- // Regardless which control box is active, after the timer
- // period we want either one to fade to hidden.
- [self hideHudWithAnimation:fPictureControlBox];
- [self hideHudWithAnimation:fMoviePlaybackControlBox];
-
+ if (self.currentHUD.canBeHidden)
+ {
+ [self hideHudWithAnimation:self.currentHUD.view];
+ }
[self stopHudTimer];
}
-#pragma mark -
-#pragma mark Still previews mode
+#pragma mark - Still previews mode
+
+- (void)enterPictureState
+{
+ [self displayPreviewAtIndex:self.pictureHUD.selectedIndex];
+}
/**
* Adjusts the window to draw the current picture (fPicture) adjusting its size as
@@ -611,6 +437,11 @@ typedef enum ViewMode : NSUInteger {
*/
- (void)displayPreviewAtIndex:(NSUInteger)idx
{
+ if (!self.generator)
+ {
+ return;
+ }
+
if (self.window.isVisible)
{
CGImageRef fPreviewImage = [self.generator copyImageAtIndex:idx shouldCache:YES];
@@ -625,33 +456,18 @@ typedef enum ViewMode : NSUInteger {
// Scale the window to the image size
NSSize windowSize = [self.previewView optimalViewSizeForImageSize:imageScaledSize minSize:NSMakeSize(MIN_WIDTH, MIN_HEIGHT)];
- [self resizeWindowForViewSize:windowSize animate:self.window.isVisible];
+ [self.window HB_resizeToBestSizeForViewSize:windowSize center:self.windowCenterPoint animate:self.window.isVisible];
}
[self updateSizeLabels];
}
-- (IBAction)previewDurationPopUpChanged:(id)sender
-{
- [[NSUserDefaults standardUserDefaults] setObject:[fPreviewMovieLengthPopUp titleOfSelectedItem] forKey:@"PreviewLength"];
-}
-
-- (IBAction)pictureSliderChanged:(id)sender
-{
- if ((self.pictureIndex != [fPictureSlider intValue] || !sender) && self.generator) {
- self.pictureIndex = [fPictureSlider intValue];
- [self displayPreviewAtIndex:self.pictureIndex];
- }
-}
-
-- (IBAction)toggleScaleToScreen:(id)sender
+- (void)toggleScaleToScreen
{
if (self.previewView.fitToView == YES)
{
self.previewView.fitToView = NO;
- fScaleToScreenToggleButton.title = NSLocalizedString(@"Scale To Screen", nil);
-
- [self displayPreviewAtIndex:self.pictureIndex];
+ [self displayPreviewAtIndex:self.pictureHUD.selectedIndex];
}
else
{
@@ -660,11 +476,10 @@ typedef enum ViewMode : NSUInteger {
{
[self.window setFrame:self.window.screen.visibleFrame display:YES animate:YES];
}
- fScaleToScreenToggleButton.title = NSLocalizedString(@"Actual Scale", nil);
}
}
-- (IBAction) showPictureSettings: (id) sender
+- (void)showPictureSettings
{
if (self.pictureSettingsWindow == nil)
{
@@ -676,299 +491,137 @@ typedef enum ViewMode : NSUInteger {
[self.pictureSettingsWindow showWindow:self];
}
-#pragma mark -
-#pragma mark Movie preview mode
-
-- (void) updateProgress: (double) progress info: (NSString *) progressInfo {
- [fPreviewMovieStatusField setStringValue: progressInfo];
+#pragma mark - Encoding mode
- [fMovieCreationProgressIndicator setIndeterminate: NO];
- [fMovieCreationProgressIndicator setDoubleValue: progress];
-}
-
-- (void)didCancelMovieCreation
-{
- [self switchViewToMode:ViewModePicturePreview];
-}
-
-- (void) didCreateMovieAtURL: (NSURL *) fileURL
+- (void)enterEncodingState
{
- /* Load the new movie into fMovieView */
- if (fileURL)
- {
- NSError *outError;
- NSDictionary *movieAttributes = @{QTMovieURLAttribute: fileURL,
- QTMovieAskUnresolvedDataRefsAttribute: @NO,
- @"QTMovieOpenForPlaybackAttribute": @YES,
- @"QTMovieOpenAsyncRequiredAttribute": @NO,
- @"QTMovieOpenAsyncOKAttribute": @NO,
- @"QTMovieIsSteppableAttribute": @YES,
- QTMovieApertureModeAttribute: QTMovieApertureModeClean};
-
- QTMovie *movie = [[QTMovie alloc] initWithAttributes:movieAttributes error:&outError];
-
- if (!movie)
- {
- NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"HandBrake can't open the preview.", nil)
- defaultButton:NSLocalizedString(@"Open in external player", nil)
- alternateButton:NSLocalizedString(@"Cancel", nil)
- otherButton:nil
- informativeTextWithFormat:NSLocalizedString(@"HandBrake can't playback this combination of video/audio/container format. Do you want to open it in an external player?", nil)];
- [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
- if (returnCode == NSModalResponseOK)
- {
- [[NSWorkspace sharedWorkspace] openURL:fileURL];
- }
- }];
- [self switchViewToMode:ViewModePicturePreview];
- }
- else
- {
- // Scale the fMovieView to the picture player size
- [fMovieView setFrame:self.previewView.pictureFrame];
-
- [fMovieView setMovie:movie];
- [movie setDelegate:self];
-
- // get and enable subtitles
- NSArray *subtitlesArray = [movie tracksOfMediaType:QTMediaTypeSubtitle];
- if (subtitlesArray.count)
- {
- // enable the first tx3g subtitle track
- [subtitlesArray[0] setEnabled:YES];
- }
- else
- {
- // Perian subtitles
- subtitlesArray = [movie tracksOfMediaType: QTMediaTypeVideo];
- if (subtitlesArray.count >= 2)
- {
- // track 0 should be video, other video tracks should
- // be subtitles; force-enable the first subs track
- [subtitlesArray[1] setEnabled:YES];
- }
- }
-
- // to actually play the movie
- self.movie = movie;
-
- [self switchViewToMode:ViewModeMoviePreview];
-
- [fMovieView play:movie];
- }
- }
+ self.encodingHUD.progress = 0;
}
-- (IBAction) cancelCreateMoviePreview: (id) sender
+- (void)cancelEncoding
{
[self.generator cancel];
}
-- (IBAction) createMoviePreview: (id) sender
+- (void)createMoviePreviewWithPictureIndex:(NSUInteger)index duration:(NSUInteger)duration
{
- if (!self.generator)
- return;
-
- if ([self.generator createMovieAsyncWithImageAtIndex:self.pictureIndex
- duration:[[fPreviewMovieLengthPopUp titleOfSelectedItem] intValue]])
+ if ([self.generator createMovieAsyncWithImageAtIndex:index duration:duration])
{
- [self switchViewToMode:ViewModeEncoding];
+ [self switchStateToHUD:self.encodingHUD];
}
}
-- (IBAction) toggleMoviePreviewPlayPause: (id) sender
+- (void)updateProgress:(double)progress info:(NSString *)progressInfo
{
- // make sure a movie is even loaded up
- if (self.movie)
- {
- if ([self.movie isPlaying]) // we are playing
- {
- [fMovieView pause:self.movie];
- [fPlayPauseButton setState: NSOnState];
- }
- else // we are paused or stopped
- {
- [fMovieView play:self.movie];
- [fPlayPauseButton setState: NSOffState];
- }
- }
+ self.encodingHUD.progress = progress;
+ self.encodingHUD.info = progressInfo;
}
-- (IBAction) moviePlaybackGoToBeginning: (id) sender
+- (void)didCancelMovieCreation
{
- [fMovieView gotoBeginning:self.movie];
+ [self switchStateToHUD:self.pictureHUD];
}
-- (IBAction) moviePlaybackGoToEnd: (id) sender
+- (void)showAlert:(NSURL *)fileURL;
{
- [fMovieView gotoEnd:self.movie];
+ NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"HandBrake can't open the preview.", nil)
+ defaultButton:NSLocalizedString(@"Open in external player", nil)
+ alternateButton:NSLocalizedString(@"Cancel", nil)
+ otherButton:nil
+ informativeTextWithFormat:NSLocalizedString(@"HandBrake can't playback this combination of video/audio/container format. Do you want to open it in an external player?", nil)];
+
+ [alert beginSheetModalForWindow:self.window modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:(void *)CFBridgingRetain(fileURL)];
}
-- (void) startMovieTimer
+- (void)alertDidEnd:(NSAlert *)alert
+ returnCode:(NSInteger)returnCode
+ contextInfo:(void *)contextInfo
{
- if (!self.movieTimer)
+ NSURL *fileURL = CFBridgingRelease(contextInfo);
+ if (returnCode == NSModalResponseOK)
{
- self.movieTimer = [NSTimer scheduledTimerWithTimeInterval:0.09 target:self
- selector:@selector(movieTimerFired:)
- userInfo:nil repeats:YES];
+ [[NSWorkspace sharedWorkspace] openURL:fileURL];
}
}
-- (void) stopMovieTimer
-{
- [self.movieTimer invalidate];
- self.movieTimer = nil;
-}
-
-- (void) movieTimerFired: (NSTimer *)theTimer
+- (void)setUpPlaybackOfURL:(NSURL *)fileURL;
{
- if (self.movie != nil)
+ if (self.player.isPlayable && self.currentHUD == self.encodingHUD)
{
- [self adjustPreviewScrubberForCurrentMovieTime];
- [fMovieInfoField setStringValue: [self.movie timecode]];
+ [self switchStateToHUD:self.playerHUD];
+ }
+ else
+ {
+ [self showAlert:fileURL];
+ [self switchStateToHUD:self.pictureHUD];
}
}
-- (IBAction) showPicturesPreview: (id) sender
+- (void)didCreateMovieAtURL:(NSURL *)fileURL
{
- [self switchViewToMode:ViewModePicturePreview];
-}
+ if (fileURL)
+ {
+ self.player = [[HBAVPlayer alloc] initWithURL:fileURL];
-#pragma mark -
-#pragma mark Movie Playback Scrubber
+ if (self.player)
+ {
+ [self.player loadPlayableValueAsynchronouslyWithCompletionHandler:^{
-// Initialize the preview scrubber min/max to appropriate values for the current movie
-- (void) initPreviewScrubberForMovie
-{
- QTTime duration = [self.movie duration];
- CGFloat result = duration.timeValue / duration.timeScale;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self setUpPlaybackOfURL:fileURL];
+ });
- [fMovieScrubberSlider setMinValue:0.0];
- [fMovieScrubberSlider setMaxValue: result];
- [fMovieScrubberSlider setDoubleValue: 0.0];
+ }];
+ }
+ else
+ {
+ [self showAlert:fileURL];
+ [self switchStateToHUD:self.pictureHUD];
+ }
+ }
}
-- (void) adjustPreviewScrubberForCurrentMovieTime
-{
- QTTime time = [self.movie currentTime];
-
- CGFloat result = (CGFloat)time.timeValue / (CGFloat)time.timeScale;;
- [fMovieScrubberSlider setDoubleValue:result];
-}
+#pragma mark - Player mode
-- (IBAction) previewScrubberChanged: (id) sender
+- (void)enterPlayerState
{
- [fMovieView pause:self.movie];
- [self.movie setCurrentTimeDouble:[fMovieScrubberSlider doubleValue]];
- [fMovieInfoField setStringValue: [self.movie timecode]];
-}
+ // Scale the layer to the picture player size
+ CALayer *playerLayer = self.player.layer;
+ playerLayer.frame = self.previewView.pictureFrame;
-#pragma mark -
-#pragma mark Movie Notifications
+ [self.window.contentView.layer insertSublayer:playerLayer atIndex:1];
-- (void) addMovieObservers
-{
- // Notification for any time the movie rate changes
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(movieRateDidChange:)
- name:@"QTMovieRateDidChangeNotification"
- object:self.movie];
+ self.playerHUD.player = self.player;
}
-- (void) removeMovieObservers
+- (void)exitPlayerState
{
- // Notification for any time the movie rate changes
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:@"QTMovieRateDidChangeNotification"
- object:self.movie];
+ self.playerHUD.player = nil;
+ [self.player pause];
+ [self.player.layer removeFromSuperlayer];
+ self.player = nil;
}
-- (void) movieRateDidChange: (NSNotification *) notification
+- (void)stopPlayer
{
- if (self.movie.isPlaying)
- [fPlayPauseButton setState: NSOnState];
- else
- [fPlayPauseButton setState: NSOffState];
+ [self switchStateToHUD:self.pictureHUD];
}
-#pragma mark -
-#pragma mark Keyboard and mouse wheel control
+#pragma mark - Scroll
-/* fMovieView Keyboard controls */
-- (void) keyDown: (NSEvent *) event
+- (void)keyDown:(NSEvent *)event
{
- unichar key = [[event charactersIgnoringModifiers] characterAtIndex:0];
- QTMovie *movie = self.movie;
-
- if (movie)
- {
- if (key == 32)
- {
- if ([movie isPlaying])
- [fMovieView pause:movie];
- else
- [fMovieView play:movie];
- }
- else if (key == 'k')
- [fMovieView pause:movie];
- else if (key == 'l')
- {
- float rate = [movie rate];
- rate += 1.0f;
- [fMovieView play:movie];
- [movie setRate:rate];
- }
- else if (key == 'j')
- {
- float rate = [movie rate];
- rate -= 1.0f;
- [fMovieView play:movie];
- [movie setRate:rate];
- }
- else if ([event modifierFlags] & NSAlternateKeyMask && key == NSLeftArrowFunctionKey)
- [fMovieView gotoBeginning:self];
- else if ([event modifierFlags] & NSAlternateKeyMask && key == NSRightArrowFunctionKey)
- [fMovieView gotoEnd:self];
- else if (key == NSLeftArrowFunctionKey)
- [fMovieView stepBackward:self];
- else if (key == NSRightArrowFunctionKey)
- [fMovieView stepForward:self];
- else
- [super keyDown:event];
- }
- else if (self.currentViewMode != ViewModeEncoding)
+ if ([self.currentHUD HB_keyDown:event] == NO)
{
- if (key == NSLeftArrowFunctionKey)
- {
- [fPictureSlider setIntegerValue:self.pictureIndex > [fPictureSlider minValue] ? self.pictureIndex - 1 : self.pictureIndex];
- [self pictureSliderChanged:self];
- }
- else if (key == NSRightArrowFunctionKey)
- {
- [fPictureSlider setIntegerValue:self.pictureIndex < [fPictureSlider maxValue] ? self.pictureIndex + 1 : self.pictureIndex];
- [self pictureSliderChanged:self];
- }
- else
- [super keyDown:event];
- }
- else
[super keyDown:event];
+ }
}
-- (void)scrollWheel:(NSEvent *)theEvent
+- (void)scrollWheel:(NSEvent *)event
{
- if (self.currentViewMode != ViewModeEncoding)
+ if ([self.currentHUD HB_scrollWheel:event] == NO)
{
- if (theEvent.deltaY < 0)
- {
- [fPictureSlider setIntegerValue:self.pictureIndex < [fPictureSlider maxValue] ? self.pictureIndex + 1 : self.pictureIndex];
- [self pictureSliderChanged:self];
- }
- else if (theEvent.deltaY > 0)
- {
- [fPictureSlider setIntegerValue:self.pictureIndex > [fPictureSlider minValue] ? self.pictureIndex - 1 : self.pictureIndex];
- [self pictureSliderChanged:self];
- }
+ [super scrollWheel:event];
}
}