summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr55 <[email protected]>2020-06-30 21:05:09 +0100
committersr55 <[email protected]>2020-06-30 21:05:09 +0100
commit4d5798c812a1caa4d3fdf0f6c505a9d612d33837 (patch)
tree04c20cdd2952efe725aa2ecbecf16e05e2fd2832
parent2e6809f9c3b7cda87269e4e6902138d42da95569 (diff)
WinGui: Presets UI overhaul.
- Remove the deprecated side panel. The in-line preset selector is now always shown in it's place. This frees up significant horizontal space for upcoming enhancements. - The toolbar "Presets" button now launches a new preset manager. Same design language as the Queue window allowing for better management of presets. -- Add option to delete all built-in presets. #2963 This is considered an experimental design for now. It may or may not change.
-rw-r--r--win/CS/HandBrakeWPF/Properties/Resources.Designer.cs74
-rw-r--r--win/CS/HandBrakeWPF/Properties/Resources.resx26
-rw-r--r--win/CS/HandBrakeWPF/Services/Presets/Interfaces/IPresetService.cs8
-rw-r--r--win/CS/HandBrakeWPF/Services/Presets/PresetService.cs7
-rw-r--r--win/CS/HandBrakeWPF/Services/UserSettingService.cs1
-rw-r--r--win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs3
-rw-r--r--win/CS/HandBrakeWPF/Startup/StartupOptions.cs1
-rw-r--r--win/CS/HandBrakeWPF/UserSettingConstants.cs1
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/Interfaces/IPresetManagerViewModel.cs16
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs43
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/PresetManagerViewModel.cs406
-rw-r--r--win/CS/HandBrakeWPF/Views/MainView.xaml195
-rw-r--r--win/CS/HandBrakeWPF/Views/MainView.xaml.cs54
-rw-r--r--win/CS/HandBrakeWPF/Views/PresetManagerView.xaml268
-rw-r--r--win/CS/HandBrakeWPF/Views/PresetManagerView.xaml.cs93
15 files changed, 917 insertions, 279 deletions
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
index 330db2cb3..32f288ff2 100644
--- a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
+++ b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
@@ -2560,7 +2560,34 @@ namespace HandBrakeWPF.Properties {
}
/// <summary>
- /// Looks up a localized string similar to Manage Preset.
+ /// Looks up a localized string similar to Delete Built-in Presets.
+ /// </summary>
+ public static string ManagePresetView_DeleteBuiltIn {
+ get {
+ return ResourceManager.GetString("ManagePresetView_DeleteBuiltIn", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Export selected preset.
+ /// </summary>
+ public static string ManagePresetView_Export {
+ get {
+ return ResourceManager.GetString("ManagePresetView_Export", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Import Preset(s) from file.
+ /// </summary>
+ public static string ManagePresetView_Import {
+ get {
+ return ResourceManager.GetString("ManagePresetView_Import", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Manage Presets.
/// </summary>
public static string ManagePresetView_ManagePreset {
get {
@@ -2569,6 +2596,33 @@ namespace HandBrakeWPF.Properties {
}
/// <summary>
+ /// Looks up a localized string similar to Preset Information:.
+ /// </summary>
+ public static string ManagePresetView_PresetInfo {
+ get {
+ return ResourceManager.GetString("ManagePresetView_PresetInfo", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Build in presets can not be modified..
+ /// </summary>
+ public static string ManagePresetView_RestrictedPreset {
+ get {
+ return ResourceManager.GetString("ManagePresetView_RestrictedPreset", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Set selected preset as default.
+ /// </summary>
+ public static string ManagePresetView_SetDefault {
+ get {
+ return ResourceManager.GetString("ManagePresetView_SetDefault", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to Actors:.
/// </summary>
public static string MetadataView_Actors {
@@ -4311,6 +4365,24 @@ namespace HandBrakeWPF.Properties {
}
/// <summary>
+ /// Looks up a localized string similar to Delete Preset.
+ /// </summary>
+ public static string PresetManagerView_Delete {
+ get {
+ return ResourceManager.GetString("PresetManagerView_Delete", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Manage Presets.
+ /// </summary>
+ public static string PresetManger_Title {
+ get {
+ return ResourceManager.GetString("PresetManger_Title", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to Custom.
/// </summary>
public static string PresetPictureSettingsMode_Custom {
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.resx b/win/CS/HandBrakeWPF/Properties/Resources.resx
index f514f7535..76159350c 100644
--- a/win/CS/HandBrakeWPF/Properties/Resources.resx
+++ b/win/CS/HandBrakeWPF/Properties/Resources.resx
@@ -1128,7 +1128,7 @@ Would you like to overwrite it?</value>
<value>Web Optimized</value>
</data>
<data name="ManagePresetView_ManagePreset" xml:space="preserve">
- <value>Manage Preset</value>
+ <value>Manage Presets</value>
</data>
<data name="MetaDataView_Title" xml:space="preserve">
<value>Metadata</value>
@@ -2313,4 +2313,28 @@ Please choose a different preset.</value>
<data name="PictureSettingsResLimitModes_none" xml:space="preserve">
<value>None</value>
</data>
+ <data name="PresetManger_Title" xml:space="preserve">
+ <value>Manage Presets</value>
+ </data>
+ <data name="ManagePresetView_DeleteBuiltIn" xml:space="preserve">
+ <value>Delete Built-in Presets</value>
+ </data>
+ <data name="ManagePresetView_Export" xml:space="preserve">
+ <value>Export selected preset</value>
+ </data>
+ <data name="ManagePresetView_Import" xml:space="preserve">
+ <value>Import Preset(s) from file</value>
+ </data>
+ <data name="ManagePresetView_PresetInfo" xml:space="preserve">
+ <value>Preset Information:</value>
+ </data>
+ <data name="ManagePresetView_RestrictedPreset" xml:space="preserve">
+ <value>Build in presets can not be modified.</value>
+ </data>
+ <data name="ManagePresetView_SetDefault" xml:space="preserve">
+ <value>Set selected preset as default</value>
+ </data>
+ <data name="PresetManagerView_Delete" xml:space="preserve">
+ <value>Delete Preset</value>
+ </data>
</root> \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Services/Presets/Interfaces/IPresetService.cs b/win/CS/HandBrakeWPF/Services/Presets/Interfaces/IPresetService.cs
index 8c41b728b..251028438 100644
--- a/win/CS/HandBrakeWPF/Services/Presets/Interfaces/IPresetService.cs
+++ b/win/CS/HandBrakeWPF/Services/Presets/Interfaces/IPresetService.cs
@@ -26,6 +26,8 @@ namespace HandBrakeWPF.Services.Presets.Interfaces
/// </summary>
ObservableCollection<IPresetObject> Presets { get; }
+ List<Preset> FlatPresetList { get; }
+
/// <summary>
/// Gets DefaultPreset.
/// </summary>
@@ -36,6 +38,12 @@ namespace HandBrakeWPF.Services.Presets.Interfaces
/// </summary>
void Load();
+
+ /// <summary>
+ /// Force save updates to the preset files. Rarely should need to be called. Only used by the preset manager.
+ /// </summary>
+ void Save();
+
/// <summary>
/// Save the state of the Preset Treview
/// </summary>
diff --git a/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs b/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs
index c34ca617f..4bb53eced 100644
--- a/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs
+++ b/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs
@@ -67,6 +67,8 @@ namespace HandBrakeWPF.Services.Presets
}
}
+ public List<Preset> FlatPresetList => this.flatPresetList.ToList();
+
public Preset DefaultPreset
{
get
@@ -491,6 +493,11 @@ namespace HandBrakeWPF.Services.Presets
return categoriesList;
}
+ public void Save()
+ {
+ this.SavePresetFiles();
+ }
+
private string ArchivePresetFile(string file, bool delete)
{
try
diff --git a/win/CS/HandBrakeWPF/Services/UserSettingService.cs b/win/CS/HandBrakeWPF/Services/UserSettingService.cs
index a28ed12cb..674073f6c 100644
--- a/win/CS/HandBrakeWPF/Services/UserSettingService.cs
+++ b/win/CS/HandBrakeWPF/Services/UserSettingService.cs
@@ -327,7 +327,6 @@ namespace HandBrakeWPF.Services
defaults.Add(UserSettingConstants.SimultaneousEncodes, 1);
// Misc
- defaults.Add(UserSettingConstants.ShowPresetPanel, false);
defaults.Add(UserSettingConstants.ScalingMode, 0);
defaults.Add(UserSettingConstants.ForcePresetReset, 3);
diff --git a/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs b/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs
index e2280ee80..794d9c9c3 100644
--- a/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs
+++ b/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs
@@ -98,7 +98,8 @@ namespace HandBrakeWPF.Startup
this.container.Singleton<IVideoViewModel, VideoViewModel>();
this.container.Singleton<IMetaDataViewModel, MetaDataViewModel>();
this.container.Singleton<ISummaryViewModel, SummaryViewModel>();
-
+ this.container.Singleton<IPresetManagerViewModel, PresetManagerViewModel>();
+
// Shell
this.container.Singleton<IShellViewModel, ShellViewModel>();
this.container.Singleton<INotifyIconService, NotifyIconService>();
diff --git a/win/CS/HandBrakeWPF/Startup/StartupOptions.cs b/win/CS/HandBrakeWPF/Startup/StartupOptions.cs
index 72a350c3d..c712c649b 100644
--- a/win/CS/HandBrakeWPF/Startup/StartupOptions.cs
+++ b/win/CS/HandBrakeWPF/Startup/StartupOptions.cs
@@ -20,6 +20,7 @@ namespace HandBrakeWPF.Startup
/// Gets or sets a value indicating whether auto restart queue.
/// </summary>
public static bool AutoRestartQueue { get; set; }
+
public static List<string> QueueRecoveryIds { get; set; }
}
}
diff --git a/win/CS/HandBrakeWPF/UserSettingConstants.cs b/win/CS/HandBrakeWPF/UserSettingConstants.cs
index 05f660eb6..5e21ae961 100644
--- a/win/CS/HandBrakeWPF/UserSettingConstants.cs
+++ b/win/CS/HandBrakeWPF/UserSettingConstants.cs
@@ -38,7 +38,6 @@ namespace HandBrakeWPF
public const string PauseOnLowDiskspace = "PauseOnLowDiskspace";
public const string PauseQueueOnLowDiskspaceLevel = "LowDiskSpaceWarningLevelInBytes";
public const string RemovePunctuation = "RemovePunctuation";
- public const string ShowPresetPanel = "ShowPresetPanelOption";
public const string ResetWhenDoneAction = "ResetWhenDoneAction";
public const string DisableLibDvdNav = "DisableLibDvdNav";
public const string EnableQuickSyncDecoding = "EnableQuickSyncDecoding";
diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IPresetManagerViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IPresetManagerViewModel.cs
new file mode 100644
index 000000000..4966dc5d8
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IPresetManagerViewModel.cs
@@ -0,0 +1,16 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IPresetManagerViewModel.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the IPresetManagerViewModel type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels.Interfaces
+{
+ public interface IPresetManagerViewModel
+ {
+ bool IsOpen { get; set; }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
index f0b005625..1d013bd26 100644
--- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
@@ -83,7 +83,6 @@ namespace HandBrakeWPF.ViewModels
private Preset selectedPreset;
private QueueTask queueEditTask;
private int lastEncodePercentage;
- private bool isPresetPanelShowing;
private bool showSourceSelection;
private BindingList<SourceMenuItem> drives;
private bool showAlertWindow;
@@ -113,6 +112,7 @@ namespace HandBrakeWPF.ViewModels
IStaticPreviewViewModel staticPreviewViewModel,
IQueueViewModel queueViewModel,
IMetaDataViewModel metaDataViewModel,
+ IPresetManagerViewModel presetManagerViewModel,
INotifyIconService notifyIconService,
ISystemService systemService)
: base(userSettingService)
@@ -136,6 +136,7 @@ namespace HandBrakeWPF.ViewModels
this.SubtitleViewModel = subtitlesViewModel;
this.ChaptersViewModel = chaptersViewModel;
this.StaticPreviewViewModel = staticPreviewViewModel;
+ this.PresetManagerViewModel = presetManagerViewModel;
// Setup Properties
this.WindowTitle = Resources.HandBrake_Title;
@@ -207,6 +208,8 @@ namespace HandBrakeWPF.ViewModels
public ISummaryViewModel SummaryViewModel { get; set; }
+ public IPresetManagerViewModel PresetManagerViewModel { get; set; }
+
public int SelectedTab { get; set; }
@@ -704,28 +707,6 @@ namespace HandBrakeWPF.ViewModels
}
}
- public bool IsPresetPanelShowing
- {
- get
- {
- return this.isPresetPanelShowing;
- }
- set
- {
- if (!Equals(this.isPresetPanelShowing, value))
- {
- this.isPresetPanelShowing = value;
- this.NotifyOfPropertyChange(() => this.IsPresetPanelShowing);
-
- // Save the setting if it has changed.
- if (this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ShowPresetPanel) != value)
- {
- this.userSettingService.SetUserSetting(UserSettingConstants.ShowPresetPanel, value);
- }
- }
- }
- }
-
public int ProgressPercentage { get; set; }
public bool ShowSourceSelection
@@ -939,9 +920,6 @@ namespace HandBrakeWPF.ViewModels
// Perform an update check if required
this.updateService.PerformStartupUpdateCheck(this.HandleUpdateCheckResults);
- // Show or Hide the Preset Panel.
- this.IsPresetPanelShowing = this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ShowPresetPanel);
-
// Setup the presets.
this.presetService.Load();
this.PresetsCategories = this.presetService.Presets;
@@ -1089,9 +1067,18 @@ namespace HandBrakeWPF.ViewModels
}
}
- public void ShowPresetPane()
+ public void OpenPresetWindow()
{
- this.IsPresetPanelShowing = !this.IsPresetPanelShowing;
+ if (!this.PresetManagerViewModel.IsOpen)
+ {
+ this.PresetManagerViewModel.IsOpen = true;
+ this.windowManager.ShowWindow(this.PresetManagerViewModel);
+ }
+ else if (this.PresetManagerViewModel.IsOpen)
+ {
+ Window window = Application.Current.Windows.Cast<Window>().FirstOrDefault(x => x.GetType() == typeof(PresetManagerView));
+ window?.Focus();
+ }
}
public void LaunchHelp()
diff --git a/win/CS/HandBrakeWPF/ViewModels/PresetManagerViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/PresetManagerViewModel.cs
new file mode 100644
index 000000000..3512a6747
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/PresetManagerViewModel.cs
@@ -0,0 +1,406 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="PresetManagerViewModel.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the PresetManagerViewModel type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels
+{
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Linq;
+ using System.Windows;
+
+ using Caliburn.Micro;
+
+ using HandBrakeWPF.Factories;
+ using HandBrakeWPF.Model.Picture;
+ using HandBrakeWPF.Properties;
+ using HandBrakeWPF.Services.Interfaces;
+ using HandBrakeWPF.Services.Presets.Interfaces;
+ using HandBrakeWPF.Services.Presets.Model;
+ using HandBrakeWPF.Utilities;
+ using HandBrakeWPF.ViewModels.Interfaces;
+ using HandBrakeWPF.Views;
+
+ using Microsoft.Win32;
+
+ public class PresetManagerViewModel : ViewModelBase, IPresetManagerViewModel
+ {
+ private readonly IPresetService presetService;
+ private readonly IErrorService errorService;
+ private readonly IWindowManager windowManager;
+
+ private IPresetObject selectedPresetCategory;
+ private Preset selectedPreset;
+ private PictureSettingsResLimitModes selectedPictureSettingsResLimitMode;
+
+ public PresetManagerViewModel(IPresetService presetService, IErrorService errorService, IWindowManager windowManager)
+ {
+ this.presetService = presetService;
+ this.errorService = errorService;
+ this.windowManager = windowManager;
+
+ this.PresetsCategories = this.presetService.Presets;
+ this.NotifyOfPropertyChange(() => this.PresetsCategories);
+ this.presetService.LoadCategoryStates();
+ this.Title = Resources.PresetManger_Title;
+ }
+
+ public bool IsOpen { get; set; }
+
+ public IEnumerable<IPresetObject> PresetsCategories { get; set; }
+
+ public string SelectedItem { get; set; }
+
+ public IPresetObject SelectedPresetCategory
+ {
+ get => this.selectedPresetCategory;
+ set
+ {
+ if (!object.Equals(this.selectedPresetCategory, value))
+ {
+ this.selectedPresetCategory = value;
+ this.NotifyOfPropertyChange(() => this.SelectedPresetCategory);
+
+ this.SelectedItem = value?.Category;
+ this.NotifyOfPropertyChange(() => this.SelectedItem);
+
+ this.selectedPreset = null;
+ this.NotifyOfPropertyChange(() => this.SelectedPreset);
+ }
+ }
+ }
+
+ public Preset SelectedPreset
+ {
+ get => this.selectedPreset;
+
+ set
+ {
+ if (!object.Equals(this.selectedPreset, value))
+ {
+ this.selectedPreset = value;
+ this.NotifyOfPropertyChange(() => this.SelectedPreset);
+
+ if (value != null)
+ {
+ this.SelectedItem = value.Name;
+ this.NotifyOfPropertyChange(() => this.SelectedItem);
+
+ this.IsBuildIn = value.IsBuildIn;
+
+ this.CustomWidth = value.Task.MaxWidth;
+ this.CustomHeight = value.Task.MaxHeight;
+ this.SetSelectedPictureSettingsResLimitMode();
+ }
+ else
+ {
+ this.selectedPresetCategory = null;
+ this.NotifyOfPropertyChange(() => this.SelectedPresetCategory);
+ }
+ }
+
+ this.NotifyOfPropertyChange(() => this.IsBuildIn);
+ }
+ }
+
+ public bool IsBuildIn { get; private set; }
+
+ public bool IsPresetSelected => this.SelectedPreset != null;
+
+ public BindingList<PictureSettingsResLimitModes> ResolutionLimitModes => new BindingList<PictureSettingsResLimitModes>
+ {
+ PictureSettingsResLimitModes.None,
+ PictureSettingsResLimitModes.Size8K,
+ PictureSettingsResLimitModes.Size4K,
+ PictureSettingsResLimitModes.Size1080p,
+ PictureSettingsResLimitModes.Size720p,
+ PictureSettingsResLimitModes.Size576p,
+ PictureSettingsResLimitModes.Size480p,
+ PictureSettingsResLimitModes.Custom,
+ };
+
+ public PictureSettingsResLimitModes SelectedPictureSettingsResLimitMode
+ {
+ get => this.selectedPictureSettingsResLimitMode;
+ set
+ {
+ if (value == this.selectedPictureSettingsResLimitMode)
+ {
+ return;
+ }
+
+ this.selectedPictureSettingsResLimitMode = value;
+ this.NotifyOfPropertyChange(() => this.SelectedPictureSettingsResLimitMode);
+
+ this.IsCustomMaxRes = value == PictureSettingsResLimitModes.Custom;
+ this.NotifyOfPropertyChange(() => this.IsCustomMaxRes);
+
+ // Enforce the new limit
+ ResLimit limit = EnumHelper<PictureSettingsResLimitModes>.GetAttribute<ResLimit, PictureSettingsResLimitModes>(value);
+ if (limit != null)
+ {
+ this.CustomWidth = limit.Width;
+ this.CustomHeight = limit.Height;
+ this.NotifyOfPropertyChange(() => this.CustomWidth);
+ this.NotifyOfPropertyChange(() => this.CustomHeight);
+ }
+
+ if (value == PictureSettingsResLimitModes.None)
+ {
+ this.CustomWidth = null;
+ this.CustomHeight = null;
+ }
+ }
+ }
+
+ public int? CustomWidth
+ {
+ get => this.selectedPreset?.Task.MaxWidth ?? null;
+ set
+ {
+ if (value == this.selectedPreset.Task.MaxWidth)
+ {
+ return;
+ }
+
+ this.selectedPreset.Task.MaxWidth = value;
+ this.NotifyOfPropertyChange(() => this.CustomWidth);
+ }
+ }
+
+ public int? CustomHeight
+ {
+ get => this.selectedPreset?.Task.MaxHeight ?? null;
+ set
+ {
+ if (value == this.selectedPreset.Task.MaxHeight)
+ {
+ return;
+ }
+
+ this.selectedPreset.Task.MaxHeight = value;
+ this.NotifyOfPropertyChange(() => this.CustomHeight);
+ }
+ }
+
+ public bool IsCustomMaxRes { get; private set; }
+
+ public void DeletePreset()
+ {
+ if (this.selectedPreset != null)
+ {
+ if (this.selectedPreset.IsDefault)
+ {
+ this.errorService.ShowMessageBox(
+ Resources.MainViewModel_CanNotDeleteDefaultPreset,
+ Resources.Warning,
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+
+ return;
+ }
+
+ MessageBoxResult result =
+ this.errorService.ShowMessageBox(
+ Resources.MainViewModel_PresetRemove_AreYouSure + this.selectedPreset.Name + " ?",
+ Resources.Question,
+ MessageBoxButton.YesNo,
+ MessageBoxImage.Question);
+
+ if (result == MessageBoxResult.No)
+ {
+ return;
+ }
+
+ this.presetService.Remove(this.selectedPreset);
+ this.NotifyOfPropertyChange(() => this.PresetsCategories);
+ this.SelectedPreset = this.presetService.DefaultPreset;
+ }
+ else
+ {
+ this.errorService.ShowMessageBox(Resources.Main_SelectPreset, Resources.Warning, MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ }
+
+ public void SetDefault()
+ {
+ if (this.selectedPreset != null)
+ {
+ this.presetService.SetDefault(this.selectedPreset);
+ this.errorService.ShowMessageBox(string.Format(Resources.Main_NewDefaultPreset, this.selectedPreset.Name), Resources.Main_Presets, MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ else
+ {
+ this.errorService.ShowMessageBox(Resources.Main_SelectPreset, Resources.Warning, MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ }
+
+ public void Import()
+ {
+ OpenFileDialog dialog = new OpenFileDialog { Filter = "Preset Files|*.json;*.plist", CheckFileExists = true };
+ bool? dialogResult = dialog.ShowDialog();
+ if (dialogResult.HasValue && dialogResult.Value)
+ {
+ this.presetService.Import(dialog.FileName);
+ this.NotifyOfPropertyChange(() => this.PresetsCategories);
+ }
+ }
+
+ public void Export()
+ {
+ if (this.selectedPreset != null && !this.selectedPreset.IsBuildIn)
+ {
+ SaveFileDialog savefiledialog = new SaveFileDialog
+ {
+ Filter = "json|*.json",
+ CheckPathExists = true,
+ AddExtension = true,
+ DefaultExt = ".json",
+ OverwritePrompt = true,
+ FilterIndex = 0
+ };
+
+ savefiledialog.ShowDialog();
+ string filename = savefiledialog.FileName;
+
+ if (!string.IsNullOrEmpty(filename))
+ {
+ this.presetService.Export(savefiledialog.FileName, this.selectedPreset, HBConfigurationFactory.Create());
+ }
+ }
+ else
+ {
+ this.errorService.ShowMessageBox(Resources.Main_SelectPreset, Resources.Warning, MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ }
+
+ public void DeleteBuiltInPresets()
+ {
+ List<Preset> allPresets = this.presetService.FlatPresetList;
+ bool foundDefault = false;
+ foreach (Preset preset in allPresets)
+ {
+ if (preset.IsBuildIn)
+ {
+ if (preset.IsDefault)
+ {
+ foundDefault = true;
+ }
+
+ this.presetService.Remove(preset);
+ }
+ }
+
+ if (foundDefault)
+ {
+ Preset preset = this.presetService.FlatPresetList.FirstOrDefault();
+ if (preset != null)
+ {
+ this.presetService.SetDefault(preset);
+ this.SelectedPreset = preset;
+ }
+ }
+
+ this.NotifyOfPropertyChange(() => this.PresetsCategories);
+ }
+
+ public void ResetBuiltInPresets()
+ {
+ this.presetService.UpdateBuiltInPresets();
+
+ this.NotifyOfPropertyChange(() => this.PresetsCategories);
+
+ this.SetDefaultPreset();
+
+ this.errorService.ShowMessageBox(Resources.Presets_ResetComplete, Resources.Presets_ResetHeader, MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+
+ public void EditAudioDefaults()
+ {
+ if (this.selectedPreset == null)
+ {
+ return;
+ }
+
+ IAudioDefaultsViewModel audioDefaultsViewModel = new AudioDefaultsViewModel(this.selectedPreset.Task);
+ audioDefaultsViewModel.ResetApplied();
+ audioDefaultsViewModel.Setup(this.selectedPreset, this.selectedPreset.Task);
+
+ this.windowManager.ShowDialog(audioDefaultsViewModel);
+ if (audioDefaultsViewModel.IsApplied)
+ {
+ this.SelectedPreset.AudioTrackBehaviours = audioDefaultsViewModel.AudioBehaviours.Clone();
+ }
+ }
+
+ public void EditSubtitleDefaults()
+ {
+ if (this.selectedPreset == null)
+ {
+ return;
+ }
+
+ ISubtitlesDefaultsViewModel subtitlesDefaultsViewModel = new SubtitlesDefaultsViewModel();
+ subtitlesDefaultsViewModel.ResetApplied();
+ SubtitlesDefaultsView view = new SubtitlesDefaultsView();
+ view.DataContext = subtitlesDefaultsViewModel;
+ view.ShowDialog();
+
+ if (subtitlesDefaultsViewModel.IsApplied)
+ {
+ this.SelectedPreset.SubtitleTrackBehaviours = subtitlesDefaultsViewModel.SubtitleBehaviours.Clone();
+ }
+ }
+
+ public void Close()
+ {
+ this.presetService.Save();
+ this.IsOpen = false;
+ }
+
+ private void SetDefaultPreset()
+ {
+ // Preset Selection
+ if (this.presetService.DefaultPreset != null)
+ {
+ PresetDisplayCategory category =
+ (PresetDisplayCategory)this.PresetsCategories.FirstOrDefault(
+ p => p.Category == this.presetService.DefaultPreset.Category);
+
+ this.SelectedPresetCategory = category;
+ this.SelectedPreset = this.presetService.DefaultPreset;
+ }
+ }
+
+ private void SetSelectedPictureSettingsResLimitMode()
+ {
+ // Look for a matching resolution.
+ foreach (PictureSettingsResLimitModes limit in EnumHelper<PictureSettingsResLimitModes>.GetEnumList())
+ {
+ ResLimit resLimit = EnumHelper<PictureSettingsResLimitModes>.GetAttribute<ResLimit, PictureSettingsResLimitModes>(limit);
+ if (resLimit != null)
+ {
+ if (resLimit.Width == this.CustomWidth && resLimit.Height == this.CustomHeight)
+ {
+ this.SelectedPictureSettingsResLimitMode = limit;
+ return;
+ }
+ }
+ }
+
+ if (this.CustomWidth.HasValue || this.CustomHeight.HasValue)
+ {
+ this.SelectedPictureSettingsResLimitMode = PictureSettingsResLimitModes.Custom;
+ }
+ else
+ {
+ this.SelectedPictureSettingsResLimitMode = PictureSettingsResLimitModes.None;
+ }
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Views/MainView.xaml b/win/CS/HandBrakeWPF/Views/MainView.xaml
index 20afae2a8..96a5adb0a 100644
--- a/win/CS/HandBrakeWPF/Views/MainView.xaml
+++ b/win/CS/HandBrakeWPF/Views/MainView.xaml
@@ -5,12 +5,9 @@
xmlns:Converters="clr-namespace:HandBrakeWPF.Converters"
xmlns:Properties="clr-namespace:HandBrakeWPF.Properties"
xmlns:cal="http://www.caliburnproject.org"
- xmlns:menu="clr-namespace:HandBrakeWPF.Commands.Menu"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:commands="clr-namespace:HandBrakeWPF.Commands"
- xmlns:helpers="clr-namespace:HandBrakeWPF.Helpers"
xmlns:loc="clr-namespace:HandBrakeWPF.Services.Presets.Model"
- xmlns:queue="clr-namespace:HandBrakeWPF.Converters.Queue"
xmlns:behaviours="clr-namespace:HandBrakeWPF.Behaviours"
xmlns:main="clr-namespace:HandBrakeWPF.Converters.Main"
AllowDrop="True"
@@ -36,11 +33,6 @@
<Converters:BooleanToVisibilityConverter x:Key="boolToVisConverter" />
- <Style x:Key="textBlockOrangeStyle" TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
- <Setter Property="FontWeight" Value="Bold" />
- <Setter Property="Padding" Value="5,5" />
- </Style>
-
<Style TargetType="ToolTip" BasedOn="{StaticResource {x:Type ToolTip}}">
<Style.Resources>
<Style TargetType="ContentPresenter">
@@ -120,8 +112,6 @@
<Separator />
<MenuItem Header="{x:Static Properties:Resources.MainView_SetCurrentAsDefault}" cal:Message.Attach="[Event Click] = [Action PresetSetDefault]" />
<MenuItem Header="{x:Static Properties:Resources.MainView_ResetPresets}" cal:Message.Attach="[Event Click] = [Action PresetReset]" />
- <Separator />
- <MenuItem IsCheckable="True" x:Name="showPresetPanelMenuItem" IsChecked="{Binding IsPresetPanelShowing}" Header="{x:Static Properties:Resources.MainView_ShowPresetPanel}" />
</MenuItem>
<MenuItem Header="{x:Static Properties:Resources.MainView_QueueMenu}" x:Name="queueMenu" Visibility="{Binding HasSource, Converter={StaticResource booleanConverter}, ConverterParameter=false}">
@@ -318,7 +308,7 @@
</Button>
- <Button Name="PresetPane" AutomationProperties.Name="Show Preset Pane" cal:Message.Attach="[Event Click] = [Action ShowPresetPane]">
+ <Button Name="PresetPane" AutomationProperties.Name="Show Preset Pane" cal:Message.Attach="[Event Click] = [Action OpenPresetWindow]">
<StackPanel Orientation="Horizontal">
<Image Width="32"
Height="32"
@@ -453,7 +443,7 @@
<!-- Presets Options -->
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10,10,10,5" IsEnabled="{Binding HasSource, Converter={StaticResource booleanConverter}, ConverterParameter=false}">
<Label Content="{x:Static Properties:Resources.MainView_SelectedPresets}" FontWeight="Bold" VerticalAlignment="Center" Margin="0,0,5,0" />
- <StackPanel Orientation="Horizontal" Margin="5,0,0,0" Visibility="{Binding IsPresetPanelShowing, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}">
+ <StackPanel Orientation="Horizontal" Margin="5,0,0,0">
<Button x:Name="SelectPresetsButton" VerticalAlignment="Center" Click="SelectPreset_OnClick" Width="255">
<Button.Content>
@@ -517,10 +507,6 @@
</Button.ContextMenu>
</Button>
</StackPanel>
- <StackPanel Margin="8,0,0,0" Orientation="Horizontal" Visibility="{Binding IsPresetPanelShowing, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}">
- <TextBlock Text="{Binding SelectedPreset.Name}" Margin="5,0,0,0" />
- <TextBlock Text="{x:Static Properties:Resources.MainView_ModifiedPreset}" FontStyle="Italic" Visibility="{Binding IsModifiedPreset, Converter={StaticResource boolToVisConverter}}" Margin="5,0,0,0" />
- </StackPanel>
</StackPanel>
<!-- Tab Control -->
@@ -589,183 +575,8 @@
/>
</Grid>
</StackPanel>
-
- <!-- Presets -->
- <GroupBox Grid.Row="0" Grid.RowSpan="5"
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Header="Presets"
- Margin="0,5,5,5"
- MaxWidth="270"
- IsEnabled="{Binding HasSource, Converter={StaticResource booleanConverter}, ConverterParameter=false}"
- Visibility="{Binding IsPresetPanelShowing, Converter={StaticResource boolToVisConverter}}">
-
-
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
-
- <Grid.Resources>
-
- <HierarchicalDataTemplate DataType="{x:Type loc:Preset}">
- <StackPanel Orientation="Horizontal" >
- <StackPanel.Resources>
- <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
- <Style.Triggers>
- <DataTrigger Binding="{Binding IsDefault}" Value="True" >
- <Setter Property="FontStyle" Value="Italic" />
- </DataTrigger>
- <DataTrigger Binding="{Binding IsDefault}" Value="False" >
- <Setter Property="FontStyle" Value="Normal" />
- </DataTrigger>
- <DataTrigger Binding="{Binding IsSelected}" Value="True">
- <Setter Property="FontWeight" Value="Bold"/>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </StackPanel.Resources>
- <TextBlock Text="{Binding Name}" TextTrimming="CharacterEllipsis" />
- </StackPanel>
- </HierarchicalDataTemplate>
-
- <HierarchicalDataTemplate DataType="{x:Type loc:PresetDisplayCategory}" ItemsSource="{Binding Presets}">
- <StackPanel Orientation="Horizontal" >
- <TextBlock Text="{Binding Category}" FontSize="14" />
- </StackPanel>
- </HierarchicalDataTemplate>
- </Grid.Resources>
-
- <TreeView x:Name="presetListTree" HorizontalAlignment="Stretch" AutomationProperties.Name="Presets List" ToolTip="{x:Static Properties:ResourcesTooltips.MainView_Presets}"
- VerticalAlignment="Stretch" BorderThickness="0,0,0,1" BorderBrush="LightGray"
- ItemsSource="{Binding PresetsCategories}" MaxWidth="265"
- SelectedItemChanged="PresetListTree_OnSelectedItemChanged"
- PreviewMouseRightButtonDown="PresetListTree_OnPreviewMouseRightButtonDown">
-
- <TreeView.ItemContainerStyle>
- <Style BasedOn="{StaticResource {x:Type TreeViewItem}}" TargetType="TreeViewItem">
- <Setter Property="HorizontalAlignment" Value="Stretch" />
- <Setter Property="Padding" Value="4" />
- <Setter Property="ToolTip" Value="{Binding Description}" />
- <Setter Property="ToolTipService.InitialShowDelay" Value="1500"/>
- <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
- <EventSetter Event="TreeViewItem.Collapsed" Handler="PresetTreeviewItemCollasped" />
- <Style.Triggers>
- <Trigger Property="HasItems" Value="True">
- <Setter Property="Focusable" Value="false" />
- </Trigger>
-
- </Style.Triggers>
- </Style>
- </TreeView.ItemContainerStyle>
-
- <TreeView.ContextMenu>
- <ContextMenu AutomationProperties.Name="Presets List Context Menu">
- <MenuItem Header="{x:Static Properties:Resources.MainView_SetDefault}" cal:Message.Attach="[Event Click] = [Action PresetSetDefault]" />
- <Separator />
- <MenuItem Header="{x:Static Properties:Resources.MainView_UpdateSelectedPreset}" cal:Message.Attach="[Event Click] = [Action PresetUpdate]" />
- <MenuItem Header="{x:Static Properties:Resources.MainView_PresetManage}" cal:Message.Attach="[Event Click] = [Action PresetManage]" />
- <Separator />
- <MenuItem Header="{x:Static Properties:Resources.Preset_Import}" cal:Message.Attach="[Event Click] = [Action PresetImport]" />
- <MenuItem Header="{x:Static Properties:Resources.Preset_Export}" cal:Message.Attach="[Event Click] = [Action PresetExport]" />
- <Separator />
- <MenuItem Header="{x:Static Properties:Resources.MainView_ResetBuiltInPresets}" cal:Message.Attach="[Event Click] = [Action PresetReset]" />
- </ContextMenu>
-
- </TreeView.ContextMenu>
-
- <i:Interaction.Triggers>
- <commands:InputBindingTrigger>
- <commands:InputBindingTrigger.InputBinding>
- <KeyBinding Key="Delete"/>
- </commands:InputBindingTrigger.InputBinding>
- <cal:ActionMessage MethodName="PresetRemove" />
- </commands:InputBindingTrigger>
- </i:Interaction.Triggers>
-
- </TreeView>
-
- <ToolBar Name="presetsToolBar"
- Grid.Row="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- SnapsToDevicePixels="False"
- UseLayoutRounding="False"
- ToolBar.OverflowMode="Never"
- Background="Transparent"
- ToolBarTray.IsLocked="True"
- Loaded="ToolBarLoaded"
- KeyboardNavigation.TabNavigation="Continue" >
-
- <ToolBar.Resources>
- <Style TargetType="{x:Type ToolBarPanel}">
- <Setter Property="Orientation" Value="Vertical"/>
- <Setter Property="VerticalAlignment" Value="Center"/>
- </Style>
-
- <Style BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" TargetType="{x:Type Button}" />
- </ToolBar.Resources>
-
- <ToolBarOverflowPanel>
- <Button cal:Message.Attach="[Event Click] = [Action PresetAdd]" AutomationProperties.Name="Add Preset" ToolTip="{x:Static Properties:ResourcesTooltips.MainView_AddPreset}">
- <Button.Content>
- <StackPanel Orientation="Horizontal">
- <Image Width="18" Height="18" SnapsToDevicePixels="True"
- Source="{Binding Converter={StaticResource themeConverter}, ConverterParameter='Add.png'}" />
- <TextBlock Margin="2,0,0,0"
- VerticalAlignment="Center"
- Style="{StaticResource textBlockOrangeStyle}"
- Text="{x:Static Properties:Resources.Generic_Add}"
- />
- </StackPanel>
- </Button.Content>
- </Button>
-
- <Button Background="Transparent" cal:Message.Attach="[Event Click] = [Action PresetRemove]" AutomationProperties.Name="Remove Preset" ToolTip="{x:Static Properties:ResourcesTooltips.MainView_RemovePreset}">
- <Button.Content>
- <StackPanel Orientation="Horizontal">
- <Image Width="18" Height="18"
- Source="{Binding Converter={StaticResource themeConverter}, ConverterParameter='Remove.png'}" SnapsToDevicePixels="True" />
- <TextBlock Margin="2,0,0,0"
- VerticalAlignment="Center"
- Style="{StaticResource textBlockOrangeStyle}"
- Text="{x:Static Properties:Resources.MainView_Remove}" />
- </StackPanel>
- </Button.Content>
- </Button>
-
- <Menu Background="Transparent" AutomationProperties.Name="Preset Options Dropdown" MinHeight="22" ToolTip="{x:Static Properties:ResourcesTooltips.MainView_PresetAdditionalOptions}">
- <MenuItem ToolBar.OverflowMode="Never">
- <MenuItem.Header>
- <StackPanel Orientation="Horizontal">
- <Image Width="20" Height="20" SnapsToDevicePixels="True"
- Source="{Binding Converter={StaticResource themeConverter}, ConverterParameter='Advanced.png'}"
- RenderOptions.BitmapScalingMode="Linear" />
- <TextBlock Margin="2,0,0,0"
- VerticalAlignment="Center"
- Style="{StaticResource textBlockOrangeStyle}"
- Text="{x:Static Properties:Resources.MainView_Options}" />
- </StackPanel>
- </MenuItem.Header>
- <MenuItem Header="{x:Static Properties:Resources.MainView_SetDefault}" cal:Message.Attach="[Event Click] = [Action PresetSetDefault]" />
- <Separator />
- <MenuItem Header="{x:Static Properties:Resources.MainView_UpdateSelectedPreset}" cal:Message.Attach="[Event Click] = [Action PresetUpdate]" />
- <Separator />
- <MenuItem Header="{x:Static Properties:Resources.Preset_Import}" cal:Message.Attach="[Event Click] = [Action PresetImport]" />
- <MenuItem Header="{x:Static Properties:Resources.Preset_Export}" cal:Message.Attach="[Event Click] = [Action PresetExport]" />
- <Separator />
- <MenuItem Header="{x:Static Properties:Resources.MainView_ResetBuiltInPresets}" cal:Message.Attach="[Event Click] = [Action PresetReset]" />
- </MenuItem>
- </Menu>
- </ToolBarOverflowPanel>
-
- </ToolBar>
- </Grid>
- </GroupBox>
</Grid>
-
+
<!-- Source Selection-->
<Controls:SourceSelection x:Name="sourceSelection"
Grid.Row="0" Grid.RowSpan="3"
diff --git a/win/CS/HandBrakeWPF/Views/MainView.xaml.cs b/win/CS/HandBrakeWPF/Views/MainView.xaml.cs
index a75981286..eb12c38c0 100644
--- a/win/CS/HandBrakeWPF/Views/MainView.xaml.cs
+++ b/win/CS/HandBrakeWPF/Views/MainView.xaml.cs
@@ -100,59 +100,5 @@ namespace HandBrakeWPF.Views
button.ContextMenu.IsOpen = true;
}
}
-
- private void ToolBarLoaded(object sender, RoutedEventArgs e)
- {
- ToolBar toolBar = sender as ToolBar;
- if (toolBar != null)
- {
- var overflowGrid = toolBar.Template.FindName("OverflowGrid", toolBar) as FrameworkElement;
- if (overflowGrid != null)
- {
- overflowGrid.Visibility = Visibility.Collapsed;
- }
- }
- }
- private void PresetListTree_OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
- {
- TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject);
-
- if (treeViewItem != null)
- {
- treeViewItem.Focus();
- e.Handled = true;
- }
- }
-
- private static TreeViewItem VisualUpwardSearch(DependencyObject source)
- {
- while (source != null && !(source is TreeViewItem))
- source = VisualTreeHelper.GetParent(source);
-
- return source as TreeViewItem;
- }
-
- private void PresetTreeviewItemCollasped(object sender, RoutedEventArgs e)
- {
- if (e.Source.GetType() == typeof(TreeViewItem))
- {
- TreeViewItem item = e.Source as TreeViewItem;
- if (item != null && item.DataContext?.GetType() == typeof(PresetDisplayCategory))
- {
- item.IsSelected = false;
- }
- }
- }
-
- private void PresetListTree_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
- {
- if (e.Source.GetType() == typeof(TreeView))
- {
- if (e.NewValue != null && e.NewValue.GetType() == typeof(Preset))
- {
- ((MainViewModel)this.DataContext).SelectedPreset = (Preset)e.NewValue;
- }
- }
- }
}
}
diff --git a/win/CS/HandBrakeWPF/Views/PresetManagerView.xaml b/win/CS/HandBrakeWPF/Views/PresetManagerView.xaml
new file mode 100644
index 000000000..f0c011965
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/PresetManagerView.xaml
@@ -0,0 +1,268 @@
+<Window x:Class="HandBrakeWPF.Views.PresetManagerView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:Properties="clr-namespace:HandBrakeWPF.Properties"
+ xmlns:converters="clr-namespace:HandBrakeWPF.Converters"
+ xmlns:loc="clr-namespace:HandBrakeWPF.Services.Presets.Model"
+ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+ xmlns:commands="clr-namespace:HandBrakeWPF.Commands"
+ xmlns:controls="clr-namespace:HandBrakeWPF.Controls"
+ xmlns:picture="clr-namespace:HandBrakeWPF.Converters.Picture"
+ Title="{Binding Title}"
+ Width="750"
+ Height="500"
+ MinWidth="750"
+ MinHeight="500"
+ WindowStartupLocation="CenterScreen"
+ TextOptions.TextFormattingMode="Display">
+
+ <Window.Resources>
+ <converters:ThemeImageConverter x:Key="themeConverter" />
+ <converters:BooleanToVisibilityConverter x:Key="boolToVisConverter" />
+ <picture:ResolutionLimitConverter x:Key="resolutionLimitConverter" />
+ <converters:BooleanConverter x:Key="booleanConverter" />
+ </Window.Resources>
+
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+
+ <!-- Header -->
+ <Grid Grid.Row="0" Grid.ColumnSpan="2">
+
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+ <TextBlock Text="{x:Static Properties:Resources.ManagePresetView_ManagePreset}" FontSize="28" VerticalAlignment="Center" FontFamily="Segoe UI Light" Margin="10,0,0,0" Grid.Row="0" />
+ </Grid>
+
+ <!-- Preset List -->
+ <Grid Grid.Row="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+
+ <Grid.Resources>
+
+ <HierarchicalDataTemplate DataType="{x:Type loc:Preset}">
+ <StackPanel Orientation="Horizontal" >
+ <StackPanel.Resources>
+ <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsDefault}" Value="True" >
+ <Setter Property="FontStyle" Value="Italic" />
+ </DataTrigger>
+ <DataTrigger Binding="{Binding IsDefault}" Value="False" >
+ <Setter Property="FontStyle" Value="Normal" />
+ </DataTrigger>
+ <DataTrigger Binding="{Binding IsSelected}" Value="True">
+ <Setter Property="FontWeight" Value="Bold"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </StackPanel.Resources>
+ <TextBlock Text="{Binding Name}" TextTrimming="CharacterEllipsis" />
+ </StackPanel>
+ </HierarchicalDataTemplate>
+
+ <HierarchicalDataTemplate DataType="{x:Type loc:PresetDisplayCategory}" ItemsSource="{Binding Presets}">
+ <StackPanel Orientation="Horizontal" >
+ <TextBlock Text="{Binding Category}" FontSize="14" />
+ </StackPanel>
+ </HierarchicalDataTemplate>
+ </Grid.Resources>
+
+ <Menu HorizontalAlignment="Right" Background="Transparent" VerticalAlignment="Bottom" Grid.Row="1" Margin="0,0,0,0" >
+ <MenuItem>
+ <MenuItem.Header>
+ <StackPanel Height="27" Orientation="Horizontal">
+ <Image Source="{Binding Converter={StaticResource themeConverter}, ConverterParameter='Advanced.png'}" Width="20" Height="20" VerticalAlignment="Center" />
+ <TextBlock VerticalAlignment="Center"
+ Text="{x:Static Properties:Resources.QueueView_Options}" Margin="5,0,0,0" />
+ <Path Height="5"
+ Margin="2,2,0,0"
+ Data="M 0 0 L 4 4 L 8 0 Z"
+ Fill="{DynamicResource GlyphBrush}" />
+ </StackPanel>
+ </MenuItem.Header>
+
+ <MenuItem cal:Message.Attach="[Event Click] = [Action Import]" Header="{x:Static Properties:Resources.ManagePresetView_Import}" />
+ <MenuItem cal:Message.Attach="[Event Click] = [Action Export]" Header="{x:Static Properties:Resources.ManagePresetView_Export}" />
+ <Separator />
+ <MenuItem cal:Message.Attach="[Event Click] = [Action SetDefault]" Header="{x:Static Properties:Resources.ManagePresetView_SetDefault}" />
+
+ <MenuItem cal:Message.Attach="[Event Click] = [Action DeletePreset]" Header="{x:Static Properties:Resources.PresetManagerView_Delete}" />
+ <Separator />
+ <MenuItem cal:Message.Attach="[Event Click] = [Action ResetBuiltInPresets]" Header="{x:Static Properties:Resources.MainView_ResetPresets}" />
+ <MenuItem cal:Message.Attach="[Event Click] = [Action DeleteBuiltInPresets]" Header="{x:Static Properties:Resources.ManagePresetView_DeleteBuiltIn}" />
+ </MenuItem>
+ </Menu>
+
+ <TreeView x:Name="presetListTree" HorizontalAlignment="Stretch" AutomationProperties.Name="Presets List" ToolTip="{x:Static Properties:ResourcesTooltips.MainView_Presets}"
+ VerticalAlignment="Stretch" BorderThickness="1" BorderBrush="LightGray" Grid.Row="2" Margin="10,0,0,10"
+ ItemsSource="{Binding PresetsCategories}" Width="300"
+ SelectedItemChanged="PresetListTree_OnSelectedItemChanged"
+ PreviewMouseRightButtonDown="PresetListTree_OnPreviewMouseRightButtonDown">
+
+ <TreeView.ItemContainerStyle>
+ <Style BasedOn="{StaticResource {x:Type TreeViewItem}}" TargetType="TreeViewItem">
+ <Setter Property="HorizontalAlignment" Value="Stretch" />
+ <Setter Property="Padding" Value="4" />
+ <Setter Property="ToolTip" Value="{Binding Description}" />
+ <Setter Property="ToolTipService.InitialShowDelay" Value="1500"/>
+ <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
+ <EventSetter Event="TreeViewItem.Collapsed" Handler="PresetTreeviewItemCollasped" />
+ <Style.Triggers>
+ <Trigger Property="HasItems" Value="True">
+ <Setter Property="Focusable" Value="false" />
+ </Trigger>
+
+ </Style.Triggers>
+ </Style>
+ </TreeView.ItemContainerStyle>
+
+ <TreeView.ContextMenu>
+ <ContextMenu AutomationProperties.Name="Presets List Context Menu">
+ <MenuItem Header="{x:Static Properties:Resources.MainView_SetDefault}" cal:Message.Attach="[Event Click] = [Action SetDefault]" />
+ <Separator />
+ <MenuItem cal:Message.Attach="[Event Click] = [Action DeletePreset]" Header="{x:Static Properties:Resources.PresetManagerView_Delete}" />
+ </ContextMenu>
+ </TreeView.ContextMenu>
+
+ <i:Interaction.Triggers>
+ <commands:InputBindingTrigger>
+ <commands:InputBindingTrigger.InputBinding>
+ <KeyBinding Key="Delete"/>
+ </commands:InputBindingTrigger.InputBinding>
+ <cal:ActionMessage MethodName="DeletePreset" />
+ </commands:InputBindingTrigger>
+ </i:Interaction.Triggers>
+
+ </TreeView>
+ </Grid>
+
+ <!-- Control Panel -->
+ <Border BorderThickness="1,0,0,0" BorderBrush="LightGray" Grid.Column="1" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="5"
+ Visibility="{Binding IsPresetSelected, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}"
+ IsEnabled="{Binding IsBuildIn, Converter={StaticResource booleanConverter}, ConverterParameter=true}">
+ <Grid >
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+ <!-- Row 1 -->
+ <TextBlock Text="{x:Static Properties:Resources.ManagePresetView_PresetInfo}" FontSize="16" Margin="10,0,0,15" Grid.Row="0" />
+
+ <!-- Row 2 -->
+ <TextBlock Text="{x:Static Properties:Resources.ManagePresetView_RestrictedPreset}" HorizontalAlignment="Center" FontStyle="Italic" Grid.Row="1"
+ Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
+
+ <!-- Row 3 -->
+ <StackPanel Orientation="Horizontal" Grid.Row="2" Margin="10,0,0,15" HorizontalAlignment="Stretch" >
+
+ <StackPanel.Resources>
+ <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
+ <Setter Property="Padding" Value="8,2" />
+ </Style>
+ </StackPanel.Resources>
+
+ <Button Margin="0,0,0,0" AutomationProperties.Name="{x:Static Properties:Resources.PresetManagerView_Delete}"
+ cal:Message.Attach="[Event Click] = [Action DeletePreset]"
+ Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" >
+ <Button.Content>
+ <StackPanel Orientation="Horizontal">
+ <Image Width="20" Height="20" VerticalAlignment="Center" Margin="0,0,5,0"
+ Source="{Binding Converter={StaticResource themeConverter}, ConverterParameter='Remove.png'}">
+ </Image>
+ <TextBlock Text="{x:Static Properties:Resources.PresetManagerView_Delete}" VerticalAlignment="Center" />
+ </StackPanel>
+
+ </Button.Content>
+ </Button>
+
+ </StackPanel>
+
+ <!-- Header -->
+ <Grid Grid.Row="3" Margin="10,0,10,0">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="120" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+
+ <!-- Name -->
+ <TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Static Properties:Resources.AddPresetView_Name}" />
+ <TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" Text="{Binding SelectedPreset.Name, UpdateSourceTrigger=PropertyChanged}" />
+
+
+ <!-- Description -->
+ <TextBlock Grid.Row="2" Grid.Column="0" Margin="0,10,0,0" Text="{x:Static Properties:Resources.AddPresetView_Description}" VerticalAlignment="Top" />
+ <TextBox Grid.Row="2" Grid.Column="1" Margin="0,10,0,0" Text="{Binding SelectedPreset.Description, UpdateSourceTrigger=PropertyChanged}" Height="80" TextWrapping="WrapWithOverflow" VerticalContentAlignment="Top"
+ Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+ <TextBlock Grid.Row="2" Grid.Column="1" Margin="0,10,0,0" Text="{Binding SelectedPreset.Description, UpdateSourceTrigger=PropertyChanged}" TextWrapping="WrapWithOverflow"
+ Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
+
+ <!-- Settings -->
+ <TextBlock Text="{x:Static Properties:Resources.PictureSettingsView_ResLimit}" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Margin="0,15,0,5"
+ Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+ <ComboBox ItemsSource="{Binding ResolutionLimitModes, Converter={StaticResource resolutionLimitConverter}}"
+ SelectedItem="{Binding SelectedPictureSettingsResLimitMode, Converter={StaticResource resolutionLimitConverter}}"
+ Width="150" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left" Margin="0,15,0,5"
+ AutomationProperties.Name="{x:Static Properties:Resources.PictureSettingsView_ResLimit}"
+ Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+
+
+ <!-- MAX Width and MAX Height -->
+ <StackPanel Grid.Row="5" Grid.Column="1" Orientation="Horizontal" Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}">
+ <controls:NumberBox Number="{Binding CustomWidth, Mode=TwoWay}" UpdateBindingOnTextChange="True"
+ Modulus="2" Minimum="0" Width="60"
+ AutomationProperties.Name="{x:Static Properties:Resources.PictureSettingsView_MaxWidth}" Visibility="{Binding IsCustomMaxRes, Converter={StaticResource boolToVisConverter}}" />
+
+ <TextBlock Text="x" Visibility="{Binding IsCustomMaxRes, Converter={StaticResource boolToVisConverter}}" VerticalAlignment="Center" Margin="10,0,10,0" />
+ <controls:NumberBox Number="{Binding CustomHeight, Mode=TwoWay}" UpdateBindingOnTextChange="True"
+ Modulus="2" Minimum="0" Width="60"
+ AutomationProperties.Name="{x:Static Properties:Resources.PictureSettingsView_MaxHeight}" Visibility="{Binding IsCustomMaxRes, Converter={StaticResource boolToVisConverter}}" />
+ </StackPanel>
+
+ <TextBlock Text="Audio:" Grid.Row="6" VerticalAlignment="Center" Margin="0,15,0,0" Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+ <Button Content="{x:Static Properties:Resources.AudioViewModel_ConfigureDefaults}" Grid.Row="6" Grid.Column="1" HorizontalAlignment="Left" Margin="0,15,0,0" Padding="8,2"
+ cal:Message.Attach="[Event Click] = [Action EditAudioDefaults]" Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+
+ <TextBlock Text="Subtitles:" Grid.Row="7" VerticalAlignment="Center" Margin="0,5,0,0" Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+ <Button Content="{x:Static Properties:Resources.SubtitlesViewModel_ConfigureDefaults}" Grid.Row="7" Grid.Column="1" HorizontalAlignment="Left" Margin="0,5,0,0" Padding="8,2"
+ cal:Message.Attach="[Event Click] = [Action EditSubtitleDefaults]" Visibility="{Binding IsBuildIn, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+
+ </Grid>
+
+ </Grid>
+ </Border>
+
+ </Grid>
+</Window>
diff --git a/win/CS/HandBrakeWPF/Views/PresetManagerView.xaml.cs b/win/CS/HandBrakeWPF/Views/PresetManagerView.xaml.cs
new file mode 100644
index 000000000..dfc6fefca
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/PresetManagerView.xaml.cs
@@ -0,0 +1,93 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="PresetManagerView.xaml.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Interaction logic for PresetManagerView.xaml
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Views
+{
+ using System.Windows;
+ using System.Windows.Controls;
+ using System.Windows.Input;
+ using System.Windows.Media;
+
+ using HandBrakeWPF.Services.Presets.Model;
+ using HandBrakeWPF.ViewModels;
+
+ public partial class PresetManagerView : Window
+ {
+ public PresetManagerView()
+ {
+ this.InitializeComponent();
+ this.Closing += this.PresetManagerView_Closing;
+ }
+
+ private void PresetManagerView_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ this.Closing -= this.PresetManagerView_Closing;
+ ((PresetManagerViewModel)this.DataContext).Close();
+ }
+
+ private void PresetTreeviewItemCollasped(object sender, RoutedEventArgs e)
+ {
+ if (e.Source.GetType() == typeof(TreeViewItem))
+ {
+ TreeViewItem item = e.Source as TreeViewItem;
+ if (item != null && item.DataContext?.GetType() == typeof(PresetDisplayCategory))
+ {
+ item.IsSelected = false;
+ }
+ }
+ }
+
+ private void PresetListTree_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
+ {
+ if (e.Source.GetType() == typeof(TreeView))
+ {
+ if (e.NewValue != null && e.NewValue.GetType() == typeof(Preset))
+ {
+ ((PresetManagerViewModel)this.DataContext).SelectedPreset = (Preset)e.NewValue;
+ }
+ else if (e.NewValue != null && e.NewValue.GetType() == typeof(PresetDisplayCategory))
+ {
+ ((PresetManagerViewModel)this.DataContext).SelectedPresetCategory = (PresetDisplayCategory)e.NewValue;
+ }
+ }
+ }
+
+ private void PresetListTree_OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
+ {
+ TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject);
+
+ if (treeViewItem != null)
+ {
+ treeViewItem.Focus();
+ e.Handled = true;
+ }
+ }
+
+ private static TreeViewItem VisualUpwardSearch(DependencyObject source)
+ {
+ while (source != null && !(source is TreeViewItem))
+ source = VisualTreeHelper.GetParent(source);
+
+ return source as TreeViewItem;
+ }
+
+ private void ToolBarLoaded(object sender, RoutedEventArgs e)
+ {
+ ToolBar toolBar = sender as ToolBar;
+ if (toolBar != null)
+ {
+ var overflowGrid = toolBar.Template.FindName("OverflowGrid", toolBar) as FrameworkElement;
+ if (overflowGrid != null)
+ {
+ overflowGrid.Visibility = Visibility.Collapsed;
+ }
+ }
+ }
+ }
+}