X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=macosx%2FHBPreviewController.mm;h=052648de96ba6ed5ce9cd66894240ad825652a6e;hb=44946a6f8be82a70e65ca534541183a26fdb804b;hp=10c8855877902045a6ba8d39a510116b8a88eda0;hpb=ef0b19bdea57cbac11197c002962c0e7e1af5f0e;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/macosx/HBPreviewController.mm b/macosx/HBPreviewController.mm index 10c88558..052648de 100644 --- a/macosx/HBPreviewController.mm +++ b/macosx/HBPreviewController.mm @@ -6,7 +6,6 @@ #import "HBPreviewController.h" #import "Controller.h" -//#import "PictureController.h" @interface PreviewController (Private) @@ -43,117 +42,6 @@ } -- (void) mouseMoved:(NSEvent *)theEvent -{ - [super mouseMoved:theEvent]; - - if (isEncoding == NO) - { - if (hudTimerSeconds == 0) - { - hudTimerSeconds ++; - [self startHudTimer]; - } - - if (hudTimerSeconds > 20) - { - - - [self stopHudTimer]; - [self showHideHudControls]; - } - - } -} - -- (void) startHudTimer -{ - if (!fHudTimer) - { - fHudTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hudTimerFired:) userInfo:nil repeats:YES]; - [fHudTimer retain]; - } -} - -- (void) stopHudTimer -{ - if (fHudTimer) - { - [fHudTimer invalidate]; - [fHudTimer release]; - fHudTimer = nil; - hudTimerSeconds = 0; - } -} - -- (void) hudTimerFired: (NSTimer*)theTimer -{ - hudTimerSeconds ++; - [self showHideHudControls]; - -} - -- (void) showHideHudControls -{ - /* Test for mouse location to show/hide hud controls */ - NSPoint mouseLoc; - NSRect targetFrame; - NSRect controlBoxFrame; - targetFrame = [fPictureViewArea frame]; - controlBoxFrame = [fPictureControlBox frame]; - - if (isFullScreen) - { - mouseLoc = [fFullScreenWindow mouseLocationOutsideOfEventStream]; - } - else - { - mouseLoc = [fPreviewWindow mouseLocationOutsideOfEventStream]; - } - - /* if the pointer is inside the picture view areas but not - * in the controlbox, check the hudTimerSeconds to see if - * its in the allowable time span - */ - if ( hudTimerSeconds > 0 && hudTimerSeconds < 20) - { - if (NSPointInRect (mouseLoc, controlBoxFrame)) - { - /* Mouse is over the preview area so show hud controls so just - * reset the timer to keep the control box visible - */ - //[fPictureControlBox setHidden: NO]; - hudTimerSeconds = 1; - return; - } - - /* Else, if we are not encoding a preview, we show/hide the hud controls */ - if (isEncoding == NO) - { - /* Re-verify we are within the target frame */ - if (NSPointInRect (mouseLoc, targetFrame)) - { - /* Mouse is over the preview area so show hud controls */ - [[fPictureControlBox animator] setHidden: NO]; - /* increment our timer by one */ - hudTimerSeconds ++; - } - else - { - [[fPictureControlBox animator] setHidden: YES]; - [self stopHudTimer]; - } - } - - } - else - { - [[fPictureControlBox animator] setHidden: YES]; - } - -} - - //------------------------------------------------------------------------------------ // Displays and brings the picture window to the front @@ -161,8 +49,11 @@ - (IBAction) showPreviewWindow: (id)sender { [self showWindow:sender]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PreviewWindowIsOpen"]; + /* lets set the preview window to accept mouse moved events */ [fPreviewWindow setAcceptsMouseMovedEvents:YES]; + hudTimerSeconds = 0; [self pictureSliderChanged:nil]; [self startReceivingLibhbNotifications]; } @@ -175,6 +66,11 @@ - (void)awakeFromNib { [fPreviewWindow setDelegate:self]; + if( ![[self window] setFrameUsingName:@"Preview"] ) + [[self window] center]; + [self setWindowFrameAutosaveName:@"Preview"]; + [[self window] setExcludedFromWindowsMenu:YES]; + /* lets set the preview window to accept mouse moved events */ [fPreviewWindow setAcceptsMouseMovedEvents:YES]; //[self pictureSliderChanged:nil]; @@ -182,6 +78,10 @@ isFullScreen = NO; hudTimerSeconds = 0; + /* we set the progress indicator to not use threaded animation + * as it causes a conflict with the qtmovieview's controllerbar + */ + [fMovieCreationProgressIndicator setUsesThreadedAnimation:NO]; /* Setup our layers for core animation */ [fPictureViewArea setWantsLayer:YES]; @@ -196,12 +96,24 @@ [fPictureSlider setWantsLayer:YES]; [fFullScreenToggleButton setWantsLayer:YES]; [fPictureSettingsToggleButton setWantsLayer:YES]; + [fScaleToScreenToggleButton setWantsLayer:YES]; [fCreatePreviewMovieButton setWantsLayer:YES]; [fEncodingControlBox setWantsLayer:YES]; [fShowPreviewMovieButton setWantsLayer:YES]; + /* Since the xib has everything off center for easy acess + * we align our views and windows here we an align to anything + * since it will actually change later upon source load, but + * for convenience we will use the fPictureViewArea + */ + + /* Align the still preview image view to the picture box */ + [fPictureView setFrameSize:[fPictureViewArea frame].size]; + [fMovieView setFrameSize:[fPictureViewArea frame].size]; + //[fPreviewWindow setFrameSize:[fPictureViewArea frame].size]; + } - (BOOL)acceptsMouseMovedEvents @@ -211,6 +123,8 @@ return YES; - (void)windowWillClose:(NSNotification *)aNotification { + + /* Upon Closing the picture window, we make sure we clean up any * preview movie that might be playing */ @@ -221,18 +135,16 @@ return YES; [fPictureView setHidden:NO]; [fMovieView pause:nil]; [fMovieView setHidden:YES]; - if (isFullScreen) - { - [self goWindowedScreen:nil]; - } isFullScreen = NO; hudTimerSeconds = 0; + [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"PreviewWindowIsOpen"]; } - (BOOL)windowShouldClose:(id)fPictureWindow { - return YES; + + return YES; } - (void) dealloc @@ -297,10 +209,10 @@ return YES; - (void) SetTitle: (hb_title_t *) title { hb_job_t * job = title->job; - + fTitle = title; -fPicture = 0; -MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; + fPicture = 0; + MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; MaxOutputHeight = title->height - job->crop[0] - job->crop[1]; [self SettingsChanged: nil]; } @@ -311,7 +223,7 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; // necessary to display as much of the picture as possible. - (void) displayPreview { - hb_job_t * job = fTitle->job; + hb_job_t * job = fTitle->job; /* lets make sure that the still picture view is not hidden and that * the movie preview is */ @@ -321,85 +233,152 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; [fMovieCreationProgressIndicator setHidden: YES]; [fPictureView setHidden:NO]; - - [fPictureView setImage: [self imageForPicture: fPicture]]; - - NSSize displaySize = NSMakeSize( ( CGFloat )fTitle->width, ( CGFloat )fTitle->height ); + + //[fHBController writeToActivityLog: "displayPreview called"]; + + NSImage *fPreviewImage = [self imageForPicture: fPicture]; + NSSize imageScaledSize = [fPreviewImage size]; + [fPictureView setImage: fPreviewImage]; + + NSSize displaySize = NSMakeSize( ( CGFloat )fTitle->width, ( CGFloat )fTitle->height ); + NSString *sizeInfoString; /* Set the picture size display fields below the Preview Picture*/ - if( fTitle->job->pixel_ratio == 1 ) // Original PAR Implementation + if( fTitle->job->anamorphic.mode == 1 ) // Original PAR Implementation { output_width = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]; output_height = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]; - display_width = output_width * fTitle->job->pixel_aspect_width / fTitle->job->pixel_aspect_height; - [fInfoField setStringValue:[NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d", - fTitle->width, fTitle->height, output_width, output_height, display_width, output_height]]; - displaySize.width *= ( ( CGFloat )fTitle->job->pixel_aspect_width ) / ( ( CGFloat )fTitle->job->pixel_aspect_height ); + display_width = output_width * fTitle->job->anamorphic.par_width / fTitle->job->anamorphic.par_height; + sizeInfoString = [NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Strict", + fTitle->width, fTitle->height, output_width, output_height, display_width, output_height]; + + displaySize.width = display_width; + displaySize.height = fTitle->height; + imageScaledSize.width = display_width; + imageScaledSize.height = output_height; } - else if (fTitle->job->pixel_ratio == 2) // Loose Anamorphic + else if (fTitle->job->anamorphic.mode == 2) // Loose Anamorphic { - hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height); + hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height); display_width = output_width * output_par_width / output_par_height; - [fInfoField setStringValue:[NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d", - fTitle->width, fTitle->height, output_width, output_height, display_width, output_height]]; + sizeInfoString = [NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Loose", + fTitle->width, fTitle->height, output_width, output_height, display_width, output_height]; displaySize.width = display_width; + displaySize.height = fTitle->height; + imageScaledSize.width = display_width; + imageScaledSize.height = output_height; } + else if (fTitle->job->anamorphic.mode == 3) // Custom Anamorphic + { + hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height); + display_width = output_width * output_par_width / output_par_height; + sizeInfoString = [NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Custom", + fTitle->width, fTitle->height, output_width, output_height, fTitle->job->anamorphic.dar_width, fTitle->job->anamorphic.dar_height]; + + displaySize.width = fTitle->job->anamorphic.dar_width + fTitle->job->crop[2] + fTitle->job->crop[3]; + displaySize.height = fTitle->job->anamorphic.dar_height + fTitle->job->crop[0] + fTitle->job->crop[1]; + imageScaledSize.width = (int)fTitle->job->anamorphic.dar_width; + imageScaledSize.height = (int)fTitle->job->height; + } else // No Anamorphic { - [fInfoField setStringValue: [NSString stringWithFormat: - @"Source: %dx%d, Output: %dx%d", fTitle->width, fTitle->height, - fTitle->job->width, fTitle->job->height]]; + sizeInfoString = [NSString stringWithFormat: + @"Source: %dx%d, Output: %dx%d", fTitle->width, fTitle->height, + fTitle->job->width, fTitle->job->height]; + + displaySize.width = fTitle->width; + displaySize.height = fTitle->height; + imageScaledSize.width = fTitle->job->width; + imageScaledSize.height = fTitle->job->height; } - + NSSize viewSize = [self optimalViewSizeForImageSize:displaySize]; - if( [self viewNeedsToResizeToSize:viewSize] ) + + /* Initially set our preview image here */ + /* + if (scaleToScreen == YES) + { + viewSize.width = viewSize.width - (viewSize.width - imageScaledSize.width); + viewSize.height = viewSize.height - (viewSize.height - imageScaledSize.height); + [fPreviewImage setSize: viewSize]; + //[fPictureView setFrameSize: viewSize]; + } + + else + { + [fPreviewImage setSize: imageScaledSize]; + [fPictureView setFrameSize: imageScaledSize]; + } + [fPictureView setImage: fPreviewImage]; + // center it vertically and horizontally + NSPoint origin = [fPictureViewArea frame].origin; + origin.y += ([fPictureViewArea frame].size.height - + [fPictureView frame].size.height) / 2.0; + + origin.x += ([fPictureViewArea frame].size.width - + [fPictureView frame].size.width) / 2.0; + [fPictureView setFrameOrigin:origin]; + */ + /* we also need to take into account scaling to full screen to activate switching the view size */ + if( [self viewNeedsToResizeToSize:viewSize]) { - /* In the case of loose anamorphic, do not resize the window when scaling down */ - // FIX ME: we need a new way to do this as we do not havefWidthField anymore - //if (fTitle->job->pixel_ratio != 2 || [fWidthField intValue] == fTitle->width) - if (fTitle->job->pixel_ratio != 2 || (fTitle->job->pixel_ratio == 2 && output_width == fTitle->width)) + if (fTitle->job->anamorphic.mode != 2 || (fTitle->job->anamorphic.mode == 2 && fTitle->width == fTitle->job->width)) { [self resizeSheetForViewSize:viewSize]; - [self setViewSize:viewSize]; + //[self setViewSize:viewSize]; + } + } + + viewSize.width = viewSize.width - (viewSize.width - imageScaledSize.width); + viewSize.height = viewSize.height - (viewSize.height - imageScaledSize.height); + [self setViewSize:viewSize]; + + /* special case for scaleToScreen */ + if (scaleToScreen == YES) + { + [fPreviewImage setSize: viewSize]; + [fPictureView setImage: fPreviewImage]; } - - // Show the scaled text (use the height to check since the width can vary - // with anamorphic video). - if( ( ( int )viewSize.height ) != fTitle->height ) + + NSString *scaleString; + + if( imageScaledSize.height > [fPictureView frame].size.height) { - CGFloat scale = viewSize.width / ( ( CGFloat ) fTitle->width ); - NSString *scaleString = [NSString stringWithFormat: - NSLocalizedString( @" (Preview scaled to %.0f%% actual size)", - @"String shown when a preview is scaled" ), - scale * 100.0]; - [fInfoField setStringValue: [[fInfoField stringValue] stringByAppendingString:scaleString]]; + CGFloat scale = ( ( CGFloat )[fPictureView frame].size.width) / ( ( CGFloat )imageScaledSize.width); + scaleString = [NSString stringWithFormat: + NSLocalizedString( @" (Scaled to %.0f%% actual size)", + @"String shown when a preview is scaled" ), scale * 100.0]; } - + else + { + scaleString = @""; + } + /* Set the info fields in the hud controller */ + [fInfoField setStringValue: [NSString stringWithFormat: + @"%@", sizeInfoString]]; + + [fscaleInfoField setStringValue: [NSString stringWithFormat: + @"%@", scaleString]]; + /* Set the info field in the window title bar */ + [[self window] setTitle:[NSString stringWithFormat: @"Preview - %@ %@",sizeInfoString, scaleString]]; } - (IBAction) previewDurationPopUpChanged: (id) sender { - -[[NSUserDefaults standardUserDefaults] setObject:[fPreviewMovieLengthPopUp titleOfSelectedItem] forKey:@"PreviewLength"]; - -} + [[NSUserDefaults standardUserDefaults] setObject:[fPreviewMovieLengthPopUp titleOfSelectedItem] forKey:@"PreviewLength"]; + +} - - - - (IBAction) SettingsChanged: (id) sender { // Purge the existing picture previews so they get recreated the next time // they are needed. [self purgeImageCache]; - /* We actually call displayPreview now from pictureSliderChanged which keeps - * our picture preview slider in sync with the previews being shown - */ - //[self displayPreview]; [self pictureSliderChanged:nil]; } @@ -422,20 +401,153 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; - (IBAction)showPreviewPanel: (id)sender forTitle: (hb_title_t *)title { - [self SetTitle:title]; - [self showWindow:sender]; - isFullScreen = NO; - hudTimerSeconds = 0; + //[self SetTitle:title]; + + if ([fPreviewWindow isVisible]) + { + + [fPreviewWindow close]; + + } + else + { + [self showWindow:sender]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PreviewWindowIsOpen"]; + [fPreviewWindow setAcceptsMouseMovedEvents:YES]; + isFullScreen = NO; + scaleToScreen = NO; + hudTimerSeconds = 0; + [self pictureSliderChanged:nil]; + [self startHudTimer]; + } + +} +- (NSString*) pictureSizeInfoString +{ + return [fInfoField stringValue]; } - (IBAction)showPictureSettings:(id)sender { -[fHBController showPicturePanel:self]; + [fHBController showPicturePanel:self]; } +#pragma mark Hud Control Overlay +- (void) mouseMoved:(NSEvent *)theEvent +{ + [super mouseMoved:theEvent]; + + if (isEncoding == NO) + { + if (hudTimerSeconds == 0) + { + hudTimerSeconds ++; + [self startHudTimer]; + } + + if (hudTimerSeconds > 20) + { + + + [self stopHudTimer]; + [self showHideHudControls]; + } + + } +} -#pragma mark Cocoa For Fullscreen Mode +- (void) startHudTimer +{ + if (!fHudTimer) + { + fHudTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hudTimerFired:) userInfo:nil repeats:YES]; + [fHudTimer retain]; + } +} + +- (void) stopHudTimer +{ + if (fHudTimer) + { + [fHudTimer invalidate]; + [fHudTimer release]; + fHudTimer = nil; + hudTimerSeconds = 0; + } +} + +- (void) hudTimerFired: (NSTimer*)theTimer +{ + hudTimerSeconds ++; + [self showHideHudControls]; + +} + +- (void) showHideHudControls +{ + /* Test for mouse location to show/hide hud controls */ + NSPoint mouseLoc; + NSRect targetFrame; + NSRect controlBoxFrame; + targetFrame = [fPictureViewArea frame]; + controlBoxFrame = [fPictureControlBox frame]; + + if (isFullScreen) + { + mouseLoc = [fFullScreenWindow mouseLocationOutsideOfEventStream]; + [fScaleToScreenToggleButton setHidden:NO]; + } + else + { + mouseLoc = [fPreviewWindow mouseLocationOutsideOfEventStream]; + [fScaleToScreenToggleButton setHidden:YES]; + } + + /* if the pointer is inside the picture view areas but not + * in the controlbox, check the hudTimerSeconds to see if + * its in the allowable time span + */ + if ( hudTimerSeconds > 0 && hudTimerSeconds < 20) + { + + if (isEncoding == NO) + { + if (NSPointInRect (mouseLoc, controlBoxFrame)) + { + /* Mouse is over the preview area so show hud controls so just + * reset the timer to keep the control box visible + */ + [fPictureControlBox setHidden: NO]; + hudTimerSeconds = 1; + return; + } + /* Re-verify we are within the target frame */ + if (NSPointInRect (mouseLoc, targetFrame)) + { + /* Mouse is over the preview area so show hud controls */ + [[fPictureControlBox animator] setHidden: NO]; + /* increment our timer by one */ + hudTimerSeconds ++; + } + else + { + [[fPictureControlBox animator] setHidden: YES]; + [self stopHudTimer]; + } + } + + } + else + { + [[fPictureControlBox animator] setHidden: YES]; + [self stopHudTimer]; + } + +} + + +#pragma mark Fullscreen Mode - (IBAction)toggleScreenMode:(id)sender { @@ -449,6 +561,24 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; } } +- (IBAction)toggleScaleToScreen:(id)sender +{ + if (scaleToScreen == YES) + { + scaleToScreen = NO; + /* make sure we are set to a still preview */ + [self pictureSliderChanged:nil]; + [fScaleToScreenToggleButton setTitle:@"<->"]; + } + else + { + scaleToScreen = YES; + /* make sure we are set to a still preview */ + [self pictureSliderChanged:nil]; + [fScaleToScreenToggleButton setTitle:@">-<"]; + } +} + - (BOOL)fullScreen { return isFullScreen; @@ -457,7 +587,7 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; - (IBAction)goFullScreen:(id)sender { // Get the screen information. - NSScreen* mainScreen = [NSScreen mainScreen]; + NSScreen* mainScreen = [fPreviewWindow screen]; NSDictionary* screenInfo = [mainScreen deviceDescription]; NSNumber* screenID = [screenInfo objectForKey:@"NSScreenNumber"]; // Capture the screen. @@ -467,13 +597,20 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; if (err == CGDisplayNoErr) { + /* make sure we are set to a still preview and not scaled to screen */ + scaleToScreen = NO; + [self pictureSliderChanged:nil]; + // Create the full-screen window. - NSRect winRect = [fPreviewWindow frame]; + //NSRect winRect = [mainScreen frame]; + //fPictureViewArea + NSRect winRect = [fPictureViewArea frame]; + fFullScreenWindow = [[NSWindow alloc] initWithContentRect:winRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO - screen:[NSScreen mainScreen]]; + screen:mainScreen]; // Establish the window attributes. [fFullScreenWindow setReleasedWhenClosed:NO]; @@ -484,30 +621,27 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; [fFullScreenWindow setContentView:fPictureViewArea]; [fPictureViewArea setNeedsDisplay:YES]; - // Center the window - /* Better to center the window using the screen's frame * and the windows origin. Note that we should take into * account the auto sizing and alignment that occurs in * setViewSize each time the preview changes. + * Note: by using [fFullScreenWindow screen] (instead of + * [NSScreen mainScreen]) in referencing the screen + * coordinates, the full screen window will show up on + * whichever display was being used in windowed mode + * on multi-display systems */ - NSSize screenSize = [[NSScreen mainScreen] frame].size; + NSSize screenSize = [[fFullScreenWindow screen] frame].size; NSSize windowSize = [fFullScreenWindow frame].size; NSPoint windowOrigin = [fFullScreenWindow frame].origin; /* Adjust our origin y (vertical) based on the screen height */ - windowOrigin.y = (screenSize.height - windowSize.height) / 2.0; - windowOrigin.x = (screenSize.width - windowSize.width) / 2.0; + windowOrigin.y += (screenSize.height - windowSize.height) / 2.0; + windowOrigin.x += (screenSize.width - windowSize.width) / 2.0; [fFullScreenWindow setFrameOrigin:windowOrigin]; - /* Using the simple center method for NSWindow - * though note this will cause the window to be slightly - * higher than center - */ - //[fFullScreenWindow center]; - /* lets kill the timer for now */ [self stopReceivingLibhbNotifications]; @@ -524,8 +658,6 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; // Show the window. [fFullScreenWindow makeKeyAndOrderFront:self]; - [fPreviewWindow setAcceptsMouseMovedEvents:NO]; - [fFullScreenWindow setAcceptsMouseMovedEvents:YES]; /* Change the name of fFullScreenToggleButton appropriately */ [fFullScreenToggleButton setTitle: @"Windowed"]; @@ -534,27 +666,48 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; [self startReceivingLibhbNotifications]; isFullScreen = YES; + [fScaleToScreenToggleButton setHidden:NO]; /* make sure we are set to a still preview */ [self pictureSliderChanged:nil]; - /* set the picture settings pallete above the shielding level */ - //[fHBController picturePanelFullScreen]; + [fFullScreenWindow setAcceptsMouseMovedEvents:YES]; + + + hudTimerSeconds = 0; + [self startHudTimer]; } } +// Title-less windows normally don't receive key presses, override this +- (BOOL)canBecomeKeyWindow +{ + return YES; +} + +// Title-less windows normally can't become main which means that another +// non-fullscreen window will have the "active" titlebar in expose. Bad, fix it. +- (BOOL)canBecomeMainWindow +{ + return YES; +} + + - (IBAction)goWindowedScreen:(id)sender { /* Get the screen info to release the display but don't actually do * it until the windowed screen is setup. - */ + */ + scaleToScreen = NO; + [self pictureSliderChanged:nil]; + [fScaleToScreenToggleButton setTitle:@"<->"]; + NSScreen* mainScreen = [NSScreen mainScreen]; NSDictionary* screenInfo = [mainScreen deviceDescription]; NSNumber* screenID = [screenInfo objectForKey:@"NSScreenNumber"]; CGDirectDisplayID displayID = (CGDirectDisplayID)[screenID longValue]; - [fFullScreenWindow setAcceptsMouseMovedEvents:NO]; [fFullScreenWindow dealloc]; [fFullScreenWindow release]; @@ -569,22 +722,28 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; /* Set the window back to regular level */ [fPreviewWindow setLevel:NSNormalWindowLevel]; - [fPreviewWindow setAcceptsMouseMovedEvents:YES]; - - /* Set the isFullScreen flag back to NO */ isFullScreen = NO; + scaleToScreen = NO; + /* make sure we are set to a still preview */ + [self pictureSliderChanged:nil]; [self showPreviewWindow:nil]; /* Change the name of fFullScreenToggleButton appropriately */ [fFullScreenToggleButton setTitle: @"Full Screen"]; - + // [fScaleToScreenToggleButton setHidden:YES]; /* set the picture settings pallete back to normal level */ [fHBController picturePanelWindowed]; /* Release the display now that the we are back in windowed mode */ CGDisplayRelease(displayID); + [fPreviewWindow setAcceptsMouseMovedEvents:YES]; + //[fFullScreenWindow setAcceptsMouseMovedEvents:NO]; + + hudTimerSeconds = 0; + [self startHudTimer]; + } @@ -599,141 +758,61 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; + (NSImage *) makeImageForPicture: (int)pictureIndex libhb:(hb_handle_t*)handle title:(hb_title_t*)title - removeBorders:(BOOL)removeBorders { - if (removeBorders) + static uint8_t * buffer; + static int bufferSize; + + // Make sure we have a big enough buffer to receive the image from libhb. libhb + int dstWidth = title->job->width; + int dstHeight = title->job->height; + + int newSize; + newSize = dstWidth * dstHeight * 4; + if( bufferSize < newSize ) { - // |<---------- title->width ----------->| - // | |<---- title->job->width ---->| | - // | | | | - // ....................................... - // ....+-----------------------------+.... - // ....| |....<-- gray border - // ....| |.... - // ....| |.... - // ....| |<------- image - // ....| |.... - // ....| |.... - // ....| |.... - // ....| |.... - // ....| |.... - // ....+-----------------------------+.... - // ....................................... - - static uint8_t * buffer; - static int bufferSize; - - // Make sure we have a big enough buffer to receive the image from libhb. libhb - // creates images with a one-pixel border around the original content. Hence we - // add 2 pixels horizontally and vertically to the buffer size. - int srcWidth = title->width + 2; - int srcHeight= title->height + 2; - int newSize; - newSize = srcWidth * srcHeight * 4; - if( bufferSize < newSize ) - { - bufferSize = newSize; - buffer = (uint8_t *) realloc( buffer, bufferSize ); - } + bufferSize = newSize; + buffer = (uint8_t *) realloc( buffer, bufferSize ); + } - hb_get_preview( handle, title, pictureIndex, buffer ); + hb_get_preview( handle, title, pictureIndex, buffer ); - // Create an NSBitmapImageRep and copy the libhb image into it, converting it from - // libhb's format to one suitable for NSImage. Along the way, we'll strip off the - // border around libhb's image. - - // The image data returned by hb_get_preview is 4 bytes per pixel, BGRA format. - // Alpha is ignored. + // Create an NSBitmapImageRep and copy the libhb image into it, converting it from + // libhb's format to one suitable for NSImage. Along the way, we'll strip off the + // border around libhb's image. - int dstWidth = title->job->width; - int dstHeight = title->job->height; - NSBitmapFormat bitmapFormat = (NSBitmapFormat)NSAlphaFirstBitmapFormat; - NSBitmapImageRep * imgrep = [[[NSBitmapImageRep alloc] - initWithBitmapDataPlanes:nil - pixelsWide:dstWidth - pixelsHigh:dstHeight - bitsPerSample:8 - samplesPerPixel:3 // ignore alpha - hasAlpha:NO - isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace - bitmapFormat:bitmapFormat - bytesPerRow:dstWidth * 4 - bitsPerPixel:32] autorelease]; - - int borderTop = (srcHeight - dstHeight) / 2; - int borderLeft = (srcWidth - dstWidth) / 2; + // The image data returned by hb_get_preview is 4 bytes per pixel, BGRA format. + // Alpha is ignored. - UInt32 * src = (UInt32 *)buffer; - UInt32 * dst = (UInt32 *)[imgrep bitmapData]; - src += borderTop * srcWidth; // skip top rows in src to get to first row of dst - src += borderLeft; // skip left pixels in src to get to first pixel of dst - for (int r = 0; r < dstHeight; r++) - { - for (int c = 0; c < dstWidth; c++) -#if TARGET_RT_LITTLE_ENDIAN - *dst++ = Endian32_Swap(*src++); -#else - *dst++ = *src++; -#endif - src += (srcWidth - dstWidth); // skip to next row in src - } - - NSImage * img = [[[NSImage alloc] initWithSize: NSMakeSize(dstWidth, dstHeight)] autorelease]; - [img addRepresentation:imgrep]; - - return img; - } - else + NSBitmapFormat bitmapFormat = (NSBitmapFormat)NSAlphaFirstBitmapFormat; + NSBitmapImageRep * imgrep = [[[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:nil + pixelsWide:dstWidth + pixelsHigh:dstHeight + bitsPerSample:8 + samplesPerPixel:3 // ignore alpha + hasAlpha:NO + isPlanar:NO + colorSpaceName:NSCalibratedRGBColorSpace + bitmapFormat:bitmapFormat + bytesPerRow:dstWidth * 4 + bitsPerPixel:32] autorelease]; + + UInt32 * src = (UInt32 *)buffer; + UInt32 * dst = (UInt32 *)[imgrep bitmapData]; + for (int r = 0; r < dstHeight; r++) { - // Make sure we have big enough buffer - static uint8_t * buffer; - static int bufferSize; - - int newSize; - newSize = ( title->width + 2 ) * (title->height + 2 ) * 4; - if( bufferSize < newSize ) - { - bufferSize = newSize; - buffer = (uint8_t *) realloc( buffer, bufferSize ); - } - - hb_get_preview( handle, title, pictureIndex, buffer ); - - // The image data returned by hb_get_preview is 4 bytes per pixel, BGRA format. - // We'll copy that into an NSImage swapping it to ARGB in the process. Alpha is - // ignored. - int width = title->width + 2; // hblib adds a one-pixel border to the image - int height = title->height + 2; - int numPixels = width * height; - NSBitmapFormat bitmapFormat = (NSBitmapFormat)NSAlphaFirstBitmapFormat; - NSBitmapImageRep * imgrep = [[[NSBitmapImageRep alloc] - initWithBitmapDataPlanes:nil - pixelsWide:width - pixelsHigh:height - bitsPerSample:8 - samplesPerPixel:3 // ignore alpha - hasAlpha:NO - isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace - bitmapFormat:bitmapFormat - bytesPerRow:width * 4 - bitsPerPixel:32] autorelease]; - - UInt32 * src = (UInt32 *)buffer; - UInt32 * dst = (UInt32 *)[imgrep bitmapData]; - for (int i = 0; i < numPixels; i++) + for (int c = 0; c < dstWidth; c++) #if TARGET_RT_LITTLE_ENDIAN *dst++ = Endian32_Swap(*src++); #else *dst++ = *src++; #endif + } - NSImage * img = [[[NSImage alloc] initWithSize: NSMakeSize(width, height)] autorelease]; - [img addRepresentation:imgrep]; + NSImage * img = [[[NSImage alloc] initWithSize: NSMakeSize(dstWidth, dstHeight)] autorelease]; + [img addRepresentation:imgrep]; - return img; - } + return img; } // Returns the preview image for the specified index, retrieving it from its internal @@ -748,7 +827,7 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; NSImage * theImage = [fPicturePreviews objectForKey:key]; if (!theImage) { - theImage = [PreviewController makeImageForPicture:pictureIndex libhb:fHandle title:fTitle removeBorders: NO]; + theImage = [PreviewController makeImageForPicture:pictureIndex libhb:fHandle title:fTitle]; [fPicturePreviews setObject:theImage forKey:key]; } return theImage; @@ -849,7 +928,33 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; /* lets go ahead and send it off to libhb * Note: unlike a full encode, we only send 1 pass regardless if the final encode calls for 2 passes. * this should suffice for a fairly accurate short preview and cuts our preview generation time in half. + * However we also need to take into account the indepth scan for subtitles. + */ + /* + * If scanning we need to do some extra setup of the job. */ + if( job->indepth_scan == 1 ) + { + char *x264opts_tmp; + + /* + * When subtitle scan is enabled do a fast pre-scan job + * which will determine which subtitles to enable, if any. + */ + job->pass = -1; + x264opts_tmp = job->x264opts; + + job->x264opts = NULL; + job->indepth_scan = 1; + /* + * Add the pre-scan job + */ + hb_add( fPreviewLibhb, job ); + job->x264opts = x264opts_tmp; + } + /* Go ahead and perform the actual encoding preview scan */ + job->indepth_scan = 0; + job->pass = 0; hb_add( fPreviewLibhb, job ); [fEncodingControlBox setHidden: NO]; @@ -997,33 +1102,31 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; [fMovieView setMovie:nil]; aMovie = [QTMovie movieWithFile:path error:nil]; - + /* we get some size information from the preview movie */ - Rect movieBox; - GetMovieBox ([aMovie quickTimeMovie], &movieBox); + NSSize movieSize= [[aMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]; movieBounds = [fMovieView movieBounds]; - movieBounds.size.height = movieBox.bottom - movieBox.top; - + movieBounds.size.height = movieSize.height; + if ([fMovieView isControllerVisible]) movieBounds.size.height += [fMovieView controllerBarHeight]; /* since for whatever the reason I cannot seem to get the [fMovieView controllerBarHeight] * For now just use 15 for additional height as it seems to line up well */ movieBounds.size.height += 15; - - movieBounds.size.width = movieBox.right - movieBox.left; - + + movieBounds.size.width = movieSize.width; + /* We need to find out if the preview movie needs to be scaled down so * that it doesn't overflow our available viewing container (just like for image * in -displayPreview) for HD sources, etc. [fPictureViewArea frame].size.height*/ - if( ((int)movieBounds.size.height) > [fPictureView frame].size.height ) + if( ((int)movieBounds.size.height) > [fPictureViewArea frame].size.height || scaleToScreen == YES) { /* The preview movie would be larger than the available viewing area * in the preview movie, so we go ahead and scale it down to the same size * as the still preview or we readjust our window to allow for the added height if need be */ NSSize displaySize = NSMakeSize( (float)movieBounds.size.width, (float)movieBounds.size.height ); - //NSSize displaySize = NSMakeSize( (float)fTitle->width, (float)fTitle->height ); NSSize viewSize = [self optimalViewSizeForImageSize:displaySize]; if( [self viewNeedsToResizeToSize:viewSize] ) { @@ -1033,6 +1136,7 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; } + [fMovieView setPreservesAspectRatio:YES]; [fMovieView setFrameSize:viewSize]; } else @@ -1040,8 +1144,12 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; /* Since the preview movie is smaller than the available viewing area * we can go ahead and use the preview movies native size */ [fMovieView setFrameSize:movieBounds.size]; + } + + + // lets reposition the movie if need be NSPoint origin = [fPictureViewArea frame].origin; @@ -1141,13 +1249,38 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; resultSize.height = maxHeight; } - return resultSize; + if (scaleToScreen == YES) + { + CGFloat screenAspect; + CGFloat viewAreaAspect; + //note, a mbp 15" at 1440 x 900 is a 1.6 ar + screenAspect = screenSize.width / screenSize.height; + + // Note, a standard dvd will use 720 x 480 which is a 1.5 + viewAreaAspect = viewAreaSize.width / viewAreaSize.height; + + if (screenAspect < viewAreaAspect) + { + resultSize.width = screenSize.width; + resultSize.height = (screenSize.width / viewAreaAspect); + } + else + { + resultSize.height = screenSize.height; + resultSize.width = resultSize.height * viewAreaAspect; + } + + } + + return resultSize; + + } // // -[PictureController(Private) resizePanelForViewSize:animate:] // -// Resizes the entire sheet to accomodate a view of a particular size. +// Resizes the entire window to accomodate a view of a particular size. // - (void)resizeSheetForViewSize: (NSSize)viewSize { @@ -1155,7 +1288,7 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; NSSize currentSize = [fPictureViewArea frame].size; CGFloat deltaX = viewSize.width - currentSize.width; CGFloat deltaY = viewSize.height - currentSize.height; - + // Now resize the whole panel by those same deltas, but don't exceed the min NSRect frame = [[self window] frame]; NSSize maxSize = [[self window] maxSize]; @@ -1172,24 +1305,51 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; frame.size.height = minSize.height; } - + // But now the sheet is off-center, so also shift the origin to center it and // keep the top aligned. if( frame.size.width != [[self window] frame].size.width ) frame.origin.x -= (deltaX / 2.0); - + if (isFullScreen) { - if( frame.size.height != [[self window] frame].size.height ) - frame.origin.y -= (deltaY / 2.0); + if( frame.size.height != [[self window] frame].size.height ) + { + frame.origin.y -= (deltaY / 2.0); + } + else + { + if( frame.size.height != [[self window] frame].size.height ) + frame.origin.y -= deltaY; + } + + [[self window] setFrame:frame display:YES animate:NO]; } else { - if( frame.size.height != [[self window] frame].size.height ) - frame.origin.y -= deltaY; + /* 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 = [[[self window] screen] frame].size; + NSPoint screenOrigin = [[[self window] screen] frame].origin; + /* 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; + } + + [[self window] setFrame:frame display:YES animate:YES]; } - - [[self window] setFrame:frame display:YES animate:YES]; + } // @@ -1199,13 +1359,36 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; // Assumes resizeSheetForViewSize: has already been called. // - (void)setViewSize: (NSSize)viewSize -{ +{ + /* special case for scaleToScreen */ + if (scaleToScreen == YES) + { + /* for scaleToScreen, we expand the fPictureView to fit the entire screen */ + NSSize areaSize = [fPictureViewArea frame].size; + CGFloat viewSizeAspect = viewSize.width / viewSize.height; + if (viewSizeAspect > 1.0) // we are wider than taller, so expand the width to fill the area and scale the height + { + viewSize.width = areaSize.width; + viewSize.height = viewSize.width / viewSizeAspect; + } + else + { + viewSize.height = areaSize.height; + viewSize.width = viewSize.height * viewSizeAspect; + } + + } + [fPictureView setFrameSize:viewSize]; - // center it vertically + // center it vertically and horizontally NSPoint origin = [fPictureViewArea frame].origin; origin.y += ([fPictureViewArea frame].size.height - [fPictureView frame].size.height) / 2.0; + + origin.x += ([fPictureViewArea frame].size.width - + [fPictureView frame].size.width) / 2.0; + [fPictureView setFrameOrigin:origin]; NSPoint controlboxorigin = [fPictureView frame].origin; @@ -1214,7 +1397,15 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; controlboxorigin.y += 100; controlboxorigin.x += ([fPictureViewArea frame].size.width - - [fPictureControlBox frame].size.width) / 2.0; + [fPictureControlBox frame].size.width) / 2.0; + + + /* origin should be rounded to integer otherwise font/antialiasing + * may be blurry. + */ + controlboxorigin.x = floor( controlboxorigin.x ); + controlboxorigin.y = floor( controlboxorigin.y ); + /* requires that thefPictureControlBox and the fEncodingControlBox * are the same width to line up. */ @@ -1226,7 +1417,7 @@ MaxOutputWidth = title->width - job->crop[2] - job->crop[3]; - (BOOL)viewNeedsToResizeToSize: (NSSize)newSize { - NSSize viewSize = [fPictureView frame].size; + NSSize viewSize = [fPictureViewArea frame].size; return (newSize.width != viewSize.width || newSize.height != viewSize.height); }