diff options
author | sr55 <[email protected]> | 2012-02-11 23:13:12 +0000 |
---|---|---|
committer | sr55 <[email protected]> | 2012-02-11 23:13:12 +0000 |
commit | c3077f8c91764b1e5258b802a17d086c6afc02af (patch) | |
tree | abce8ba7664b3688863c3418b2625782d2cad15c | |
parent | 1d504d557ecc008e3f7924df4181f07b793448fc (diff) |
WinGui: (WPF) Initial wire-up work on the Picture settings panel and setup the auto-nameing feature for the destination path.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4445 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | win/CS/HandBrake.ApplicationServices/Parsing/Title.cs | 2 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/HandBrakeWPF.csproj | 1 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs | 25 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs | 26 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs | 462 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml | 73 |
6 files changed, 523 insertions, 66 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs b/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs index 6b3d517c9..4c800f24c 100644 --- a/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs +++ b/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs @@ -188,7 +188,7 @@ namespace HandBrake.ApplicationServices.Parsing {
thisTitle.Resolution = new Size(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));
thisTitle.ParVal = new Size(int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value));
- thisTitle.AspectRatio = float.Parse(m.Groups[5].Value, CultureInfo.InvariantCulture);
+ thisTitle.AspectRatio = Math.Round(float.Parse(m.Groups[5].Value, CultureInfo.InvariantCulture), 2);
thisTitle.Fps = float.Parse(m.Groups[6].Value, CultureInfo.InvariantCulture);
}
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj index 06abbad46..3e940794f 100644 --- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj +++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj @@ -63,6 +63,7 @@ <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
<Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\libraries\caliburn\System.Windows.Interactivity.dll</HintPath>
</Reference>
diff --git a/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs b/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs index f0b942120..589c698e2 100644 --- a/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs +++ b/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs @@ -13,6 +13,8 @@ namespace HandBrakeWPF.Helpers using System.IO;
using System.Linq;
+ using Caliburn.Micro;
+
using HandBrake.ApplicationServices.Extensions;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Model.Encoding;
@@ -24,22 +26,6 @@ namespace HandBrakeWPF.Helpers public class AutoNameHelper
{
/// <summary>
- /// Backing field for the user setting service
- /// </summary>
- private static IUserSettingService userSettingService;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="AutoNameHelper"/> class.
- /// </summary>
- /// <param name="userSetting">
- /// The user Setting.
- /// </param>
- public AutoNameHelper(IUserSettingService userSetting)
- {
- userSettingService = userSetting;
- }
-
- /// <summary>
/// Function which generates the filename and path automatically based on
/// the Source Name, DVD title and DVD Chapters
/// </summary>
@@ -54,6 +40,13 @@ namespace HandBrakeWPF.Helpers /// </returns>
public static string AutoName(EncodeTask task, string sourceOrLabelName)
{
+
+ IUserSettingService userSettingService = IoC.Get<IUserSettingService>();
+ if (task.Destination == null)
+ {
+ task.Destination = string.Empty;
+ }
+
string autoNamePath = string.Empty;
if (task.Title != 0) // TODO check.
{
diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs index 9bb31ee5a..51e032e9a 100644 --- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs @@ -27,6 +27,7 @@ namespace HandBrakeWPF.ViewModels using HandBrake.ApplicationServices.Services.Interfaces;
using HandBrake.ApplicationServices.Utilities;
+ using HandBrakeWPF.Helpers;
using HandBrakeWPF.ViewModels.Interfaces;
using Ookii.Dialogs.Wpf;
@@ -329,7 +330,7 @@ namespace HandBrakeWPF.ViewModels {
get
{
- // TODO
+ // TODO Disc Label
//if (this.selectedSourceType == SourceType.DvdDrive)
//{
// return this.dvdDriveLabel;
@@ -510,6 +511,12 @@ namespace HandBrakeWPF.ViewModels this.SelectedEndPoint = selectedTitle.Chapters.Last().ChapterNumber;
this.SelectedPointToPoint = PointToPointMode.Chapters;
this.SelectedAngle = 1;
+
+ this.CurrentTask.Destination = AutoNameHelper.AutoName(this.CurrentTask, this.SourceName);
+ this.NotifyOfPropertyChange("CurrentTask");
+
+ // Setup the tab controls
+ this.SetupTabs();
}
}
}
@@ -1023,13 +1030,16 @@ namespace HandBrakeWPF.ViewModels private void SetupTabs()
{
// Setup the Tabs
- this.PictureSettingsViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
- this.VideoViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
- this.FiltersViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
- this.AudioViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
- this.SubtitleViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
- this.ChaptersViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
- this.AdvancedViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
+ if (this.selectedTitle != null)
+ {
+ this.PictureSettingsViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
+ this.VideoViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
+ this.FiltersViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
+ this.AudioViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
+ this.SubtitleViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
+ this.ChaptersViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
+ this.AdvancedViewModel.SetSource(this.SelectedTitle, this.SelectedPreset, this.CurrentTask);
+ }
}
#endregion
diff --git a/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs index 4a1a76cd6..6f741dea1 100644 --- a/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs @@ -9,8 +9,10 @@ namespace HandBrakeWPF.ViewModels
{
+ using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
+ using System.Drawing;
using Caliburn.Micro;
@@ -27,7 +29,14 @@ namespace HandBrakeWPF.ViewModels [Export(typeof(IPictureSettingsViewModel))]
public class PictureSettingsViewModel : ViewModelBase, IPictureSettingsViewModel
{
- #region Constants and Fields
+ /*
+ * TODO:
+ * Handle Presets when a new title is set
+ * Handle changes in cropping affecting the resolution calcuation.
+ *
+ */
+
+ #region Backing Fields
/// <summary>
/// The crop bottom.
@@ -104,6 +113,39 @@ namespace HandBrakeWPF.ViewModels /// </summary>
private int width;
+ /// <summary>
+ /// Backing field for show custom anamorphic controls
+ /// </summary>
+ private bool showCustomAnamorphicControls;
+
+ /// <summary>
+ /// Backing field for for height control enabled
+ /// </summary>
+ private bool heightControlEnabled = true;
+
+ /// <summary>
+ /// Backing field for width control enabled.
+ /// </summary>
+ private bool widthControlEnabled = true;
+
+ #endregion
+
+ #region Source Information
+
+ /// <summary>
+ /// Source Resolution
+ /// </summary>
+ private Size sourceResolution;
+
+ /// <summary>
+ /// Source Aspect Ratio
+ /// </summary>
+ private double sourceAspectRatio;
+
+ /// <summary>
+ /// Source Par Values
+ /// </summary>
+ private Size sourceParValues;
#endregion
#region Constructors and Destructors
@@ -120,6 +162,7 @@ namespace HandBrakeWPF.ViewModels public PictureSettingsViewModel(IWindowManager windowManager, IUserSettingService userSettingService)
{
this.SelectedModulus = 16;
+ this.MaintainAspectRatio = true;
}
#endregion
@@ -148,7 +191,7 @@ namespace HandBrakeWPF.ViewModels }
set
{
- this.cropBottom = value;
+ this.cropBottom = this.CorrectForModulus(this.cropBottom, value);
this.NotifyOfPropertyChange(() => this.CropBottom);
}
}
@@ -164,7 +207,7 @@ namespace HandBrakeWPF.ViewModels }
set
{
- this.cropLeft = value;
+ this.cropLeft = this.CorrectForModulus(this.cropLeft, value);
this.NotifyOfPropertyChange(() => this.CropLeft);
}
}
@@ -180,7 +223,7 @@ namespace HandBrakeWPF.ViewModels }
set
{
- this.cropRight = value;
+ this.cropRight = this.CorrectForModulus(this.cropRight, value);
this.NotifyOfPropertyChange(() => this.CropRight);
}
}
@@ -196,7 +239,7 @@ namespace HandBrakeWPF.ViewModels }
set
{
- this.cropTop = value;
+ this.cropTop = this.CorrectForModulus(this.cropTop, value);
this.NotifyOfPropertyChange(() => this.CropTop);
}
}
@@ -229,27 +272,12 @@ namespace HandBrakeWPF.ViewModels set
{
this.displayWidth = value;
+ this.CustomAnamorphicAdjust();
this.NotifyOfPropertyChange(() => this.DisplayWidth);
}
}
/// <summary>
- /// Gets or sets Height.
- /// </summary>
- public int Height
- {
- get
- {
- return this.height;
- }
- set
- {
- this.height = value;
- this.NotifyOfPropertyChange(() => this.Height);
- }
- }
-
- /// <summary>
/// Gets or sets a value indicating whether IsCustomCrop.
/// </summary>
public bool IsCustomCrop
@@ -277,6 +305,7 @@ namespace HandBrakeWPF.ViewModels set
{
this.maintainAspectRatio = value;
+ this.WidthAdjust();
this.NotifyOfPropertyChange(() => this.MaintainAspectRatio);
}
}
@@ -304,6 +333,7 @@ namespace HandBrakeWPF.ViewModels set
{
this.parHeight = value;
+ this.CustomAnamorphicAdjust();
this.NotifyOfPropertyChange(() => this.ParHeight);
}
}
@@ -320,6 +350,7 @@ namespace HandBrakeWPF.ViewModels set
{
this.parWidth = value;
+ this.CustomAnamorphicAdjust();
this.NotifyOfPropertyChange(() => this.ParWidth);
}
}
@@ -336,6 +367,7 @@ namespace HandBrakeWPF.ViewModels set
{
this.selectedAnamorphicMode = value;
+ this.AnamorphicAdjust();
this.NotifyOfPropertyChange(() => this.SelectedAnamorphicMode);
}
}
@@ -352,6 +384,7 @@ namespace HandBrakeWPF.ViewModels set
{
this.selectedModulus = value;
+ this.ModulusAdjust();
this.NotifyOfPropertyChange(() => this.SelectedModulus);
}
}
@@ -384,10 +417,76 @@ namespace HandBrakeWPF.ViewModels set
{
this.width = value;
+ this.WidthAdjust();
this.NotifyOfPropertyChange(() => this.Width);
}
}
+ /// <summary>
+ /// Gets or sets Height.
+ /// </summary>
+ public int Height
+ {
+ get
+ {
+ return this.height;
+ }
+ set
+ {
+ this.height = value;
+ this.HeightAdjust();
+ this.NotifyOfPropertyChange(() => this.Height);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether ShowCustomAnamorphicControls.
+ /// </summary>
+ public bool ShowCustomAnamorphicControls
+ {
+ get
+ {
+ return this.showCustomAnamorphicControls;
+ }
+ set
+ {
+ this.showCustomAnamorphicControls = value;
+ this.NotifyOfPropertyChange(() => ShowCustomAnamorphicControls);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether HeightControlEnabled.
+ /// </summary>
+ public bool HeightControlEnabled
+ {
+ get
+ {
+ return this.heightControlEnabled;
+ }
+ set
+ {
+ this.heightControlEnabled = value;
+ this.NotifyOfPropertyChange(() => HeightControlEnabled);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether WidthControlEnabled.
+ /// </summary>
+ public bool WidthControlEnabled
+ {
+ get
+ {
+ return this.widthControlEnabled;
+ }
+ set
+ {
+ this.widthControlEnabled = value;
+ this.NotifyOfPropertyChange(() => WidthControlEnabled);
+ }
+ }
+
#endregion
#region Public Methods
@@ -406,7 +505,328 @@ namespace HandBrakeWPF.ViewModels /// </param>
public void SetSource(Title title, Preset preset, EncodeTask task)
{
+ if (title != null)
+ {
+ // Set cached info
+ this.sourceAspectRatio = title.AspectRatio;
+ this.sourceParValues = title.ParVal;
+ this.sourceResolution = title.Resolution;
+
+ // Set Screen Controls
+ this.SourceInfo = string.Format("{0}x{1}, Aspect Ratio: {2:0.00}", title.Resolution.Width, title.Resolution.Height, title.AspectRatio);
+ this.CropTop = title.AutoCropDimensions.Top;
+ this.CropBottom = title.AutoCropDimensions.Bottom;
+ this.CropLeft = title.AutoCropDimensions.Left;
+ this.CropRight = title.AutoCropDimensions.Right;
+
+ // TODO handle preset max width / height
+ this.Width = title.Resolution.Width;
+ this.Height = title.Resolution.Height;
+ this.MaintainAspectRatio = true;
+ }
}
#endregion
+
+ /// <summary>
+ /// Adjust other values after the user has altered the width
+ /// </summary>
+ private void WidthAdjust()
+ {
+ if (this.width > this.sourceResolution.Width)
+ {
+ this.width = this.sourceResolution.Width;
+ }
+
+ switch (SelectedAnamorphicMode)
+ {
+ case Anamorphic.None:
+ if (this.MaintainAspectRatio)
+ {
+ double crop_width = this.sourceResolution.Width - this.CropLeft - this.CropRight;
+ double crop_height = this.sourceResolution.Height - this.CropTop - this.CropBottom;
+
+ if (SourceAspect.Width == 0 && SourceAspect.Height == 0)
+ break;
+
+ double newHeight = ((double)this.Width * this.sourceResolution.Width * SourceAspect.Height * crop_height) /
+ (this.sourceResolution.Height * SourceAspect.Width * crop_width);
+
+ this.height = (int)Math.Round(GetModulusValue(newHeight), 0);
+ this.NotifyOfPropertyChange("Height");
+ }
+ break;
+ case Anamorphic.Strict:
+ this.width = 0;
+ this.height = 0;
+
+ this.NotifyOfPropertyChange("Width");
+ this.NotifyOfPropertyChange("Height");
+ this.SetDisplaySize();
+ break;
+ case Anamorphic.Loose:
+ this.height = 0;
+ this.NotifyOfPropertyChange("Width");
+ this.NotifyOfPropertyChange("Height");
+ this.SetDisplaySize();
+ break;
+ case Anamorphic.Custom:
+ this.SetDisplaySize();
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Adjust other values after the user has altered the height
+ /// </summary>
+ private void HeightAdjust()
+ {
+ if (this.height > this.sourceResolution.Height)
+ {
+ this.height = this.sourceResolution.Height;
+ }
+
+ switch (SelectedAnamorphicMode)
+ {
+ case Anamorphic.None:
+ if (this.MaintainAspectRatio)
+ {
+ double crop_width = this.sourceResolution.Width - this.CropLeft - this.CropRight;
+ double crop_height = this.sourceResolution.Height - this.CropTop - this.CropBottom;
+
+ double new_width = ((double)this.Height * this.sourceResolution.Height * SourceAspect.Width * crop_width) /
+ (this.sourceResolution.Width * SourceAspect.Height * crop_height);
+
+ this.Width = (int)Math.Round(GetModulusValue(new_width), 0);
+ this.NotifyOfPropertyChange("Width");
+ }
+ break;
+ case Anamorphic.Custom:
+ this.SetDisplaySize();
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Adjust other values after the user has altered one of the custom anamorphic settings
+ /// </summary>
+ private void CustomAnamorphicAdjust()
+ {
+ this.SetDisplaySize();
+ }
+
+ /// <summary>
+ /// Adjust other values after the user has altered the modulus
+ /// </summary>
+ private void ModulusAdjust()
+ {
+ this.WidthAdjust();
+ }
+
+ /// <summary>
+ /// Adjust other values after the user has altered the anamorphic.
+ /// </summary>
+ private void AnamorphicAdjust()
+ {
+ this.DisplaySize = this.sourceResolution.IsEmpty
+ ? "No Title Selected"
+ : string.Format("{0}x{1}",
+ this.CalculateAnamorphicSizes().Width,
+ this.CalculateAnamorphicSizes().Height);
+
+ switch (SelectedAnamorphicMode)
+ {
+ case Anamorphic.None:
+ this.WidthControlEnabled = true;
+ this.HeightControlEnabled = true;
+ this.ShowCustomAnamorphicControls = false;
+ this.Width = sourceResolution.Width;
+ this.SetDisplaySize();
+ break;
+ case Anamorphic.Strict:
+ this.WidthControlEnabled = false;
+ this.HeightControlEnabled = false;
+ this.ShowCustomAnamorphicControls = false;
+
+ this.width = 0;
+ this.height = 0;
+ this.NotifyOfPropertyChange(() => Width);
+ this.NotifyOfPropertyChange(() => Height);
+ this.SetDisplaySize();
+ break;
+
+ case Anamorphic.Loose:
+ this.WidthControlEnabled = true;
+ this.HeightControlEnabled = false;
+ this.ShowCustomAnamorphicControls = false;
+
+ this.width = this.sourceResolution.Width;
+ this.height = 0;
+ this.NotifyOfPropertyChange(() => Width);
+ this.NotifyOfPropertyChange(() => Height);
+ this.SetDisplaySize();
+ break;
+
+ case Anamorphic.Custom:
+ this.WidthControlEnabled = true;
+ this.HeightControlEnabled = true;
+ this.ShowCustomAnamorphicControls = true;
+
+ this.width = this.sourceResolution.Width;
+ this.height = 0;
+ this.NotifyOfPropertyChange(() => Width);
+ this.NotifyOfPropertyChange(() => Height);
+
+ this.displayWidth = this.CalculateAnamorphicSizes().Width;
+ this.parWidth = this.sourceParValues.Width;
+ this.parHeight = this.sourceParValues.Height;
+ this.NotifyOfPropertyChange(() => ParHeight);
+ this.NotifyOfPropertyChange(() => ParWidth);
+ this.NotifyOfPropertyChange(() => DisplayWidth);
+
+ this.SetDisplaySize();
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Gets SourceAspect.
+ /// </summary>
+ private Size SourceAspect
+ {
+ get
+ {
+ // display aspect = (width * par_width) / (height * par_height)
+ return new Size((this.sourceParValues.Width * this.sourceResolution.Width),
+ (this.sourceParValues.Height * this.sourceResolution.Height));
+ }
+ }
+
+ /// <summary>
+ /// Set the display size text
+ /// </summary>
+ private void SetDisplaySize()
+ {
+ this.DisplaySize = this.sourceResolution.IsEmpty
+ ? "No Title Selected"
+ : string.Format("{0}x{1}",
+ this.CalculateAnamorphicSizes().Width,
+ this.CalculateAnamorphicSizes().Height);
+ }
+
+ /// <summary>
+ /// Calculate the Anamorphic Resolution for the selected title.
+ /// </summary>
+ /// <returns>
+ /// A Size With Width/Height for this title.
+ /// </returns>
+ private Size CalculateAnamorphicSizes()
+ {
+ if (this.sourceResolution.IsEmpty)
+ {
+ return new Size(0, 0);
+ }
+
+ /* Set up some variables to make the math easier to follow. */
+ int croppedWidth = this.sourceResolution.Width - this.CropLeft - this.CropRight;
+ int croppedHeight = this.sourceResolution.Height - this.CropTop - this.CropBottom;
+ double storageAspect = (double)croppedWidth / croppedHeight;
+
+ /* Figure out what width the source would display at. */
+ double sourceDisplayWidth = (double)croppedWidth * this.sourceParValues.Width / this.sourceParValues.Height;
+
+ /*
+ 3 different ways of deciding output dimensions:
+ - 1: Strict anamorphic, preserve source dimensions
+ - 2: Loose anamorphic, round to mod16 and preserve storage aspect ratio
+ - 3: Power user anamorphic, specify everything
+ */
+ double calcWidth, calcHeight;
+ switch (this.SelectedAnamorphicMode)
+ {
+ default:
+ case Anamorphic.Strict:
+ /* Strict anamorphic */
+ double dispWidth = ((double)croppedWidth * this.sourceParValues.Width / this.sourceParValues.Height);
+ dispWidth = Math.Round(dispWidth, 0);
+ Size output = new Size((int)dispWidth, croppedHeight);
+ return output;
+
+ case Anamorphic.Loose:
+ /* "Loose" anamorphic.
+ - Uses mod16-compliant dimensions,
+ - Allows users to set the width
+ */
+ calcWidth = GetModulusValue(this.Width); /* Time to get picture width that divide cleanly.*/
+ calcHeight = (calcWidth / storageAspect) + 0.5;
+ calcHeight = GetModulusValue(calcHeight); /* Time to get picture height that divide cleanly.*/
+
+ /* The film AR is the source's display width / cropped source height.
+ The output display width is the output height * film AR.
+ The output PAR is the output display width / output storage width. */
+ double pixelAspectWidth = calcHeight * sourceDisplayWidth / croppedHeight;
+ double pixelAspectHeight = calcWidth;
+
+ double disWidthLoose = (calcWidth * pixelAspectWidth / pixelAspectHeight);
+ if (double.IsNaN(disWidthLoose))
+ disWidthLoose = 0;
+
+ return new Size((int)disWidthLoose, (int)calcHeight);
+
+ case Anamorphic.Custom:
+ // Get the User Interface Values
+ double UIdisplayWidth;
+ double.TryParse(this.DisplayWidth.ToString(), out UIdisplayWidth);
+
+ /* Anamorphic 3: Power User Jamboree - Set everything based on specified values */
+ calcHeight = GetModulusValue(this.Height);
+
+ if (this.MaintainAspectRatio)
+ return new Size((int)Math.Truncate(UIdisplayWidth), (int)calcHeight);
+
+ return new Size((int)Math.Truncate(UIdisplayWidth), (int)calcHeight);
+ }
+ }
+
+ /// <summary>
+ /// For a given value, correct so that it matches the users currently selected modulus value
+ /// </summary>
+ /// <param name="value">
+ /// The value.
+ /// </param>
+ /// <returns>
+ /// Value corrected so that value % selected modulus == 0
+ /// </returns>
+ private double GetModulusValue(double value)
+ {
+ double remainder = value % this.SelectedModulus;
+
+ if (remainder == 0)
+ return value;
+
+ return remainder >= ((double)this.SelectedModulus / 2) ? value + (this.SelectedModulus - remainder) : value - remainder;
+ }
+
+ /// <summary>
+ /// Correct the new value so that the result of the modulus of that value is 0
+ /// </summary>
+ /// <param name="oldValue">
+ /// The old value.
+ /// </param>
+ /// <param name="newValue">
+ /// The new value.
+ /// </param>
+ /// <returns>
+ /// The Value corrected so that for a given modulus the result is 0
+ /// </returns>
+ private int CorrectForModulus(int oldValue, int newValue)
+ {
+ int remainder = newValue % 2;
+ if (remainder == 0)
+ {
+ return newValue;
+ }
+
+ return newValue > oldValue ? newValue + remainder : newValue - remainder;
+ }
}
}
\ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml b/win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml index 5ebe36b33..d9ed6cef2 100644 --- a/win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml +++ b/win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml @@ -6,6 +6,7 @@ <UserControl.Resources>
<Converters:BooleanConverter x:Key="boolConverter" />
+ <Converters:BooleanToVisibilityConverter x:Key="boolToVisConverter" />
</UserControl.Resources>
<StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
@@ -16,16 +17,18 @@ <!-- Row 1-->
<StackPanel Orientation="Horizontal" Margin="5,0,5,0">
- <Label Content="Source" Grid.Row="0" Grid.Column="0" />
+ <Label Content="Source:" Grid.Row="0" Grid.Column="0" />
<Label Content="{Binding SourceInfo}" Name="sourceResolution" Grid.Row="0" Grid.Column="1" />
</StackPanel>
<!-- Row 2-->
<StackPanel Orientation="Horizontal" Margin="5,0,5,0">
<Label Content="Width:" Grid.Row="1" Grid.Column="0" />
- <NumericUpDown:NumericUpDown Value="{Binding Width}" Minimum="0" Grid.Row="1" Grid.Column="1" Width="45" />
+ <NumericUpDown:NumericUpDown Value="{Binding Width, Mode=TwoWay}" IsEnabled="{Binding WidthControlEnabled}" SmallChange="{Binding SelectedModulus, Mode=OneWay}"
+ Minimum="0" Grid.Row="1" Grid.Column="1" Width="60" />
<Label Content="Height:" Grid.Row="1" Grid.Column="2" />
- <NumericUpDown:NumericUpDown Value="{Binding Height}" Minimum="0" Grid.Row="1" Grid.Column="3" Width="45" />
+ <NumericUpDown:NumericUpDown Value="{Binding Height, Mode=TwoWay}" IsEnabled="{Binding HeightControlEnabled}" SmallChange="{Binding SelectedModulus, Mode=OneWay}"
+ Minimum="0" Grid.Row="1" Grid.Column="3" Width="60" />
<CheckBox Content="Keep Aspect Ratio" IsChecked="{Binding MaintainAspectRatio}" VerticalAlignment="Center" Margin="5,0,0,0" />
</StackPanel>
@@ -34,10 +37,6 @@ <Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
@@ -47,21 +46,51 @@ <Label Content="Anamorphic:" Grid.Row="0" Grid.Column="0" />
<Label Content="Modulus:" Grid.Row="1" Grid.Column="0" />
- <Label Content="Display Width:" Grid.Row="2" Grid.Column="0" />
- <Label Content="PAR Width:" Grid.Row="3" Grid.Column="0" />
- <Label Content="PAR Height:" Grid.Row="4" Grid.Column="0" />
- <Label Content="Display Size:" Grid.Row="5" Grid.Column="0" />
<ComboBox Width="110" Grid.Row="0" ItemsSource="{Binding AnamorphicModes}" SelectedItem="{Binding SelectedAnamorphicMode}" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
<ComboBox Width="110" Grid.Row="1" ItemsSource="{Binding ModulusValues}" SelectedItem="{Binding SelectedModulus}" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
- <NumericUpDown:NumericUpDown Width="45" Value="{Binding DisplayWidth}" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
- <NumericUpDown:NumericUpDown Width="45" Value="{Binding ParWidth}" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
- <NumericUpDown:NumericUpDown Width="45" Value="{Binding ParHeight}" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
- <Label Content="{Binding DisplaySize}" Grid.Row="5" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
</Grid>
- </StackPanel>
+
+ <!-- Row 4-->
+ <Grid Margin="5,15,5,0" Visibility="{Binding ShowCustomAnamorphicControls, Converter={StaticResource boolToVisConverter}}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <Label Content="Display Width:" Grid.Row="0" Grid.Column="0" />
+ <Label Content="PAR Width:" Grid.Row="1" Grid.Column="0" />
+ <Label Content="PAR Height:" Grid.Row="5" Grid.Column="0" />
+
+ <NumericUpDown:NumericUpDown Width="60" Value="{Binding DisplayWidth, Mode=TwoWay}" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
+ <NumericUpDown:NumericUpDown Width="60" Value="{Binding ParWidth, Mode=TwoWay}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
+ <NumericUpDown:NumericUpDown Width="60" Value="{Binding ParHeight, Mode=TwoWay}" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
+ </Grid>
+
+ <!-- Row 5-->
+ <Grid Margin="5,15,5,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+
+ <Label Content="Display Size:" Grid.Row="0" Grid.Column="0" />
+
+ <Label Content="{Binding DisplaySize}" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
+ </Grid>
+ </StackPanel>
+ <!-- Crop Panel -->
<StackPanel Name="CropPanel" Margin="50,0,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Label Content="Cropping" FontWeight="Bold" />
<RadioButton Content="Automatic" IsChecked="{Binding IsCustomCrop, Converter={StaticResource boolConverter}, ConverterParameter=true}" Margin="10,0,0,0"/>
@@ -89,10 +118,14 @@ <Label Content="Left" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Center" />
<Label Content="Right" Grid.Row="2" Grid.Column="4" HorizontalAlignment="Center" />
- <NumericUpDown:NumericUpDown Width="45" Value="{Binding CropTop}" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" Margin="0,0,0,5" />
- <NumericUpDown:NumericUpDown Width="45" Value="{Binding CropBottom}" Grid.Row="3" Grid.Column="2" HorizontalAlignment="Left" Margin="0,0,0,5" />
- <NumericUpDown:NumericUpDown Width="45" Value="{Binding CropLeft}" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5" />
- <NumericUpDown:NumericUpDown Width="45" Value="{Binding CropRight}" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Margin="0,0,0,5" />
+ <NumericUpDown:NumericUpDown Width="45" Value="{Binding CropTop, Mode=TwoWay}" IsEnabled="{Binding IsCustomCrop}" Grid.Row="1" Grid.Column="2"
+ HorizontalAlignment="Left" Margin="0,0,0,5" />
+ <NumericUpDown:NumericUpDown Width="45" Value="{Binding CropBottom, Mode=TwoWay}" IsEnabled="{Binding IsCustomCrop}" Grid.Row="3" Grid.Column="2"
+ HorizontalAlignment="Left" Margin="0,0,0,5" />
+ <NumericUpDown:NumericUpDown Width="45" Value="{Binding CropLeft, Mode=TwoWay}" IsEnabled="{Binding IsCustomCrop}" Grid.Row="2" Grid.Column="1"
+ HorizontalAlignment="Left" Margin="0,0,0,5" />
+ <NumericUpDown:NumericUpDown Width="45" Value="{Binding CropRight, Mode=TwoWay}" IsEnabled="{Binding IsCustomCrop}" Grid.Row="2" Grid.Column="3"
+ HorizontalAlignment="Left" Margin="0,0,0,5" />
</Grid>
|