OSDN Git Service

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