OSDN Git Service

MacGui: Adds a popup menu item for Hadamard-transformed exhaustive motion estimation...
[handbrake-jp/handbrake-jp-git.git] / macosx / PictureController.mm
1 /* $Id: PictureController.mm,v 1.11 2005/08/01 15:10:44 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #import "PictureController.h"
8 #import "Controller.h"
9 #import "HBPreviewController.h"
10 #import "HBFilterController.h"
11
12
13 @implementation PictureController
14
15 - (id)init
16 {
17         if (self = [super initWithWindowNibName:@"PictureSettings"])
18         {
19         // NSWindowController likes to lazily load its window. However since
20         // this controller tries to set all sorts of outlets before the window
21         // is displayed, we need it to load immediately. The correct way to do
22         // this, according to the documentation, is simply to invoke the window
23         // getter once.
24         //
25         // If/when we switch a lot of this stuff to bindings, this can probably
26         // go away.
27         [self window];
28         
29         fPreviewController = [[PreviewController alloc] init];
30     //fPictureFilterController = [[PictureFilterController alloc] init];
31     }
32         return self;
33 }
34
35 //------------------------------------------------------------------------------------
36 // Displays and brings the picture window to the front
37 //------------------------------------------------------------------------------------
38 - (IBAction) showPictureWindow: (id)sender
39 {
40     if ([[self window] isVisible])
41     {
42         [[self window] close];
43     }
44     else
45     {
46         [self showWindow:sender];
47         [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PictureSizeWindowIsOpen"];
48         if ([fPreviewController fullScreen] == YES)
49         {
50             [self setToFullScreenMode];
51         }
52         else
53         {
54             [self setToWindowedMode];
55         }
56     }
57 }
58
59 - (IBAction) showPreviewWindow: (id)sender
60 {
61     [fPreviewController showWindow:sender];
62 }
63
64 - (IBAction) showFilterWindow: (id)sender
65 {
66     [fHBController showFiltersPanel:sender];
67 }
68
69
70 - (void) setToFullScreenMode
71 {
72     int32_t shieldLevel = CGShieldingWindowLevel(); 
73     
74     [fPictureWindow setLevel:shieldLevel + 1]; 
75     // Show the window. 
76     [fPictureWindow makeKeyAndOrderFront:self];
77 }
78
79 - (void) setToWindowedMode
80 {
81     /* Set the window back to regular level */
82     [[self window] setLevel:NSNormalWindowLevel];
83 }
84
85 - (void)setHBController: (HBController *)controller
86 {
87     fHBController = controller;
88     //[fPictureFilterController   setHBController: controller];
89     [fPreviewController   setHBController: controller];
90     
91 }
92
93 - (void)awakeFromNib
94 {
95     [fPictureWindow setDelegate:self];
96     if( ![[self window] setFrameUsingName:@"PictureSizing"] )
97         [[self window] center];
98     [self setWindowFrameAutosaveName:@"PictureSizing"];
99     [[self window] setExcludedFromWindowsMenu:YES];
100 }
101
102
103 - (void)windowWillClose:(NSNotification *)aNotification
104 {
105 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"PictureSizeWindowIsOpen"];
106 }
107
108 - (BOOL)windowShouldClose:(id)fPictureWindow
109 {
110     return YES;
111 }
112
113 - (void) dealloc
114 {
115     [fPictureFilterController release];
116     [fPreviewController release];
117     [super dealloc];
118 }
119
120 - (void) SetHandle: (hb_handle_t *) handle
121 {
122     fHandle = handle;
123     
124     [fWidthStepper  setValueWraps: NO];
125     [fWidthStepper  setIncrement: 16];
126     [fWidthStepper  setMinValue: 64];
127     [fHeightStepper setValueWraps: NO];
128     [fHeightStepper setIncrement: 16];
129     [fHeightStepper setMinValue: 64];
130     
131     [fCropTopStepper    setIncrement: 2];
132     [fCropTopStepper    setMinValue:  0];
133     [fCropBottomStepper setIncrement: 2];
134     [fCropBottomStepper setMinValue:  0];
135     [fCropLeftStepper   setIncrement: 2];
136     [fCropLeftStepper   setMinValue:  0];
137     [fCropRightStepper  setIncrement: 2];
138     [fCropRightStepper  setMinValue:  0];
139     
140     [fPreviewController SetHandle: fHandle];
141     [fPictureFilterController SetHandle: fHandle];
142     
143
144 }
145
146 - (void) SetTitle: (hb_title_t *) title
147 {
148     hb_job_t * job = title->job;
149
150     fTitle = title;
151     
152     
153     
154     [fWidthStepper      setMaxValue: title->width];
155     [fWidthStepper      setIntValue: job->width];
156     [fWidthField        setIntValue: job->width];
157     [fHeightStepper     setMaxValue: title->height];
158     [fHeightStepper     setIntValue: job->height];
159     [fHeightField       setIntValue: job->height];
160     [fRatioCheck        setState:    job->keep_ratio ? NSOnState : NSOffState];
161     [fCropTopStepper    setMaxValue: title->height/2-2];
162     [fCropBottomStepper setMaxValue: title->height/2-2];
163     [fCropLeftStepper   setMaxValue: title->width/2-2];
164     [fCropRightStepper  setMaxValue: title->width/2-2];
165
166     /* Populate the Anamorphic NSPopUp button here */
167     [fAnamorphicPopUp removeAllItems];
168     [fAnamorphicPopUp addItemWithTitle: @"None"];
169     [fAnamorphicPopUp addItemWithTitle: @"Strict"];
170     if (allowLooseAnamorphic)
171     {
172     [fAnamorphicPopUp addItemWithTitle: @"Loose"];
173     }
174     [fAnamorphicPopUp selectItemAtIndex: job->anamorphic.mode];
175     
176     /* We initially set the previous state of keep ar to on */
177     keepAspectRatioPreviousState = 1;
178         if (!autoCrop)
179         {
180         [fCropMatrix  selectCellAtRow: 1 column:0];
181         /* If auto, lets set the crop steppers according to current job->crop values */
182         [fCropTopStepper    setIntValue: job->crop[0]];
183         [fCropTopField      setIntValue: job->crop[0]];
184         [fCropBottomStepper setIntValue: job->crop[1]];
185         [fCropBottomField   setIntValue: job->crop[1]];
186         [fCropLeftStepper   setIntValue: job->crop[2]];
187         [fCropLeftField     setIntValue: job->crop[2]];
188         [fCropRightStepper  setIntValue: job->crop[3]];
189         [fCropRightField    setIntValue: job->crop[3]];
190         }
191         else
192         {
193         [fCropMatrix  selectCellAtRow: 0 column:0];
194         }
195         
196         /* Set filters widgets according to the filters struct */
197     /* this has now been movied to the filters controller */
198     /*
199         [fDetelecineCheck setState:fPictureFilterSettings.detelecine];
200     [fDeinterlacePopUp selectItemAtIndex: fPictureFilterSettings.deinterlace];
201     [fDenoisePopUp selectItemAtIndex: fPictureFilterSettings.denoise];
202     [fDeblockCheck setState: fPictureFilterSettings.deblock];
203     [fDecombCheck setState: fPictureFilterSettings.decomb];
204     */
205     
206     fPicture = 0;
207     MaxOutputWidth = title->width - job->crop[2] - job->crop[3];
208     MaxOutputHeight = title->height - job->crop[0] - job->crop[1];
209     
210     [self SettingsChanged: nil];
211 }
212
213     
214
215 - (IBAction) SettingsChanged: (id) sender
216 {
217     hb_job_t * job = fTitle->job;
218     
219     autoCrop = ( [fCropMatrix selectedRow] == 0 );
220     [fCropTopStepper    setEnabled: !autoCrop];
221     [fCropBottomStepper setEnabled: !autoCrop];
222     [fCropLeftStepper   setEnabled: !autoCrop];
223     [fCropRightStepper  setEnabled: !autoCrop];
224
225     if( autoCrop )
226     {
227         memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
228     }
229     else
230     {
231         job->crop[0] = [fCropTopStepper    intValue];
232         job->crop[1] = [fCropBottomStepper intValue];
233         job->crop[2] = [fCropLeftStepper   intValue];
234         job->crop[3] = [fCropRightStepper  intValue];
235     }
236     
237         if( [fAnamorphicPopUp indexOfSelectedItem] > 0 )
238         {
239         if ([fAnamorphicPopUp indexOfSelectedItem] == 2) // Loose anamorphic
240         {
241             job->anamorphic.mode = 2;
242             [fWidthStepper setEnabled: YES];
243             [fWidthField setEnabled: YES];
244             /* We set job->width and call hb_set_anamorphic_size in libhb to do a "dry run" to get
245              * the values to be used by libhb for loose anamorphic
246              */
247             /* if the sender is the anamorphic popup, then we know that loose anamorphic has just
248              * been turned on, so snap the width to full width for the source.
249              */
250             if (sender == fAnamorphicPopUp)
251             {
252                 [fWidthStepper      setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
253                 [fWidthField        setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
254             }
255             job->width       = [fWidthStepper  intValue];
256             hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height);
257             [fHeightStepper      setIntValue: output_height];
258             [fHeightField        setIntValue: output_height];
259             job->height      = [fHeightStepper intValue];
260             
261         }
262         else // must be "1" or strict anamorphic
263         {
264             [fWidthStepper      setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
265             [fWidthField        setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
266             
267             /* This will show correct anamorphic height values, but
268              show distorted preview picture ratio */
269             [fHeightStepper      setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]];
270             [fHeightField        setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]];
271             job->width       = [fWidthStepper  intValue];
272             job->height      = [fHeightStepper intValue];
273             
274             job->anamorphic.mode = 1;
275             [fWidthStepper setEnabled: NO];
276             [fWidthField setEnabled: NO];
277         }
278         
279         /* if the sender is the Anamorphic checkbox, record the state
280          of KeepAspect Ratio so it can be reset if Anamorphic is unchecked again */
281         if (sender == fAnamorphicPopUp)
282         {
283             keepAspectRatioPreviousState = [fRatioCheck state];
284         }
285         [fRatioCheck setState:NSOffState];
286         [fRatioCheck setEnabled: NO];
287         
288         
289         [fHeightStepper setEnabled: NO];
290         [fHeightField setEnabled: NO];
291         
292     }
293     else
294         {
295         job->width       = [fWidthStepper  intValue];
296         job->height      = [fHeightStepper intValue];
297         job->anamorphic.mode = 0;
298         [fWidthStepper setEnabled: YES];
299         [fWidthField setEnabled: YES];
300         [fHeightStepper setEnabled: YES];
301         [fHeightField setEnabled: YES];
302         [fRatioCheck setEnabled: YES];
303         /* if the sender is the Anamorphic checkbox, we return the
304          keep AR checkbox to its previous state */
305         if (sender == fAnamorphicPopUp)
306         {
307             [fRatioCheck setState:keepAspectRatioPreviousState];
308         }
309         
310         }
311         
312     job->keep_ratio  = ( [fRatioCheck state] == NSOnState );
313
314     if( job->keep_ratio )
315     {
316         if( sender == fWidthStepper || sender == fRatioCheck ||
317            sender == fCropTopStepper || sender == fCropBottomStepper )
318         {
319             hb_fix_aspect( job, HB_KEEP_WIDTH );
320             if( job->height > fTitle->height )
321             {
322                 job->height = fTitle->height;
323                 hb_fix_aspect( job, HB_KEEP_HEIGHT );
324             }
325         }
326         else
327         {
328             hb_fix_aspect( job, HB_KEEP_HEIGHT );
329             if( job->width > fTitle->width )
330             {
331                 job->width = fTitle->width;
332                 hb_fix_aspect( job, HB_KEEP_WIDTH );
333             }
334         }
335         // hb_get_preview can't handle sizes that are larger than the original title
336         // dimensions
337         if( job->width > fTitle->width )
338             job->width = fTitle->width;
339
340         if( job->height > fTitle->height )
341             job->height = fTitle->height;
342     }
343
344     [fWidthStepper      setIntValue: job->width];
345     [fWidthField        setIntValue: job->width];
346     if( [fAnamorphicPopUp indexOfSelectedItem] < 2 )
347         {
348         [fHeightStepper     setIntValue: job->height];
349         [fHeightField       setIntValue: job->height];
350     }
351     [fCropTopStepper    setIntValue: job->crop[0]];
352     [fCropTopField      setIntValue: job->crop[0]];
353     [fCropBottomStepper setIntValue: job->crop[1]];
354     [fCropBottomField   setIntValue: job->crop[1]];
355     [fCropLeftStepper   setIntValue: job->crop[2]];
356     [fCropLeftField     setIntValue: job->crop[2]];
357     [fCropRightStepper  setIntValue: job->crop[3]];
358     [fCropRightField    setIntValue: job->crop[3]];
359     
360     [fPreviewController SetTitle:fTitle];
361     /* Sanity Check Here for < 16 px preview to avoid
362      crashing hb_get_preview. In fact, just for kicks
363      lets getting previews at a min limit of 32, since
364      no human can see any meaningful detail below that */
365     if (job->width >= 64 && job->height >= 64)
366     {
367        
368          // Purge the existing picture previews so they get recreated the next time
369         // they are needed.
370         [fPreviewController purgeImageCache];
371         /* We actually call displayPreview now from pictureSliderChanged which keeps
372          * our picture preview slider in sync with the previews being shown
373          */
374
375     //[fPreviewController pictureSliderChanged:nil];
376     [self reloadStillPreview];
377     }
378
379     /* we get the sizing info to display from fPreviewController */
380     [fSizeInfoField setStringValue: [fPreviewController pictureSizeInfoString]];
381
382     if (sender != nil)
383     {
384         [fHBController pictureSettingsDidChange];
385     }   
386     
387 }
388
389 - (NSString*) getPictureSizeInfoString
390 {
391     return [fSizeInfoField stringValue];
392 }
393
394 - (void)reloadStillPreview
395
396    hb_job_t * job = fTitle->job; 
397    
398    [fPreviewController SetTitle:fTitle];
399     /* Sanity Check Here for < 16 px preview to avoid
400      crashing hb_get_preview. In fact, just for kicks
401      lets getting previews at a min limit of 32, since
402      no human can see any meaningful detail below that */
403     if (job->width >= 64 && job->height >= 64)
404     {
405        
406          // Purge the existing picture previews so they get recreated the next time
407         // they are needed.
408         [fPreviewController purgeImageCache];
409         /* We actually call displayPreview now from pictureSliderChanged which keeps
410          * our picture preview slider in sync with the previews being shown
411          */
412
413     [fPreviewController pictureSliderChanged:nil];
414     }
415     
416 }
417
418
419 #pragma mark -
420
421 - (BOOL) autoCrop
422 {
423     return autoCrop;
424 }
425 - (void) setAutoCrop: (BOOL) setting
426 {
427     autoCrop = setting;
428 }
429
430 - (BOOL) allowLooseAnamorphic
431 {
432     return allowLooseAnamorphic;
433 }
434
435 - (void) setAllowLooseAnamorphic: (BOOL) setting
436 {
437     allowLooseAnamorphic = setting;
438 }
439
440 - (IBAction)showPreviewPanel: (id)sender forTitle: (hb_title_t *)title
441 {
442     [self SetTitle:title];
443     [self showWindow:sender];
444
445 }
446
447 @end
448