Homepage: <http://handbrake.fr/>.
It may be used under the terms of the GNU General Public License. */
-#include "PictureController.h"
+#import "PictureController.h"
@interface PictureController (Private)
- (id)initWithDelegate:(id)del
{
- if (self = [super init])
+ if (self = [super initWithWindowNibName:@"PictureSettings"])
{
+ // NSWindowController likes to lazily load its window. However since
+ // this controller tries to set all sorts of outlets before the window
+ // is displayed, we need it to load immediately. The correct way to do
+ // this, according to the documentation, is simply to invoke the window
+ // getter once.
+ //
+ // If/when we switch a lot of this stuff to bindings, this can probably
+ // go away.
+ [self window];
+
delegate = del;
- [self loadMyNibFile];
fPicturePreviews = [[NSMutableDictionary dictionaryWithCapacity: HB_NUM_HBLIB_PICTURES] retain];
}
return self;
}
/* Set filters widgets according to the filters struct */
- [fVFRCheck setState:fPictureFilterSettings.vfr];
- [fDetelecineCheck setState:fPictureFilterSettings.detelecine];
+ [fDetelecineCheck setState:fPictureFilterSettings.detelecine];
[fDeinterlacePopUp selectItemAtIndex: fPictureFilterSettings.deinterlace];
[fDenoisePopUp selectItemAtIndex: fPictureFilterSettings.denoise];
[fDeblockCheck setState: fPictureFilterSettings.deblock];
[fDenoisePopUp addItemWithTitle: @"Strong"];
/* Set denoises level according to the integer in the main window */
[fDenoisePopUp selectItemAtIndex: fPictureFilterSettings.denoise];
+
+ /* we use a popup to show the decomb settings */
+ [fDecombPopUp removeAllItems];
+ [fDecombPopUp addItemWithTitle: @"None"];
+ [fDecombPopUp addItemWithTitle: @"Default"];
+ [fDecombPopUp addItemWithTitle: @"Custom"];
+ /* Set denoises level according to the integer in the main window */
+ [fDecombPopUp selectItemAtIndex: fPictureFilterSettings.decomb];
}
{
[fPictureView setImage: [self imageForPicture: fPicture]];
- NSSize displaySize = NSMakeSize( (float)fTitle->width, (float)fTitle->height );
+ NSSize displaySize = NSMakeSize( ( CGFloat )fTitle->width, ( CGFloat )fTitle->height );
/* Set the picture size display fields below the Preview Picture*/
if( fTitle->job->pixel_ratio == 1 ) // Original PAR Implementation
{
[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 *= ((float)fTitle->job->pixel_aspect_width) / ((float)fTitle->job->pixel_aspect_height);
+ displaySize.width *= ( ( CGFloat )fTitle->job->pixel_aspect_width ) / ( ( CGFloat )fTitle->job->pixel_aspect_height );
}
else if (fTitle->job->pixel_ratio == 2) // Loose Anamorphic
{
@"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d",
fTitle->width, fTitle->height, output_width, output_height, display_width, output_height]];
- /* FIXME: needs to be fixed so that the picture window does not resize itself on the first
- anamorphic width drop
- */
- if (fTitle->width - 8 < output_width)
- {
- displaySize.width *= ((float)output_par_width) / ((float)output_par_height);
- }
+ /* FIXME: use the original aspect ratio to calculate the displaySize,
+ probably the size will not be the right one,
+ but at least the windows does not resize every time. */
+ displaySize.width *= ( ( CGFloat )fTitle->job->pixel_aspect_width) / ( ( CGFloat )fTitle->job->pixel_aspect_height );
}
else // No Anamorphic
{
@"Source: %dx%d, Output: %dx%d", fTitle->width, fTitle->height,
fTitle->job->width, fTitle->job->height]];
}
-
+
NSSize viewSize = [self optimalViewSizeForImageSize:displaySize];
if( [self viewNeedsToResizeToSize:viewSize] )
{
[self resizeSheetForViewSize:viewSize];
[self setViewSize:viewSize];
}
-
+
// Show the scaled text (use the height to check since the width can vary
// with anamorphic video).
- if( ((int)viewSize.height) != fTitle->height )
+ if( ( ( int )viewSize.height ) != fTitle->height )
{
- float scale = viewSize.width / ((float)fTitle->width);
+ 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]];
+ [fInfoField setStringValue: [[fInfoField stringValue] stringByAppendingString:scaleString]];
}
-
+
[fPrevButton setEnabled: ( fPicture > 0 )];
[fNextButton setEnabled: ( fPicture < 9 )];
}
+- (IBAction) deblockSliderChanged: (id) sender
+{
+ if ([fDeblockSlider floatValue] == 4.0)
+ {
+ [fDeblockField setStringValue: [NSString stringWithFormat: @"Off"]];
+ }
+ else
+ {
+ [fDeblockField setStringValue: [NSString stringWithFormat: @"%.0f", [fDeblockSlider floatValue]]];
+ }
+ [self SettingsChanged: sender];
+}
+
- (IBAction) SettingsChanged: (id) sender
{
hb_job_t * job = fTitle->job;
+ autoCrop = ( [fCropMatrix selectedRow] == 0 );
+ [fCropTopStepper setEnabled: !autoCrop];
+ [fCropBottomStepper setEnabled: !autoCrop];
+ [fCropLeftStepper setEnabled: !autoCrop];
+ [fCropRightStepper setEnabled: !autoCrop];
+
+ if( autoCrop )
+ {
+ memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
+ }
+ else
+ {
+ job->crop[0] = [fCropTopStepper intValue];
+ job->crop[1] = [fCropBottomStepper intValue];
+ job->crop[2] = [fCropLeftStepper intValue];
+ job->crop[3] = [fCropRightStepper intValue];
+ }
+
if( [fAnamorphicPopUp indexOfSelectedItem] > 0 )
{
if ([fAnamorphicPopUp indexOfSelectedItem] == 2) // Loose anamorphic
/* We set job->width and call hb_set_anamorphic_size in libhb to do a "dry run" to get
* the values to be used by libhb for loose anamorphic
*/
+ /* if the sender is the anamorphic popup, then we know that loose anamorphic has just
+ * been turned on, so snap the width to full width for the source.
+ */
+ if (sender == fAnamorphicPopUp)
+ {
+ [fWidthStepper setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
+ [fWidthField setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
+ }
job->width = [fWidthStepper intValue];
hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height);
[fHeightStepper setIntValue: output_height];
}
-
job->keep_ratio = ( [fRatioCheck state] == NSOnState );
fPictureFilterSettings.deinterlace = [fDeinterlacePopUp indexOfSelectedItem];
job->deinterlace = 0;
}
fPictureFilterSettings.denoise = [fDenoisePopUp indexOfSelectedItem];
- fPictureFilterSettings.vfr = [fVFRCheck state];
- if (fPictureFilterSettings.vfr > 0)
- {
- [fDetelecineCheck setState:NSOnState];
- [fDetelecineCheck setEnabled: NO];
- }
- else
- {
- [fDetelecineCheck setEnabled: YES];
- }
- fPictureFilterSettings.detelecine = [fDetelecineCheck state];
- fPictureFilterSettings.deblock = [fDeblockCheck state];
- //job->pixel_ratio = ( [fPARCheck state] == NSOnState );
- autoCrop = ( [fCropMatrix selectedRow] == 0 );
- [fCropTopStepper setEnabled: !autoCrop];
- [fCropBottomStepper setEnabled: !autoCrop];
- [fCropLeftStepper setEnabled: !autoCrop];
- [fCropRightStepper setEnabled: !autoCrop];
+ fPictureFilterSettings.detelecine = [fDetelecineCheck state];
- if( autoCrop )
+ if ([fDeblockField stringValue] == @"Off")
{
- memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
+ fPictureFilterSettings.deblock = 0;
}
else
{
- job->crop[0] = [fCropTopStepper intValue];
- job->crop[1] = [fCropBottomStepper intValue];
- job->crop[2] = [fCropLeftStepper intValue];
- job->crop[3] = [fCropRightStepper intValue];
+ fPictureFilterSettings.deblock = [fDeblockField intValue];
}
+ fPictureFilterSettings.decomb = [fDecombPopUp indexOfSelectedItem];
+
if( job->keep_ratio )
{
if( sender == fWidthStepper || sender == fRatioCheck ||
hb_fix_aspect( job, HB_KEEP_WIDTH );
}
}
+ // hb_get_preview can't handle sizes that are larger than the original title
+ // dimensions
+ if( job->width > fTitle->width )
+ job->width = fTitle->width;
+
+ if( job->height > fTitle->height )
+ job->height = fTitle->height;
}
-
+
[fWidthStepper setIntValue: job->width];
[fWidthField setIntValue: job->width];
if( [fAnamorphicPopUp indexOfSelectedItem] < 2 )
{
if ([delegate respondsToSelector:@selector(pictureSettingsDidChange)])
[delegate pictureSettingsDidChange];
-
- [NSApp endSheet: fPicturePanel];
- [fPicturePanel orderOut: self];
+
+ [NSApp endSheet:[self window]];
+ [[self window] orderOut:self];
}
- (BOOL) autoCrop
fPictureFilterSettings.detelecine = setting;
}
-- (int) vfr
-{
- return fPictureFilterSettings.vfr;
-}
-
-- (void) setVFR: (int) setting
-{
- fPictureFilterSettings.vfr = setting;
-}
-
- (int) deinterlace
{
return fPictureFilterSettings.deinterlace;
- (void) setDeinterlace: (int) setting {
fPictureFilterSettings.deinterlace = setting;
}
+- (int) decomb
+{
+ return fPictureFilterSettings.decomb;
+}
+- (void) setDecomb: (int) setting {
+ fPictureFilterSettings.decomb = setting;
+}
- (int) denoise
{
return fPictureFilterSettings.denoise;
- (void)showPanelInWindow: (NSWindow *)fWindow forTitle: (hb_title_t *)title
{
[self SetTitle:title];
-
- [NSApp beginSheet:fPicturePanel
+
+ [NSApp beginSheet:[self window]
modalForWindow:fWindow
modalDelegate:nil
didEndSelector:nil
[fPicturePreviews removeAllObjects];
}
-- (BOOL) loadMyNibFile
-{
- if(![NSBundle loadNibNamed:@"PictureSettings" owner:self])
- {
- NSLog(@"Warning! Could not load myNib file.\n");
- return NO;
- }
-
- return YES;
-}
-
@end
@implementation PictureController (Private)
// -[PictureController(Private) optimalViewSizeForImageSize:]
//
// Given the size of the preview image to be shown, returns the best possible
-// size for the OpenGL view.
+// size for the view.
//
- (NSSize)optimalViewSizeForImageSize: (NSSize)imageSize
{
// The min size is 320x240
- float minWidth = 320.0;
- float minHeight = 240.0;
-
+ CGFloat minWidth = 320.0;
+ CGFloat minHeight = 240.0;
+
// The max size of the view is when the sheet is taking up 85% of the screen.
NSSize screenSize = [[NSScreen mainScreen] frame].size;
- NSSize sheetSize = [fPicturePanel frame].size;
+ NSSize sheetSize = [[self window] frame].size;
NSSize viewAreaSize = [fPictureViewArea frame].size;
- float paddingX = sheetSize.width - viewAreaSize.width;
- float paddingY = sheetSize.height - viewAreaSize.height;
- float maxWidth = (0.85 * screenSize.width) - paddingX;
- float maxHeight = (0.85 * screenSize.height) - paddingY;
+ CGFloat paddingX = sheetSize.width - viewAreaSize.width;
+ CGFloat paddingY = sheetSize.height - viewAreaSize.height;
+ CGFloat maxWidth = (0.85 * screenSize.width) - paddingX;
+ CGFloat maxHeight = (0.85 * screenSize.height) - paddingY;
NSSize resultSize = imageSize;
//
// -[PictureController(Private) resizePanelForViewSize:animate:]
//
-// Resizes the entire sheet to accomodate an OpenGL view of a particular size.
+// Resizes the entire sheet to accomodate a view of a particular size.
//
- (void)resizeSheetForViewSize: (NSSize)viewSize
{
// Figure out the deltas for the new frame area
NSSize currentSize = [fPictureViewArea frame].size;
- float deltaX = viewSize.width - currentSize.width;
- float deltaY = viewSize.height - currentSize.height;
-
+ 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 = [fPicturePanel frame];
- NSSize maxSize = [fPicturePanel maxSize];
- NSSize minSize = [fPicturePanel minSize];
+ NSRect frame = [[self window] frame];
+ NSSize maxSize = [[self window] maxSize];
+ NSSize minSize = [[self window] minSize];
frame.size.width += deltaX;
frame.size.height += deltaY;
if( frame.size.width < minSize.width )
// But now the sheet is off-center, so also shift the origin to center it and
// keep the top aligned.
- frame.origin.x -= (deltaX / 2.0);
- frame.origin.y -= deltaY;
+ if( frame.size.width != [[self window] frame].size.width )
+ frame.origin.x -= (deltaX / 2.0);
- [fPicturePanel setFrame:frame display:YES animate:YES];
+ if( frame.size.height != [[self window] frame].size.height )
+ frame.origin.y -= deltaY;
+
+ [[self window] setFrame:frame display:YES animate:YES];
}
//
// -[PictureController(Private) setViewSize:]
//
-// Changes the OpenGL view's size and centers it vertially inside of its area.
+// Changes the view's size and centers it vertically inside of its area.
// Assumes resizeSheetForViewSize: has already been called.
//
- (void)setViewSize: (NSSize)viewSize
return (newSize.width != viewSize.width || newSize.height != viewSize.height);
}
-
@end