OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Controls / PictureSettings.cs
1 using System;\r
2 using System.ComponentModel;\r
3 using System.Drawing;\r
4 using System.Globalization;\r
5 using System.Windows.Forms;\r
6 using Handbrake.Parsing;\r
7 \r
8 namespace Handbrake.Controls\r
9 {\r
10 \r
11     //  TODO Custom Anamorphic\r
12     /*  NOT KEEPING DISPLAY ASPECT   == [Complete]\r
13        \r
14         KEEPING DISPLAY ASPECT RATIO == [TODO]\r
15         DAR = DISPLAY WIDTH / DISPLAY HEIGHT (cache after every modification)\r
16         Disable editing: PIXEL WIDTH, PIXEL HEIGHT\r
17         Changing DISPLAY WIDTH:\r
18             Changes HEIGHT to keep DAR\r
19             Changes PIXEL WIDTH to new DISPLAY WIDTH\r
20             Changes PIXEL HEIGHT to STORAGE WIDTH\r
21         Changing HEIGHT\r
22             Changes DISPLAY WIDTH to keep DAR\r
23             Changes PIXEL WIDTH to new DISPLAY WIDTH\r
24             Changes PIXEL HEIGHT to STORAGE WIDTH\r
25         Changing STORAGE_WIDTH:\r
26             Changes PIXEL WIDTH to DISPLAY WIDTH\r
27             Changes PIXEL HEIGHT to new STORAGE WIDTH\r
28      * */\r
29 \r
30 \r
31     public partial class PictureSettings : UserControl\r
32     {\r
33         private readonly CultureInfo Culture = new CultureInfo("en-US", false);\r
34         public event EventHandler PictureSettingsChanged;\r
35 \r
36         private Boolean preventChangingWidth, preventChangingHeight, preventChangingCustom, preventChangingDisplayWidth;\r
37         private int _PresetMaximumWidth, _PresetMaximumHeight;\r
38         private Title _SourceTitle;\r
39 \r
40         public PictureSettings()\r
41         {\r
42             InitializeComponent();\r
43 \r
44             drp_anamorphic.SelectedIndex = 1;\r
45             drp_modulus.SelectedIndex = 0;\r
46         }\r
47 \r
48         /// <summary>\r
49         /// Gets or sets the source media used by this control.\r
50         /// </summary>\r
51         [Browsable(false)]\r
52         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
53         public Title Source\r
54         {\r
55             get { return _SourceTitle; }\r
56             set\r
57             {\r
58                 _SourceTitle = value;\r
59                 Enabled = _SourceTitle != null;\r
60 \r
61                 // Set the Aspect Ratio\r
62                 lbl_Aspect.Text = _SourceTitle.AspectRatio.ToString(Culture);\r
63                 lbl_src_res.Text = _SourceTitle.Resolution.Width + " x " + _SourceTitle.Resolution.Height;\r
64 \r
65                 // Set the Recommended Cropping values\r
66                 crop_top.Value = GetCropMod2Clean(_SourceTitle.AutoCropDimensions[0]);\r
67                 crop_bottom.Value = GetCropMod2Clean(_SourceTitle.AutoCropDimensions[1]);\r
68                 crop_left.Value = GetCropMod2Clean(_SourceTitle.AutoCropDimensions[2]);\r
69                 crop_right.Value = GetCropMod2Clean(_SourceTitle.AutoCropDimensions[3]);\r
70 \r
71                 // Set the Resolution Boxes\r
72                 if (drp_anamorphic.SelectedIndex == 0)\r
73                 {\r
74                     if (text_width.Value == 0) // Only update the values if the fields don't already have values.\r
75                         text_width.Value = _SourceTitle.Resolution.Width;\r
76 \r
77                     check_KeepAR.Checked = true; // Forces Resolution to be correct.\r
78                 }\r
79                 else\r
80                 {\r
81                     text_width.Value = _SourceTitle.Resolution.Width;\r
82                     text_height.Value = _SourceTitle.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
83                     labelDisplaySize.Text = calculateAnamorphicSizes().Width + "x" + calculateAnamorphicSizes().Height;\r
84                 }\r
85 \r
86                 updownDisplayWidth.Value = calculateAnamorphicSizes().Width;\r
87                 updownParWidth.Value = _SourceTitle.ParVal.Width;\r
88                 updownParHeight.Value = _SourceTitle.ParVal.Height;\r
89             }\r
90         }\r
91 \r
92         /// <summary>\r
93         /// Gets or sets the maximum allowable size for the encoded resolution. Set a value to\r
94         /// "0" if the maximum does not matter.\r
95         /// </summary>\r
96         [Browsable(false)]\r
97         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
98         public Size PresetMaximumResolution\r
99         {\r
100             get { return new Size(_PresetMaximumWidth, _PresetMaximumHeight); }\r
101             set\r
102             {\r
103                 _PresetMaximumWidth = value.Width;\r
104                 _PresetMaximumHeight = value.Height;\r
105 \r
106                 if (value.Width != 0 && value.Height != 0)\r
107                     lbl_max.Text = "Max Width / Height";\r
108                 else if (value.Width != 0)\r
109                     lbl_max.Text = "Max Width";\r
110                 else if (value.Height != 0)\r
111                     lbl_max.Text = "Max Height";\r
112                 else\r
113                     lbl_max.Text = "";\r
114             }\r
115         }\r
116 \r
117         // Picture Controls\r
118         private void text_width_ValueChanged(object sender, EventArgs e)\r
119         {\r
120             if (preventChangingWidth)\r
121                 return;\r
122 \r
123             // Make sure the new value doesn't exceed the maximum\r
124             if (Source != null)\r
125                 if (text_width.Value > Source.Resolution.Width)\r
126                     text_width.Value = Source.Resolution.Width;\r
127 \r
128             switch (drp_anamorphic.SelectedIndex)\r
129             {\r
130                 case 0:\r
131                     if (check_KeepAR.Checked && Source != null)\r
132                     {\r
133                         preventChangingHeight = true;\r
134 \r
135                         int width = (int)text_width.Value;\r
136 \r
137                         double crop_width = Source.Resolution.Width - (double)crop_left.Value - (double)crop_right.Value;\r
138                         double crop_height = Source.Resolution.Height - (double)crop_top.Value - (double)crop_bottom.Value;\r
139                         double newHeight = (width * Source.Resolution.Width * sourceAspect.Height * crop_height) /\r
140                                            (Source.Resolution.Height * sourceAspect.Width * crop_width);\r
141                         text_height.Value = (decimal)GetModulusValue(newHeight);\r
142 \r
143                         preventChangingHeight = false;\r
144                     }\r
145                     break;\r
146                 case 3:\r
147                     if (check_KeepAR.CheckState == CheckState.Unchecked && Source != null)\r
148                     {\r
149                         if (preventChangingCustom)\r
150                             break;\r
151 \r
152                         preventChangingDisplayWidth = true; \r
153                         updownDisplayWidth.Value = text_width.Value * updownParWidth.Value / updownParHeight.Value;\r
154                         preventChangingDisplayWidth = false;\r
155 \r
156                         labelDisplaySize.Text = Math.Truncate(updownDisplayWidth.Value) + "x" + text_height.Value;\r
157                     }\r
158                     break;\r
159                 default:\r
160                     labelDisplaySize.Text = calculateAnamorphicSizes().Width + "x" + calculateAnamorphicSizes().Height;\r
161                     break;\r
162             }\r
163 \r
164             preventChangingWidth = false;\r
165         }\r
166         private void text_height_ValueChanged(object sender, EventArgs e)\r
167         {\r
168             if (preventChangingHeight)\r
169                 return;\r
170 \r
171             if (Source != null)\r
172                 if (text_height.Value > Source.Resolution.Height)\r
173                     text_height.Value = Source.Resolution.Height;\r
174 \r
175             switch (drp_anamorphic.SelectedIndex)\r
176             {\r
177                 case 0:\r
178                     if (check_KeepAR.Checked && Source != null)\r
179                     {\r
180                         preventChangingWidth = true;\r
181 \r
182                         double crop_width = Source.Resolution.Width - (double)crop_left.Value - (double)crop_right.Value;\r
183                         double crop_height = Source.Resolution.Height - (double)crop_top.Value - (double)crop_bottom.Value;\r
184 \r
185                         double new_width = ((double)text_height.Value * Source.Resolution.Height * sourceAspect.Width * crop_width) /\r
186                                             (Source.Resolution.Width * sourceAspect.Height * crop_height);\r
187 \r
188                         text_width.Value = (decimal)GetModulusValue(new_width);\r
189 \r
190                         preventChangingWidth = false;\r
191                     }\r
192                     break;\r
193                 case 3:\r
194                     labelDisplaySize.Text = Math.Truncate(updownDisplayWidth.Value) + "x" + text_height.Value;\r
195                     break;\r
196                 default:\r
197                     labelDisplaySize.Text = calculateAnamorphicSizes().Width + "x" + calculateAnamorphicSizes().Height;\r
198                     break;\r
199             }\r
200 \r
201             preventChangingHeight = false;\r
202         }\r
203         private void check_KeepAR_CheckedChanged(object sender, EventArgs e)\r
204         {\r
205             //Force TextWidth to recalc height\r
206             if (check_KeepAR.Checked)\r
207                 text_width_ValueChanged(this, new EventArgs());\r
208 \r
209             // Disable the Custom Anamorphic Par Controls if checked.\r
210             if (drp_anamorphic.SelectedIndex == 3)\r
211             {\r
212                 updownParWidth.Enabled = !check_KeepAR.Checked;\r
213                 updownParHeight.Enabled = !check_KeepAR.Checked;\r
214             }\r
215 \r
216             // Raise the Picture Settings Changed Event\r
217             if (PictureSettingsChanged != null)\r
218                 PictureSettingsChanged(this, new EventArgs());\r
219         }\r
220         private void updownDisplayWidth_ValueChanged(object sender, EventArgs e)\r
221         {\r
222             if (preventChangingDisplayWidth == false && check_KeepAR.CheckState == CheckState.Unchecked)\r
223             {\r
224                 preventChangingCustom = true;\r
225                 updownParWidth.Value = updownDisplayWidth.Value;\r
226                 updownParHeight.Value = text_width.Value;\r
227                 preventChangingCustom = false;\r
228             }\r
229         }\r
230 \r
231         // Anamorphic Controls\r
232         private void drp_anamorphic_SelectedIndexChanged(object sender, EventArgs e)\r
233         {\r
234             switch (drp_anamorphic.SelectedIndex)\r
235             {\r
236                 case 0:\r
237                     text_width.Enabled = true;\r
238                     text_height.Enabled = true;\r
239                     check_KeepAR.Enabled = true;\r
240 \r
241                     setCustomAnamorphicOptionsVisible(false);\r
242                     labelStaticDisplaySize.Visible = false;\r
243                     labelDisplaySize.Visible = false;\r
244 \r
245                     check_KeepAR.Checked = true;\r
246                     drp_modulus.SelectedIndex = 0;\r
247 \r
248                     if (check_KeepAR.Checked)\r
249                         text_width_ValueChanged(this, new EventArgs());\r
250                     // Don't update display size if we're not using anamorphic\r
251                     return;\r
252                 case 1:\r
253                     text_width.Enabled = false;\r
254                     text_height.Enabled = false;\r
255                     check_KeepAR.Enabled = false;\r
256 \r
257                     setCustomAnamorphicOptionsVisible(false);\r
258                     labelStaticDisplaySize.Visible = true;\r
259                     labelDisplaySize.Visible = true;\r
260                     drp_modulus.SelectedIndex = 0;\r
261 \r
262                     check_KeepAR.Checked = true;\r
263                     break;\r
264                 case 2:\r
265                     text_width.Enabled = true;\r
266                     text_height.Enabled = false;\r
267                     check_KeepAR.Enabled = false;\r
268 \r
269                     setCustomAnamorphicOptionsVisible(false);\r
270                     labelStaticDisplaySize.Visible = true;\r
271                     labelDisplaySize.Visible = true;\r
272                     drp_modulus.SelectedIndex = 0;\r
273 \r
274                     check_KeepAR.Checked = true;\r
275                     break;\r
276                 case 3:\r
277                     text_width.Enabled = true;\r
278                     text_height.Enabled = true;\r
279                     check_KeepAR.Enabled = true;\r
280 \r
281                     setCustomAnamorphicOptionsVisible(true);\r
282                     labelStaticDisplaySize.Visible = true;\r
283                     labelDisplaySize.Visible = true;\r
284 \r
285                     check_KeepAR.Checked = true;\r
286                     break;\r
287             }\r
288 \r
289             labelDisplaySize.Text = calculateAnamorphicSizes().Width + "x" + calculateAnamorphicSizes().Height;\r
290 \r
291             if (check_KeepAR.Checked)\r
292                 text_width_ValueChanged(this, new EventArgs());\r
293 \r
294             if (PictureSettingsChanged != null)\r
295                 PictureSettingsChanged(this, new EventArgs());\r
296         }\r
297         private void drp_modulus_SelectedIndexChanged(object sender, EventArgs e)\r
298         {\r
299             preventChangingWidth = true;\r
300             preventChangingHeight = true;\r
301 \r
302             text_width.Value = (decimal)GetModulusValue((double)text_width.Value);\r
303             text_height.Value = (decimal)GetModulusValue((double)text_height.Value);\r
304 \r
305             preventChangingWidth = false;\r
306             preventChangingHeight = false;\r
307 \r
308             text_width.Increment = int.Parse(drp_modulus.SelectedItem.ToString());\r
309             text_height.Increment = int.Parse(drp_modulus.SelectedItem.ToString());\r
310 \r
311             if (PictureSettingsChanged != null)\r
312                 PictureSettingsChanged(this, new EventArgs());\r
313         }\r
314 \r
315         // Cropping Controls\r
316         private void check_autoCrop_CheckedChanged(object sender, EventArgs e)\r
317         {\r
318             crop_top.Enabled = check_customCrop.Checked;\r
319             crop_bottom.Enabled = check_customCrop.Checked;\r
320             crop_left.Enabled = check_customCrop.Checked;\r
321             crop_right.Enabled = check_customCrop.Checked;\r
322         }\r
323         private void crop_ValueChanged(object sender, EventArgs e)\r
324         {\r
325             text_width_ValueChanged(this, new EventArgs());\r
326         }\r
327 \r
328         // GUI Functions\r
329         private void setCustomAnamorphicOptionsVisible(bool visible)\r
330         {\r
331             lbl_modulus.Visible = visible;\r
332             lbl_displayWidth.Visible = visible;\r
333             lbl_parWidth.Visible = visible;\r
334             lbl_parHeight.Visible = visible;\r
335 \r
336             drp_modulus.Visible = visible;\r
337             updownDisplayWidth.Visible = visible;\r
338             updownParWidth.Visible = visible;\r
339             updownParHeight.Visible = visible;\r
340         }\r
341 \r
342         // Calculation Functions\r
343         private Size sourceAspect\r
344         {\r
345             get\r
346             {\r
347                 if (Source != null)\r
348                 {\r
349                     if (Source.AspectRatio == 1.78F)\r
350                         return new Size(16, 9);\r
351                     if (Source.AspectRatio == 1.33F)\r
352                         return new Size(4, 3);\r
353                 }\r
354                 return new Size(0, 0);\r
355             }\r
356         }\r
357         private Size calculateAnamorphicSizes()\r
358         {\r
359             if (Source != null)\r
360             {\r
361                 /* Set up some variables to make the math easier to follow. */\r
362                 int cropped_width = Source.Resolution.Width - (int)crop_left.Value - (int)crop_right.Value;\r
363                 int cropped_height = Source.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
364                 double storage_aspect = (double)cropped_width / cropped_height;\r
365 \r
366                 /* Figure out what width the source would display at. */\r
367                 double source_display_width = (double)cropped_width * Source.ParVal.Width / Source.ParVal.Height;\r
368 \r
369                 /*\r
370                      3 different ways of deciding output dimensions:\r
371                       - 1: Strict anamorphic, preserve source dimensions\r
372                       - 2: Loose anamorphic, round to mod16 and preserve storage aspect ratio\r
373                       - 3: Power user anamorphic, specify everything\r
374                   */\r
375                 double width, height;\r
376                 switch (drp_anamorphic.SelectedIndex)\r
377                 {\r
378                     case 1:\r
379                         /* Strict anamorphic */\r
380                         double displayWidth = ((double)cropped_width * Source.ParVal.Width / Source.ParVal.Height);\r
381                         displayWidth = Math.Round(displayWidth, 0);\r
382                         Size output = new Size((int)displayWidth, cropped_height);\r
383                         return output;\r
384                     case 2:\r
385                         /* "Loose" anamorphic.\r
386                             - Uses mod16-compliant dimensions,\r
387                             - Allows users to set the width\r
388                         */\r
389                         width = (int)text_width.Value - (int)crop_left.Value - (int)crop_right.Value;\r
390                         width = GetModulusValue(width); /* Time to get picture width that divide cleanly.*/\r
391 \r
392                         height = (width / storage_aspect) + 0.5;\r
393                         height = GetModulusValue(height); /* Time to get picture height that divide cleanly.*/\r
394 \r
395                         /* The film AR is the source's display width / cropped source height.\r
396                            The output display width is the output height * film AR.\r
397                            The output PAR is the output display width / output storage width. */\r
398                         double pixel_aspect_width = height * source_display_width / cropped_height;\r
399                         double pixel_aspect_height = width;\r
400 \r
401                         double disWidthLoose = (width * pixel_aspect_width / pixel_aspect_height);\r
402                         return new Size((int)disWidthLoose, (int)height);\r
403                     case 3:\r
404 \r
405                         // Get the User Interface Values\r
406                         double UIdisplayWidth;\r
407                         double.TryParse(updownDisplayWidth.Text, out UIdisplayWidth);\r
408 \r
409                         /* Anamorphic 3: Power User Jamboree - Set everything based on specified values */\r
410                         height = GetModulusValue((double)text_height.Value);\r
411 \r
412                         if (check_KeepAR.Checked)\r
413                             return new Size((int)Math.Truncate(UIdisplayWidth), (int)height);\r
414 \r
415                         return new Size((int)Math.Truncate(UIdisplayWidth), (int)height);\r
416                 }\r
417             }\r
418 \r
419             // Return a default value of 0,0 to indicate failure\r
420             return new Size(0, 0);\r
421         }\r
422         private double GetModulusValue(double value)\r
423         {\r
424             int mod = int.Parse(drp_modulus.SelectedItem.ToString());\r
425             double remainder = value % mod;\r
426 \r
427             if (remainder == 0)\r
428                 return value;\r
429 \r
430             return remainder >= ((double)mod / 2) ? value + (mod - remainder) : value - remainder;\r
431         }\r
432         private static int GetCropMod2Clean(int value)\r
433         {\r
434             int remainder = value % 2;\r
435             if (remainder == 0) return value;\r
436             return (value + remainder);\r
437         }\r
438     }\r
439 }