OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Controls / PictureSettings.cs
index 88f0e8f..d3196ae 100644 (file)
-using System;\r
+using System;\r
+using System.ComponentModel;\r
 using System.Drawing;\r
+using System.Globalization;\r
 using System.Windows.Forms;\r
 using Handbrake.Parsing;\r
 \r
 namespace Handbrake.Controls\r
 {\r
-    // TODO\r
-    // - Tie in the cropping controls.\r
-    \r
     public partial class PictureSettings : UserControl\r
     {\r
-        // Globals\r
-        public int maxWidth, maxHeight;\r
-        int widthVal, heightVal;\r
-        private double darValue;\r
-        private double storageAspect; // Storage Aspect Cache for current source and title\r
-        public Title selectedTitle { private get; set; }\r
-        private Boolean heightChangeGuard;\r
-        private Boolean looseAnamorphicHeightGuard;\r
-        private Boolean heightModJumpGaurd;\r
-\r
-        // Window Setup\r
+        private readonly CultureInfo Culture = new CultureInfo("en-US", false);\r
+        public event EventHandler PictureSettingsChanged;\r
+\r
+        private Boolean preventChangingWidth, preventChangingHeight;\r
+        private int _PresetMaximumWidth, _PresetMaximumHeight;\r
+        private Title _SourceTitle;\r
+\r
         public PictureSettings()\r
         {\r
             InitializeComponent();\r
-            lbl_max.Text = "";\r
-            drop_modulus.SelectedIndex = 0;\r
-            storageAspect = 0;\r
+\r
+            drp_anamorphic.SelectedIndex = 1;\r
+            drp_modulus.SelectedIndex = 0;\r
         }\r
-        public void setComponentsAfterScan(Title st)\r
+\r
+        /// <summary>\r
+        /// Gets or sets the source media used by this control.\r
+        /// </summary>\r
+        [Browsable(false)]\r
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
+        public Title Source\r
         {\r
-            storageAspect = 0;\r
-            selectedTitle = st;\r
-            // Set the Aspect Ratio\r
-            lbl_Aspect.Text = selectedTitle.AspectRatio.ToString();\r
-            lbl_src_res.Text = selectedTitle.Resolution.Width + " x " + selectedTitle.Resolution.Height;\r
+            get { return _SourceTitle; }\r
+            set\r
+            {\r
+                _SourceTitle = value;\r
+                Enabled = _SourceTitle != null;\r
 \r
-            // Set the Recommended Cropping values\r
-            crop_top.Text = selectedTitle.AutoCropDimensions[0].ToString();\r
-            crop_bottom.Text = selectedTitle.AutoCropDimensions[1].ToString();\r
-            crop_left.Text = selectedTitle.AutoCropDimensions[2].ToString();\r
-            crop_right.Text = selectedTitle.AutoCropDimensions[3].ToString();\r
+                // Set the Aspect Ratio\r
+                lbl_Aspect.Text = _SourceTitle.AspectRatio.ToString(Culture);\r
+                lbl_src_res.Text = _SourceTitle.Resolution.Width + " x " + _SourceTitle.Resolution.Height;\r
 \r
+                // Set the Recommended Cropping values\r
+                crop_top.Value = GetCropMod2Clean(_SourceTitle.AutoCropDimensions[0]);\r
+                crop_bottom.Value = GetCropMod2Clean(_SourceTitle.AutoCropDimensions[1]);\r
+                crop_left.Value = GetCropMod2Clean(_SourceTitle.AutoCropDimensions[2]);\r
+                crop_right.Value = GetCropMod2Clean(_SourceTitle.AutoCropDimensions[3]);\r
 \r
-            // Set the Resolution Boxes\r
-            text_width.Value = selectedTitle.Resolution.Width;\r
+                // Set the Resolution Boxes\r
+                text_width.Value = _SourceTitle.Resolution.Width;\r
 \r
-            if (drp_anamorphic.SelectedIndex == 0)\r
-                text_height.Value = cacluateHeight(selectedTitle.Resolution.Width);\r
-            else if (drp_anamorphic.SelectedIndex == 1 || drp_anamorphic.SelectedIndex == 3)\r
-            {\r
-                heightModJumpGaurd = true;\r
-                text_height.Value = selectedTitle.Resolution.Height - (int) crop_top.Value - (int) crop_bottom.Value;\r
-            }\r
-            else if (drp_anamorphic.SelectedIndex == 2)\r
-            {\r
-                heightModJumpGaurd = false;\r
-                text_height.Value = selectedTitle.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
-            }\r
+                if (drp_anamorphic.SelectedIndex == 0)\r
+                {\r
+                    int width = _SourceTitle.Resolution.Width;\r
 \r
-            if (drp_anamorphic.SelectedIndex == 3)\r
-            {\r
-                txt_parWidth.Text = selectedTitle.ParVal.Width.ToString();\r
-                txt_parHeight.Text = selectedTitle.ParVal.Height.ToString();\r
-                txt_displayWidth.Text = displayWidth().ToString();\r
-            }\r
+                    double crop_width = _SourceTitle.Resolution.Width - (double)crop_left.Value - (double)crop_right.Value;\r
+                    double crop_height = _SourceTitle.Resolution.Height - (double)crop_top.Value - (double)crop_bottom.Value;\r
+                    double newHeight = (width * _SourceTitle.Resolution.Width * sourceAspect.Height * crop_height) / (_SourceTitle.Resolution.Height * sourceAspect.Width * crop_width);\r
+                    text_height.Value = (decimal)GetModulusValue(newHeight);\r
+                }\r
+                else\r
+                {\r
+                    text_height.Value = _SourceTitle.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
+                    labelDisplaySize.Text = calculateAnamorphicSizes().Width + "x" + calculateAnamorphicSizes().Height;\r
+                }\r
+\r
+                updownParWidth.Value = _SourceTitle.ParVal.Width;\r
+                updownParHeight.Value = _SourceTitle.ParVal.Height;\r
+                updownDisplayWidth.Value = calculateAnamorphicSizes().Width;\r
 \r
-            setMax();\r
+            }\r
         }\r
-        public void setMax()\r
+\r
+        /// <summary>\r
+        /// Gets or sets the maximum allowable size for the encoded resolution. Set a value to\r
+        /// "0" if the maximum does not matter.\r
+        /// </summary>\r
+        [Browsable(false)]\r
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
+        public Size PresetMaximumResolution\r
         {\r
-            if (maxWidth != 0 && maxHeight != 0)\r
-                lbl_max.Text = "Max Width / Height";\r
-            else if (maxWidth != 0)\r
-                lbl_max.Text = "Max Width";\r
-            else\r
-                lbl_max.Text = "";\r
+            get { return new Size(_PresetMaximumWidth, _PresetMaximumHeight); }\r
+            set\r
+            {\r
+                _PresetMaximumWidth = value.Width;\r
+                _PresetMaximumHeight = value.Height;\r
+\r
+                if (value.Width != 0 && value.Height != 0)\r
+                    lbl_max.Text = "Max Width / Height";\r
+                else if (value.Width != 0)\r
+                    lbl_max.Text = "Max Width";\r
+                else if (value.Height != 0)\r
+                    lbl_max.Text = "Max Height";\r
+                else\r
+                    lbl_max.Text = "";\r
+            }\r
         }\r
 \r
-        // Basic Picture Setting Controls\r
+        // Picture Controls\r
         private void text_width_ValueChanged(object sender, EventArgs e)\r
         {\r
-            maxWidth = 0;\r
-            setMax();\r
-            \r
-            // Get the Modulus\r
-            int mod;\r
-            int.TryParse(drop_modulus.SelectedItem.ToString(), out mod);\r
+            if (preventChangingWidth)\r
+                return;\r
 \r
-            // Increase or decrease value by the correct mod.\r
-            text_width.Value = widthChangeMod(mod);\r
+            // Make sure the new value doesn't exceed the maximum\r
+            if (Source != null)\r
+                if (text_width.Value > Source.Resolution.Width)\r
+                    text_width.Value = Source.Resolution.Width;\r
 \r
-            // Mode Switch\r
             switch (drp_anamorphic.SelectedIndex)\r
             {\r
                 case 0:\r
-                    if (calculateUnchangeValue(true) != -1 && check_KeepAR.Checked)\r
-                        text_height.Value = calculateUnchangeValue(true);\r
-                    break;\r
-                case 1:\r
-                    lbl_anamorphic.Text = strictAnamorphic();\r
-                    break;\r
-                case 2:\r
-                    lbl_anamorphic.Text = looseAnamorphic();\r
+                    if (check_KeepAR.Checked && Source != null)\r
+                    {\r
+                        preventChangingHeight = true;\r
+\r
+                        int width = (int)text_width.Value;\r
+\r
+                        double crop_width = Source.Resolution.Width - (double)crop_left.Value - (double)crop_right.Value;\r
+                        double crop_height = Source.Resolution.Height - (double)crop_top.Value - (double)crop_bottom.Value;\r
+                        double newHeight = (width * Source.Resolution.Width * sourceAspect.Height * crop_height) /\r
+                                           (Source.Resolution.Height * sourceAspect.Width * crop_width);\r
+                        text_height.Value = (decimal)GetModulusValue(newHeight);\r
+\r
+                        preventChangingHeight = false;\r
+                    }\r
                     break;\r
-                case 3:\r
-                    customAnamorphic(text_width);\r
+                default:\r
+                    labelDisplaySize.Text = calculateAnamorphicSizes().Width + "x" + calculateAnamorphicSizes().Height;\r
                     break;\r
             }\r
-                \r
+\r
+            preventChangingWidth = false;\r
         }\r
         private void text_height_ValueChanged(object sender, EventArgs e)\r
         {\r
-            maxHeight = 0;\r
-            setMax();\r
+            if (preventChangingHeight)\r
+                return;\r
 \r
-            // Get the Modulus\r
-            int mod;\r
-            int.TryParse(drop_modulus.SelectedItem.ToString(), out mod);\r
+            if (Source != null)\r
+                if (text_height.Value > Source.Resolution.Height)\r
+                    text_height.Value = Source.Resolution.Height;\r
 \r
-            // Increase or decrease value by the correct mod.\r
-            if (drp_anamorphic.SelectedIndex != 2 && !heightModJumpGaurd)\r
-            {\r
-                decimal val = heightChangeMod(mod);\r
-                heightChangeGuard = true;\r
-                if (text_height.Value != val)\r
-                {\r
-                    heightChangeGuard = false;\r
-                    text_height.Value = val;\r
-                }\r
-            }\r
-\r
-            // Mode Switch\r
             switch (drp_anamorphic.SelectedIndex)\r
             {\r
                 case 0:\r
-                    if (drp_anamorphic.SelectedIndex != 3)\r
+                    if (check_KeepAR.Checked && Source != null)\r
                     {\r
-                        if (calculateUnchangeValue(false) != -1)\r
-                            text_width.Value = calculateUnchangeValue(false);\r
+                        preventChangingWidth = true;\r
+\r
+                        double crop_width = Source.Resolution.Width - (double)crop_left.Value - (double)crop_right.Value;\r
+                        double crop_height = Source.Resolution.Height - (double)crop_top.Value - (double)crop_bottom.Value;\r
+\r
+                        double new_width = ((double)text_height.Value * Source.Resolution.Height * sourceAspect.Width * crop_width) /\r
+                                            (Source.Resolution.Width * sourceAspect.Height * crop_height);\r
+\r
+                        text_width.Value = (decimal)GetModulusValue(new_width);\r
+\r
+                        preventChangingWidth = false;\r
                     }\r
                     break;\r
-                case 1:\r
-                    lbl_anamorphic.Text = strictAnamorphic();\r
-                    break;\r
-                case 2:\r
-                    if (!looseAnamorphicHeightGuard)\r
-                        lbl_anamorphic.Text = looseAnamorphic();\r
-                    break;\r
-                case 3:\r
-                    if (!heightChangeGuard)\r
-                        customAnamorphic(text_height);\r
+                default:\r
+                    labelDisplaySize.Text = calculateAnamorphicSizes().Width + "x" + calculateAnamorphicSizes().Height;\r
                     break;\r
             }\r
-            heightChangeGuard = false;\r
-            looseAnamorphicHeightGuard = false;\r
-            heightModJumpGaurd = false;\r
+\r
+            preventChangingHeight = false;\r
         }\r
         private void check_KeepAR_CheckedChanged(object sender, EventArgs e)\r
         {\r
-            // Recalculate Height based on width when enabled\r
-            if (drp_anamorphic.SelectedIndex != 3 && check_KeepAR.Checked && selectedTitle != null)\r
-                text_height.Value = cacluateHeight(widthVal);\r
-\r
-            // Enable Par Width/Height Check boxes if Keep AR is enabled, otherwise disable them\r
+            //Force TextWidth to recalc height\r
             if (check_KeepAR.Checked)\r
+                text_width_ValueChanged(this, new EventArgs());\r
+\r
+            // Disable the Custom Anamorphic Par Controls if checked.\r
+            if (drp_anamorphic.SelectedIndex == 3)\r
             {\r
-                txt_parWidth.Enabled = false;\r
-                txt_parHeight.Enabled = false;\r
-            }\r
-            else\r
-            {\r
-                txt_parWidth.Enabled = true;\r
-                txt_parHeight.Enabled = true;\r
+                updownParWidth.Enabled = !check_KeepAR.Checked;\r
+                updownParHeight.Enabled = !check_KeepAR.Checked;\r
             }\r
+\r
+            // Raise the Picture Settings Changed Event\r
+            if (PictureSettingsChanged != null)\r
+                PictureSettingsChanged(this, new EventArgs());\r
         }\r
+\r
+        // Anamorphic Controls\r
         private void drp_anamorphic_SelectedIndexChanged(object sender, EventArgs e)\r
         {\r
             switch (drp_anamorphic.SelectedIndex)\r
             {\r
-                case 0: // None\r
-                    text_height.Enabled = true;\r
+                case 0:\r
                     text_width.Enabled = true;\r
-                    check_KeepAR.CheckState = CheckState.Checked;\r
-                    check_KeepAR.Enabled = true;\r
-                    disableCustomAnaControls();\r
-                    if (selectedTitle != null)\r
-                    {\r
-                        text_width.Value = selectedTitle.Resolution.Width;\r
-                        text_height.Value = selectedTitle.Resolution.Height;\r
-                    }\r
+                    text_height.Enabled = true;\r
                     check_KeepAR.Enabled = true;\r
-                    lbl_anamorphic.Text = "";\r
-                    lbl_anamprohicLbl.Visible = false;\r
-                    break;\r
-                case 1: // Strict\r
-                    if (selectedTitle != null)\r
-                    {\r
-                        heightModJumpGaurd = true;\r
-                        text_width.Value = selectedTitle.Resolution.Width - (int)crop_left.Value - (int)crop_right.Value;\r
-                        text_height.Value = selectedTitle.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
-                    }\r
-                    text_height.Enabled = false;\r
+\r
+                    setCustomAnamorphicOptionsVisible(false);\r
+                    labelStaticDisplaySize.Visible = false;\r
+                    labelDisplaySize.Visible = false;\r
+\r
+                    check_KeepAR.Checked = true;\r
+                    drp_modulus.SelectedIndex = 0;\r
+\r
+                    if (check_KeepAR.Checked)\r
+                        text_width_ValueChanged(this, new EventArgs());\r
+                    // Don't update display size if we're not using anamorphic\r
+                    return;\r
+                case 1:\r
                     text_width.Enabled = false;\r
-                    check_KeepAR.CheckState = CheckState.Unchecked;\r
-                    check_KeepAR.Enabled = false;\r
-                    disableCustomAnaControls();\r
-                    lbl_anamorphic.Text = strictAnamorphic();\r
-                    lbl_anamprohicLbl.Visible = true;\r
-                    break;\r
-                case 2: // Loose\r
-                    disableCustomAnaControls();\r
-                    storageAspect = 0;\r
                     text_height.Enabled = false;\r
-                    text_width.Enabled = true;\r
-                    if (selectedTitle != null)\r
-                    {\r
-                        heightModJumpGaurd = true;\r
-                        text_width.Value = selectedTitle.Resolution.Width;\r
-                        text_height.Value = selectedTitle.Resolution.Height - (int) crop_top.Value - (int) crop_bottom.Value;\r
-                    }\r
-                    lbl_anamorphic.Text = looseAnamorphic();\r
-                    lbl_anamprohicLbl.Visible = true;\r
-                    break;\r
-                case 3: // Custom\r
+                    check_KeepAR.Enabled = false;\r
 \r
-                    // Display Elements\r
-                    enableCustomAnaControls();\r
-                    text_height.Enabled = true;\r
-                    text_width.Enabled = true;\r
+                    setCustomAnamorphicOptionsVisible(false);\r
+                    labelStaticDisplaySize.Visible = true;\r
+                    labelDisplaySize.Visible = true;\r
+                    drp_modulus.SelectedIndex = 0;\r
 \r
-                    // Actual Work  \r
-                    if (selectedTitle != null)\r
-                    {\r
-                        heightModJumpGaurd = true;\r
-                        widthVal = selectedTitle.Resolution.Width;\r
-                        text_width.Value = selectedTitle.Resolution.Width - (int)crop_left.Value - (int)crop_right.Value;\r
-                        text_height.Value = selectedTitle.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
-                        txt_parWidth.Text = selectedTitle.ParVal.Width.ToString();\r
-                        txt_parHeight.Text = selectedTitle.ParVal.Height.ToString();\r
-                        txt_displayWidth.Text = displayWidth().ToString();\r
-                    }\r
-   \r
-                    darValue = calculateDar();\r
+                    check_KeepAR.Checked = true;\r
+                    break;\r
+                case 2:\r
+                    text_width.Enabled = true;\r
+                    text_height.Enabled = false;\r
+                    check_KeepAR.Enabled = false;\r
 \r
-                    check_KeepAR.CheckState = CheckState.Checked;\r
-                    check_KeepAR.Enabled = true;\r
-                    lbl_anamprohicLbl.Visible = true;\r
+                    setCustomAnamorphicOptionsVisible(false);\r
+                    labelStaticDisplaySize.Visible = true;\r
+                    labelDisplaySize.Visible = true;\r
+                    drp_modulus.SelectedIndex = 0;\r
 \r
+                    check_KeepAR.Checked = true;\r
                     break;\r
-            }\r
-        }\r
+                case 3:\r
+                    text_width.Enabled = true;\r
+                    text_height.Enabled = true;\r
+                    check_KeepAR.Enabled = true;\r
 \r
-        // Custom Anamorphic Controls\r
-        private void txt_displayWidth_Keyup(object sender, KeyEventArgs e)\r
-        {\r
-            if (e.KeyCode == Keys.Enter)\r
-                customAnamorphic(txt_displayWidth);\r
-        }\r
-        private void txt_parHeight_Keyup(object sender, KeyEventArgs e)\r
-        {\r
-            if (e.KeyCode == Keys.Enter)\r
-                customAnamorphic(txt_parHeight);\r
-        }\r
-        private void txt_parWidth_Keyup(object sender, KeyEventArgs e)\r
-        {\r
-            if (e.KeyCode == Keys.Enter)\r
-                customAnamorphic(txt_parWidth);\r
-        }\r
-        \r
-        // Cropping Controls\r
-        private void check_autoCrop_CheckedChanged(object sender, EventArgs e)\r
-        {\r
-            crop_left.Enabled = false;\r
-            crop_right.Enabled = false;\r
-            crop_top.Enabled = false;\r
-            crop_bottom.Enabled = false;\r
-        }\r
-        private void check_customCrop_CheckedChanged(object sender, EventArgs e)\r
-        {\r
-            crop_left.Enabled = true;\r
-            crop_right.Enabled = true;\r
-            crop_top.Enabled = true;\r
-            crop_bottom.Enabled = true;\r
-            if (selectedTitle != null)\r
-            {\r
-                crop_top.Text = selectedTitle.AutoCropDimensions[0].ToString();\r
-                crop_bottom.Text = selectedTitle.AutoCropDimensions[1].ToString();\r
-                crop_left.Text = selectedTitle.AutoCropDimensions[2].ToString();\r
-                crop_right.Text = selectedTitle.AutoCropDimensions[3].ToString();\r
-            }\r
-            else\r
-            {\r
-                crop_left.Text = "0";\r
-                crop_right.Text = "0";\r
-                crop_top.Text = "0";\r
-                crop_bottom.Text = "0";\r
-            }\r
-        }\r
-        private void crop_left_ValueChanged(object sender, EventArgs e)\r
-        {\r
-            if (crop_left.Value % 2 != 0)\r
-                crop_left.Value++;\r
-        }\r
-        private void crop_right_ValueChanged(object sender, EventArgs e)\r
-        {\r
-            if (crop_right.Value % 2 != 0)\r
-                crop_right.Value++;\r
-        }\r
-        private void crop_top_ValueChanged(object sender, EventArgs e)\r
-        {\r
-            if (crop_top.Value % 2 != 0)\r
-                crop_top.Value++;\r
-        }\r
-        private void crop_bottom_ValueChanged(object sender, EventArgs e)\r
-        {\r
-            if (crop_bottom.Value % 2 != 0)\r
-                crop_bottom.Value++;\r
-        }\r
+                    setCustomAnamorphicOptionsVisible(true);\r
+                    labelStaticDisplaySize.Visible = true;\r
+                    labelDisplaySize.Visible = true;\r
 \r
-        // Custom Anamorphic Code\r
-        private void customAnamorphic(Control control)\r
-        {\r
-            // Get and parse all the required values\r
-            int cropLeft = (int)crop_left.Value;\r
-            int cropRight = (int)crop_right.Value;\r
-\r
-            int width = (int)text_width.Value;\r
-            int cropped_width = width - cropLeft - cropRight;\r
-\r
-            int mod = 16;\r
-            int.TryParse(drop_modulus.SelectedItem.ToString(), out mod);\r
-\r
-            int parW, parH;\r
-            double displayWidth;\r
-            int.TryParse(txt_parWidth.Text, out parW);\r
-            int.TryParse(txt_parHeight.Text, out parH);\r
-            double.TryParse(txt_displayWidth.Text, out displayWidth);\r
-\r
-            /* NOT KEEPING DISPLAY ASPECT\r
-             * Changing STORAGE WIDTH changes DISPLAY WIDTH to STORAGE WIDTH * PIXEL WIDTH / PIXEL HEIGHT\r
-             * Changing PIXEL dimensions changes DISPLAY WIDTH to STORAGE WIDTH * PIXEL WIDTH / PIXEL HEIGHT\r
-             * Changing DISPLAY WIDTH changes PIXEL WIDTH to DISPLAY WIDTH and PIXEL HEIGHT to STORAGE WIDTH\r
-             * Changing HEIGHT just....changes the height.\r
-             */\r
-            if (!check_KeepAR.Checked)\r
-            {\r
-                switch (control.Name)\r
-                {\r
-                    case "text_width":\r
-                        double dw = (double)cropped_width * parW / parH;\r
-                        dw = Math.Round(dw, 2);\r
-                        txt_displayWidth.Text = dw.ToString();\r
-                        break;\r
-                    case "txt_parWidth":\r
-                        double dwpw = (double)cropped_width * parW / parH;\r
-                        dwpw = Math.Round(dwpw, 2);\r
-                        txt_displayWidth.Text = dwpw.ToString();\r
-                        break;\r
-                    case "txt_parHeight":\r
-                        double dwph = (double)cropped_width * parW / parH;\r
-                        dwph = Math.Round(dwph, 2);\r
-                        txt_displayWidth.Text = dwph.ToString();\r
-                        break;\r
-                    case "txt_displayWidth":\r
-                        txt_parWidth.Text = Math.Round(displayWidth, 0).ToString();\r
-                        txt_parHeight.Text = text_width.Text;\r
-                        break;\r
-                }\r
+                    check_KeepAR.Checked = true;\r
+                    break;\r
             }\r
 \r
-            /*\r
-             * KEEPING DISPLAY ASPECT RATIO\r
-             * DAR = DISPLAY WIDTH / DISPLAY HEIGHT (cache after every modification)\r
-             * Disable editing: PIXEL WIDTH, PIXEL HEIGHT\r
-             * Changing DISPLAY WIDTH:\r
-             *     Changes HEIGHT to keep DAR\r
-             *     Changes PIXEL WIDTH to new DISPLAY WIDTH\r
-             *     Changes PIXEL HEIGHT to STORAGE WIDTH\r
-             * Changing HEIGHT\r
-             *     Changes DISPLAY WIDTH to keep DAR\r
-             *     Changes PIXEL WIDTH to new DISPLAY WIDTH\r
-             *     Changes PIXEL HEIGHT to STORAGE WIDTH\r
-             * Changing STORAGE_WIDTH:\r
-             *     Changes PIXEL WIDTH to DISPLAY WIDTH\r
-             *     Changes PIXEL HEIGHT to new STORAGE WIDTH \r
-             */\r
+            labelDisplaySize.Text = calculateAnamorphicSizes().Width + "x" + calculateAnamorphicSizes().Height;\r
 \r
             if (check_KeepAR.Checked)\r
-            {\r
-                switch (control.Name)\r
-                {\r
-                    case "txt_displayWidth":\r
-                        heightChangeGuard = true;\r
-                        text_height.Value = (decimal)getHeightKeepDar();  //Changes HEIGHT to keep DAR\r
-                        //darValue = calculateDar(); // Cache the dar value\r
-                        txt_parWidth.Text = txt_displayWidth.Text;\r
-                        txt_parHeight.Text = cropped_width.ToString();\r
-                        break;\r
-                    case "text_height":\r
-                        heightChangeGuard = true;\r
-                        txt_displayWidth.Text = getDisplayWidthKeepDar().ToString();  //Changes DISPLAY WIDTH to keep DAR\r
-                        txt_parWidth.Text = txt_displayWidth.Text;\r
-                        txt_parHeight.Text = cropped_width.ToString();\r
-                        break; \r
-                    case "text_width":\r
-                        txt_parWidth.Text = txt_displayWidth.Text;\r
-                        txt_parHeight.Text = cropped_width.ToString();\r
-                        break;\r
-                }\r
-            }\r
-        }\r
-        private double getDisplayWidthKeepDar()\r
-        {\r
-            double displayWidth;\r
-            double.TryParse(txt_displayWidth.Text, out displayWidth);\r
-            double currentDar = calculateDar();\r
-            double newDwValue = displayWidth;\r
+                text_width_ValueChanged(this, new EventArgs());\r
 \r
-            // Correct display width up or down to correct for dar.           \r
-            if (currentDar > darValue)\r
-            {\r
-                while (currentDar > darValue)\r
-                {\r
-                    displayWidth--;\r
-                    newDwValue = displayWidth;\r
-                    currentDar = calculateDarByVal(text_height.Value, displayWidth);\r
-                }\r
-            }\r
-            else\r
-            {\r
-                while (currentDar < darValue)\r
-                {\r
-                    displayWidth++;\r
-                    newDwValue = displayWidth;\r
-                    currentDar = calculateDarByVal(text_height.Value, displayWidth);\r
-                }\r
-            }\r
-\r
-            return Math.Round(newDwValue, 2);\r
+            if (PictureSettingsChanged != null)\r
+                PictureSettingsChanged(this, new EventArgs());\r
         }\r
-        private double getHeightKeepDar()\r
+        private void drp_modulus_SelectedIndexChanged(object sender, EventArgs e)\r
         {\r
-            double displayWidth;\r
-            double.TryParse(txt_displayWidth.Text, out displayWidth);\r
-            double currentDar = calculateDar();\r
-            double newHeightVal = heightVal;\r
+            preventChangingWidth = true;\r
+            preventChangingHeight = true;\r
 \r
-            // Correct display width up or down.\r
-            if (currentDar > darValue)\r
-            {\r
-                while (currentDar > darValue)\r
-                {\r
-                    heightVal++;\r
-                    newHeightVal = heightVal;\r
-                    currentDar = calculateDarByVal(heightVal, displayWidth);\r
-                }\r
-            }\r
-            else\r
-            {\r
-                while (currentDar < darValue)\r
-                {\r
-                    heightVal--;\r
-                    newHeightVal = heightVal;\r
-                    currentDar = calculateDarByVal(heightVal, displayWidth);\r
-                }\r
-            }\r
+            text_width.Value = (decimal)GetModulusValue((double)text_width.Value);\r
+            text_height.Value = (decimal)GetModulusValue((double)text_height.Value);\r
 \r
-            return newHeightVal;\r
-        }\r
-        private double calculateDar()\r
-        {\r
-            // DAR = DISPLAY WIDTH / DISPLAY HEIGHT (cache after every modification)\r
-            double displayWidth;\r
-            double.TryParse(txt_displayWidth.Text, out displayWidth);\r
+            preventChangingWidth = false;\r
+            preventChangingHeight = false;\r
 \r
-            double calculatedDar = displayWidth / (int)text_height.Value;\r
+            text_width.Increment = int.Parse(drp_modulus.SelectedItem.ToString());\r
+            text_height.Increment = int.Parse(drp_modulus.SelectedItem.ToString());\r
 \r
-            return calculatedDar;\r
+            if (PictureSettingsChanged != null)\r
+                PictureSettingsChanged(this, new EventArgs());\r
         }\r
-        private double calculateDarByVal(decimal croppedHeight, double displayWidth)\r
-        {\r
-            // DAR = DISPLAY WIDTH / DISPLAY HEIGHT (cache after every modification)\r
-            double calculatedDar = darValue;\r
-            if (croppedHeight > 0)\r
-                calculatedDar = displayWidth / (double)croppedHeight;\r
 \r
-            return calculatedDar;\r
-        }\r
-        private int displayWidth()\r
+        // Cropping Controls\r
+        private void check_autoCrop_CheckedChanged(object sender, EventArgs e)\r
         {\r
-            if (selectedTitle != null)\r
-            {\r
-                int actualWidth = (int)text_width.Value;\r
-                int displayWidth = 0;\r
-                int parW, parH;\r
-\r
-                int.TryParse(txt_parWidth.Text, out parW);\r
-                int.TryParse(txt_parHeight.Text, out parH);\r
-\r
-                if (drp_anamorphic.SelectedIndex != 3)\r
-                    displayWidth = (actualWidth * selectedTitle.ParVal.Width / selectedTitle.ParVal.Height);\r
-                else if (parW > 0 && parH > 0)\r
-                    displayWidth = (actualWidth * parW / parH);\r
-\r
-                return displayWidth;\r
-            }\r
-            return -1;\r
+            crop_top.Enabled = check_customCrop.Checked;\r
+            crop_bottom.Enabled = check_customCrop.Checked;\r
+            crop_left.Enabled = check_customCrop.Checked;\r
+            crop_right.Enabled = check_customCrop.Checked;\r
         }\r
-\r
-        // Resolution calculation and controls\r
-        private decimal widthChangeMod(int mod)\r
+        private void crop_ValueChanged(object sender, EventArgs e)\r
         {\r
-            // Increase or decrease the height based on the users input.\r
-            decimal returnVal = text_width.Value > widthVal ? getResolutionJump(mod, text_width.Value, true) : getResolutionJump(mod, text_width.Value, false);\r
-\r
-            // Make sure we don't go above source value\r
-            if (selectedTitle != null)\r
-                if (selectedTitle.Resolution.Width < returnVal)\r
-                    returnVal = selectedTitle.Resolution.Width;\r
-\r
-            // Set the global tracker\r
-            widthVal = (int)returnVal;\r
-\r
-            return returnVal;\r
+            text_width_ValueChanged(this, new EventArgs());\r
         }\r
-        private decimal heightChangeMod(int mod)\r
-        {\r
-            // Increase or decrease the height based on the users input.\r
-            decimal returnVal = text_height.Value > heightVal ? getResolutionJump(mod, text_height.Value, true) : getResolutionJump(mod, text_height.Value, false);\r
 \r
-            // Make sure we don't go above source value\r
-            if (selectedTitle != null)\r
-                if (selectedTitle.Resolution.Height < returnVal)\r
-                    returnVal = selectedTitle.Resolution.Height;\r
-\r
-            // Set the global tracker\r
-            heightVal = (int)returnVal;     // TODO THIS IS CAUSING PROBLEM\r
-\r
-            return returnVal;\r
-        }\r
-        private decimal calculateUnchangeValue(Boolean widthChangeFromControl)\r
+        // GUI Functions\r
+        private void setCustomAnamorphicOptionsVisible(bool visible)\r
         {\r
-            decimal newValue = -1;\r
-            if (selectedTitle != null && drp_anamorphic.SelectedIndex != 3 && drp_anamorphic.SelectedIndex != 2)\r
-                if (widthChangeFromControl)\r
-                    newValue = cacluateHeight(widthVal);\r
-                else\r
-                {\r
-                    if (check_KeepAR.Checked)\r
-                        newValue = cacluateWidth(heightVal);\r
-                }\r
+            lbl_modulus.Visible = visible;\r
+            lbl_displayWidth.Visible = visible;\r
+            lbl_parWidth.Visible = visible;\r
+            lbl_parHeight.Visible = visible;\r
 \r
-            return newValue;\r
-        }\r
-        private int getResolutionJump(int mod, decimal value, Boolean up)\r
-        {\r
-            if (up)\r
-                while ((value % mod) != 0)\r
-                    value++;\r
-            else\r
-                while ((value % mod) != 0)\r
-                    value--;\r
-\r
-            return (int)value;\r
+            drp_modulus.Visible = visible;\r
+            updownDisplayWidth.Visible = visible;\r
+            updownParWidth.Visible = visible;\r
+            updownParHeight.Visible = visible;\r
         }\r
-        private double getModulusAuto(int mod, double value)\r
-        {\r
-            int modDiv2 = mod / 2;\r
 \r
-            if ((value % mod) != 0)\r
+        // Calculation Functions\r
+        private Size sourceAspect\r
+        {\r
+            get\r
             {\r
-                double modVal = (int)value % mod;\r
-                if (modVal >= modDiv2)\r
+                if (Source != null)\r
                 {\r
-                    modVal = 16 - modVal;\r
-                    value = (int)value + (int)modVal;\r
-                }\r
-                else\r
-                {\r
-                    value = (int)value - (int)modVal;\r
+                    if (Source.AspectRatio == 1.78F)\r
+                        return new Size(16, 9);\r
+                    if (Source.AspectRatio == 1.33F)\r
+                        return new Size(4, 3);\r
                 }\r
+                return new Size(0, 0);\r
             }\r
-            return value;\r
         }\r
-        private int cacluateHeight(int width)\r
+        private Size calculateAnamorphicSizes()\r
         {\r
-            if (selectedTitle != null)\r
+            if (Source != null)\r
             {\r
-                int aw = 0;\r
-                int ah = 0;\r
-                if (selectedTitle.AspectRatio.ToString() == "1.78")\r
-                {\r
-                    aw = 16;\r
-                    ah = 9;\r
-                }\r
-                else if (selectedTitle.AspectRatio.ToString() == "1.33")\r
+                /* Set up some variables to make the math easier to follow. */\r
+                int cropped_width = Source.Resolution.Width - (int)crop_left.Value - (int)crop_right.Value;\r
+                int cropped_height = Source.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
+                double storage_aspect = (double)cropped_width / cropped_height;\r
+\r
+                /* Figure out what width the source would display at. */\r
+                double source_display_width = (double)cropped_width * Source.ParVal.Width / Source.ParVal.Height;\r
+\r
+                /*\r
+                     3 different ways of deciding output dimensions:\r
+                      - 1: Strict anamorphic, preserve source dimensions\r
+                      - 2: Loose anamorphic, round to mod16 and preserve storage aspect ratio\r
+                      - 3: Power user anamorphic, specify everything\r
+                  */\r
+                double width, height;\r
+                switch (drp_anamorphic.SelectedIndex)\r
                 {\r
-                    aw = 4;\r
-                    ah = 3;\r
+                    case 1:\r
+                        /* Strict anamorphic */\r
+                        double displayWidth = ((double)cropped_width * Source.ParVal.Width / Source.ParVal.Height);\r
+                        displayWidth = Math.Round(displayWidth, 0);\r
+                        Size output = new Size((int)displayWidth, cropped_height);\r
+                        return output;\r
+                    case 2:\r
+                        /* "Loose" anamorphic.\r
+                            - Uses mod16-compliant dimensions,\r
+                            - Allows users to set the width\r
+                        */\r
+                        width = (int)text_width.Value - (int)crop_left.Value - (int)crop_right.Value;\r
+                        width = GetModulusValue(width); /* Time to get picture width that divide cleanly.*/\r
+\r
+                        height = (width / storage_aspect) + 0.5;\r
+                        height = GetModulusValue(height); /* Time to get picture height that divide cleanly.*/\r
+\r
+                        /* The film AR is the source's display width / cropped source height.\r
+                           The output display width is the output height * film AR.\r
+                           The output PAR is the output display width / output storage width. */\r
+                        double pixel_aspect_width = height * source_display_width / cropped_height;\r
+                        double pixel_aspect_height = width;\r
+\r
+                        double disWidthLoose = (width * pixel_aspect_width / pixel_aspect_height);\r
+                        return new Size((int)disWidthLoose, (int)height);\r
+                    case 3:\r
+\r
+                        // Get the User Interface Values\r
+                        double UIdisplayWidth;\r
+                        double.TryParse(updownDisplayWidth.Text, out UIdisplayWidth);\r
+\r
+                        /* Anamorphic 3: Power User Jamboree - Set everything based on specified values */\r
+                        height = GetModulusValue((double)text_height.Value);\r
+\r
+                        if (check_KeepAR.Checked)\r
+                            return new Size((int)Math.Truncate(UIdisplayWidth), (int)height);\r
+\r
+                        return new Size((int)Math.Truncate(UIdisplayWidth), (int)height);\r
                 }\r
-\r
-                if (aw != 0)\r
-                {\r
-                    // Crop_Width = Title->Width - crop_Left - crop_right\r
-                    // Crop_Height = Title->Height - crop_top - crop_bottom\r
-                    double crop_width = selectedTitle.Resolution.Width - (double) crop_left.Value -\r
-                                        (double) crop_right.Value;\r
-                    double crop_height = selectedTitle.Resolution.Height - (double) crop_top.Value -\r
-                                         (double) crop_bottom.Value;\r
-\r
-                    double new_height = (width*selectedTitle.Resolution.Width*ah*crop_height)/\r
-                                        (selectedTitle.Resolution.Height*aw*crop_width);\r
-\r
-                    if (drp_anamorphic.SelectedIndex == 3)\r
-                        new_height = getModulusAuto(int.Parse(drop_modulus.SelectedItem.ToString()), new_height);\r
-                    else\r
-                        new_height = getModulusAuto(16, new_height);\r
-\r
-                    //16 * (421 / 16)\r
-                    //double z = ( 16 * (( y + 8 ) / 16 ) );\r
-                    int x = int.Parse(new_height.ToString());\r
-                    if (x < 64)\r
-                        x = 64;\r
-                    return x;\r
-                }\r
-            }\r
-            return 0;\r
-        }\r
-        private int cacluateWidth(int height)\r
-        {\r
-            int aw = 0;\r
-            int ah = 0;\r
-            if (selectedTitle.AspectRatio.ToString() == "1.78")\r
-            {\r
-                aw = 16;\r
-                ah = 9;\r
-            }\r
-            else if (selectedTitle.AspectRatio.ToString() == "1.33")\r
-            {\r
-                aw = 4;\r
-                ah = 3;\r
             }\r
 \r
-            if (aw != 0)\r
-            {\r
-\r
-                double crop_width = selectedTitle.Resolution.Width - (double)crop_left.Value - (double)crop_right.Value;\r
-                double crop_height = selectedTitle.Resolution.Height - (double)crop_top.Value - (double)crop_bottom.Value;\r
-\r
-                double new_width = (height * selectedTitle.Resolution.Height * aw * crop_width) /\r
-                                    (selectedTitle.Resolution.Width * ah * crop_height);\r
-\r
-                if (drp_anamorphic.SelectedIndex == 3)\r
-                    new_width = getModulusAuto(int.Parse(drop_modulus.SelectedItem.ToString()), new_width);\r
-                else\r
-                    new_width = getModulusAuto(16, new_width);\r
-\r
-                //16 * (421 / 16)\r
-                //double z = ( 16 * (( y + 8 ) / 16 ) );\r
-                int x = int.Parse(new_width.ToString());\r
-                return x;\r
-            }\r
-            return 0;\r
-        }\r
-\r
-        // Calculate Resolution for Anamorphic functions\r
-        private string strictAnamorphic()\r
-        {\r
-            // TODO Make sure cropping is Mod2\r
-            if (selectedTitle != null)\r
-            {\r
-                // Calculate the Actual Height\r
-                int actualWidth = (int)text_width.Value - (int)crop_left.Value - (int)crop_right.Value; ;\r
-                int actualHeight = selectedTitle.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
-\r
-                // Calculate Actual Width\r
-                double displayWidth = ((double)actualWidth * selectedTitle.ParVal.Width / selectedTitle.ParVal.Height);\r
-                return Math.Round(displayWidth, 0) + "x" + actualHeight;\r
-            }\r
-            return "Select a Title";\r
+            // Return a default value of 0,0 to indicate failure\r
+            return new Size(0, 0);\r
         }\r
-        private string looseAnamorphic()\r
+        private double GetModulusValue(double value)\r
         {\r
-            if (selectedTitle != null)\r
-            {\r
-                // Get some values\r
-                int actualWidth = (int)text_width.Value - (int)crop_left.Value - (int)crop_right.Value;\r
-\r
-                int source_display_width = selectedTitle.Resolution.Width * selectedTitle.ParVal.Width / selectedTitle.ParVal.Height;\r
-                int source_cropped_height = selectedTitle.Resolution.Height - (int)crop_top.Value - (int)crop_bottom.Value;\r
-\r
-                // Calculate storage Aspect and cache it for reuse\r
-                if (storageAspect == 0)\r
-                    storageAspect = (double)actualWidth / source_cropped_height;               \r
-\r
-                // Calculate the new height based on the input cropped width\r
-                double hcalc = (actualWidth / storageAspect) + 0.5;\r
-                double newHeight = getModulusAuto(16, hcalc);\r
-                looseAnamorphicHeightGuard = true;\r
+            int mod = int.Parse(drp_modulus.SelectedItem.ToString());\r
+            double remainder = value % mod;\r
 \r
-                if (newHeight < 64)\r
-                    newHeight = 64;\r
-                text_height.Value = (decimal)newHeight;   // BUG Out of Range Exception with Width too low here.\r
-\r
-                // Calculate the anamorphic width\r
-                double parW = newHeight * source_display_width / source_cropped_height;\r
-                double parH = actualWidth;\r
-                double displayWidth = (actualWidth * parW / parH);\r
-\r
-                // Now correct DisplayWidth to maintain Aspect ratio.  ActualHeight was mod16'd and thus AR is slightly different than the worked out displayWidths\r
-                return Math.Truncate(displayWidth) + "x" + newHeight;  \r
-            }\r
-            return "Select a Title";\r
+            if (remainder == 0)\r
+                return value;\r
 \r
+            return remainder >= ((double)mod / 2) ? value + (mod - remainder) : value - remainder;\r
         }\r
-        \r
-        // GUI\r
-        private void disableCustomAnaControls()\r
+        private static int GetCropMod2Clean(int value)\r
         {\r
-            // Disable Custom Anamorphic Stuff\r
-            lbl_modulus.Visible = false;\r
-            lbl_displayWidth.Visible = false;\r
-            lbl_parWidth.Visible = false;\r
-            lbl_parHeight.Visible = false;\r
-            drop_modulus.Visible = false;\r
-            txt_displayWidth.Visible = false;\r
-            txt_parWidth.Visible = false;\r
-            txt_parHeight.Visible = false;\r
-            check_KeepAR.Enabled = false;\r
+            int remainder = value % 2;\r
+            if (remainder == 0) return value;\r
+            return (value + remainder);\r
         }\r
-        private void enableCustomAnaControls()\r
-        {\r
-            // Disable Custom Anamorphic Stuff\r
-            lbl_modulus.Visible = true;\r
-            lbl_displayWidth.Visible = true;\r
-            lbl_parWidth.Visible = true;\r
-            lbl_parHeight.Visible = true;\r
-            drop_modulus.Visible = true;\r
-            txt_displayWidth.Visible = true;\r
-            txt_parWidth.Visible = true;\r
-            txt_parHeight.Visible = true;\r
-            check_KeepAR.Enabled = true;\r
-        }\r
-\r
     }\r
 }
\ No newline at end of file