diff options
author | sr55 <[email protected]> | 2020-06-30 21:05:09 +0100 |
---|---|---|
committer | sr55 <[email protected]> | 2020-06-30 21:05:09 +0100 |
commit | 4d5798c812a1caa4d3fdf0f6c505a9d612d33837 (patch) | |
tree | 04c20cdd2952efe725aa2ecbecf16e05e2fd2832 | |
parent | 2e6809f9c3b7cda87269e4e6902138d42da95569 (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.cs | 74 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Properties/Resources.resx | 26 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Services/Presets/Interfaces/IPresetService.cs | 8 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Services/Presets/PresetService.cs | 7 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Services/UserSettingService.cs | 1 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs | 3 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Startup/StartupOptions.cs | 1 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/UserSettingConstants.cs | 1 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/ViewModels/Interfaces/IPresetManagerViewModel.cs | 16 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs | 43 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/ViewModels/PresetManagerViewModel.cs | 406 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Views/MainView.xaml | 195 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Views/MainView.xaml.cs | 54 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Views/PresetManagerView.xaml | 268 | ||||
-rw-r--r-- | win/CS/HandBrakeWPF/Views/PresetManagerView.xaml.cs | 93 |
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; + } + } + } + } +} |