From ba0f5b6074579743c03626466cdd6e25da99ae67 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 19 Nov 2020 22:31:20 +0100 Subject: [PATCH 01/38] Removed MetroWindow, added theming support and modernWPF --- .../editor/FancyZonesEditor/App.xaml | 8 +- .../editor/FancyZonesEditor/App.xaml.cs | 4 + .../editor/FancyZonesEditor/EditorWindow.cs | 3 +- .../FancyZonesEditor/FancyZonesEditor.csproj | 182 +++++++++++++++- .../editor/FancyZonesEditor/MainWindow.xaml | 10 +- .../FancyZonesEditor/MainWindow.xaml.cs | 3 +- .../editor/FancyZonesEditor/Overlay.cs | 5 - .../editor/FancyZonesEditor/Themes/Dark.xaml | 24 +++ .../Themes/HighContrast1.xaml | 24 +++ .../Themes/HighContrast2.xaml | 25 +++ .../Themes/HighContrastBlack.xaml | 25 +++ .../Themes/HighContrastWhite.xaml | 25 +++ .../editor/FancyZonesEditor/Themes/Light.xaml | 25 +++ .../Utils/CustomLibraryThemeProvider.cs | 24 +++ .../FancyZonesEditor/Utils/ThemeManager.cs | 200 ++++++++++++++++++ 15 files changed, 563 insertions(+), 24 deletions(-) create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Utils/CustomLibraryThemeProvider.cs create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Utils/ThemeManager.cs diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml index 8baea2aed95a..89c98f9184c9 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml @@ -2,15 +2,13 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:FancyZonesEditor" + xmlns:ui="http://schemas.modernwpf.com/2019" Startup="OnStartup"> - - - - - + + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs index e1f07e19a039..1384f75ce043 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs @@ -49,6 +49,8 @@ public partial class App : Application public static int PowerToysPID { get; set; } + private ThemeManager _themeManager; + public static bool DebugMode { get @@ -82,6 +84,8 @@ private void OnStartup(object sender, StartupEventArgs e) Environment.Exit(0); }); + _themeManager = new ThemeManager(this); + FancyZonesEditorIO.ParseCommandLineArguments(); FancyZonesEditorIO.ParseDeviceInfoData(); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs b/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs index 50cd45798060..d49f745c2a46 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs @@ -5,11 +5,10 @@ using System; using System.Windows; using FancyZonesEditor.Models; -using MahApps.Metro.Controls; namespace FancyZonesEditor { - public class EditorWindow : MetroWindow + public class EditorWindow : Window { protected void OnSaveApplyTemplate(object sender, RoutedEventArgs e) { diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj index f1c5ebc635f4..1a500ba835e9 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj +++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj @@ -53,7 +53,165 @@ - + + MSBuild:Compile + Designer + + + GlobalSuppressions.cs + + + + + + + LayoutOverlayWindow.xaml + + + + + + + + + CanvasEditor.xaml + + + + GridEditor.xaml + + + GridResizer.xaml + + + LayoutPreview.xaml + + + + + + + + + + GridEditorWindow.xaml + + + + + + + + + + + + + + + WindowLayout.xaml + + + CanvasEditorWindow.xaml + + + CanvasZone.xaml + + + GridZone.xaml + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + MainWindow.xaml + Code + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + PublicResXFileCodeGenerator Resources.Designer.cs @@ -65,10 +223,24 @@ - - - - + + 4.4.0 + + + 0.9.2 + + + 12.2.5 + + + 6.6.30107 + + + 4.7.2 + + + 1.1.118 + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 88c87e3e1f66..7047d7a8a07c 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -1,15 +1,15 @@ - - + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index 82e363dd324b..181b627e8809 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -7,14 +7,13 @@ using System.Windows.Controls; using System.Windows.Input; using FancyZonesEditor.Models; -using MahApps.Metro.Controls; namespace FancyZonesEditor { /// /// Interaction logic for MainWindow.xaml /// - public partial class MainWindow : MetroWindow + public partial class MainWindow : Window { // TODO: share the constants b/w C# Editor and FancyZoneLib public const int MaxZones = 40; diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs index be527fa5e8fd..cacdd281c533 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs @@ -235,9 +235,6 @@ public void OpenEditor(LayoutModel model) { (window as GridEditorWindow).NameTextBox().Focus(); } - - window.LeftWindowCommands = null; - window.RightWindowCommands = null; } public void CloseEditor() @@ -318,8 +315,6 @@ private void OpenMainWindow() _mainWindow.ShowActivated = true; _mainWindow.Topmost = true; _mainWindow.Show(); - _mainWindow.LeftWindowCommands = null; - _mainWindow.RightWindowCommands = null; // window is set to topmost to make sure it shows on top of PowerToys settings page // we can reset topmost flag now diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml new file mode 100644 index 000000000000..e1480cc87960 --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml @@ -0,0 +1,24 @@ + + + + Dark.Accent1 + PowerToysRun + Accent1 (Dark) + Dark + Accent1 + Black + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml new file mode 100644 index 000000000000..9a1f7eba524e --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml @@ -0,0 +1,24 @@ + + + + HighContrast.Accent2 + PowerToysRun + Accent2 (HighContrast) + HighContrast + Accent2 + White + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml new file mode 100644 index 000000000000..9e1271944713 --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml @@ -0,0 +1,25 @@ + + + + HighContrast.Accent3 + PowerToysRun + Accent3 (HighContrast) + HighContrast + Accent3 + White + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml new file mode 100644 index 000000000000..fe485af1b0ac --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml @@ -0,0 +1,25 @@ + + + + HighContrast.Accent4 + PowerToysRun + Accent4 (HighContrast) + HighContrast + Accent4 + White + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml new file mode 100644 index 000000000000..e41b2ed16d36 --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml @@ -0,0 +1,25 @@ + + + + HighContrast.Accent5 + PowerToysRun + Accent5 (HighContrast) + HighContrast + Accent5 + White + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml new file mode 100644 index 000000000000..a4a03fbc9223 --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml @@ -0,0 +1,25 @@ + + + + Light.Accent1 + PowerToysRun + Accent1 (Light) + Light + Accent1 + White + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/CustomLibraryThemeProvider.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/CustomLibraryThemeProvider.cs new file mode 100644 index 000000000000..7b564894dcd0 --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/CustomLibraryThemeProvider.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using ControlzEx.Theming; + +namespace FancyZonesEditor.Utils +{ + public class CustomLibraryThemeProvider : LibraryThemeProvider + { + public static readonly CustomLibraryThemeProvider DefaultInstance = new CustomLibraryThemeProvider(); + + public CustomLibraryThemeProvider() + : base(true) + { + } + + /// + public override void FillColorSchemeValues(Dictionary values, RuntimeThemeColorValues colorValues) + { + } + } +} diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/ThemeManager.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/ThemeManager.cs new file mode 100644 index 000000000000..2316d51712dd --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/ThemeManager.cs @@ -0,0 +1,200 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System; +using System.Linq; +using System.Windows; +using ControlzEx.Theming; +using Microsoft.Win32; + +namespace FancyZonesEditor.Utils +{ + public class ThemeManager : IDisposable + { + private readonly Application _app; + private const string LightTheme = "Light.Accent1"; + private const string DarkTheme = "Dark.Accent1"; + private const string HighContrastOneTheme = "HighContrast.Accent2"; + private const string HighContrastTwoTheme = "HighContrast.Accent3"; + private const string HighContrastBlackTheme = "HighContrast.Accent4"; + private const string HighContrastWhiteTheme = "HighContrast.Accent5"; + + private Theme currentTheme; + private bool _disposed; + + public event ThemeChangedHandler ThemeChanged; + + public ThemeManager(Application app) + { + _app = app; + + Uri highContrastOneThemeUri = new Uri("pack://application:,,,/Themes/HighContrast1.xaml"); + Uri highContrastTwoThemeUri = new Uri("pack://application:,,,/Themes/HighContrast2.xaml"); + Uri highContrastBlackThemeUri = new Uri("pack://application:,,,/Themes/HighContrastWhite.xaml"); + Uri highContrastWhiteThemeUri = new Uri("pack://application:,,,/Themes/HighContrastBlack.xaml"); + Uri lightThemeUri = new Uri("pack://application:,,,/Themes/Light.xaml"); + Uri darkThemeUri = new Uri("pack://application:,,,/Themes/Dark.xaml"); + + ControlzEx.Theming.ThemeManager.Current.AddLibraryTheme( + new LibraryTheme( + highContrastOneThemeUri, + CustomLibraryThemeProvider.DefaultInstance)); + ControlzEx.Theming.ThemeManager.Current.AddLibraryTheme( + new LibraryTheme( + highContrastTwoThemeUri, + CustomLibraryThemeProvider.DefaultInstance)); + ControlzEx.Theming.ThemeManager.Current.AddLibraryTheme( + new LibraryTheme( + highContrastBlackThemeUri, + CustomLibraryThemeProvider.DefaultInstance)); + ControlzEx.Theming.ThemeManager.Current.AddLibraryTheme( + new LibraryTheme( + highContrastWhiteThemeUri, + CustomLibraryThemeProvider.DefaultInstance)); + ControlzEx.Theming.ThemeManager.Current.AddLibraryTheme( + new LibraryTheme( + lightThemeUri, + CustomLibraryThemeProvider.DefaultInstance)); + ControlzEx.Theming.ThemeManager.Current.AddLibraryTheme( + new LibraryTheme( + darkThemeUri, + CustomLibraryThemeProvider.DefaultInstance)); + + ResetTheme(); + ControlzEx.Theming.ThemeManager.Current.ThemeSyncMode = ThemeSyncMode.SyncWithAppMode; + ControlzEx.Theming.ThemeManager.Current.ThemeChanged += Current_ThemeChanged; + SystemParameters.StaticPropertyChanged += SystemParameters_StaticPropertyChanged; + } + + private void SystemParameters_StaticPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(SystemParameters.HighContrast)) + { + ResetTheme(); + } + } + + public Theme GetCurrentTheme() + { + return currentTheme; + } + + private static Theme GetHighContrastBaseType() + { + string registryKey = @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes"; + string theme = (string)Registry.GetValue(registryKey, "CurrentTheme", string.Empty); + theme = theme.Split('\\').Last().Split('.').First().ToString(); + + switch (theme) + { + case "hc1": + return Theme.HighContrastOne; + case "hc2": + return Theme.HighContrastTwo; + case "hcwhite": + return Theme.HighContrastWhite; + case "hcblack": + return Theme.HighContrastBlack; + default: + return Theme.None; + } + } + + private void ResetTheme() + { + if (SystemParameters.HighContrast) + { + Theme highContrastBaseType = GetHighContrastBaseType(); + ChangeTheme(highContrastBaseType); + } + else + { + string baseColor = WindowsThemeHelper.GetWindowsBaseColor(); + ChangeTheme((Theme)Enum.Parse(typeof(Theme), baseColor)); + } + } + + private void ChangeTheme(Theme theme) + { + Theme oldTheme = currentTheme; + if (theme == currentTheme) + { + return; + } + + if (theme == Theme.HighContrastOne) + { + ControlzEx.Theming.ThemeManager.Current.ChangeTheme(_app, HighContrastOneTheme); + currentTheme = Theme.HighContrastOne; + } + else if (theme == Theme.HighContrastTwo) + { + ControlzEx.Theming.ThemeManager.Current.ChangeTheme(_app, HighContrastTwoTheme); + currentTheme = Theme.HighContrastTwo; + } + else if (theme == Theme.HighContrastWhite) + { + ControlzEx.Theming.ThemeManager.Current.ChangeTheme(_app, HighContrastWhiteTheme); + currentTheme = Theme.HighContrastWhite; + } + else if (theme == Theme.HighContrastBlack) + { + ControlzEx.Theming.ThemeManager.Current.ChangeTheme(_app, HighContrastBlackTheme); + currentTheme = Theme.HighContrastBlack; + } + else if (theme == Theme.Light) + { + ControlzEx.Theming.ThemeManager.Current.ChangeTheme(_app, LightTheme); + currentTheme = Theme.Light; + } + else if (theme == Theme.Dark) + { + ControlzEx.Theming.ThemeManager.Current.ChangeTheme(_app, DarkTheme); + currentTheme = Theme.Dark; + } + else + { + currentTheme = Theme.None; + } + + ThemeChanged?.Invoke(oldTheme, currentTheme); + } + + private void Current_ThemeChanged(object sender, ThemeChangedEventArgs e) + { + ResetTheme(); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + ControlzEx.Theming.ThemeManager.Current.ThemeChanged -= Current_ThemeChanged; + SystemParameters.StaticPropertyChanged -= SystemParameters_StaticPropertyChanged; + _disposed = true; + } + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } + + public delegate void ThemeChangedHandler(Theme oldTheme, Theme newTheme); + + public enum Theme + { + None, + Light, + Dark, + HighContrastOne, + HighContrastTwo, + HighContrastBlack, + HighContrastWhite, + } +} From 804c48a0eb90437a187e70c14724117476756a33 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 19 Nov 2020 22:51:47 +0100 Subject: [PATCH 02/38] Rmoved MahApps refs --- .../fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml | 1 - .../fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml | 1 - 2 files changed, 2 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml index a7eb95c12efb..d9f49fc06536 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml @@ -4,7 +4,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" xmlns:local="clr-namespace:FancyZonesEditor" xmlns:props="clr-namespace:FancyZonesEditor.Properties" mc:Ignorable="d" diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml index 5a35cf349b8a..7e06960abf6f 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml @@ -4,7 +4,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" xmlns:local="clr-namespace:FancyZonesEditor" xmlns:props="clr-namespace:FancyZonesEditor.Properties" mc:Ignorable="d" From da40a772b7571316a9d14aa3cff6297b56425304 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Fri, 20 Nov 2020 16:24:11 +0100 Subject: [PATCH 03/38] Removed MahApps --- installer/PowerToysSetup/Product.wxs | 1 - 1 file changed, 1 deletion(-) diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index bd976f35e845..33218dc41042 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -360,7 +360,6 @@ - From f6e8f69f4b085f22513a346c8ad9a460078b4c73 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sat, 21 Nov 2020 13:54:23 +0100 Subject: [PATCH 04/38] Updated canvas zones --- .../FancyZonesEditor/CanvasEditorWindow.xaml | 238 ++++++------------ .../editor/FancyZonesEditor/CanvasZone.xaml | 22 +- .../editor/FancyZonesEditor/MainWindow.xaml | 3 +- .../editor/FancyZonesEditor/Themes/Dark.xaml | 5 + .../Themes/HighContrast1.xaml | 3 + .../Themes/HighContrast2.xaml | 3 + .../Themes/HighContrastBlack.xaml | 3 + .../Themes/HighContrastWhite.xaml | 3 + .../editor/FancyZonesEditor/Themes/Light.xaml | 3 + .../Utils/FancyZonesEditorIO.cs | 65 +++-- 10 files changed, 156 insertions(+), 192 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml index d9f49fc06536..87d017d303e5 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml @@ -8,61 +8,16 @@ xmlns:props="clr-namespace:FancyZonesEditor.Properties" mc:Ignorable="d" Title="" - Width="528" + Width="536" + xmlns:ui="http://schemas.modernwpf.com/2019" + ui:WindowHelper.UseModernWindowStyle="True" SizeToContent="Height" - Background="White" + Background="{DynamicResource PrimaryBackgroundBrush}" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" Closed="OnClosed"> - - - - - - - - - - - - - - - - + --> + + + + + + + + + + - - + + - - + + + + + + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml index 7e06960abf6f..4538276adf45 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml @@ -9,176 +9,53 @@ mc:Ignorable="d" Title="" Width="528" + xmlns:ui="http://schemas.modernwpf.com/2019" + ui:WindowHelper.UseModernWindowStyle="True" SizeToContent="Height" - Background="White" + Background="{DynamicResource PrimaryBackgroundBrush}" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" Closed="OnClosed"> - - - - - - - - - - - - - - - + + + + + + - - - + - - - + + + + + - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + Foreground="{DynamicResource PrimaryForegroundBrush}" /> + - + + + + + + + + + - + + + + + + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/WindowLayout.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/WindowLayout.xaml index 3d6698fe4f8b..15940b9f5293 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/WindowLayout.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/WindowLayout.xaml @@ -17,7 +17,7 @@ - + From b64c5de71d9e08714d117e1143fe8af64641a95c Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sat, 21 Nov 2020 23:26:51 +0100 Subject: [PATCH 08/38] New layout type selection dialog --- .../editor/FancyZonesEditor/App.xaml | 1 + .../FancyZonesEditor/FancyZonesEditor.csproj | 4 + .../editor/FancyZonesEditor/MainWindow.xaml | 153 ++++++++++++------ .../FancyZonesEditor/MainWindow.xaml.cs | 46 ++++++ .../Models/MainWindowSettingsModel.cs | 4 - .../FancyZonesEditor/Styles/ButtonStyles.xaml | 97 +++++++++++ 6 files changed, 248 insertions(+), 57 deletions(-) create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml index 89c98f9184c9..544b74e064ef 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml @@ -9,6 +9,7 @@ + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj index 1a500ba835e9..dae44b04cce4 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj +++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj @@ -156,6 +156,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 2a720825f699..da4867d0c53d 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -41,7 +41,7 @@ - + - + - + - + + @@ -120,13 +121,13 @@ FontSize="12" Foreground="{DynamicResource PrimaryForegroundBrush}" Margin="16,-24,0,0" /> - + - + - - + + @@ -162,7 +163,7 @@ - + - - - - - + + + + + + + - - - - - + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index 181b627e8809..f0fd07c78a91 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -123,6 +124,12 @@ private void Select(LayoutModel newSelection) App.Overlay.CurrentDataContext = newSelection; } + private async void NewLayoutButton_Click(object sender, RoutedEventArgs e) + { + GridLayoutRadioButton.IsChecked = true; + await NewLayoutDialog.ShowAsync(); + } + private void EditLayout_Click(object sender, RoutedEventArgs e) { var mainEditor = App.Overlay; @@ -265,5 +272,44 @@ private void Reset_Click(object sender, RoutedEventArgs e) Close(); } } + + private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog sender, ModernWpf.Controls.ContentDialogButtonClickEventArgs args) + { + LayoutModel selectedLayoutModel; + + if (GridLayoutRadioButton.IsChecked == true) + { + // 1:1 Copy from MainWindowSettingsModel + int multiplier = 10000; + int zoneCount = 3; + + GridLayoutModel columnsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Columns, LayoutType.Columns) + { + Rows = 1, + RowPercents = new List(1) { multiplier }, + }; + + columnsModel.CellChildMap = new int[1, zoneCount]; + columnsModel.Columns = zoneCount; + columnsModel.ColumnPercents = new List(zoneCount); + + for (int i = 0; i < 3; i++) + { + columnsModel.CellChildMap[0, i] = i; + columnsModel.ColumnPercents.Add(((multiplier * (i + 1)) / zoneCount) - ((multiplier * i) / zoneCount)); + } + + selectedLayoutModel = columnsModel; + } + else + { + selectedLayoutModel = new CanvasLayoutModel(Properties.Resources.Custom_Layout_Create_New, LayoutType.Blank); + } + + App.Overlay.CurrentDataContext = selectedLayoutModel; + var mainEditor = App.Overlay; + Hide(); + mainEditor.OpenEditor(selectedLayoutModel); + } } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs index c48b371d56dd..d628367688bd 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs @@ -25,7 +25,6 @@ private enum DeviceIdParts VirtualDesktopId, } - private static CanvasLayoutModel _blankCustomModel; private readonly CanvasLayoutModel _focusModel; private readonly GridLayoutModel _rowsModel; private readonly GridLayoutModel _columnsModel; @@ -105,8 +104,6 @@ public MainWindowSettingsModel() _priorityGridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Priority_Grid, LayoutType.PriorityGrid); DefaultModels.Add(_priorityGridModel); - _blankCustomModel = new CanvasLayoutModel(Properties.Resources.Custom_Layout_Create_New, LayoutType.Blank); - UpdateTemplateLayoutModels(); } @@ -350,7 +347,6 @@ public static ObservableCollection CustomModels if (_customModels == null) { _customModels = LayoutModel.LoadCustomModels(); - _customModels.Insert(0, _blankCustomModel); } return _customModels; diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml new file mode 100644 index 000000000000..56fd29472c21 --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml @@ -0,0 +1,97 @@ + + + + \ No newline at end of file From 71905c51cd61d5a70d05f7ed527bd3938a341708 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sun, 22 Nov 2020 19:28:52 +0100 Subject: [PATCH 09/38] New editor UI --- .../BooleanToBrushConverter.xaml.cs | 5 +- .../FancyZonesEditor/LayoutPreview.xaml | 1 + .../FancyZonesEditor/LayoutPreview.xaml.cs | 28 +++- .../editor/FancyZonesEditor/MainWindow.xaml | 120 ++++++++++-------- .../FancyZonesEditor/MainWindow.xaml.cs | 65 +++++++++- .../editor/FancyZonesEditor/Overlay.cs | 6 +- .../editor/FancyZonesEditor/Themes/Dark.xaml | 6 +- .../Themes/HighContrast1.xaml | 2 +- .../Themes/HighContrast2.xaml | 2 +- .../Themes/HighContrastBlack.xaml | 2 +- .../Themes/HighContrastWhite.xaml | 2 +- .../editor/FancyZonesEditor/Themes/Light.xaml | 4 +- 12 files changed, 174 insertions(+), 69 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/BooleanToBrushConverter.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/BooleanToBrushConverter.xaml.cs index 3443c0480991..baf01812ab04 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/BooleanToBrushConverter.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/BooleanToBrushConverter.xaml.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Windows; using System.Windows.Data; using System.Windows.Media; @@ -10,8 +11,8 @@ namespace FancyZonesEditor.Converters { public class BooleanToBrushConverter : IValueConverter { - private static readonly Brush _selectedBrush = new SolidColorBrush(Color.FromRgb(0x00, 0x78, 0xD7)); - private static readonly Brush _normalBrush = new SolidColorBrush(Color.FromRgb(0xF2, 0xF2, 0xF2)); + private static readonly Brush _selectedBrush = Application.Current.FindResource("SystemControlBackgroundAccentBrush") as SolidColorBrush; + private static readonly Brush _normalBrush = Application.Current.FindResource("LayoutItemBackgroundBrush") as SolidColorBrush; public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml index e871f7935be5..c77481414cae 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:FancyZonesEditor" + mc:Ignorable="d" Loaded="OnLoaded" d:DesignHeight="450" d:DesignWidth="800"> diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs index 0ff7585fc7b0..752aed787e58 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs @@ -22,9 +22,13 @@ public partial class LayoutPreview : UserControl private const string PropertyZoneCountID = "ZoneCount"; private const string PropertyShowSpacingID = "ShowSpacing"; private const string PropertySpacingID = "Spacing"; + private const string PropertyZoneBackgroundID = "ZoneBackground"; + private const string PropertyZoneBorderID = "ZoneBorder"; private const string ObjectDependencyID = "IsActualSize"; public static readonly DependencyProperty IsActualSizeProperty = DependencyProperty.Register(ObjectDependencyID, typeof(bool), typeof(LayoutPreview), new PropertyMetadata(false)); + public static readonly DependencyProperty ZoneBackgroundProperty = DependencyProperty.Register(PropertyZoneBackgroundID, typeof(SolidColorBrush), typeof(LayoutPreview), new PropertyMetadata(Brushes.LightGray)); + public static readonly DependencyProperty ZoneBorderProperty = DependencyProperty.Register(PropertyZoneBorderID, typeof(SolidColorBrush), typeof(LayoutPreview), new PropertyMetadata(Brushes.DarkGray)); private LayoutModel _model; private List _zones = new List(); @@ -35,6 +39,18 @@ public bool IsActualSize set { SetValue(IsActualSizeProperty, value); } } + public SolidColorBrush ZoneBackground + { + get { return (SolidColorBrush)GetValue(ZoneBackgroundProperty); } + set { SetValue(ZoneBackgroundProperty, value); } + } + + public SolidColorBrush ZoneBorder + { + get { return (SolidColorBrush)GetValue(ZoneBorderProperty); } + set { SetValue(ZoneBorderProperty, value); } + } + public LayoutPreview() { InitializeComponent(); @@ -178,8 +194,8 @@ private void RenderActualScalePreview(GridLayoutModel grid) rect.Width = Math.Max(0, colInfo[maxCol].End - left); rect.Height = Math.Max(0, rowInfo[maxRow].End - top); rect.StrokeThickness = 1; - rect.Stroke = Brushes.DarkGray; - rect.Fill = Brushes.LightGray; + rect.Stroke = ZoneBorder; + rect.Fill = ZoneBackground; frame.Children.Add(rect); _zones.Add(new Int32Rect( (int)left, (int)top, (int)rect.Width, (int)rect.Height)); @@ -254,8 +270,8 @@ private void RenderSmallScalePreview(GridLayoutModel grid) rect.Margin = margin; rect.StrokeThickness = 1; - rect.Stroke = Brushes.DarkGray; - rect.Fill = Brushes.LightGray; + rect.Stroke = ZoneBorder; + rect.Fill = ZoneBackground; Body.Children.Add(rect); } } @@ -302,8 +318,8 @@ private void RenderCanvasPreview(CanvasLayoutModel canvas) rect.MinWidth = zone.Width; rect.MinHeight = zone.Height; rect.StrokeThickness = 5; - rect.Stroke = Brushes.DarkGray; - rect.Fill = Brushes.LightGray; + rect.Stroke = ZoneBorder; + rect.Fill = ZoneBackground; frame.Children.Add(rect); } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index da4867d0c53d..26095819ade1 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -16,6 +16,7 @@ mc:Ignorable="d" Title="" Width="1000" + ContentRendered="MainWindow1_ContentRendered" SizeToContent="Height" Background="{DynamicResource SecondaryBackgroundBrush}" ResizeMode="NoResize" @@ -164,45 +165,43 @@ - - - - - - - + + + + + @@ -290,7 +313,12 @@ KeyDown="LayoutItem_Apply"> - + + + + + + @@ -306,10 +334,12 @@ - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + Margin="32,8,16,8" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - + - + - + - + - - + + + - - - - + - + + + + + + + + + + + + + + + + + + + ItemTemplate="{StaticResource LayoutItemTemplate}" + Margin="8,8,0,0"> - - - - - - - - - - - - - - - - - - - - - - - - + @@ -384,7 +325,7 @@ @@ -397,15 +338,82 @@ + + + + + + + + PrimaryButtonClick="NewLayoutDialog_PrimaryButtonClick" + d:IsHidden="True"> @@ -457,7 +465,7 @@ diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs index e9ee173e4d79..ef62739d5384 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs @@ -358,7 +358,7 @@ public static string Reset_Layout { } /// - /// Looks up a localized string similar to Save and apply. + /// Looks up a localized string similar to Save & apply. /// public static string Save_Apply { get { diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx index 20203c17cf41..d49f3ad78311 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx @@ -169,7 +169,7 @@ Note: Hold down Shift Key to change orientation of splitter. To merge zones, select the zones and click "merge". - Save and apply + Save & apply Show space around zones diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml index cee76f4941a2..7ab4e1faaede 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml @@ -19,6 +19,8 @@ + + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml index a726d7e129bd..ca5d6dc99b1a 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml @@ -16,6 +16,8 @@ + + From 08c4c36af05c9ffc87745aa1a2f177e3ca1e3e80 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Fri, 27 Nov 2020 19:10:00 +0100 Subject: [PATCH 13/38] Updated UI --- .../editor/FancyZonesEditor/App.xaml | 6 +- .../editor/FancyZonesEditor/GridZone.xaml | 2 +- .../FancyZonesEditor/LayoutPreview.xaml | 5 +- .../FancyZonesEditor/LayoutPreview.xaml.cs | 4 +- .../editor/FancyZonesEditor/MainWindow.xaml | 65 ++++++++++++------- .../FancyZonesEditor/MainWindow.xaml.cs | 28 ++++++++ .../editor/FancyZonesEditor/Overlay.cs | 7 +- .../editor/FancyZonesEditor/Themes/Dark.xaml | 5 +- .../editor/FancyZonesEditor/Themes/Light.xaml | 2 + .../editor/FancyZonesEditor/WindowLayout.xaml | 4 +- 10 files changed, 88 insertions(+), 40 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml index 544b74e064ef..61194d16dd45 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml @@ -9,12 +9,8 @@ - + - - - - diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml index 96082699ec81..63ec7b7111c9 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml @@ -10,7 +10,7 @@ Background="{DynamicResource GridZoneBackgroundBrush}" BorderBrush="{DynamicResource SystemControlBackgroundAccentBrush}" BorderThickness="1" - Opacity="0.8" + Opacity="1" mc:Ignorable="d"> diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml index 4fc659b996a1..8947008d8d96 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml @@ -8,7 +8,6 @@ Loaded="OnLoaded" d:DesignHeight="450" d:DesignWidth="800"> - - - + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs index 752aed787e58..4260245779d1 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs @@ -27,8 +27,8 @@ public partial class LayoutPreview : UserControl private const string ObjectDependencyID = "IsActualSize"; public static readonly DependencyProperty IsActualSizeProperty = DependencyProperty.Register(ObjectDependencyID, typeof(bool), typeof(LayoutPreview), new PropertyMetadata(false)); - public static readonly DependencyProperty ZoneBackgroundProperty = DependencyProperty.Register(PropertyZoneBackgroundID, typeof(SolidColorBrush), typeof(LayoutPreview), new PropertyMetadata(Brushes.LightGray)); - public static readonly DependencyProperty ZoneBorderProperty = DependencyProperty.Register(PropertyZoneBorderID, typeof(SolidColorBrush), typeof(LayoutPreview), new PropertyMetadata(Brushes.DarkGray)); + public static readonly DependencyProperty ZoneBackgroundProperty = DependencyProperty.Register(PropertyZoneBackgroundID, typeof(SolidColorBrush), typeof(LayoutPreview), new PropertyMetadata(Brushes.Red)); + public static readonly DependencyProperty ZoneBorderProperty = DependencyProperty.Register(PropertyZoneBorderID, typeof(SolidColorBrush), typeof(LayoutPreview), new PropertyMetadata(Brushes.Red)); private LayoutModel _model; private List _zones = new List(); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 24e2c8ea6156..f6d0838a50ed 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -27,6 +27,19 @@ Initialized="OnInitialized" Closing="OnClosing"> + + + @@ -111,7 +124,7 @@ - + @@ -126,16 +139,18 @@ - + CornerRadius="4" + Margin="8" + FocusVisualStyle="{StaticResource MyFocusVisualStyle}" + FocusManager.GotFocus="LayoutItem_Focused" + KeyDown="LayoutItem_Apply"> @@ -167,7 +182,8 @@ - + @@ -204,8 +220,9 @@ + ItemTemplate="{StaticResource LayoutItemTemplate}" + TabIndex="1" + Margin="8,8,0,0"> - @@ -318,7 +337,8 @@ - @@ -339,16 +359,14 @@ - + - - - - - - - - diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml index 4538276adf45..07a351a47528 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml @@ -1,22 +1,22 @@  - + AutomationProperties.Name="{x:Static props:Resources.Grid_Layout_Editor}" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:local="clr-namespace:FancyZonesEditor" + xmlns:props="clr-namespace:FancyZonesEditor.Properties" + mc:Ignorable="d" + Title="" + Width="386" + xmlns:ui="http://schemas.modernwpf.com/2019" + ui:WindowHelper.UseModernWindowStyle="True" + SizeToContent="Height" + Background="{DynamicResource PrimaryBackgroundBrush}" + ResizeMode="NoResize" + ContentRendered="OnContentRendered" + WindowStartupLocation="CenterOwner" + Closed="OnClosed"> - - @@ -73,11 +64,11 @@ - + @@ -324,136 +365,155 @@ - - - - - - - - - - - - - - - - - - + + + + + + + - + ToolTip="{x:Static props:Resources.Reset_Layout}" + AutomationProperties.Name="{x:Static props:Resources.Reset_Layout}" + Foreground="{DynamicResource PrimaryForegroundBrush}" + Margin="8,0,0,0" + Background="Transparent" + Click="Reset_Click" /> + + + - + - - + - - + + @@ -462,11 +522,11 @@ + Text="{x:Static props:Resources.Layout_Grid_Title}" /> + Text="{x:Static props:Resources.Layout_Grid_Description}" + Foreground="{DynamicResource SecondaryForegroundBrush}" /> @@ -475,18 +535,20 @@ - - + + @@ -495,11 +557,11 @@ + Text="{x:Static props:Resources.Layout_Canvas_Title}" /> + Text="{x:Static props:Resources.Layout_Canvas_Description}" + Foreground="{DynamicResource SecondaryForegroundBrush}" /> @@ -507,4 +569,4 @@ - + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index c743b9dab3a1..4a5c98c04766 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -161,6 +161,7 @@ private void Select(LayoutModel newSelection) private async void NewLayoutButton_Click(object sender, RoutedEventArgs e) { GridLayoutRadioButton.IsChecked = true; + GridLayoutRadioButton.Focus(); await NewLayoutDialog.ShowAsync(); } @@ -173,8 +174,8 @@ private void DuplicateLayout_Click(object sender, RoutedEventArgs e) } model.IsSelected = false; - Hide(); + Hide(); bool isPredefinedLayout = MainWindowSettingsModel.IsPredefinedLayout(model); if (!MainWindowSettingsModel.CustomModels.Contains(model) || isPredefinedLayout) @@ -360,7 +361,8 @@ private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog mainEditor.OpenEditor(selectedLayoutModel); } - private void MainWindow1_ContentRendered(object sender, EventArgs e) + // This is required to fix a WPF rendering bug when using custom chrome + private void OnContentRendered(object sender, EventArgs e) { InvalidateVisual(); } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs index ef62739d5384..ab046b71c5cc 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs @@ -105,6 +105,15 @@ public static string Choose_Layout { } } + /// + /// Looks up a localized string similar to Choose layout type. + /// + public static string Choose_layout_type { + get { + return ResourceManager.GetString("Choose_layout_type", resourceCulture); + } + } + /// /// Looks up a localized string similar to Close. /// @@ -132,6 +141,24 @@ public static string Crash_Report_Message_Box_Text_Part2 { } } + /// + /// Looks up a localized string similar to Create. + /// + public static string Create { + get { + return ResourceManager.GetString("Create", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new layout. + /// + public static string Create_new_layout { + get { + return ResourceManager.GetString("Create_new_layout", resourceCulture); + } + } + /// /// Looks up a localized string similar to Custom. /// @@ -177,6 +204,15 @@ public static string Custom_Table_Layout { } } + /// + /// Looks up a localized string similar to Delete. + /// + public static string Delete { + get { + return ResourceManager.GetString("Delete", resourceCulture); + } + } + /// /// Looks up a localized string similar to Distance to highlight adjacent zones. /// @@ -186,6 +222,24 @@ public static string Distance_adjacent_zones { } } + /// + /// Looks up a localized string similar to Duplicate. + /// + public static string Duplicate { + get { + return ResourceManager.GetString("Duplicate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit. + /// + public static string Edit { + get { + return ResourceManager.GetString("Edit", resourceCulture); + } + } + /// /// Looks up a localized string similar to Edit selected layout. /// @@ -330,6 +384,60 @@ public static string Grid_Layout_Editor { } } + /// + /// Looks up a localized string similar to Create layouts that have overlapping zones. + /// + public static string Layout_Canvas_Description { + get { + return ResourceManager.GetString("Layout_Canvas_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Canvas. + /// + public static string Layout_Canvas_Title { + get { + return ResourceManager.GetString("Layout_Canvas_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create layouts that are horizontally or vertically stacked. + /// + public static string Layout_Grid_Description { + get { + return ResourceManager.GetString("Layout_Grid_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Grid. + /// + public static string Layout_Grid_Title { + get { + return ResourceManager.GetString("Layout_Grid_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Merge zones. + /// + public static string Merge_zones { + get { + return ResourceManager.GetString("Merge_zones", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Monitor. + /// + public static string Monitor { + get { + return ResourceManager.GetString("Monitor", resourceCulture); + } + } + /// /// Looks up a localized string similar to Name. /// @@ -340,7 +448,8 @@ public static string Name { } /// - /// Looks up a localized string similar to Note: Hold down Shift Key to change orientation of splitter. To merge zones, select the zones and click "merge".. + /// Looks up a localized string similar to Hold down Shift Key to change orientation of splitter. + ///To merge zones, select the zones and click "merge".. /// public static string Note_Custom_Table { get { @@ -367,38 +476,29 @@ public static string Save_Apply { } /// - /// Looks up a localized string similar to Show space around zones. - /// - public static string Show_Space_Zones { - get { - return ResourceManager.GetString("Show_Space_Zones", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Space around zones. + /// Looks up a localized string similar to Settings. /// - public static string Space_Around_Zones { + public static string Settings { get { - return ResourceManager.GetString("Space_Around_Zones", resourceCulture); + return ResourceManager.GetString("Settings", resourceCulture); } } /// - /// Looks up a localized string similar to Custom tab selected, press ctrl + tab to switch to Templates. + /// Looks up a localized string similar to Show space around zones. /// - public static string Tab_Item_Custom { + public static string Show_Space_Zones { get { - return ResourceManager.GetString("Tab_Item_Custom", resourceCulture); + return ResourceManager.GetString("Show_Space_Zones", resourceCulture); } } /// - /// Looks up a localized string similar to Templates tab selected, press ctrl + tab to switch to Custom. + /// Looks up a localized string similar to Space around zones. /// - public static string Tab_Item_Templates { + public static string Space_Around_Zones { get { - return ResourceManager.GetString("Tab_Item_Templates", resourceCulture); + return ResourceManager.GetString("Space_Around_Zones", resourceCulture); } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx index d49f3ad78311..c17acda0273b 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx @@ -132,9 +132,6 @@ Grid layout editor - - Choose your layout for this desktop - Error logged to @@ -166,7 +163,8 @@ Name - Note: Hold down Shift Key to change orientation of splitter. To merge zones, select the zones and click "merge". + Hold down Shift Key to change orientation of splitter. +To merge zones, select the zones and click "merge". Save & apply @@ -189,10 +187,6 @@ Delete custom layout - - Create new custom - As in Create new custom layout - FancyZones Editor arguments are invalid. @@ -220,12 +214,6 @@ Rows - - Custom tab selected, press ctrl + tab to switch to Templates - - - Templates tab selected, press ctrl + tab to switch to Custom - Close @@ -257,4 +245,56 @@ Reset layout as in Reset to a blank value + + Choose your layout for this desktop + + + Choose layout type + Dialog header that allows the user to select a specific layout type + + + Create + Button label that creates a new layout + + + Create new layout + Button label that allows the user to create a new layout + + + Create new custom + + + Delete + Context menu label that allows the user duplicate a layout + + + Duplicate + Context menu label that allows the user duplicate a layout + + + Edit + Context menu label that allows the user edit a layout + + + Create layouts that have overlapping zones + + + Canvas + + + Create layouts that are horizontally or vertically stacked + + + Grid + + + Merge zones + Button label that allows the user to merge 2 or more zones together + + + Monitor + + + Settings + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml index 56fd29472c21..a0d8b7e1d484 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml @@ -25,21 +25,19 @@ - - + @@ -48,35 +46,33 @@ - + CornerRadius="2" + BorderThickness="2" + BorderBrush="{DynamicResource SystemControlBackgroundAccentBrush}" /> - + - - - + + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml index a423712d247c..95893aea5843 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml @@ -11,7 +11,7 @@ Black - + @@ -32,7 +32,7 @@ - + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml index 827093199213..df23e471d383 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml @@ -12,7 +12,7 @@ - + @@ -33,5 +33,7 @@ - + + + \ No newline at end of file From 1d070f44e95c88f30df9abec54b83249bdbb26d2 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sun, 29 Nov 2020 22:33:03 +0100 Subject: [PATCH 16/38] Accesibility and styling improvements --- .../editor/FancyZonesEditor/MainWindow.xaml | 214 ++++++++---------- .../FancyZonesEditor/MainWindow.xaml.cs | 23 +- .../Properties/Resources.Designer.cs | 15 +- .../Properties/Resources.resx | 9 +- 4 files changed, 113 insertions(+), 148 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 81343d9b290e..b8b87c4b7f14 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -10,6 +10,7 @@ xmlns:props="clr-namespace:FancyZonesEditor.Properties" xmlns:local1="clr-namespace:FancyZonesEditor.ViewModels" xmlns:ui="http://schemas.modernwpf.com/2019" + xmlns:i="http://schemas.microsoft.com/xaml/behaviors" ui:WindowHelper.UseModernWindowStyle="True" ui:TitleBar.IsIconVisible="True" ui:TitleBar.Background="{DynamicResource SecondaryBackgroundBrush}" @@ -27,8 +28,7 @@ Initialized="OnInitialized" Closing="OnClosing"> - - - - - - - - - - - - - - - @@ -167,12 +76,75 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + - - + VerticalAlignment="Center" + Foreground="{DynamicResource PrimaryForegroundBrush}" /> + + + Value="{DynamicResource SystemAccentColorLight1Brush}" /> @@ -258,8 +228,8 @@ @@ -267,11 +237,12 @@ @@ -286,6 +257,7 @@ HorizontalAlignment="Center" FontFamily="Segoe MDL2 Assets" Style="{StaticResource DefaultButtonStyle}" + ToolTip="{x:Static props:Resources.Zone_Count_Increment}" AutomationProperties.Name="{x:Static props:Resources.Zone_Count_Increment}" Click="IncrementZones_Click" /> @@ -309,6 +281,7 @@ HorizontalAlignment="Center" Background="Transparent" FontFamily="Segoe MDL2 Assets" + ToolTip="{x:Static props:Resources.Zone_Count_Decrement}" AutomationProperties.Name="{x:Static props:Resources.Zone_Count_Decrement}" Style="{StaticResource DefaultButtonStyle}" Click="DecrementZones_Click" /> @@ -319,7 +292,7 @@ + + @@ -222,6 +263,7 @@ ItemTemplate="{StaticResource LayoutItemTemplate}" AutomationProperties.LabeledBy="{Binding ElementName=TemplatesHeaderBlock}" TabIndex="1" + x:Name="DefaultModelsItemsControl" Margin="8,8,8,0"> @@ -233,9 +275,7 @@ @@ -318,9 +358,9 @@ Margin="8,8,0,0"> - @@ -371,58 +411,10 @@ - - + Background="{DynamicResource TertiaryBackgroundBrush}"> + - - - /// Looks up a localized string similar to Settings. + /// Looks up a localized string similar to Template settings. /// public static string Settings { get { diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx index 3efe20f4d683..67786a42f562 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx @@ -292,6 +292,6 @@ To merge zones, select the zones and click "merge". Monitor - Settings + Template settings \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Styles/LayoutPreviewStyles.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Styles/LayoutPreviewStyles.xaml new file mode 100644 index 000000000000..c80b6819ddb6 --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Styles/LayoutPreviewStyles.xaml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml index 95893aea5843..ab06f4797917 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml @@ -10,29 +10,18 @@ Accent1 Black - - - - - - - - - - - - - - + + - + + + + + - - - - + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml index 05eb0357a0d7..fc4276513921 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml @@ -10,19 +10,19 @@ Accent2 White - - - - - - - - - + + + + + + + + + + + + - - - \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml index 09c71dc57ba4..a3b4bd2e0556 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml @@ -10,19 +10,18 @@ Accent3 White - - - - - - - - - - - + + + + - - - + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml index d266b9abf336..ac7df737b1b6 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml @@ -10,19 +10,18 @@ Accent4 White - - - - - - - - - - + + + - - - + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml index bda1377de11a..7a56034edc91 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml @@ -12,11 +12,9 @@ - + - - diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml index df23e471d383..758792c24e2c 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml @@ -10,30 +10,18 @@ Accent1 White - - - - - - - - - - - - - - - - - - + + - + + + + + + + - - - + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/images/ChromeClose.png b/src/modules/fancyzones/editor/FancyZonesEditor/images/ChromeClose.png deleted file mode 100644 index 11dd67a2d7e2aff4c481dcaca508bd9a0c6521ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 434 zcmV;j0ZsmiP)pf$#fvd+t#_ zP{Z-{#7#MeKnITH?L@XA(0}>5m9v7Yhd`Zf-GzamL8svcN0@b)ZZw2dhvfwpz$)8p zp#iYYL~%plm4*C=z&iuS02K5u;}C>`?=uVoQT#)~EZAa=C0Gzx={1E3k(nM>P`}Vf zZ7Aqmtf%Hu(6L}@`3h=_rkAgvz9CY|SJ3eg=JH?q@C(}b5<(l_#AxHkDBAc%hBp3` zKpTI|u^_V2YXSxW7Hdp_VK53F0*62pGz5-8$ax6l|105@f#R-Hth10}Z!*hFvxO#L zHG6ph1DJJ~ZghZAm*Iv0P^VLO;RT=$x1yZ#71SQ0vo3OaFo94N{u cUqNqF@ul zJ}dTuUPxc~??3Cb)y!)f*2YU1tP9;g%PGfwwZnDM#ZDiqOH01tbFyC@|t;E*v zz9t~PFC$iBi+;6n&;28Z%X$`s+g{L^t5M06VDjH- oxv*}gz<=ovYmV7+&Hm3M_nT9KF^4f)?}^0Nc(*4@s!EbhIj>T16I zx^fEvhx-|}qUxy?G-HlS+Kc$>;;hrKb!__@{)$>B!rth!F(lS*0 z-KW*Q(j^o{S1-f%>%OX9aV7udZ+$PhcsAsaZp{HM!*@!|Ik!&f0o~2u>FVdQ&MBb@ E0N83_t^fc4 From 463728d59f56d8b69c52e2f6222df3b635ad78b6 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Mon, 7 Dec 2020 22:25:21 +0100 Subject: [PATCH 19/38] Updated UX --- .../FancyZonesEditor/CanvasEditorWindow.xaml | 50 +- .../CanvasEditorWindow.xaml.cs | 6 - .../FancyZonesEditor/GridEditorWindow.xaml | 31 +- .../FancyZonesEditor/GridEditorWindow.xaml.cs | 16 - .../editor/FancyZonesEditor/GridResizer.xaml | 30 +- .../FancyZonesEditor/GridResizer.xaml.cs | 2 +- .../editor/FancyZonesEditor/MainWindow.xaml | 469 ++++++++++-------- .../FancyZonesEditor/MainWindow.xaml.cs | 86 +--- .../editor/FancyZonesEditor/Overlay.cs | 8 +- .../Properties/Resources.Designer.cs | 42 +- .../Properties/Resources.resx | 16 +- .../editor/FancyZonesEditor/Themes/Dark.xaml | 2 +- .../ViewModels/MonitorViewModel.cs | 2 +- 13 files changed, 375 insertions(+), 385 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml index db50a5c0ac8c..b67db3647059 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml @@ -8,13 +8,13 @@ xmlns:props="clr-namespace:FancyZonesEditor.Properties" mc:Ignorable="d" Title="" - Width="386" + Width="320" + BorderThickness="0" xmlns:ui="http://schemas.modernwpf.com/2019" ui:WindowHelper.UseModernWindowStyle="True" SizeToContent="Height" Background="{DynamicResource PrimaryBackgroundBrush}" ResizeMode="NoResize" - ContentRendered="OnContentRendered" WindowStartupLocation="CenterOwner" Closed="OnClosed"> @@ -23,6 +23,13 @@ Margin="0,-36,0,0" VerticalAlignment="Top" HorizontalAlignment="Stretch"> + - - - - - + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml.cs index b4d403efb994..7b07a97669e4 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml.cs @@ -58,11 +58,5 @@ private void CanvasEditorWindow_KeyUp(object sender, KeyEventArgs e) OnCancel(sender, null); } } - - // This is required to fix a WPF rendering bug when using custom chrome - private void OnContentRendered(object sender, EventArgs e) - { - InvalidateVisual(); - } } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml index 07a351a47528..ead7dd2ee8c1 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml @@ -8,13 +8,13 @@ xmlns:props="clr-namespace:FancyZonesEditor.Properties" mc:Ignorable="d" Title="" - Width="386" + Width="320" + BorderThickness="0" xmlns:ui="http://schemas.modernwpf.com/2019" ui:WindowHelper.UseModernWindowStyle="True" SizeToContent="Height" Background="{DynamicResource PrimaryBackgroundBrush}" ResizeMode="NoResize" - ContentRendered="OnContentRendered" WindowStartupLocation="CenterOwner" Closed="OnClosed"> @@ -24,6 +24,13 @@ Margin="0,-36,0,0" VerticalAlignment="Top" HorizontalAlignment="Stretch"> + - - - - - - - + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml.cs index b7502ee9e904..b624e7243dac 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml.cs @@ -40,21 +40,5 @@ private void GridEditorWindow_KeyUp(object sender, KeyEventArgs e) } private GridLayoutModel _stashedModel; - - private void NameTextBox_GotFocus(object sender, RoutedEventArgs e) - { - customLayoutNameTextBox.CaretIndex = customLayoutNameTextBox.Text.Length; - } - - public System.Windows.Controls.TextBox NameTextBox() - { - return customLayoutNameTextBox; - } - - // This is required to fix a WPF rendering bug when using custom chrome - private void OnContentRendered(object sender, EventArgs e) - { - InvalidateVisual(); - } } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml index 86e030482883..de499119fc4a 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml @@ -8,14 +8,32 @@ d:DesignHeight="300" d:DesignWidth="300"> - - - - - + + + + + + + + + - + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml.cs index 787d921ef200..333610070fc9 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml.cs @@ -45,7 +45,7 @@ public Orientation Orientation { _orientation = value; ApplyTemplate(); - StackPanel body = (StackPanel)Template.FindName("Body", this); + Border body = (Border)Template.FindName("Body", this); if (value == Orientation.Vertical) { body.RenderTransform = null; diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 8bebcc2d9ec1..3f7f2da9866c 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -11,58 +11,27 @@ xmlns:local1="clr-namespace:FancyZonesEditor.ViewModels" xmlns:ui="http://schemas.modernwpf.com/2019" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" + mc:Ignorable="d" + Title="FancyZones Editor" ui:WindowHelper.UseModernWindowStyle="True" ui:TitleBar.IsIconVisible="True" ui:TitleBar.Background="{DynamicResource SecondaryBackgroundBrush}" ui:TitleBar.InactiveBackground="{DynamicResource SecondaryBackgroundBrush}" - mc:Ignorable="d" - Title="" - MinWidth="1000" + Width="1000" + Height="840" MaxWidth="1000" - MinHeight="800" - MaxHeight="800" + MaxHeight="840" + MinHeight="840" + MinWidth="1000" + WindowStartupLocation="CenterOwner" ContentRendered="OnContentRendered" Background="{DynamicResource PrimaryBackgroundBrush}" - ResizeMode="NoResize" - WindowStartupLocation="CenterOwner" - Initialized="OnInitialized" - Closing="OnClosing"> + Closing="OnClosing" + ResizeMode="NoResize"> - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -83,26 +52,26 @@ Opacity="0.24" ShadowDepth="1" /> - - - - - + + + + + + + + + + + + - + @@ -122,24 +89,26 @@ - + - + + FocusManager.GotFocus="LayoutItem_Focused"> + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + @@ -190,105 +285,54 @@ + + + + + + + + + + + + + + + + - + Margin="0,0,0,0"> + - - - - - - - - - - - - - - - - - - - - + @@ -440,6 +466,7 @@ HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.RowSpan="3" + Background="{DynamicResource PrimaryBackgroundBrush}" PrimaryButtonStyle="{StaticResource AccentButtonStyle}" SecondaryButtonText="{x:Static props:Resources.Cancel}" PrimaryButtonText="{x:Static props:Resources.Create}" @@ -448,8 +475,14 @@ + + (1) { multiplier }, @@ -347,7 +304,7 @@ private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog } else { - selectedLayoutModel = new CanvasLayoutModel(Properties.Resources.Custom_Layout_Create_New, LayoutType.Blank); + selectedLayoutModel = new CanvasLayoutModel(LayoutNameText.Text, LayoutType.Blank); } App.Overlay.CurrentDataContext = selectedLayoutModel; @@ -374,5 +331,10 @@ private void MonitorItem_MouseDown(object sender, MouseButtonEventArgs e) { monitorViewModel.SelectCommand.Execute((MonitorInfoModel)(sender as Border).DataContext); } + + private void LayoutItem_MouseLeave(object sender, MouseEventArgs e) + { + // TO DO: reset back to the applied layout + } } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs index 14fff432c693..72edf0f0147e 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs @@ -217,11 +217,10 @@ public void OpenEditor(LayoutModel model) CurrentLayoutWindow.Content = _editor; EditorWindow window; - bool isGrid = false; + if (model is GridLayoutModel) { window = new GridEditorWindow(); - isGrid = true; } else { @@ -231,11 +230,6 @@ public void OpenEditor(LayoutModel model) window.Owner = Monitors[App.Overlay.CurrentDesktop].Window; window.DataContext = model; window.Show(); - - if (isGrid) - { - (window as GridEditorWindow).NameTextBox().Focus(); - } } public void CloseEditor() diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs index 3b1d8b6ace97..ca78c859ebee 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs @@ -78,6 +78,24 @@ public static string Apply { } } + /// + /// Looks up a localized string similar to Are you sure?. + /// + public static string Are_You_Sure { + get { + return ResourceManager.GetString("Are_You_Sure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete this layout?. + /// + public static string Are_You_Sure_Description { + get { + return ResourceManager.GetString("Are_You_Sure_Description", resourceCulture); + } + } + /// /// Looks up a localized string similar to Cancel. /// @@ -186,15 +204,6 @@ public static string Custom_Layout_Creator { } } - /// - /// Looks up a localized string similar to Custom table layout creator. - /// - public static string Custom_Table_Layout { - get { - return ResourceManager.GetString("Custom_Table_Layout", resourceCulture); - } - } - /// /// Looks up a localized string similar to Delete. /// @@ -232,11 +241,20 @@ public static string Edit { } /// - /// Looks up a localized string similar to Edit selected layout. + /// Looks up a localized string similar to Edit layout. + /// + public static string Edit_Layout { + get { + return ResourceManager.GetString("Edit_Layout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit zones. /// - public static string Edit_Selected_Layout { + public static string Edit_zones { get { - return ResourceManager.GetString("Edit_Selected_Layout", resourceCulture); + return ResourceManager.GetString("Edit_zones", resourceCulture); } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx index 67786a42f562..c7ca1e8fbddf 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx @@ -144,14 +144,11 @@ Custom layout creator - - Custom table layout creator - Distance to highlight adjacent zones - - Edit selected layout + + Edit layout FancyZones Editor @@ -294,4 +291,13 @@ To merge zones, select the zones and click "merge". Template settings + + Are you sure? + + + Are you sure you want to delete this layout? + + + Edit zones + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml index ab06f4797917..4cd3bfaac5b8 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml @@ -14,7 +14,7 @@ - + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs index 080b6b509ff9..a910d6809c2c 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs @@ -57,7 +57,7 @@ public MonitorViewModel() double maxMultiplier = MaxPreviewDisplaySize / maxDimension; double minMultiplier = MinPreviewDisplaySize / minDimension; - DesktopPreviewMultiplier = (minMultiplier + maxMultiplier) / 2; + DesktopPreviewMultiplier = (minMultiplier + maxMultiplier) / 3.5; } private void RaisePropertyChanged(string propertyName) From 6d7de6bcefae3da9c784f47a6b92899f8b165d97 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 10 Dec 2020 10:32:44 +0100 Subject: [PATCH 20/38] Updated UI --- .../editor/FancyZonesEditor/MainWindow.xaml | 384 ++++++++++++------ .../FancyZonesEditor/MainWindow.xaml.cs | 5 - .../editor/FancyZonesEditor/Themes/Dark.xaml | 2 + .../Themes/HighContrast1.xaml | 1 + .../Themes/HighContrast2.xaml | 1 + .../Themes/HighContrastBlack.xaml | 1 + .../Themes/HighContrastWhite.xaml | 24 +- .../editor/FancyZonesEditor/Themes/Light.xaml | 1 + .../ViewModels/MonitorViewModel.cs | 8 - 9 files changed, 274 insertions(+), 153 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 3f7f2da9866c..8d651f866c75 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -19,15 +19,11 @@ ui:TitleBar.InactiveBackground="{DynamicResource SecondaryBackgroundBrush}" Width="1000" Height="840" - MaxWidth="1000" - MaxHeight="840" - MinHeight="840" - MinWidth="1000" WindowStartupLocation="CenterOwner" ContentRendered="OnContentRendered" Background="{DynamicResource PrimaryBackgroundBrush}" Closing="OnClosing" - ResizeMode="NoResize"> + ResizeMode="CanResize"> @@ -38,7 +34,7 @@ Height="{Binding DisplayHeight}" AutomationProperties.Name="{x:Static props:Resources.Monitor}" AutomationProperties.HelpText="{Binding Index}" - Background="{DynamicResource PrimaryBackgroundBrush}" + Background="{DynamicResource MonitorBackgroundBrush}" BorderBrush="{DynamicResource LayoutItemBackgroundBrush}" BorderThickness="1" Focusable="True" @@ -79,16 +75,14 @@ - - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - + - + - + - + + - - @@ -262,7 +398,7 @@ - + @@ -275,50 +411,22 @@ - - - - - - - - - - - - - - - - - + - - + + - - - + @@ -398,7 +505,7 @@ HorizontalAlignment="Left" AutomationProperties.Name="{x:Static props:Resources.Create_new_layout}" Background="Transparent" - TabIndex="2" + TabIndex="5" Margin="0,8,0,0"> @@ -412,9 +519,9 @@ @@ -429,39 +536,58 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - + Accent1 Black + + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml index fc4276513921..825e5c693b69 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml @@ -10,6 +10,7 @@ Accent2 White + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml index a3b4bd2e0556..9f3f474fbe70 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml @@ -10,6 +10,7 @@ Accent3 White + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml index ac7df737b1b6..c08ccd6a1465 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml @@ -10,6 +10,7 @@ Accent4 White + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml index 7a56034edc91..2fa22281f574 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml @@ -10,17 +10,19 @@ Accent5 White - - - - - - - - + + + + - - - + + + + + + + + + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml index 758792c24e2c..9ca6d6828eca 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml @@ -10,6 +10,7 @@ Accent1 White + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs index a910d6809c2c..8f1c51dd76b9 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs @@ -22,14 +22,6 @@ public class MonitorViewModel : INotifyPropertyChanged public static double DesktopPreviewMultiplier { get; private set; } - public Visibility DesktopsPanelVisibility - { - get - { - return App.Overlay.MultiMonitorMode ? Visibility.Visible : Visibility.Collapsed; - } - } - public RelayCommand AddCommand { get; set; } public RelayCommand DeleteCommand { get; set; } From 19a27b9addba64f442da5981a61d184ae4969930 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 10 Dec 2020 12:09:55 +0100 Subject: [PATCH 21/38] Added no layouts description --- .../editor/FancyZonesEditor/MainWindow.xaml | 174 ++++++++++-------- .../FancyZonesEditor/MainWindow.xaml.cs | 1 + .../Properties/Resources.Designer.cs | 9 + .../Properties/Resources.resx | 3 + 4 files changed, 113 insertions(+), 74 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 8d651f866c75..d0c514c43cbb 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -11,22 +11,20 @@ xmlns:local1="clr-namespace:FancyZonesEditor.ViewModels" xmlns:ui="http://schemas.modernwpf.com/2019" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" + xmlns:controls="clr-namespace:ModernWpf.Controls;assembly=ModernWpf" mc:Ignorable="d" Title="FancyZones Editor" ui:WindowHelper.UseModernWindowStyle="True" ui:TitleBar.IsIconVisible="True" ui:TitleBar.Background="{DynamicResource SecondaryBackgroundBrush}" ui:TitleBar.InactiveBackground="{DynamicResource SecondaryBackgroundBrush}" - Width="1000" - Height="840" + MinWidth="360" WindowStartupLocation="CenterOwner" ContentRendered="OnContentRendered" Background="{DynamicResource PrimaryBackgroundBrush}" Closing="OnClosing" ResizeMode="CanResize"> - - - - + + - - - + + + + + + + + + - - + + + + + + + + Margin="-8,4,-8,0" + Grid.Row="4"> - + @@ -589,21 +622,14 @@ - - + + /// Looks up a localized string similar to Create or duplicate a layout to get started. + /// + public static string No_Custom_Layouts_Message { + get { + return ResourceManager.GetString("No_Custom_Layouts_Message", resourceCulture); + } + } + /// /// Looks up a localized string similar to Hold down Shift key to change orientation of splitter. ///To merge zones, select the zones and click "merge".. diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx index c7ca1e8fbddf..699b08b7ac49 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx @@ -300,4 +300,7 @@ To merge zones, select the zones and click "merge". Edit zones + + Create or duplicate a layout to get started + \ No newline at end of file From ceafc69047c616bc186c4afe45e73995c3efe294 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Thu, 10 Dec 2020 12:10:45 +0100 Subject: [PATCH 22/38] Fix --- src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index d0c514c43cbb..0cb568cf2a0d 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -627,8 +627,7 @@ SecondaryButtonText="{x:Static props:Resources.Cancel}" PrimaryButtonText="{x:Static props:Resources.Create}" PrimaryButtonClick="NewLayoutDialog_PrimaryButtonClick" - Title="{x:Static props:Resources.Choose_layout_type}" - d:IsHidden="True"> + Title="{x:Static props:Resources.Choose_layout_type}"> From be675b636d462020669464e343d5002bca1905c2 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Sun, 13 Dec 2020 14:13:12 +0100 Subject: [PATCH 23/38] UI fixes --- .../FancyZonesEditor/CanvasEditorWindow.xaml | 8 +----- .../editor/FancyZonesEditor/CanvasZone.xaml | 20 ++++++++++++--- .../FancyZonesEditor/GridEditorWindow.xaml | 9 ++----- .../editor/FancyZonesEditor/GridZone.xaml | 3 ++- .../editor/FancyZonesEditor/MainWindow.xaml | 25 ++++++++++--------- .../Properties/Resources.Designer.cs | 9 +++++++ .../Properties/Resources.resx | 4 +++ 7 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml index b67db3647059..2cc908d9adb8 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml @@ -12,6 +12,7 @@ BorderThickness="0" xmlns:ui="http://schemas.modernwpf.com/2019" ui:WindowHelper.UseModernWindowStyle="True" + ui:TitleBar.IsIconVisible="True" SizeToContent="Height" Background="{DynamicResource PrimaryBackgroundBrush}" ResizeMode="NoResize" @@ -23,13 +24,6 @@ Margin="0,-36,0,0" VerticalAlignment="Top" HorizontalAlignment="Stretch"> - + @@ -101,7 +103,7 @@ Canvas.Left="10" Canvas.Bottom="10" FontSize="64" - FontFamily="Segoe UI Light" + FontWeight="SemiBold" Foreground="{DynamicResource PrimaryForegroundBrush}" Grid.Column="2" Grid.Row="2" @@ -120,10 +122,20 @@ - + public static string Delete_Zone { + get { + return ResourceManager.GetString("Delete_Zone", resourceCulture); + } + } + /// /// Looks up a localized string similar to Distance to highlight adjacent zones. /// diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx index 699b08b7ac49..514f0d6804d6 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx @@ -303,4 +303,8 @@ To merge zones, select the zones and click "merge". Create or duplicate a layout to get started + + Delete zone + A tooltip on a button that allows the user to delete a zone + \ No newline at end of file From 1f5f7db8bfda321762c2c0fa31209c0117f7601d Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Wed, 16 Dec 2020 18:08:03 +0300 Subject: [PATCH 24/38] [FZ Editor] Serialize/deserialize settings (#8615) --- .../editor/FancyZonesEditor/App.xaml.cs | 55 +- .../editor/FancyZonesEditor/EditorWindow.cs | 2 +- .../FancyZonesEditor/MainWindow.xaml.cs | 9 +- .../Models/CanvasLayoutModel.cs | 76 +-- .../Models/GridLayoutModel.cs | 62 +- .../FancyZonesEditor/Models/LayoutModel.cs | 48 +- .../Models/MainWindowSettingsModel.cs | 11 +- .../editor/FancyZonesEditor/Overlay.cs | 8 +- .../Properties/Resources.Designer.cs | 27 + .../Properties/Resources.resx | 9 + .../Utils/FancyZonesEditorIO.cs | 576 +++++++++--------- src/modules/fancyzones/lib/FancyZones.cpp | 5 +- src/modules/fancyzones/lib/FancyZonesData.cpp | 56 -- src/modules/fancyzones/lib/FancyZonesData.h | 16 +- src/modules/fancyzones/lib/JsonHelpers.cpp | 161 ----- src/modules/fancyzones/lib/JsonHelpers.h | 17 - .../tests/UnitTests/JsonHelpers.Tests.cpp | 220 ------- .../tests/UnitTests/ZoneSet.Spec.cpp | 50 +- .../tests/UnitTests/ZoneWindow.Spec.cpp | 222 +------ 19 files changed, 411 insertions(+), 1219 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs index f41fb38827b9..019b634902da 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs @@ -9,6 +9,8 @@ using System.IO; using System.Linq; using System.Text; +using System.Threading; +using System.Threading.Tasks; using System.Windows; using FancyZonesEditor.Utils; using ManagedCommon; @@ -41,6 +43,9 @@ public partial class App : Application private const string CrashReportDynamicAssemblyTag = "dynamic assembly doesn't have location"; private const string CrashReportLocationNullTag = "location is null or empty"; + private const string ParsingErrorReportTag = "Settings parsing error"; + private const string ParsingErrorDataTag = "Data: "; + public MainWindowSettingsModel MainWindowSettings { get; } public static FancyZonesEditorIO FancyZonesEditorIO { get; private set; } @@ -87,7 +92,55 @@ private void OnStartup(object sender, StartupEventArgs e) _themeManager = new ThemeManager(this); FancyZonesEditorIO.ParseCommandLineArguments(); - FancyZonesEditorIO.ParseDeviceInfoData(); + + var parseResult = FancyZonesEditorIO.ParseZoneSettings(); + + // 10ms retry loop with 1 second timeout + if (!parseResult.Result) + { + CancellationTokenSource ts = new CancellationTokenSource(); + Task t = Task.Run(() => + { + while (!parseResult.Result && !ts.IsCancellationRequested) + { + Task.Delay(10).Wait(); + parseResult = FancyZonesEditorIO.ParseZoneSettings(); + } + }); + + try + { + bool result = t.Wait(1000, ts.Token); + ts.Cancel(); + } + catch (OperationCanceledException) + { + ts.Dispose(); + } + } + + // Error message if parsing failed + if (!parseResult.Result) + { + var sb = new StringBuilder(); + sb.AppendLine(); + sb.AppendLine("## " + ParsingErrorReportTag); + sb.AppendLine(); + sb.AppendLine(parseResult.Message); + sb.AppendLine(); + sb.AppendLine(ParsingErrorDataTag); + sb.AppendLine(parseResult.MalformedData); + + string message = parseResult.Message + Environment.NewLine + Environment.NewLine + FancyZonesEditor.Properties.Resources.Error_Parsing_Zones_Settings_User_Choice; + if (MessageBox.Show(message, FancyZonesEditor.Properties.Resources.Error_Parsing_Zones_Settings_Title, MessageBoxButton.YesNo) == MessageBoxResult.No) + { + // TODO: log error + ShowExceptionReportMessageBox(sb.ToString()); + Environment.Exit(0); + } + + ShowExceptionReportMessageBox(sb.ToString()); + } MainWindowSettingsModel settings = ((App)Current).MainWindowSettings; settings.UpdateSelectedLayoutModel(); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs b/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs index d49f745c2a46..3d480996cf33 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs @@ -25,7 +25,7 @@ protected void OnSaveApplyTemplate(object sender, RoutedEventArgs e) model.Persist(); } - LayoutModel.SerializeDeletedCustomZoneSets(); + App.FancyZonesEditorIO.SerializeZoneSettings(); _backToLayoutPicker = false; Close(); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index 9c96fe2201a3..6772cd60b07a 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -196,7 +196,7 @@ private void Apply() private void OnClosing(object sender, EventArgs e) { - LayoutModel.SerializeDeletedCustomZoneSets(); + App.FancyZonesEditorIO.SerializeZoneSettings(); App.Overlay.CloseLayoutWindow(); App.Current.Shutdown(); } @@ -250,7 +250,6 @@ private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e private void Reset_Click(object sender, RoutedEventArgs e) { var overlay = App.Overlay; - MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings; if (overlay.CurrentDataContext is LayoutModel model) { @@ -258,11 +257,11 @@ private void Reset_Click(object sender, RoutedEventArgs e) model.IsApplied = false; } - overlay.CurrentLayoutSettings.ZonesetUuid = settings.BlankModel.Uuid; + overlay.CurrentLayoutSettings.ZonesetUuid = MainWindowSettingsModel.BlankModel.Uuid; overlay.CurrentLayoutSettings.Type = LayoutType.Blank; - overlay.CurrentDataContext = settings.BlankModel; + overlay.CurrentDataContext = MainWindowSettingsModel.BlankModel; - App.FancyZonesEditorIO.SerializeAppliedLayouts(); + App.FancyZonesEditorIO.SerializeZoneSettings(); if (!overlay.MultiMonitorMode) { diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs index 03ac60aaaaa3..f6bc3d061c92 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Text.Json; using System.Windows; namespace FancyZonesEditor.Models @@ -14,7 +13,7 @@ namespace FancyZonesEditor.Models public class CanvasLayoutModel : LayoutModel { // Non-localizable strings - private const string ModelTypeID = "canvas"; + public const string ModelTypeID = "canvas"; public Rect CanvasRect { get; private set; } @@ -83,84 +82,11 @@ public void RestoreTo(CanvasLayoutModel other) } } - private struct Zone - { - public int X { get; set; } - - public int Y { get; set; } - - public int Width { get; set; } - - public int Height { get; set; } - } - - private struct CanvasLayoutInfo - { - public int RefWidth { get; set; } - - public int RefHeight { get; set; } - - public Zone[] Zones { get; set; } - } - - private struct CanvasLayoutJson - { - public string Uuid { get; set; } - - public string Name { get; set; } - - public string Type { get; set; } - - public CanvasLayoutInfo Info { get; set; } - } - // PersistData // Implements the LayoutModel.PersistData abstract method protected override void PersistData() { AddCustomLayout(this); - - var canvasRect = CanvasRect; - if (canvasRect.Width == 0 || canvasRect.Height == 0) - { - canvasRect = App.Overlay.WorkArea; - } - - CanvasLayoutInfo layoutInfo = new CanvasLayoutInfo - { - RefWidth = (int)canvasRect.Width, - RefHeight = (int)canvasRect.Height, - Zones = new Zone[Zones.Count], - }; - - for (int i = 0; i < Zones.Count; ++i) - { - Zone zone = new Zone - { - X = Zones[i].X, - Y = Zones[i].Y, - Width = Zones[i].Width, - Height = Zones[i].Height, - }; - - layoutInfo.Zones[i] = zone; - } - - CanvasLayoutJson jsonObj = new CanvasLayoutJson - { - Uuid = Uuid, - Name = Name, - Type = ModelTypeID, - Info = layoutInfo, - }; - JsonSerializerOptions options = new JsonSerializerOptions - { - PropertyNamingPolicy = new DashCaseNamingPolicy(), - }; - - string jsonString = JsonSerializer.Serialize(jsonObj, options); - AddCustomLayoutJson(JsonSerializer.Deserialize(jsonString)); - SerializeCreatedCustomZonesets(); } } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs index 1dbc391e13d8..ed2ff44130a5 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs @@ -4,8 +4,6 @@ using System; using System.Collections.Generic; -using System.Text.Json; -using System.Windows; namespace FancyZonesEditor.Models { @@ -14,7 +12,7 @@ namespace FancyZonesEditor.Models public class GridLayoutModel : LayoutModel { // Non-localizable strings - private const string ModelTypeID = "grid"; + public const string ModelTypeID = "grid"; // Rows - number of rows in the Grid public int Rows @@ -173,69 +171,11 @@ public void RestoreTo(GridLayoutModel layout) layout.ColumnPercents = colPercents; } - private struct GridLayoutInfo - { - public int Rows { get; set; } - - public int Columns { get; set; } - - public List RowsPercentage { get; set; } - - public List ColumnsPercentage { get; set; } - - public int[][] CellChildMap { get; set; } - } - - private struct GridLayoutJson - { - public string Uuid { get; set; } - - public string Name { get; set; } - - public string Type { get; set; } - - public GridLayoutInfo Info { get; set; } - } - // PersistData // Implements the LayoutModel.PersistData abstract method protected override void PersistData() { AddCustomLayout(this); - - GridLayoutInfo layoutInfo = new GridLayoutInfo - { - Rows = Rows, - Columns = Columns, - RowsPercentage = RowPercents, - ColumnsPercentage = ColumnPercents, - CellChildMap = new int[Rows][], - }; - - for (int row = 0; row < Rows; row++) - { - layoutInfo.CellChildMap[row] = new int[Columns]; - for (int col = 0; col < Columns; col++) - { - layoutInfo.CellChildMap[row][col] = CellChildMap[row, col]; - } - } - - GridLayoutJson jsonObj = new GridLayoutJson - { - Uuid = Uuid, - Name = Name, - Type = ModelTypeID, - Info = layoutInfo, - }; - JsonSerializerOptions options = new JsonSerializerOptions - { - PropertyNamingPolicy = new DashCaseNamingPolicy(), - }; - - string jsonString = JsonSerializer.Serialize(jsonObj, options); - AddCustomLayoutJson(JsonSerializer.Deserialize(jsonString)); - SerializeCreatedCustomZonesets(); } } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs index 61d3ac76bdae..4ace86920b15 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs @@ -3,11 +3,8 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; -using System.Text.Json; namespace FancyZonesEditor.Models { @@ -134,11 +131,11 @@ protected virtual void FirePropertyChanged([CallerMemberName] string propertyNam // Removes this Layout from the registry and the loaded CustomModels list public void Delete() { - int i = _customModels.IndexOf(this); + var customModels = MainWindowSettingsModel.CustomModels; + int i = customModels.IndexOf(this); if (i != -1) { - _customModels.RemoveAt(i); - _deletedCustomModels.Add(Guid.ToString().ToUpper()); + customModels.RemoveAt(i); } } @@ -146,49 +143,24 @@ public void Delete() public void AddCustomLayout(LayoutModel model) { bool updated = false; - for (int i = 0; i < _customModels.Count && !updated; i++) + var customModels = MainWindowSettingsModel.CustomModels; + for (int i = 0; i < customModels.Count && !updated; i++) { - if (_customModels[i].Uuid == model.Uuid) + if (customModels[i].Uuid == model.Uuid) { - _customModels[i] = model; + customModels[i] = model; updated = true; } } if (!updated) { - _customModels.Add(model); + customModels.Add(model); } - } - - // Add custom layouts json data that would be serialized to a temp file - public void AddCustomLayoutJson(JsonElement json) - { - _createdCustomLayouts.Add(json); - } - - public static void SerializeDeletedCustomZoneSets() - { - App.FancyZonesEditorIO.SerializeDeletedCustomZoneSets(_deletedCustomModels); - } - - public static void SerializeCreatedCustomZonesets() - { - App.FancyZonesEditorIO.SerializeCreatedCustomZonesets(_createdCustomLayouts); - } - // Loads all the custom Layouts from tmp file passed by FancyZonesLib - public static ObservableCollection LoadCustomModels() - { - _customModels = new ObservableCollection(); - App.FancyZonesEditorIO.ParseLayouts(ref _customModels, ref _deletedCustomModels); - return _customModels; + App.FancyZonesEditorIO.SerializeZoneSettings(); } - private static ObservableCollection _customModels; - private static List _deletedCustomModels = new List(); - private static List _createdCustomLayouts = new List(); - // Callbacks that the base LayoutModel makes to derived types protected abstract void PersistData(); @@ -211,7 +183,7 @@ public void Apply() App.Overlay.CurrentLayoutSettings.Type = Type; // update temp file - App.FancyZonesEditorIO.SerializeAppliedLayouts(); + App.FancyZonesEditorIO.SerializeZoneSettings(); } } } diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs index d628367688bd..294579fe507d 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs @@ -344,18 +344,13 @@ public static ObservableCollection CustomModels { get { - if (_customModels == null) - { - _customModels = LayoutModel.LoadCustomModels(); - } - return _customModels; } } - private static ObservableCollection _customModels; + private static ObservableCollection _customModels = new ObservableCollection(); - public CanvasLayoutModel BlankModel + public static CanvasLayoutModel BlankModel { get { @@ -363,7 +358,7 @@ public CanvasLayoutModel BlankModel } } - private CanvasLayoutModel _blankModel = new CanvasLayoutModel(string.Empty, LayoutType.Blank); + private static CanvasLayoutModel _blankModel = new CanvasLayoutModel(string.Empty, LayoutType.Blank); public static bool IsPredefinedLayout(LayoutModel model) { diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs index 72edf0f0147e..fa1660fc6ea8 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs @@ -29,7 +29,7 @@ public Rect WorkArea return Monitors[CurrentDesktop].Device.WorkAreaRect; } - return default(Rect); + return default; } } @@ -55,7 +55,7 @@ public Window CurrentLayoutWindow return Monitors[CurrentDesktop].Window; } - return default(Window); + return default; } } @@ -131,8 +131,8 @@ public bool SpanZonesAcrossMonitors if (_spanZonesAcrossMonitors) { - Rect workArea = default(Rect); - Rect bounds = default(Rect); + Rect workArea = default; + Rect bounds = default; foreach (Monitor monitor in Monitors) { diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs index bf2cc65c3a9c..0aab0c75a1d7 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs @@ -348,6 +348,33 @@ public static string Error_Parsing_Device_Info { } } + /// + /// Looks up a localized string similar to 'zones-settings.json' contains malformed data.. + /// + public static string Error_Parsing_Zones_Settings_Malformed_Data { + get { + return ResourceManager.GetString("Error_Parsing_Zones_Settings_Malformed_Data", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Editor settings parsing error.. + /// + public static string Error_Parsing_Zones_Settings_Title { + get { + return ResourceManager.GetString("Error_Parsing_Zones_Settings_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Would you like to continue? Malformed data will be lost.. + /// + public static string Error_Parsing_Zones_Settings_User_Choice { + get { + return ResourceManager.GetString("Error_Parsing_Zones_Settings_User_Choice", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error persisting custom layout. /// diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx index 514f0d6804d6..1dc1ca816696 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx @@ -307,4 +307,13 @@ To merge zones, select the zones and click "merge". Delete zone A tooltip on a button that allows the user to delete a zone + + 'zones-settings.json' contains malformed data. + + + Editor settings parsing error. + + + Would you like to continue? Malformed data will be lost. + \ No newline at end of file diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs index 4e9017bfc8e0..14f322102565 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs @@ -4,10 +4,8 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.IO; using System.IO.Abstractions; -using System.Linq; using System.Text; using System.Text.Json; using System.Windows; @@ -18,16 +16,6 @@ namespace FancyZonesEditor.Utils public class FancyZonesEditorIO { // Non-localizable strings: JSON tags - private const string AppliedZonesetsJsonTag = "applied-zonesets"; - private const string DeviceIdJsonTag = "device-id"; - private const string ActiveZoneSetJsonTag = "active-zoneset"; - private const string UuidJsonTag = "uuid"; - private const string TypeJsonTag = "type"; - private const string EditorShowSpacingJsonTag = "editor-show-spacing"; - private const string EditorSpacingJsonTag = "editor-spacing"; - private const string EditorZoneCountJsonTag = "editor-zone-count"; - private const string EditorSensitivityRadiusJsonTag = "editor-sensitivity-radius"; - private const string BlankJsonTag = "blank"; private const string FocusJsonTag = "focus"; private const string ColumnsJsonTag = "columns"; @@ -36,43 +24,19 @@ public class FancyZonesEditorIO private const string PriorityGridJsonTag = "priority-grid"; private const string CustomJsonTag = "custom"; - private const string NameJsonTag = "name"; - private const string CustomZoneSetsJsonTag = "custom-zone-sets"; - private const string InfoJsonTag = "info"; - private const string RowsPercentageJsonTag = "rows-percentage"; - private const string ColumnsPercentageJsonTag = "columns-percentage"; - private const string CellChildMapJsonTag = "cell-child-map"; - private const string ZonesJsonTag = "zones"; - private const string CanvasJsonTag = "canvas"; - private const string RefWidthJsonTag = "ref-width"; - private const string RefHeightJsonTag = "ref-height"; - private const string XJsonTag = "X"; - private const string YJsonTag = "Y"; - private const string WidthJsonTag = "width"; - private const string HeightJsonTag = "height"; - // Non-localizable strings: Files private const string ZonesSettingsFile = "\\Microsoft\\PowerToys\\FancyZones\\zones-settings.json"; - private const string ActiveZoneSetsTmpFileName = "FancyZonesActiveZoneSets.json"; - private const string AppliedZoneSetsTmpFileName = "FancyZonesAppliedZoneSets.json"; - private const string DeletedCustomZoneSetsTmpFileName = "FancyZonesDeletedCustomZoneSets.json"; // Non-localizable string: Multi-monitor id private const string MultiMonitorId = "FancyZones#MultiMonitorDevice"; private readonly IFileSystem _fileSystem = new FileSystem(); - private JsonSerializerOptions _options = new JsonSerializerOptions + private readonly JsonSerializerOptions _options = new JsonSerializerOptions { PropertyNamingPolicy = new DashCaseNamingPolicy(), }; - public string ActiveZoneSetTmpFile { get; private set; } - - public string AppliedZoneSetTmpFile { get; private set; } - - public string DeletedCustomZoneSetsTmpFile { get; private set; } - public string FancyZonesSettingsFile { get; private set; } private enum CmdArgs @@ -115,15 +79,15 @@ public override string ToString() } } - private struct ActiveZoneSetWrapper + private struct DeviceWrapper { - public string Uuid { get; set; } + public struct ActiveZoneSetWrapper + { + public string Uuid { get; set; } - public string Type { get; set; } - } + public string Type { get; set; } + } - private struct AppliedZoneSet - { public string DeviceId { get; set; } public ActiveZoneSetWrapper ActiveZoneset { get; set; } @@ -137,29 +101,75 @@ private struct AppliedZoneSet public int EditorSensitivityRadius { get; set; } } - private struct AppliedZonesetsToDesktops + private struct CanvasInfoWrapper { - public List AppliedZonesets { get; set; } + public struct CanvasZoneWrapper + { + public int X { get; set; } + + public int Y { get; set; } + + public int Width { get; set; } + + public int Height { get; set; } + } + + public int RefWidth { get; set; } + + public int RefHeight { get; set; } + + public List Zones { get; set; } } - private struct DeletedCustomZoneSetsWrapper + private struct GridInfoWrapper { - public List DeletedCustomZoneSets { get; set; } + public int Rows { get; set; } + + public int Columns { get; set; } + + public List RowsPercentage { get; set; } + + public List ColumnsPercentage { get; set; } + + public int[][] CellChildMap { get; set; } } - private struct CreatedCustomZoneSetsWrapper + private struct CustomLayoutWrapper { - public List CreatedCustomZoneSets { get; set; } + public string Uuid { get; set; } + + public string Name { get; set; } + + public string Type { get; set; } + + public JsonElement Info { get; set; } // CanvasInfoWrapper or GridInfoWrapper } - public FancyZonesEditorIO() + private struct ZoneSettingsWrapper { - string tmpDirPath = _fileSystem.Path.GetTempPath(); + public List Devices { get; set; } + + public List CustomZoneSets { get; set; } + } + + public struct ParsingResult + { + public bool Result { get; } + + public string Message { get; } + + public string MalformedData { get; } - ActiveZoneSetTmpFile = tmpDirPath + ActiveZoneSetsTmpFileName; - AppliedZoneSetTmpFile = tmpDirPath + AppliedZoneSetsTmpFileName; - DeletedCustomZoneSetsTmpFile = tmpDirPath + DeletedCustomZoneSetsTmpFileName; + public ParsingResult(bool result, string message = "", string data = "") + { + Result = result; + Message = message; + MalformedData = data; + } + } + public FancyZonesEditorIO() + { var localAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); FancyZonesSettingsFile = localAppDataDir + ZonesSettingsFile; } @@ -319,301 +329,279 @@ public static void ParseCommandLineArguments() } } - public void ParseDeviceInfoData() + public ParsingResult ParseZoneSettings() { - try + if (_fileSystem.File.Exists(FancyZonesSettingsFile)) { - JsonElement jsonObject = default(JsonElement); + ZoneSettingsWrapper zoneSettings; + string settingsString = string.Empty; - if (_fileSystem.File.Exists(ActiveZoneSetTmpFile)) + try { - Stream inputStream = _fileSystem.File.Open(ActiveZoneSetTmpFile, FileMode.Open); - jsonObject = JsonDocument.Parse(inputStream, options: default).RootElement; - inputStream.Close(); + settingsString = ReadZoneSettings(FancyZonesSettingsFile); + zoneSettings = JsonSerializer.Deserialize(settingsString, _options); + } + catch (Exception ex) + { + return new ParsingResult(false, ex.Message, settingsString); + } - JsonElement json = jsonObject.GetProperty(AppliedZonesetsJsonTag); + try + { + bool devicesParsingResult = SetDevices(zoneSettings.Devices); + bool customZonesParsingResult = SetCustomLayouts(zoneSettings.CustomZoneSets); - int layoutId = 0; - for (int i = 0; i < json.GetArrayLength() && layoutId < App.Overlay.DesktopsCount; i++) + if (!devicesParsingResult || !customZonesParsingResult) { - var zonesetData = json[i]; - - string deviceId = zonesetData.GetProperty(DeviceIdJsonTag).GetString(); - - string currentLayoutType = zonesetData.GetProperty(ActiveZoneSetJsonTag).GetProperty(TypeJsonTag).GetString(); - LayoutType type = JsonTagToLayoutType(currentLayoutType); - - if (!App.Overlay.SpanZonesAcrossMonitors) - { - var monitors = App.Overlay.Monitors; - for (int monitorIndex = 0; monitorIndex < monitors.Count; monitorIndex++) - { - if (monitors[monitorIndex].Device.Id == deviceId) - { - monitors[monitorIndex].Settings = new LayoutSettings - { - ZonesetUuid = zonesetData.GetProperty(ActiveZoneSetJsonTag).GetProperty(UuidJsonTag).GetString(), - ShowSpacing = zonesetData.GetProperty(EditorShowSpacingJsonTag).GetBoolean(), - Spacing = zonesetData.GetProperty(EditorSpacingJsonTag).GetInt32(), - Type = type, - ZoneCount = zonesetData.GetProperty(EditorZoneCountJsonTag).GetInt32(), - SensitivityRadius = zonesetData.GetProperty(EditorSensitivityRadiusJsonTag).GetInt32(), - }; - - break; - } - } - } - else - { - bool isLayoutMultiMonitor = deviceId.StartsWith(MultiMonitorId); - if (isLayoutMultiMonitor) - { - // one zoneset for all desktops - App.Overlay.Monitors[App.Overlay.CurrentDesktop].Settings = new LayoutSettings - { - ZonesetUuid = zonesetData.GetProperty(ActiveZoneSetJsonTag).GetProperty(UuidJsonTag).GetString(), - ShowSpacing = zonesetData.GetProperty(EditorShowSpacingJsonTag).GetBoolean(), - Spacing = zonesetData.GetProperty(EditorSpacingJsonTag).GetInt32(), - Type = type, - ZoneCount = zonesetData.GetProperty(EditorZoneCountJsonTag).GetInt32(), - SensitivityRadius = zonesetData.GetProperty(EditorSensitivityRadiusJsonTag).GetInt32(), - }; - - App.Overlay.Monitors[App.Overlay.CurrentDesktop].Device.Id = deviceId; - - break; - } - } + return new ParsingResult(false, Properties.Resources.Error_Parsing_Zones_Settings_Malformed_Data, settingsString); } } + catch (Exception ex) + { + return new ParsingResult(false, ex.Message, settingsString); + } } - catch (Exception ex) - { - App.ShowExceptionMessageBox(Properties.Resources.Error_Parsing_Device_Info, ex); - } + + return new ParsingResult(true); } - public void ParseLayouts(ref ObservableCollection custom, ref List deleted) + public void SerializeZoneSettings() { - try - { - Stream inputStream = _fileSystem.File.Open(FancyZonesSettingsFile, FileMode.Open); - JsonDocument jsonObject = JsonDocument.Parse(inputStream, options: default); - JsonElement.ArrayEnumerator customZoneSetsEnumerator = jsonObject.RootElement.GetProperty(CustomZoneSetsJsonTag).EnumerateArray(); + ZoneSettingsWrapper zoneSettings = new ZoneSettingsWrapper { }; + zoneSettings.Devices = new List(); + zoneSettings.CustomZoneSets = new List(); - while (customZoneSetsEnumerator.MoveNext()) + // Serialize devices + foreach (var monitor in App.Overlay.Monitors) + { + LayoutSettings zoneset = monitor.Settings; + if (zoneset.ZonesetUuid.Length == 0) { - var current = customZoneSetsEnumerator.Current; - string name = current.GetProperty(NameJsonTag).GetString(); - string type = current.GetProperty(TypeJsonTag).GetString(); - string uuid = current.GetProperty(UuidJsonTag).GetString(); - var info = current.GetProperty(InfoJsonTag); + continue; + } - if (type.Equals(GridJsonTag, StringComparison.OrdinalIgnoreCase)) + zoneSettings.Devices.Add(new DeviceWrapper + { + DeviceId = monitor.Device.Id, + ActiveZoneset = new DeviceWrapper.ActiveZoneSetWrapper { - bool error = false; - - int rows = info.GetProperty(RowsJsonTag).GetInt32(); - int columns = info.GetProperty(ColumnsJsonTag).GetInt32(); - - List rowsPercentage = new List(rows); - JsonElement.ArrayEnumerator rowsPercentageEnumerator = info.GetProperty(RowsPercentageJsonTag).EnumerateArray(); - - List columnsPercentage = new List(columns); - JsonElement.ArrayEnumerator columnsPercentageEnumerator = info.GetProperty(ColumnsPercentageJsonTag).EnumerateArray(); - - if (rows <= 0 || columns <= 0 || rowsPercentageEnumerator.Count() != rows || columnsPercentageEnumerator.Count() != columns) - { - error = true; - } - - while (!error && rowsPercentageEnumerator.MoveNext()) - { - int percentage = rowsPercentageEnumerator.Current.GetInt32(); - if (percentage <= 0) - { - error = true; - break; - } - - rowsPercentage.Add(percentage); - } - - while (!error && columnsPercentageEnumerator.MoveNext()) - { - int percentage = columnsPercentageEnumerator.Current.GetInt32(); - if (percentage <= 0) - { - error = true; - break; - } - - columnsPercentage.Add(percentage); - } + Uuid = zoneset.ZonesetUuid, + Type = LayoutTypeToJsonTag(zoneset.Type), + }, + EditorShowSpacing = zoneset.ShowSpacing, + EditorSpacing = zoneset.Spacing, + EditorZoneCount = zoneset.ZoneCount, + EditorSensitivityRadius = zoneset.SensitivityRadius, + }); + } - int i = 0; - JsonElement.ArrayEnumerator cellChildMapRows = info.GetProperty(CellChildMapJsonTag).EnumerateArray(); - int[,] cellChildMap = new int[rows, columns]; + // Serialize custom zonesets + foreach (LayoutModel layout in MainWindowSettingsModel.CustomModels) + { + if (layout.Type == LayoutType.Blank) + { + continue; + } - if (cellChildMapRows.Count() != rows) - { - error = true; - } + JsonElement info; + string type; - while (!error && cellChildMapRows.MoveNext()) - { - int j = 0; - JsonElement.ArrayEnumerator cellChildMapRowElems = cellChildMapRows.Current.EnumerateArray(); - if (cellChildMapRowElems.Count() != columns) - { - error = true; - break; - } + if (layout is CanvasLayoutModel) + { + type = CanvasLayoutModel.ModelTypeID; + var canvasLayout = layout as CanvasLayoutModel; - while (cellChildMapRowElems.MoveNext()) - { - cellChildMap[i, j++] = cellChildMapRowElems.Current.GetInt32(); - } + var canvasRect = canvasLayout.CanvasRect; + if (canvasRect.Width == 0 || canvasRect.Height == 0) + { + canvasRect = App.Overlay.WorkArea; + } - i++; - } + var wrapper = new CanvasInfoWrapper + { + RefWidth = (int)canvasRect.Width, + RefHeight = (int)canvasRect.Height, + Zones = new List(), + }; - if (error) + foreach (var zone in canvasLayout.Zones) + { + wrapper.Zones.Add(new CanvasInfoWrapper.CanvasZoneWrapper { - App.ShowExceptionMessageBox(string.Format(Properties.Resources.Error_Layout_Malformed_Data, name)); - deleted.Add(Guid.Parse(uuid).ToString().ToUpperInvariant()); - continue; - } - - custom.Add(new GridLayoutModel(uuid, name, LayoutType.Custom, rows, columns, rowsPercentage, columnsPercentage, cellChildMap)); + X = zone.X, + Y = zone.Y, + Width = zone.Width, + Height = zone.Height, + }); } - else if (type.Equals(CanvasJsonTag, StringComparison.OrdinalIgnoreCase)) - { - int workAreaWidth = info.GetProperty(RefWidthJsonTag).GetInt32(); - int workAreaHeight = info.GetProperty(RefHeightJsonTag).GetInt32(); - - JsonElement.ArrayEnumerator zonesEnumerator = info.GetProperty(ZonesJsonTag).EnumerateArray(); - IList zones = new List(); - bool error = false; + string json = JsonSerializer.Serialize(wrapper, _options); + info = JsonSerializer.Deserialize(json); + } + else if (layout is GridLayoutModel) + { + type = GridLayoutModel.ModelTypeID; + var gridLayout = layout as GridLayoutModel; - if (workAreaWidth <= 0 || workAreaHeight <= 0) + var cells = new int[gridLayout.Rows][]; + for (int row = 0; row < gridLayout.Rows; row++) + { + cells[row] = new int[gridLayout.Columns]; + for (int column = 0; column < gridLayout.Columns; column++) { - error = true; + cells[row][column] = gridLayout.CellChildMap[row, column]; } + } - while (!error && zonesEnumerator.MoveNext()) - { - int x = zonesEnumerator.Current.GetProperty(XJsonTag).GetInt32(); - int y = zonesEnumerator.Current.GetProperty(YJsonTag).GetInt32(); - int width = zonesEnumerator.Current.GetProperty(WidthJsonTag).GetInt32(); - int height = zonesEnumerator.Current.GetProperty(HeightJsonTag).GetInt32(); - - if (width <= 0 || height <= 0) - { - error = true; - break; - } - - zones.Add(new Int32Rect(x, y, width, height)); - } + var wrapper = new GridInfoWrapper + { + Rows = gridLayout.Rows, + Columns = gridLayout.Columns, + RowsPercentage = gridLayout.RowPercents, + ColumnsPercentage = gridLayout.ColumnPercents, + CellChildMap = cells, + }; + + string json = JsonSerializer.Serialize(wrapper, _options); + info = JsonSerializer.Deserialize(json); + } + else + { + // Error + continue; + } - if (error) - { - App.ShowExceptionMessageBox(string.Format(Properties.Resources.Error_Layout_Malformed_Data, name)); - deleted.Add(Guid.Parse(uuid).ToString().ToUpperInvariant()); - continue; - } + CustomLayoutWrapper customLayout = new CustomLayoutWrapper + { + Uuid = layout.Uuid, + Name = layout.Name, + Type = type, + Info = info, + }; - custom.Add(new CanvasLayoutModel(uuid, name, LayoutType.Custom, zones, workAreaWidth, workAreaHeight)); - } - } + zoneSettings.CustomZoneSets.Add(customLayout); + } - inputStream.Close(); + try + { + string jsonString = JsonSerializer.Serialize(zoneSettings, _options); + _fileSystem.File.WriteAllText(FancyZonesSettingsFile, jsonString); } catch (Exception ex) { - App.ShowExceptionMessageBox(Properties.Resources.Error_Loading_Custom_Layouts, ex); + App.ShowExceptionMessageBox(Properties.Resources.Error_Applying_Layout, ex); } } - public void SerializeAppliedLayouts() + private string ReadZoneSettings(string fileName) { - AppliedZonesetsToDesktops applied = new AppliedZonesetsToDesktops { }; - applied.AppliedZonesets = new List(); + Stream inputStream = _fileSystem.File.Open(fileName, FileMode.Open); + StreamReader reader = new StreamReader(inputStream); + string data = reader.ReadToEnd(); + inputStream.Close(); + return data; + } - foreach (var monitor in App.Overlay.Monitors) + private bool SetDevices(List devices) + { + bool result = true; + var monitors = App.Overlay.Monitors; + foreach (var device in devices) { - LayoutSettings zoneset = monitor.Settings; - if (zoneset.ZonesetUuid.Length == 0) + if (device.DeviceId == null || device.DeviceId.Length == 0 || device.ActiveZoneset.Uuid == null || device.ActiveZoneset.Uuid.Length == 0) { + result = false; continue; } - ActiveZoneSetWrapper activeZoneSet = new ActiveZoneSetWrapper + var settings = new LayoutSettings { - Uuid = zoneset.ZonesetUuid, + ZonesetUuid = device.ActiveZoneset.Uuid, + ShowSpacing = device.EditorShowSpacing, + Spacing = device.EditorSpacing, + Type = JsonTagToLayoutType(device.ActiveZoneset.Type), + ZoneCount = device.EditorZoneCount, + SensitivityRadius = device.EditorSensitivityRadius, }; - activeZoneSet.Type = LayoutTypeToJsonTag(zoneset.Type); - - applied.AppliedZonesets.Add(new AppliedZoneSet + if (!App.Overlay.SpanZonesAcrossMonitors) { - DeviceId = monitor.Device.Id, - ActiveZoneset = activeZoneSet, - EditorShowSpacing = zoneset.ShowSpacing, - EditorSpacing = zoneset.Spacing, - EditorZoneCount = zoneset.ZoneCount, - EditorSensitivityRadius = zoneset.SensitivityRadius, - }); + foreach (Monitor monitor in monitors) + { + if (monitor.Device.Id == device.DeviceId) + { + monitor.Settings = settings; + break; + } + } + } + else + { + bool isLayoutMultiMonitor = device.DeviceId.StartsWith(MultiMonitorId); + if (isLayoutMultiMonitor) + { + // one zoneset for all desktops + App.Overlay.Monitors[App.Overlay.CurrentDesktop].Settings = settings; + App.Overlay.Monitors[App.Overlay.CurrentDesktop].Device.Id = device.DeviceId; + break; + } + } } - try - { - string jsonString = JsonSerializer.Serialize(applied, _options); - _fileSystem.File.WriteAllText(ActiveZoneSetTmpFile, jsonString); - } - catch (Exception ex) - { - App.ShowExceptionMessageBox(Properties.Resources.Error_Applying_Layout, ex); - } + return result; } - public void SerializeDeletedCustomZoneSets(List models) + private bool SetCustomLayouts(List customLayouts) { - DeletedCustomZoneSetsWrapper deletedLayouts = new DeletedCustomZoneSetsWrapper - { - DeletedCustomZoneSets = models, - }; + MainWindowSettingsModel.CustomModels.Clear(); + bool result = true; - try + foreach (var zoneSet in customLayouts) { - string jsonString = JsonSerializer.Serialize(deletedLayouts, _options); - _fileSystem.File.WriteAllText(DeletedCustomZoneSetsTmpFile, jsonString); - } - catch (Exception ex) - { - App.ShowExceptionMessageBox(Properties.Resources.Error_Serializing_Deleted_Layouts, ex); - } - } + if (zoneSet.Uuid == null || zoneSet.Uuid.Length == 0) + { + result = false; + continue; + } - public void SerializeCreatedCustomZonesets(List models) - { - CreatedCustomZoneSetsWrapper layouts = new CreatedCustomZoneSetsWrapper - { - CreatedCustomZoneSets = models, - }; + LayoutModel layout; + if (zoneSet.Type == CanvasLayoutModel.ModelTypeID) + { + var info = JsonSerializer.Deserialize(zoneSet.Info.GetRawText(), _options); - try - { - string jsonString = JsonSerializer.Serialize(layouts, _options); - _fileSystem.File.WriteAllText(AppliedZoneSetTmpFile, jsonString); - } - catch (Exception ex) - { - App.ShowExceptionMessageBox(Properties.Resources.Error_Persisting_Custom_Layout, ex); + var zones = new List(); + foreach (var zone in info.Zones) + { + zones.Add(new Int32Rect { X = (int)zone.X, Y = (int)zone.Y, Width = (int)zone.Width, Height = (int)zone.Height }); + } + + layout = new CanvasLayoutModel(zoneSet.Uuid, zoneSet.Name, LayoutType.Custom, zones, info.RefWidth, info.RefHeight); + } + else if (zoneSet.Type == GridLayoutModel.ModelTypeID) + { + var info = JsonSerializer.Deserialize(zoneSet.Info.GetRawText(), _options); + + var cells = new int[info.Rows, info.Columns]; + for (int row = 0; row < info.Rows; row++) + { + for (int column = 0; column < info.Columns; column++) + { + cells[row, column] = info.CellChildMap[row][column]; + } + } + + layout = new GridLayoutModel(zoneSet.Uuid, zoneSet.Name, LayoutType.Custom, info.Rows, info.Columns, info.RowsPercentage, info.ColumnsPercentage, cells); + } + else + { + result = false; + continue; + } + + MainWindowSettingsModel.CustomModels.Add(layout); } + + return result; } private LayoutType JsonTagToLayoutType(string tag) @@ -648,23 +636,21 @@ private string LayoutTypeToJsonTag(LayoutType type) { switch (type) { - case LayoutType.Blank: - return BlankJsonTag; case LayoutType.Focus: return FocusJsonTag; - case LayoutType.Rows: - return RowsJsonTag; case LayoutType.Columns: return ColumnsJsonTag; + case LayoutType.Rows: + return RowsJsonTag; case LayoutType.Grid: return GridJsonTag; case LayoutType.PriorityGrid: return PriorityGridJsonTag; case LayoutType.Custom: return CustomJsonTag; + default: + return string.Empty; } - - return string.Empty; } private static string ParsingCmdArgsErrorReport(string args, int count, string targetMonitorName, List monitorData, List monitors) diff --git a/src/modules/fancyzones/lib/FancyZones.cpp b/src/modules/fancyzones/lib/FancyZones.cpp index 80ddcd760740..d738710aa672 100644 --- a/src/modules/fancyzones/lib/FancyZones.cpp +++ b/src/modules/fancyzones/lib/FancyZones.cpp @@ -711,9 +711,6 @@ void FancyZones::ToggleEditor() noexcept //} }.detach(); } - const auto& fancyZonesData = FancyZonesDataInstance(); - fancyZonesData.SerializeDeviceInfoToTmpFile(m_currentDesktopId); - SHELLEXECUTEINFO sei{ sizeof(sei) }; sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI }; sei.lpFile = NonLocalizable::FZEditorExecutablePath; @@ -1308,7 +1305,7 @@ bool FancyZones::IsSplashScreen(HWND window) void FancyZones::OnEditorExitEvent() noexcept { // Collect information about changes in zone layout after editor exited. - FancyZonesDataInstance().ParseDataFromTmpFiles(); + FancyZonesDataInstance().LoadFancyZonesData(); UpdateZoneSets(); } diff --git a/src/modules/fancyzones/lib/FancyZonesData.cpp b/src/modules/fancyzones/lib/FancyZonesData.cpp index 7880714642cc..68676d4cec5b 100644 --- a/src/modules/fancyzones/lib/FancyZonesData.cpp +++ b/src/modules/fancyzones/lib/FancyZonesData.cpp @@ -26,10 +26,6 @@ namespace NonLocalizable const wchar_t FancyZonesAppZoneHistoryFile[] = L"app-zone-history.json"; const wchar_t DefaultGuid[] = L"{00000000-0000-0000-0000-000000000000}"; const wchar_t RegistryPath[] = L"Software\\SuperFancyZones"; - - const wchar_t ActiveZoneSetsTmpFileName[] = L"FancyZonesActiveZoneSets.json"; - const wchar_t AppliedZoneSetsTmpFileName[] = L"FancyZonesAppliedZoneSets.json"; - const wchar_t DeletedCustomZoneSetsTmpFileName[] = L"FancyZonesDeletedCustomZoneSets.json"; } namespace @@ -151,10 +147,6 @@ FancyZonesData::FancyZonesData() zonesSettingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesDataFile); appZoneHistoryFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesAppZoneHistoryFile); - - activeZoneSetTmpFileName = GetTempDirPath() + NonLocalizable::ActiveZoneSetsTmpFileName; - appliedZoneSetTmpFileName = GetTempDirPath() + NonLocalizable::AppliedZoneSetsTmpFileName; - deletedCustomZoneSetsTmpFileName = GetTempDirPath() + NonLocalizable::DeletedCustomZoneSetsTmpFileName; } std::optional FancyZonesData::FindDeviceInfo(const std::wstring& zoneWindowId) const @@ -479,54 +471,6 @@ void FancyZonesData::SetActiveZoneSet(const std::wstring& deviceId, const FancyZ } } -void FancyZonesData::SerializeDeviceInfoToTmpFile(const GUID& currentVirtualDesktop) const -{ - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, currentVirtualDesktop, activeZoneSetTmpFileName); -} - -void FancyZonesData::ParseDataFromTmpFiles() -{ - ParseDeviceInfoFromTmpFile(activeZoneSetTmpFileName); - ParseDeletedCustomZoneSetsFromTmpFile(deletedCustomZoneSetsTmpFileName); - ParseCustomZoneSetsFromTmpFile(appliedZoneSetTmpFileName); - SaveFancyZonesData(); -} - -void FancyZonesData::ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath) -{ - std::scoped_lock lock{ dataLock }; - const auto& appliedZonesets = JSONHelpers::ParseDeviceInfoFromTmpFile(tmpFilePath); - - if (appliedZonesets) - { - for (const auto& zoneset : *appliedZonesets) - { - deviceInfoMap[zoneset.first] = std::move(zoneset.second); - } - } -} - -void FancyZonesData::ParseCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath) -{ - std::scoped_lock lock{ dataLock }; - const auto& customZoneSets = JSONHelpers::ParseCustomZoneSetsFromTmpFile(tmpFilePath); - - for (const auto& zoneSet : customZoneSets) - { - customZoneSetsMap[zoneSet.uuid] = zoneSet.data; - } -} - -void FancyZonesData::ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath) -{ - std::scoped_lock lock{ dataLock }; - const auto& deletedCustomZoneSets = JSONHelpers::ParseDeletedCustomZoneSetsFromTmpFile(tmpFilePath); - for (const auto& zoneSet : deletedCustomZoneSets) - { - customZoneSetsMap.erase(zoneSet); - } -} - json::JsonObject FancyZonesData::GetPersistFancyZonesJSON() { return JSONHelpers::GetPersistFancyZonesJSON(zonesSettingsFileName, appZoneHistoryFileName); diff --git a/src/modules/fancyzones/lib/FancyZonesData.h b/src/modules/fancyzones/lib/FancyZonesData.h index 2a37d4ee564b..846a05cdc145 100644 --- a/src/modules/fancyzones/lib/FancyZonesData.h +++ b/src/modules/fancyzones/lib/FancyZonesData.h @@ -77,9 +77,6 @@ class FancyZonesData void SetActiveZoneSet(const std::wstring& deviceId, const FancyZonesDataTypes::ZoneSetData& zoneSet); - void SerializeDeviceInfoToTmpFile(const GUID& currentVirtualDesktop) const; - void ParseDataFromTmpFiles(); - json::JsonObject GetPersistFancyZonesJSON(); void LoadFancyZonesData(); @@ -98,6 +95,11 @@ class FancyZonesData deviceInfoMap[deviceId] = data; } + inline void SetCustomZonesets(const std::wstring& uuid, FancyZonesDataTypes::CustomZoneSetData data) + { + customZoneSetsMap[uuid] = data; + } + inline bool ParseDeviceInfos(const json::JsonObject& fancyZonesDataJSON) { deviceInfoMap = JSONHelpers::ParseDeviceInfos(fancyZonesDataJSON); @@ -118,10 +120,6 @@ class FancyZonesData appZoneHistoryFileName = result + L"\\" + std::wstring(L"app-zone-history.json"); } #endif - void ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath); - void ParseCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath); - void ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath); - void RemoveDesktopAppZoneHistory(const std::wstring& desktopId); // Maps app path to app's zone history data @@ -134,10 +132,6 @@ class FancyZonesData std::wstring zonesSettingsFileName; std::wstring appZoneHistoryFileName; - std::wstring activeZoneSetTmpFileName; - std::wstring appliedZoneSetTmpFileName; - std::wstring deletedCustomZoneSetsTmpFileName; - mutable std::recursive_mutex dataLock; }; diff --git a/src/modules/fancyzones/lib/JsonHelpers.cpp b/src/modules/fancyzones/lib/JsonHelpers.cpp index 865d6e41d5bc..05bc0808a67f 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.cpp +++ b/src/modules/fancyzones/lib/JsonHelpers.cpp @@ -17,16 +17,13 @@ namespace NonLocalizable { const wchar_t ActiveZoneSetStr[] = L"active-zoneset"; - const wchar_t AppliedZonesets[] = L"applied-zonesets"; const wchar_t AppPathStr[] = L"app-path"; const wchar_t AppZoneHistoryStr[] = L"app-zone-history"; const wchar_t CanvasStr[] = L"canvas"; const wchar_t CellChildMapStr[] = L"cell-child-map"; const wchar_t ColumnsPercentageStr[] = L"columns-percentage"; const wchar_t ColumnsStr[] = L"columns"; - const wchar_t CreatedCustomZoneSets[] = L"created-custom-zone-sets"; const wchar_t CustomZoneSetsStr[] = L"custom-zone-sets"; - const wchar_t DeletedCustomZoneSetsStr[] = L"deleted-custom-zone-sets"; const wchar_t DeviceIdStr[] = L"device-id"; const wchar_t DevicesStr[] = L"devices"; const wchar_t EditorShowSpacingStr[] = L"editor-show-spacing"; @@ -449,64 +446,6 @@ namespace JSONHelpers } } - json::JsonObject AppliedZonesetsJSON::ToJson(const TDeviceInfoMap& deviceInfoMap) - { - json::JsonObject result{}; - - json::JsonArray array; - for (const auto& info : deviceInfoMap) - { - JSONHelpers::DeviceInfoJSON deviceInfoJson{ info.first, info.second }; - array.Append(JSONHelpers::DeviceInfoJSON::ToJson(deviceInfoJson)); - } - - result.SetNamedValue(NonLocalizable::AppliedZonesets, array); - return result; - } - - json::JsonObject AppliedZonesetsJSON::ToJson(const TDeviceInfoMap& deviceInfoMap, const GUID& currentVirtualDesktop) - { - json::JsonObject result{}; - - json::JsonArray array; - for (const auto& info : deviceInfoMap) - { - std::optional id = FancyZonesUtils::ParseDeviceId(info.first); - if (id.has_value() && id->virtualDesktopId == currentVirtualDesktop) - { - JSONHelpers::DeviceInfoJSON deviceInfoJson{ info.first, info.second }; - array.Append(JSONHelpers::DeviceInfoJSON::ToJson(deviceInfoJson)); - } - } - - result.SetNamedValue(NonLocalizable::AppliedZonesets, array); - return result; - } - - std::optional AppliedZonesetsJSON::FromJson(const json::JsonObject& json) - { - try - { - std::unordered_map appliedZonesets; - - auto zonesets = json.GetNamedArray(NonLocalizable::AppliedZonesets); - for (const auto& zoneset : zonesets) - { - std::optional device = DeviceInfoJSON::FromJson(zoneset.GetObjectW()); - if (device.has_value()) - { - appliedZonesets.insert(std::make_pair(device->deviceId, device->data)); - } - } - - return appliedZonesets; - } - catch (const winrt::hresult_error&) - { - return std::nullopt; - } - } - json::JsonObject GetPersistFancyZonesJSON(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName) { auto result = json::from_file(zonesSettingsFileName); @@ -661,104 +600,4 @@ namespace JSONHelpers return customZoneSetsJSON; } - - void SerializeDeviceInfoToTmpFile(const TDeviceInfoMap& deviceInfoMap, const GUID& currentVirtualDesktop, std::wstring_view tmpFilePath) - { - json::to_file(tmpFilePath, JSONHelpers::AppliedZonesetsJSON::ToJson(deviceInfoMap, currentVirtualDesktop)); - } - - void SerializeCustomZoneSetsToTmpFile(const TCustomZoneSetsMap& customZoneSetsMap, std::wstring_view tmpFilePath) - { - json::JsonObject result{}; - - json::JsonArray array; - for (const auto& zoneSet : customZoneSetsMap) - { - CustomZoneSetJSON json{ zoneSet.first, zoneSet.second }; - array.Append(JSONHelpers::CustomZoneSetJSON::ToJson(json)); - } - - result.SetNamedValue(NonLocalizable::CreatedCustomZoneSets, array); - json::to_file(tmpFilePath, result); - } - - std::optional ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath) - { - std::optional result{ std::nullopt }; - if (std::filesystem::exists(tmpFilePath)) - { - if (auto zoneSetJson = json::from_file(tmpFilePath); zoneSetJson.has_value()) - { - if (auto deviceInfo = JSONHelpers::AppliedZonesetsJSON::FromJson(zoneSetJson.value()); deviceInfo.has_value()) - { - result = std::move(deviceInfo); - } - else - { - Logger::trace(L"ParseDeviceInfoFromTmpFile: AppliedZonesetsJSON::FromJson parsing error, {}", zoneSetJson.value().Stringify()); - } - } - } - - DeleteTmpFile(tmpFilePath); - return result; - } - - std::vector ParseCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath) - { - std::vector result; - if (std::filesystem::exists(tmpFilePath)) - { - try - { - if (auto customZoneSetJson = json::from_file(tmpFilePath); customZoneSetJson.has_value()) - { - auto zoneSetArray = customZoneSetJson.value().GetNamedArray(NonLocalizable::CreatedCustomZoneSets); - for (const auto& zoneSet : zoneSetArray) - { - if (auto customZoneSet = JSONHelpers::CustomZoneSetJSON::FromJson(zoneSet.GetObjectW()); customZoneSet.has_value()) - { - result.emplace_back(std::move(*customZoneSet)); - } - else - { - Logger::trace(L"ParseCustomZoneSetsFromTmpFile: CustomZoneSetJSON::FromJson parsing error, {}", zoneSet.GetObjectW().Stringify()); - } - } - } - } - catch (const winrt::hresult_error& err) - { - Logger::trace(L"ParseCustomZoneSetsFromTmpFile: CustomZoneSetJSON::FromJson parsing error, {}", err.message()); - } - - DeleteTmpFile(tmpFilePath); - } - return result; - } - - std::vector ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath) - { - std::vector result{}; - if (std::filesystem::exists(tmpFilePath)) - { - auto deletedZoneSetsJson = json::from_file(tmpFilePath); - try - { - auto deletedCustomZoneSets = deletedZoneSetsJson->GetNamedArray(NonLocalizable::DeletedCustomZoneSetsStr); - for (auto zoneSet : deletedCustomZoneSets) - { - std::wstring uuid = L"{" + std::wstring{ zoneSet.GetString() } + L"}"; - result.push_back(uuid); - } - } - catch (const winrt::hresult_error&) - { - } - - DeleteTmpFile(tmpFilePath); - } - - return result; - } } \ No newline at end of file diff --git a/src/modules/fancyzones/lib/JsonHelpers.h b/src/modules/fancyzones/lib/JsonHelpers.h index 81f5911391fa..720b77d1f95f 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.h +++ b/src/modules/fancyzones/lib/JsonHelpers.h @@ -59,13 +59,6 @@ namespace JSONHelpers using TDeviceInfoMap = std::unordered_map; using TCustomZoneSetsMap = std::unordered_map; - struct AppliedZonesetsJSON - { - static json::JsonObject ToJson(const TDeviceInfoMap& deviceInfoMap); - static json::JsonObject ToJson(const TDeviceInfoMap& deviceInfoMap, const GUID& currentVirtualDesktop); - static std::optional FromJson(const json::JsonObject& json); - }; - json::JsonObject GetPersistFancyZonesJSON(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName); void SaveFancyZonesData(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName, @@ -81,14 +74,4 @@ namespace JSONHelpers TCustomZoneSetsMap ParseCustomZoneSets(const json::JsonObject& fancyZonesDataJSON); json::JsonArray SerializeCustomZoneSets(const TCustomZoneSetsMap& customZoneSetsMap); - - void SerializeDeviceInfoToTmpFile(const TDeviceInfoMap& deviceInfoMap, const GUID& currentVirtualDesktop, std::wstring_view tmpFilePath); - std::optional ParseDeviceInfoFromTmpFile(std::wstring_view tmpFilePath); - std::vector ParseCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath); - std::vector ParseDeletedCustomZoneSetsFromTmpFile(std::wstring_view tmpFilePath); - -#if defined(UNIT_TESTS) - void SerializeCustomZoneSetsToTmpFile(const TCustomZoneSetsMap& customZoneSetsMap, std::wstring_view tmpFilePath); -#endif - } diff --git a/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp b/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp index 61b1a1415f03..18ed9467e3ae 100644 --- a/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp +++ b/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp @@ -938,92 +938,6 @@ namespace FancyZonesUnitTests } }; - TEST_CLASS(AppliedZonesetsUnitTests) - { - TEST_METHOD(SingleDevice) - { - const std::wstring deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}"; - const std::wstring zoneUuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}"; - const ZoneSetLayoutType type = ZoneSetLayoutType::Custom; - DeviceInfoData data{ ZoneSetData{ zoneUuid, type }, true, 10, 4 }; - - TDeviceInfoMap expected; - expected.insert(std::make_pair(deviceId, data)); - - json::JsonObject json = AppliedZonesetsJSON::ToJson(expected); - auto actual = AppliedZonesetsJSON::FromJson(json); - - Assert::IsTrue(actual.has_value()); - Assert::AreEqual(expected.size(), actual->size()); - for (const auto& exp : expected) - { - Assert::IsTrue(actual->contains(exp.first)); - - const auto act = actual->find(exp.first); - Assert::AreEqual(exp.second.zoneCount, act->second.zoneCount); - Assert::AreEqual(exp.second.showSpacing, act->second.showSpacing); - Assert::AreEqual(exp.second.spacing, act->second.spacing); - Assert::AreEqual(exp.second.activeZoneSet.uuid, act->second.activeZoneSet.uuid); - Assert::AreEqual((int)exp.second.activeZoneSet.type, (int)act->second.activeZoneSet.type); - } - } - - TEST_METHOD (MultipleDevices) - { - TDeviceInfoMap expected; - expected.insert(std::make_pair(L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}", DeviceInfoData{ ZoneSetData{ L"{33A2B101-06E0-437B-A61E-CDBECF502906}", ZoneSetLayoutType::Columns }, true, 10, 4 })); - expected.insert(std::make_pair(L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1538}", DeviceInfoData{ ZoneSetData{ L"{33A2B101-06E0-437B-A61E-CDBECF502905}", ZoneSetLayoutType::Rows }, false, 8, 5 })); - expected.insert(std::make_pair(L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1537}", DeviceInfoData{ ZoneSetData{ L"{33A2B101-06E0-437B-A61E-CDBECF502904}", ZoneSetLayoutType::Grid }, true, 9, 6 })); - - json::JsonObject json = AppliedZonesetsJSON::ToJson(expected); - auto actual = AppliedZonesetsJSON::FromJson(json); - - Assert::IsTrue(actual.has_value()); - Assert::AreEqual(expected.size(), actual->size()); - for (const auto& exp : expected) - { - Assert::IsTrue(actual->contains(exp.first)); - - const auto act = actual->find(exp.first); - Assert::AreEqual(exp.second.zoneCount, act->second.zoneCount); - Assert::AreEqual(exp.second.showSpacing, act->second.showSpacing); - Assert::AreEqual(exp.second.spacing, act->second.spacing); - Assert::AreEqual(exp.second.activeZoneSet.uuid, act->second.activeZoneSet.uuid); - Assert::AreEqual((int)exp.second.activeZoneSet.type, (int)act->second.activeZoneSet.type); - } - } - - TEST_METHOD (FromJsonNoDeviceId) - { - json::JsonObject json = json::JsonObject::Parse(L"{\"applied-zonesets\": [{\"device-id\": \"\",\"active-zoneset\": {\"uuid\": \"{81B9FCD3-88CA-4B21-A681-5D1129A1527F}\",\"type\": \"grid\"},\"editor-show-spacing\": true,\"editor-spacing\": 5,\"editor-zone-count\": 4},{\"device-id\": \"\",\"active-zoneset\": {\"uuid\": \"{8110E0D5-4815-4A35-A5AC-DF82A65FF58B}\",\"type\": \"priority-grid\"},\"editor-show-spacing\": false,\"editor-spacing\": 6,\"editor-zone-count\": 2}]}"); - auto actual = AppliedZonesetsJSON::FromJson(json); - Assert::IsTrue(actual.has_value()); - Assert::IsTrue(actual->empty()); - } - - TEST_METHOD (FromInvalidJsonNotArray) - { - json::JsonObject json = json::JsonObject::Parse(L"{\"applied-zonesets\": {\"device-id\": \"\",\"active-zoneset\": {\"uuid\": \"{81B9FCD3-88CA-4B21-A681-5D1129A1527F}\",\"type\": \"grid\"},\"editor-show-spacing\": true,\"editor-spacing\": 5,\"editor-zone-count\": 4}}"); - auto actual = AppliedZonesetsJSON::FromJson(json); - Assert::IsFalse(actual.has_value()); - } - - TEST_METHOD (FromEmptyJson) - { - json::JsonObject json = json::JsonObject::Parse(L"{}"); - auto actual = AppliedZonesetsJSON::FromJson(json); - Assert::IsFalse(actual.has_value()); - } - - TEST_METHOD (FromEmptyDeviceArray) - { - json::JsonObject json = json::JsonObject::Parse(L"{\"applied-zonesets\": []}"); - auto actual = AppliedZonesetsJSON::FromJson(json); - Assert::IsTrue(actual.has_value()); - Assert::IsTrue(actual->empty()); - } - }; - TEST_CLASS (FancyZonesDataUnitTests) { private: @@ -1186,74 +1100,6 @@ namespace FancyZonesUnitTests compareJsonArrays(expectedDevices, actual); } - TEST_METHOD (DeviceInfoSaveTemp) - { - FancyZonesData data; - data.SetSettingsModulePath(m_moduleName); - - TDeviceInfoMap deviceInfoMap; - DeviceInfoData deviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 }; - deviceInfoMap.insert(std::make_pair(m_defaultDeviceId, deviceInfoData)); - - const std::wstring path = data.zonesSettingsFileName + L".test_tmp"; - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, m_defaultVDId, path); - - bool actualFileExists = std::filesystem::exists(path); - Assert::IsTrue(actualFileExists); - - auto expectedData = AppliedZonesetsJSON::ToJson(deviceInfoMap); - auto actualSavedData = json::from_file(path); - std::filesystem::remove(path); //clean up before compare asserts - - Assert::IsTrue(actualSavedData.has_value()); - compareJsonObjects(expectedData, *actualSavedData); - } - - TEST_METHOD (DeviceInfoReadTemp) - { - FancyZonesData data; - data.SetSettingsModulePath(m_moduleName); - - const std::wstring deviceId = m_defaultDeviceId; - DeviceInfoData expected{ ZoneSetData{ L"{33A2B101-06E0-437B-A61E-CDBECF502906}", ZoneSetLayoutType::Custom }, true, 16, 3 }; - - TDeviceInfoMap expectedDeviceInfoMap; - expectedDeviceInfoMap.insert(std::make_pair(deviceId, expected)); - - const std::wstring path = data.zonesSettingsFileName + L".test_tmp"; - JSONHelpers::SerializeDeviceInfoToTmpFile(expectedDeviceInfoMap, m_defaultVDId, path); - - data.ParseDeviceInfoFromTmpFile(path); - - bool actualFileExists = std::filesystem::exists(path); - if (actualFileExists) - { - std::filesystem::remove(path); //clean up before compare asserts - } - Assert::IsFalse(actualFileExists); - - auto devices = data.GetDeviceInfoMap(); - Assert::AreEqual((size_t)1, devices.size()); - - auto actual = devices.find(deviceId)->second; - Assert::AreEqual(expected.showSpacing, actual.showSpacing); - Assert::AreEqual(expected.spacing, actual.spacing); - Assert::AreEqual(expected.zoneCount, actual.zoneCount); - Assert::AreEqual((int)expected.activeZoneSet.type, (int)actual.activeZoneSet.type); - Assert::AreEqual(expected.activeZoneSet.uuid.c_str(), actual.activeZoneSet.uuid.c_str()); - } - - TEST_METHOD (DeviceInfoReadTempNonexistent) - { - FancyZonesData data; - data.SetSettingsModulePath(m_moduleName); - const std::wstring path = data.zonesSettingsFileName + L".test_tmp"; - data.ParseDeviceInfoFromTmpFile(path); - - auto devices = data.GetDeviceInfoMap(); - Assert::AreEqual((size_t)0, devices.size()); - } - TEST_METHOD (AppZoneHistoryParseSingle) { const std::wstring expectedAppPath = L"appPath"; @@ -1619,72 +1465,6 @@ namespace FancyZonesUnitTests compareJsonArrays(expected, actual); } - TEST_METHOD (CustomZoneSetsReadTemp) - { - //prepare device data - const std::wstring deviceId = L"default_device_id"; - - { - TDeviceInfoMap deviceInfoMap; - DeviceInfoData deviceInfoData { ZoneSetData{ L"{33A2B101-06E0-437B-A61E-CDBECF502906}", ZoneSetLayoutType::Custom }, true, 16, 3 }; - deviceInfoMap.insert(std::make_pair(deviceId, deviceInfoData)); - - const std::wstring deviceInfoPath = m_fzData.zonesSettingsFileName + L".device_info_tmp"; - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, m_defaultVDId, deviceInfoPath); - - m_fzData.ParseDeviceInfoFromTmpFile(deviceInfoPath); - std::filesystem::remove(deviceInfoPath); - } - - const std::wstring uuid = L"{33A2B101-06E0-437B-A61E-CDBECF502906}"; - const GridLayoutInfo grid(GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Full{ - .rows = 1, - .columns = 3, - .rowsPercents = { 10000 }, - .columnsPercents = { 2500, 5000, 2500 }, - .cellChildMap = { { 0, 1, 2 } } })); - CustomZoneSetData zoneSetData{ L"name", CustomLayoutType::Grid, grid }; - CustomZoneSetJSON expected{ uuid, zoneSetData }; - - FancyZonesData data; - data.SetSettingsModulePath(m_moduleName); - const std::wstring path = data.zonesSettingsFileName + L".test_tmp"; - - TCustomZoneSetsMap customZoneSets; - customZoneSets.insert(std::make_pair(uuid, zoneSetData)); - JSONHelpers::SerializeCustomZoneSetsToTmpFile(customZoneSets, path); - - m_fzData.ParseCustomZoneSetsFromTmpFile(path); - - bool actualFileExists = std::filesystem::exists(path); - if (actualFileExists) - { - std::filesystem::remove(path); //clean up before compare asserts - } - Assert::IsFalse(actualFileExists); - - auto devices = m_fzData.GetCustomZoneSetsMap(); - Assert::AreEqual((size_t)1, devices.size()); - - auto actual = devices.find(uuid)->second; - Assert::AreEqual((int)expected.data.type, (int)actual.type); - Assert::AreEqual(expected.data.name.c_str(), actual.name.c_str()); - auto expectedGrid = std::get(expected.data.info); - auto actualGrid = std::get(actual.info); - Assert::AreEqual(expectedGrid.rows(), actualGrid.rows()); - Assert::AreEqual(expectedGrid.columns(), actualGrid.columns()); - } - - TEST_METHOD (CustomZoneSetsReadTempNonexistent) - { - const std::wstring path = m_fzData.zonesSettingsFileName + L".test_tmp"; - const std::wstring deviceId = L"default_device_id"; - - m_fzData.ParseCustomZoneSetsFromTmpFile(path); - auto devices = m_fzData.GetDeviceInfoMap(); - Assert::AreEqual((size_t)0, devices.size()); - } - TEST_METHOD (SetActiveZoneSet) { FancyZonesData data; diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp index 7c4460c06649..d8ae004088ad 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp @@ -1047,34 +1047,16 @@ namespace FancyZonesUnitTests TEST_METHOD (CustomZoneFromValidCanvasLayoutInfo) { //prepare device data - { - const std::wstring zoneUuid = L"default_device_id"; - - JSONHelpers::TDeviceInfoMap deviceInfoMap; - deviceInfoMap.insert(std::make_pair(zoneUuid, DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 })); - - GUID virtualDesktopId{}; - Assert::IsTrue(VirtualDesktopUtils::GetCurrentVirtualDesktopId(&virtualDesktopId), L"Cannot create virtual desktop id"); - const std::wstring deviceInfoPath = FancyZonesDataInstance().zonesSettingsFileName + L".device_info_tmp"; - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, virtualDesktopId, deviceInfoPath); - - FancyZonesDataInstance().ParseDeviceInfoFromTmpFile(deviceInfoPath); - std::filesystem::remove(deviceInfoPath); - } + const std::wstring zoneUuid = L"default_device_id"; + FancyZonesDataInstance().SetDeviceInfo(zoneUuid, DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 }); //prepare expected data wil::unique_cotaskmem_string uuid; Assert::AreEqual(S_OK, StringFromCLSID(m_id, &uuid)); const CanvasLayoutInfo info{ 123, 321, { CanvasLayoutInfo::Rect{ 0, 0, 100, 100 }, CanvasLayoutInfo::Rect{ 50, 50, 150, 150 } } }; CustomZoneSetData zoneSetData{ L"name", CustomLayoutType::Canvas, info }; - JSONHelpers::CustomZoneSetJSON expected{ uuid.get(), zoneSetData }; - JSONHelpers::TCustomZoneSetsMap customZoneSets; - customZoneSets.insert(std::make_pair(uuid.get(), zoneSetData)); - JSONHelpers::SerializeCustomZoneSetsToTmpFile(customZoneSets, m_path); - - Assert::IsTrue(std::filesystem::exists(m_path)); - FancyZonesDataInstance().ParseCustomZoneSetsFromTmpFile(m_path); - + FancyZonesDataInstance().SetCustomZonesets(uuid.get(), zoneSetData); + //test const int spacing = 10; const int zoneCount = static_cast(info.zones.size()); @@ -1091,20 +1073,8 @@ namespace FancyZonesUnitTests TEST_METHOD (CustomZoneFromValidGridFullLayoutInfo) { //prepare device data - { - const std::wstring zoneUuid = L"default_device_id"; - - JSONHelpers::TDeviceInfoMap deviceInfoMap; - deviceInfoMap.insert(std::make_pair(zoneUuid, DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 })); - - GUID virtualDesktopId{}; - Assert::IsTrue(VirtualDesktopUtils::GetCurrentVirtualDesktopId(&virtualDesktopId), L"Cannot create virtual desktop id"); - const std::wstring deviceInfoPath = FancyZonesDataInstance().zonesSettingsFileName + L".device_info_tmp"; - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, virtualDesktopId, deviceInfoPath); - - FancyZonesDataInstance().ParseDeviceInfoFromTmpFile(deviceInfoPath); - std::filesystem::remove(deviceInfoPath); - } + const std::wstring zoneUuid = L"default_device_id"; + FancyZonesDataInstance().SetDeviceInfo(zoneUuid, DeviceInfoData{ ZoneSetData{ L"uuid", ZoneSetLayoutType::Custom }, true, 16, 3 }); //prepare expected data wil::unique_cotaskmem_string uuid; @@ -1116,13 +1086,7 @@ namespace FancyZonesUnitTests .columnsPercents = { 2500, 5000, 2500 }, .cellChildMap = { { 0, 1, 2 } } })); CustomZoneSetData zoneSetData{ L"name", CustomLayoutType::Grid, grid }; - JSONHelpers::CustomZoneSetJSON expected{ uuid.get(), zoneSetData }; - JSONHelpers::TCustomZoneSetsMap customZoneSets; - customZoneSets.insert(std::make_pair(uuid.get(), zoneSetData)); - JSONHelpers::SerializeCustomZoneSetsToTmpFile(customZoneSets, m_path); - - Assert::IsTrue(std::filesystem::exists(m_path)); - FancyZonesDataInstance().ParseCustomZoneSetsFromTmpFile(m_path); + FancyZonesDataInstance().SetCustomZonesets(uuid.get(), zoneSetData); const int spacing = 10; const int zoneCount = grid.rows() * grid.columns(); diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp index baba9c16fb2d..416514a21467 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp @@ -175,225 +175,9 @@ namespace FancyZonesUnitTests Assert::AreEqual(activeZoneSet->GetZones().size(), static_cast(3)); } - TEST_METHOD (CreateZoneWindowWithActiveZoneTmpFile) - { - using namespace FancyZonesDataTypes; - - const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName; - - for (int type = static_cast(ZoneSetLayoutType::Focus); type < static_cast(ZoneSetLayoutType::Custom); type++) - { - const auto expectedZoneSet = ZoneSetData{ Helpers::CreateGuidString(), static_cast(type) }; - const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 }; - const auto deviceInfo = JSONHelpers::DeviceInfoJSON{ m_uniqueId.str(), data }; - const auto json = JSONHelpers::DeviceInfoJSON::ToJson(deviceInfo); - json::to_file(activeZoneSetTempPath, json); - - m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); - - //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); - - testZoneWindow(actual); - - Assert::IsNotNull(actual->ActiveZoneSet()); - } - } - - TEST_METHOD (CreateZoneWindowWithActiveCustomZoneTmpFile) - { - using namespace FancyZonesDataTypes; - - const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName; - - const ZoneSetLayoutType type = ZoneSetLayoutType::Custom; - const auto expectedZoneSet = ZoneSetData{ Helpers::CreateGuidString(), type }; - const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 }; - JSONHelpers::TDeviceInfoMap deviceInfoMap; - deviceInfoMap.insert(std::make_pair(m_uniqueId.str(), data)); - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, m_virtualDesktopGuid, activeZoneSetTempPath); - - m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); - - //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); - - testZoneWindow(actual); - - //custom zone needs temp file for applied zone - Assert::IsNotNull(actual->ActiveZoneSet()); - const auto actualZoneSet = actual->ActiveZoneSet()->GetZones(); - Assert::AreEqual((size_t)0, actualZoneSet.size()); - } - - TEST_METHOD (CreateZoneWindowWithActiveCustomZoneAppliedTmpFile) - { - using namespace FancyZonesDataTypes; - - //save required data - const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName; - const auto appliedZoneSetTempPath = m_fancyZonesData.appliedZoneSetTmpFileName; - - const ZoneSetLayoutType type = ZoneSetLayoutType::Custom; - const auto customSetGuid = Helpers::CreateGuidString(); - const auto expectedZoneSet = ZoneSetData{ customSetGuid, type }; - const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 }; - JSONHelpers::TDeviceInfoMap deviceInfoMap; - deviceInfoMap.insert(std::make_pair(m_uniqueId.str(), data)); - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, m_virtualDesktopGuid, activeZoneSetTempPath); - - const auto info = CanvasLayoutInfo{ - 100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } } - }; - const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info }; - auto customZoneJson = JSONHelpers::CustomZoneSetJSON::ToJson(JSONHelpers::CustomZoneSetJSON{ customSetGuid, customZoneData }); - JSONHelpers::TCustomZoneSetsMap customZoneSets; - customZoneSets.insert(std::make_pair(customSetGuid, customZoneData)); - JSONHelpers::SerializeCustomZoneSetsToTmpFile(customZoneSets, appliedZoneSetTempPath); - m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); - m_fancyZonesData.ParseCustomZoneSetsFromTmpFile(appliedZoneSetTempPath); - - //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); - - testZoneWindow(actual); - - //custom zone needs temp file for applied zone - Assert::IsNotNull(actual->ActiveZoneSet()); - const auto actualZoneSet = actual->ActiveZoneSet()->GetZones(); - Assert::AreEqual((size_t)1, actualZoneSet.size()); - } - - TEST_METHOD (CreateZoneWindowWithActiveCustomZoneAppliedTmpFileWithDeletedCustomZones) - { - using namespace FancyZonesDataTypes; - - //save required data - const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName; - const auto appliedZoneSetTempPath = m_fancyZonesData.appliedZoneSetTmpFileName; - const auto deletedZonesTempPath = m_fancyZonesData.deletedCustomZoneSetsTmpFileName; - - const ZoneSetLayoutType type = ZoneSetLayoutType::Custom; - const auto customSetGuid = Helpers::CreateGuidString(); - const auto expectedZoneSet = ZoneSetData{ customSetGuid, type }; - const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 }; - JSONHelpers::TDeviceInfoMap deviceInfoMap; - deviceInfoMap.insert(std::make_pair(m_uniqueId.str(), data)); - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, m_virtualDesktopGuid, activeZoneSetTempPath); - - const auto info = CanvasLayoutInfo{ - 100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } } - }; - const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info }; - const auto customZoneSet = JSONHelpers::CustomZoneSetJSON{ customSetGuid, customZoneData }; - auto customZoneJson = JSONHelpers::CustomZoneSetJSON::ToJson(customZoneSet); - JSONHelpers::TCustomZoneSetsMap customZoneSets; - customZoneSets.insert(std::make_pair(customSetGuid, customZoneData)); - JSONHelpers::SerializeCustomZoneSetsToTmpFile(customZoneSets, appliedZoneSetTempPath); - - //save same zone as deleted - json::JsonObject deletedCustomZoneSets = {}; - json::JsonArray zonesArray{}; - zonesArray.Append(json::JsonValue::CreateStringValue(customZoneSet.uuid.substr(1, customZoneSet.uuid.size() - 2).c_str())); - deletedCustomZoneSets.SetNamedValue(L"deleted-custom-zone-sets", zonesArray); - json::to_file(deletedZonesTempPath, deletedCustomZoneSets); - - m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); - m_fancyZonesData.ParseDeletedCustomZoneSetsFromTmpFile(deletedZonesTempPath); - m_fancyZonesData.ParseCustomZoneSetsFromTmpFile(appliedZoneSetTempPath); - - //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); - - testZoneWindow(actual); - - Assert::IsNotNull(actual->ActiveZoneSet()); - const auto actualZoneSet = actual->ActiveZoneSet()->GetZones(); - Assert::AreEqual((size_t)1, actualZoneSet.size()); - } - - TEST_METHOD (CreateZoneWindowWithActiveCustomZoneAppliedTmpFileWithUnusedDeletedCustomZones) - { - using namespace FancyZonesDataTypes; - - //save required data - const auto activeZoneSetTempPath = m_fancyZonesData.activeZoneSetTmpFileName; - const auto appliedZoneSetTempPath = m_fancyZonesData.appliedZoneSetTmpFileName; - const auto deletedZonesTempPath = m_fancyZonesData.deletedCustomZoneSetsTmpFileName; - - const ZoneSetLayoutType type = ZoneSetLayoutType::Custom; - const auto customSetGuid = Helpers::CreateGuidString(); - const auto expectedZoneSet = ZoneSetData{ customSetGuid, type }; - const auto data = DeviceInfoData{ expectedZoneSet, true, 16, 3 }; - JSONHelpers::TDeviceInfoMap deviceInfoMap; - deviceInfoMap.insert(std::make_pair(m_uniqueId.str(), data)); - JSONHelpers::SerializeDeviceInfoToTmpFile(deviceInfoMap, m_virtualDesktopGuid, activeZoneSetTempPath); - - const auto info = CanvasLayoutInfo{ - 100, 100, std::vector{ CanvasLayoutInfo::Rect{ 0, 0, 100, 100 } } - }; - const auto customZoneData = CustomZoneSetData{ L"name", CustomLayoutType::Canvas, info }; - const auto customZoneSet = JSONHelpers::CustomZoneSetJSON{ customSetGuid, customZoneData }; - auto customZoneJson = JSONHelpers::CustomZoneSetJSON::ToJson(customZoneSet); - JSONHelpers::TCustomZoneSetsMap customZoneSets; - customZoneSets.insert(std::make_pair(customSetGuid, customZoneData)); - JSONHelpers::SerializeCustomZoneSetsToTmpFile(customZoneSets, appliedZoneSetTempPath); - - //save different zone as deleted - json::JsonObject deletedCustomZoneSets = {}; - json::JsonArray zonesArray{}; - const auto uuid = Helpers::CreateGuidString(); - zonesArray.Append(json::JsonValue::CreateStringValue(uuid.substr(1, uuid.size() - 2).c_str())); - deletedCustomZoneSets.SetNamedValue(L"deleted-custom-zone-sets", zonesArray); - json::to_file(deletedZonesTempPath, deletedCustomZoneSets); - - m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath); - m_fancyZonesData.ParseDeletedCustomZoneSetsFromTmpFile(deletedZonesTempPath); - m_fancyZonesData.ParseCustomZoneSetsFromTmpFile(appliedZoneSetTempPath); - - //temp file read on initialization - auto actual = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), {}); - - testZoneWindow(actual); - - Assert::IsNotNull(actual->ActiveZoneSet()); - const auto actualZoneSet = actual->ActiveZoneSet()->GetZones(); - Assert::AreEqual((size_t)1, actualZoneSet.size()); - } - - TEST_METHOD (CreateZoneWindowClonedFromParent) - { - using namespace FancyZonesDataTypes; - - const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid; - const int spacing = 10; - const int zoneCount = 5; - const auto customSetGuid = Helpers::CreateGuidString(); - const auto parentZoneSet = ZoneSetData{ customSetGuid, type }; - const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount }; - m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo); - - winrt::com_ptr zoneWindowHost = winrt::make_self(); - auto parentZoneWindow = MakeZoneWindow(zoneWindowHost.get(), m_hInst, m_monitor, m_parentUniqueId.str(), {}); - zoneWindowHost->m_zoneWindow = parentZoneWindow.get(); - - // newWorkArea = true - zoneWindow will be cloned from parent - auto actualZoneWindow = MakeZoneWindow(winrt::make_self().get(), m_hInst, m_monitor, m_uniqueId.str(), m_parentUniqueId.str()); - - Assert::IsNotNull(actualZoneWindow->ActiveZoneSet()); - const auto actualZoneSet = actualZoneWindow->ActiveZoneSet()->GetZones(); - Assert::AreEqual((size_t)zoneCount, actualZoneSet.size()); - - Assert::IsTrue(m_fancyZonesData.GetDeviceInfoMap().contains(m_uniqueId.str())); - auto currentDeviceInfo = m_fancyZonesData.GetDeviceInfoMap().at(m_uniqueId.str()); - Assert::AreEqual(zoneCount, currentDeviceInfo.zoneCount); - Assert::AreEqual(spacing, currentDeviceInfo.spacing); - Assert::AreEqual(static_cast(type), static_cast(currentDeviceInfo.activeZoneSet.type)); - } - - TEST_METHOD (CreateZoneWindowNotClonedFromParent) - { - using namespace FancyZonesDataTypes; + TEST_METHOD (CreateZoneWindowClonedFromParent) + { + using namespace FancyZonesDataTypes; const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid; const int spacing = 10; From 9ebef38e792210abc3d499879b39899e0c543246 Mon Sep 17 00:00:00 2001 From: Serafima Date: Thu, 17 Dec 2020 11:53:34 +0300 Subject: [PATCH 25/38] conflicts fix --- .../FancyZonesEditor/FancyZonesEditor.csproj | 191 +----------------- 1 file changed, 7 insertions(+), 184 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj index 326fbd040d1d..d91a91d8dc2e 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj +++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj @@ -53,172 +53,7 @@ - - MSBuild:Compile - Designer - - - GlobalSuppressions.cs - - - - - - - LayoutOverlayWindow.xaml - - - - - - True - True - Resources.resx - - - - - CanvasEditor.xaml - - - - GridEditor.xaml - - - GridResizer.xaml - - - LayoutPreview.xaml - - - - - - - - - - GridEditorWindow.xaml - - - - - - - - - - - - - - - WindowLayout.xaml - - - CanvasEditorWindow.xaml - - - CanvasZone.xaml - - - GridZone.xaml - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - MainWindow.xaml - Code - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - - - Code - - - True - Settings.settings - True - - + PublicResXFileCodeGenerator Resources.Designer.cs @@ -230,26 +65,14 @@ - - 4.4.0 - - - 0.9.2 - - - 12.2.5 - - - 6.6.30107 - - - 4.7.2 - - - 1.1.118 - runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + From fff8b3a50e6c1f5983a884afb741fd0ed563b489 Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Fri, 18 Dec 2020 13:22:40 +0300 Subject: [PATCH 26/38] [FZ Editor] Parse json file instead of command line args (#8649) --- .../editor/FancyZonesEditor/App.xaml.cs | 5 +- .../Utils/FancyZonesEditorIO.cs | 158 +++++++++++++++--- src/modules/fancyzones/lib/FancyZones.cpp | 26 ++- src/modules/fancyzones/lib/FancyZonesData.cpp | 48 ++++++ src/modules/fancyzones/lib/FancyZonesData.h | 3 + src/modules/fancyzones/lib/JsonHelpers.cpp | 41 +++++ src/modules/fancyzones/lib/JsonHelpers.h | 20 +++ .../tests/UnitTests/JsonHelpers.Tests.cpp | 34 ++++ 8 files changed, 300 insertions(+), 35 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs index 019b634902da..ba939028d57d 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml.cs @@ -91,7 +91,10 @@ private void OnStartup(object sender, StartupEventArgs e) _themeManager = new ThemeManager(this); - FancyZonesEditorIO.ParseCommandLineArguments(); + if (!FancyZonesEditorIO.ParseParams().Result) + { + FancyZonesEditorIO.ParseCommandLineArguments(); + } var parseResult = FancyZonesEditorIO.ParseZoneSettings(); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs index 14f322102565..636debcbe773 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs @@ -26,6 +26,7 @@ public class FancyZonesEditorIO // Non-localizable strings: Files private const string ZonesSettingsFile = "\\Microsoft\\PowerToys\\FancyZones\\zones-settings.json"; + private const string ParamsFile = "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.json"; // Non-localizable string: Multi-monitor id private const string MultiMonitorId = "FancyZones#MultiMonitorDevice"; @@ -39,6 +40,8 @@ public class FancyZonesEditorIO public string FancyZonesSettingsFile { get; private set; } + public string FancyZonesEditorParamsFile { get; private set; } + private enum CmdArgs { PowerToysPID = 0, @@ -53,27 +56,29 @@ private enum CmdArgs private struct NativeMonitorData { - public string Id { get; set; } + public string MonitorId { get; set; } public int Dpi { get; set; } - public int X { get; set; } + public int LeftCoordinate { get; set; } + + public int TopCoordinate { get; set; } - public int Y { get; set; } + public bool IsSelected { get; set; } public override string ToString() { var sb = new StringBuilder(); sb.Append("ID: "); - sb.AppendLine(Id); + sb.AppendLine(MonitorId); sb.Append("DPI: "); sb.AppendLine(Dpi.ToString()); sb.Append("X: "); - sb.AppendLine(X.ToString()); + sb.AppendLine(LeftCoordinate.ToString()); sb.Append("Y: "); - sb.AppendLine(Y.ToString()); + sb.AppendLine(TopCoordinate.ToString()); return sb.ToString(); } @@ -152,6 +157,15 @@ private struct ZoneSettingsWrapper public List CustomZoneSets { get; set; } } + private struct EditorParams + { + public int ProcessId { get; set; } + + public bool SpanZonesAcrossMonitors { get; set; } + + public List Monitors { get; set; } + } + public struct ParsingResult { public bool Result { get; } @@ -172,6 +186,7 @@ public FancyZonesEditorIO() { var localAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); FancyZonesSettingsFile = localAppDataDir + ZonesSettingsFile; + FancyZonesEditorParamsFile = localAppDataDir + ParamsFile; } // All strings in this function shouldn't be localized. @@ -239,14 +254,14 @@ public static void ParseCommandLineArguments() for (int i = 0; i < count; i++) { var nativeData = default(NativeMonitorData); - nativeData.Id = argsParts[(int)CmdArgs.MonitorId + (i * monitorArgsCount)]; + nativeData.MonitorId = argsParts[(int)CmdArgs.MonitorId + (i * monitorArgsCount)]; nativeData.Dpi = int.Parse(argsParts[(int)CmdArgs.DPI + (i * monitorArgsCount)]); - nativeData.X = int.Parse(argsParts[(int)CmdArgs.MonitorLeft + (i * monitorArgsCount)]); - nativeData.Y = int.Parse(argsParts[(int)CmdArgs.MonitorTop + (i * monitorArgsCount)]); + nativeData.LeftCoordinate = int.Parse(argsParts[(int)CmdArgs.MonitorLeft + (i * monitorArgsCount)]); + nativeData.TopCoordinate = int.Parse(argsParts[(int)CmdArgs.MonitorTop + (i * monitorArgsCount)]); nativeMonitorData.Add(nativeData); - if (nativeData.X == 0 && nativeData.Y == 0) + if (nativeData.LeftCoordinate == 0 && nativeData.TopCoordinate == 0) { primaryMonitorDPI = nativeData.Dpi; } @@ -266,15 +281,15 @@ public static void ParseCommandLineArguments() { foreach (NativeMonitorData nativeData in nativeMonitorData) { - var splittedId = nativeData.Id.Split('_'); + var splittedId = nativeData.MonitorId.Split('_'); int width = int.Parse(splittedId[1]); int height = int.Parse(splittedId[2]); - Rect bounds = new Rect(nativeData.X, nativeData.Y, width, height); - bool isPrimary = nativeData.X == 0 && nativeData.Y == 0; + Rect bounds = new Rect(nativeData.LeftCoordinate, nativeData.TopCoordinate, width, height); + bool isPrimary = nativeData.LeftCoordinate == 0 && nativeData.TopCoordinate == 0; Monitor monitor = new Monitor(bounds, bounds, isPrimary); - monitor.Device.Id = nativeData.Id; + monitor.Device.Id = nativeData.MonitorId; monitor.Device.Dpi = nativeData.Dpi; monitors.Add(monitor); @@ -293,10 +308,10 @@ public static void ParseCommandLineArguments() foreach (NativeMonitorData nativeData in nativeMonitorData) { // Can't do an exact match since the rounding algorithm used by the framework is different from ours - if (scaledBoundX >= (nativeData.X - 1) && scaledBoundX <= (nativeData.X + 1) && - scaledBoundY >= (nativeData.Y - 1) && scaledBoundY <= (nativeData.Y + 1)) + if (scaledBoundX >= (nativeData.LeftCoordinate - 1) && scaledBoundX <= (nativeData.LeftCoordinate + 1) && + scaledBoundY >= (nativeData.TopCoordinate - 1) && scaledBoundY <= (nativeData.TopCoordinate + 1)) { - monitor.Device.Id = nativeData.Id; + monitor.Device.Id = nativeData.MonitorId; monitor.Device.Dpi = nativeData.Dpi; matchFound = true; break; @@ -329,6 +344,111 @@ public static void ParseCommandLineArguments() } } + public ParsingResult ParseParams() + { + if (_fileSystem.File.Exists(FancyZonesEditorParamsFile)) + { + string data = string.Empty; + + try + { + data = ReadFile(FancyZonesEditorParamsFile); + EditorParams editorParams = JsonSerializer.Deserialize(data, _options); + + // Process ID + App.PowerToysPID = editorParams.ProcessId; + + // Span zones across monitors + App.Overlay.SpanZonesAcrossMonitors = editorParams.SpanZonesAcrossMonitors; + + if (!App.Overlay.SpanZonesAcrossMonitors) + { + // Monitors count + if (editorParams.Monitors.Count != App.Overlay.DesktopsCount) + { + MessageBox.Show(Properties.Resources.Error_Invalid_Arguments, Properties.Resources.Error_Message_Box_Title); + ((App)Application.Current).Shutdown(); + } + + string targetMonitorName = string.Empty; + + double primaryMonitorDPI = 96f; + double minimalUsedMonitorDPI = double.MaxValue; + foreach (NativeMonitorData nativeData in editorParams.Monitors) + { + if (nativeData.LeftCoordinate == 0 && nativeData.TopCoordinate == 0) + { + primaryMonitorDPI = nativeData.Dpi; + } + + if (minimalUsedMonitorDPI > nativeData.Dpi) + { + minimalUsedMonitorDPI = nativeData.Dpi; + } + + if (nativeData.IsSelected) + { + targetMonitorName = nativeData.MonitorId; + } + } + + var monitors = App.Overlay.Monitors; + double identifyScaleFactor = minimalUsedMonitorDPI / primaryMonitorDPI; + double scaleFactor = 96f / primaryMonitorDPI; + + // Update monitors data + foreach (Monitor monitor in monitors) + { + bool matchFound = false; + monitor.Scale(scaleFactor); + + double scaledBoundX = (int)(monitor.Device.UnscaledBounds.X * identifyScaleFactor); + double scaledBoundY = (int)(monitor.Device.UnscaledBounds.Y * identifyScaleFactor); + + foreach (NativeMonitorData nativeData in editorParams.Monitors) + { + // Can't do an exact match since the rounding algorithm used by the framework is different from ours + if (scaledBoundX >= (nativeData.LeftCoordinate - 1) && scaledBoundX <= (nativeData.LeftCoordinate + 1) && + scaledBoundY >= (nativeData.TopCoordinate - 1) && scaledBoundY <= (nativeData.TopCoordinate + 1)) + { + monitor.Device.Id = nativeData.MonitorId; + monitor.Device.Dpi = nativeData.Dpi; + matchFound = true; + break; + } + } + + if (matchFound == false) + { + MessageBox.Show(string.Format(Properties.Resources.Error_Monitor_Match_Not_Found, monitor.Device.UnscaledBounds.ToString())); + } + } + + // Set active desktop + for (int i = 0; i < monitors.Count; i++) + { + var monitor = monitors[i]; + if (monitor.Device.Id == targetMonitorName) + { + App.Overlay.CurrentDesktop = i; + break; + } + } + } + } + catch (Exception ex) + { + return new ParsingResult(false, ex.Message, data); + } + + return new ParsingResult(true); + } + else + { + return new ParsingResult(false); + } + } + public ParsingResult ParseZoneSettings() { if (_fileSystem.File.Exists(FancyZonesSettingsFile)) @@ -338,7 +458,7 @@ public ParsingResult ParseZoneSettings() try { - settingsString = ReadZoneSettings(FancyZonesSettingsFile); + settingsString = ReadFile(FancyZonesSettingsFile); zoneSettings = JsonSerializer.Deserialize(settingsString, _options); } catch (Exception ex) @@ -493,7 +613,7 @@ public void SerializeZoneSettings() } } - private string ReadZoneSettings(string fileName) + private string ReadFile(string fileName) { Stream inputStream = _fileSystem.File.Open(fileName, FileMode.Open); StreamReader reader = new StreamReader(inputStream); diff --git a/src/modules/fancyzones/lib/FancyZones.cpp b/src/modules/fancyzones/lib/FancyZones.cpp index d738710aa672..fc9c93874c07 100644 --- a/src/modules/fancyzones/lib/FancyZones.cpp +++ b/src/modules/fancyzones/lib/FancyZones.cpp @@ -621,6 +621,12 @@ void FancyZones::ToggleEditor() noexcept return; } + wil::unique_cotaskmem_string virtualDesktopId; + if (!SUCCEEDED(StringFromCLSID(m_currentDesktopId, &virtualDesktopId))) + { + return; + } + /* * Divider: / * Parts: @@ -639,10 +645,8 @@ void FancyZones::ToggleEditor() noexcept std::wstring params; const std::wstring divider = L"/"; params += std::to_wstring(GetCurrentProcessId()) + divider; /* Process id */ - const bool spanZonesAcrossMonitors = m_settings->GetSettings()->spanZonesAcrossMonitors; params += std::to_wstring(spanZonesAcrossMonitors) + divider; /* Span zones */ - std::vector> allMonitors; allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>(); @@ -657,17 +661,8 @@ void FancyZones::ToggleEditor() noexcept HMONITOR monitor = monitorData.first; auto monitorInfo = monitorData.second; - std::wstring monitorId; std::wstring deviceId = FancyZonesUtils::GetDisplayDeviceId(monitorInfo.szDevice, displayDeviceIdxMap); - wil::unique_cotaskmem_string virtualDesktopId; - if (SUCCEEDED(StringFromCLSID(m_currentDesktopId, &virtualDesktopId))) - { - monitorId = FancyZonesUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId.get()); - } - else - { - continue; - } + std::wstring monitorId = FancyZonesUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId.get()); if (monitor == targetMonitor) { @@ -675,7 +670,6 @@ void FancyZones::ToggleEditor() noexcept } monitorsDataStr += std::move(monitorId) + divider; /* Monitor id */ - UINT dpiX = 0; UINT dpiY = 0; if (GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY) == S_OK) @@ -690,13 +684,15 @@ void FancyZones::ToggleEditor() noexcept prevDpiY = dpiY; } - monitorsDataStr += std::to_wstring(monitorInfo.rcMonitor.left) + divider; - monitorsDataStr += std::to_wstring(monitorInfo.rcMonitor.top) + divider; + monitorsDataStr += std::to_wstring(monitorInfo.rcMonitor.left) + divider; /* Top coordinate */ + monitorsDataStr += std::to_wstring(monitorInfo.rcMonitor.top) + divider; /* Left coordinate */ } params += std::to_wstring(allMonitors.size()) + divider; /* Monitors count */ params += monitorsDataStr; + FancyZonesDataInstance().SaveFancyZonesEditorParameters(spanZonesAcrossMonitors, virtualDesktopId.get(), targetMonitor); /* Write parameters to json file */ + if (showDpiWarning) { // We must show the message box in a separate thread, since this code is called from a low-level diff --git a/src/modules/fancyzones/lib/FancyZonesData.cpp b/src/modules/fancyzones/lib/FancyZonesData.cpp index 68676d4cec5b..a83a946f368e 100644 --- a/src/modules/fancyzones/lib/FancyZonesData.cpp +++ b/src/modules/fancyzones/lib/FancyZonesData.cpp @@ -6,6 +6,7 @@ #include "Settings.h" #include +#include #include #include @@ -24,6 +25,7 @@ namespace NonLocalizable const wchar_t FancyZonesDataFile[] = L"zones-settings.json"; const wchar_t FancyZonesAppZoneHistoryFile[] = L"app-zone-history.json"; + const wchar_t FancyZonesEditorParametersFile[] = L"editor-parameters.json"; const wchar_t DefaultGuid[] = L"{00000000-0000-0000-0000-000000000000}"; const wchar_t RegistryPath[] = L"Software\\SuperFancyZones"; } @@ -147,6 +149,7 @@ FancyZonesData::FancyZonesData() zonesSettingsFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesDataFile); appZoneHistoryFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesAppZoneHistoryFile); + editorParametersFileName = saveFolderPath + L"\\" + std::wstring(NonLocalizable::FancyZonesEditorParametersFile); } std::optional FancyZonesData::FindDeviceInfo(const std::wstring& zoneWindowId) const @@ -504,6 +507,51 @@ void FancyZonesData::SaveFancyZonesData() const appZoneHistoryMap); } +void FancyZonesData::SaveFancyZonesEditorParameters(bool spanZonesAcrossMonitors, const std::wstring& virtualDesktopId, const HMONITOR& targetMonitor) const +{ + JSONHelpers::EditorArgs argsJson; /* json arguments */ + argsJson.processId = GetCurrentProcessId(); /* Process id */ + argsJson.spanZonesAcrossMonitors = spanZonesAcrossMonitors; /* Span zones */ + + std::vector> allMonitors; + allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>(); + + // device id map for correct device ids + std::unordered_map displayDeviceIdxMap; + + for (auto& monitorData : allMonitors) + { + HMONITOR monitor = monitorData.first; + auto monitorInfo = monitorData.second; + + JSONHelpers::MonitorInfo monitorJson; + + std::wstring deviceId = FancyZonesUtils::GetDisplayDeviceId(monitorInfo.szDevice, displayDeviceIdxMap); + std::wstring monitorId = FancyZonesUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId); + + if (monitor == targetMonitor) + { + monitorJson.isSelected = true; /* Is monitor selected for the main editor window opening */ + } + + monitorJson.id = monitorId; /* Monitor id */ + + UINT dpiX = 0; + UINT dpiY = 0; + if (GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY) == S_OK) + { + monitorJson.dpi = dpiX; /* DPI */ + } + + monitorJson.top = monitorInfo.rcMonitor.top; /* Top coordinate */ + monitorJson.left = monitorInfo.rcMonitor.left; /* Left coordinate */ + + argsJson.monitors.emplace_back(std::move(monitorJson)); /* add monitor data */ + } + + json::to_file(editorParametersFileName, JSONHelpers::EditorArgs::ToJson(argsJson)); +} + void FancyZonesData::RemoveDesktopAppZoneHistory(const std::wstring& desktopId) { for (auto it = std::begin(appZoneHistoryMap); it != std::end(appZoneHistoryMap);) diff --git a/src/modules/fancyzones/lib/FancyZonesData.h b/src/modules/fancyzones/lib/FancyZonesData.h index 846a05cdc145..dcecdb16c206 100644 --- a/src/modules/fancyzones/lib/FancyZonesData.h +++ b/src/modules/fancyzones/lib/FancyZonesData.h @@ -82,6 +82,8 @@ class FancyZonesData void LoadFancyZonesData(); void SaveFancyZonesData() const; + void SaveFancyZonesEditorParameters(bool spanZonesAcrossMonitors, const std::wstring& virtualDesktopId, const HMONITOR& targetMonitor) const; + private: #if defined(UNIT_TESTS) friend class FancyZonesUnitTests::FancyZonesDataUnitTests; @@ -131,6 +133,7 @@ class FancyZonesData std::wstring zonesSettingsFileName; std::wstring appZoneHistoryFileName; + std::wstring editorParametersFileName; mutable std::recursive_mutex dataLock; }; diff --git a/src/modules/fancyzones/lib/JsonHelpers.cpp b/src/modules/fancyzones/lib/JsonHelpers.cpp index 05bc0808a67f..801b1d7aebcc 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.cpp +++ b/src/modules/fancyzones/lib/JsonHelpers.cpp @@ -48,6 +48,16 @@ namespace NonLocalizable const wchar_t ZoneIndexStr[] = L"zone-index"; const wchar_t ZoneSetUuidStr[] = L"zoneset-uuid"; const wchar_t ZonesStr[] = L"zones"; + + // Editor arguments + const wchar_t Dpi[] = L"dpi"; + const wchar_t MonitorId[] = L"monitor-id"; + const wchar_t TopCoordinate[] = L"top-coordinate"; + const wchar_t LeftCoordinate[] = L"left-coordinate"; + const wchar_t IsSelected[] = L"is-selected"; + const wchar_t ProcessId[] = L"process-id"; + const wchar_t SpanZonesAcrossMonitors[] = L"span-zones-across-monitors"; + const wchar_t Monitors[] = L"monitors"; } namespace @@ -446,6 +456,37 @@ namespace JSONHelpers } } + json::JsonObject MonitorInfo::ToJson(const MonitorInfo& monitor) + { + json::JsonObject result{}; + + result.SetNamedValue(NonLocalizable::Dpi, json::value(monitor.dpi)); + result.SetNamedValue(NonLocalizable::MonitorId, json::value(monitor.id)); + result.SetNamedValue(NonLocalizable::TopCoordinate, json::value(monitor.top)); + result.SetNamedValue(NonLocalizable::LeftCoordinate, json::value(monitor.left)); + result.SetNamedValue(NonLocalizable::IsSelected, json::value(monitor.isSelected)); + + return result; + } + + json::JsonObject EditorArgs::ToJson(const EditorArgs& args) + { + json::JsonObject result{}; + + result.SetNamedValue(NonLocalizable::ProcessId, json::value(args.processId)); + result.SetNamedValue(NonLocalizable::SpanZonesAcrossMonitors, json::value(args.spanZonesAcrossMonitors)); + + json::JsonArray monitors; + for (const auto& monitor : args.monitors) + { + monitors.Append(MonitorInfo::ToJson(monitor)); + } + + result.SetNamedValue(NonLocalizable::Monitors, monitors); + + return result; + } + json::JsonObject GetPersistFancyZonesJSON(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName) { auto result = json::from_file(zonesSettingsFileName); diff --git a/src/modules/fancyzones/lib/JsonHelpers.h b/src/modules/fancyzones/lib/JsonHelpers.h index 720b77d1f95f..79201e3728ea 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.h +++ b/src/modules/fancyzones/lib/JsonHelpers.h @@ -59,6 +59,26 @@ namespace JSONHelpers using TDeviceInfoMap = std::unordered_map; using TCustomZoneSetsMap = std::unordered_map; + struct MonitorInfo + { + int dpi; + std::wstring id; + int top; + int left; + bool isSelected = false; + + static json::JsonObject ToJson(const MonitorInfo& monitor); + }; + + struct EditorArgs + { + DWORD processId; + bool spanZonesAcrossMonitors; + std::vector monitors; + + static json::JsonObject ToJson(const EditorArgs& args); + }; + json::JsonObject GetPersistFancyZonesJSON(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName); void SaveFancyZonesData(const std::wstring& zonesSettingsFileName, const std::wstring& appZoneHistoryFileName, diff --git a/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp b/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp index 18ed9467e3ae..79ba6bdb54f0 100644 --- a/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp +++ b/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp @@ -1847,4 +1847,38 @@ namespace FancyZonesUnitTests Assert::IsFalse(data.RemoveAppLastZone(nullptr, deviceId, zoneSetId)); } }; + + TEST_CLASS(EditorArgsUnitTests) + { + TEST_METHOD(MonitorToJson) + { + const auto deviceId = L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}"; + MonitorInfo monitor{ 144, deviceId, -10, 0, true }; + + const auto expectedStr = L"{\"dpi\": 144, \"monitor-id\": \"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}\", \"top-coordinate\": -10, \"left-coordinate\": 0, \"is-selected\": true}"; + const auto expected = json::JsonObject::Parse(expectedStr); + + const auto actual = MonitorInfo::ToJson(monitor); + + compareJsonObjects(expected, actual); + } + + TEST_METHOD(EditorArgsToJson) + { + MonitorInfo monitor1{ 144, L"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}", -10, 0, true }; + MonitorInfo monitor2{ 96, L"AOC2460#4&fe3a015&0&UID65793_1920_1080_{39B25DD2-130D-4B5D-8851-4791D66B1538}", 0, 1920, false }; + EditorArgs args{ + 1, true, std::vector{ monitor1, monitor2 } + }; + + const std::wstring expectedMonitor1 = L"{\"dpi\": 144, \"monitor-id\": \"AOC2460#4&fe3a015&0&UID65793_1920_1200_{39B25DD2-130D-4B5D-8851-4791D66B1539}\", \"top-coordinate\": -10, \"left-coordinate\": 0, \"is-selected\": true}"; + const std::wstring expectedMonitor2 = L"{\"dpi\": 96, \"monitor-id\": \"AOC2460#4&fe3a015&0&UID65793_1920_1080_{39B25DD2-130D-4B5D-8851-4791D66B1538}\", \"top-coordinate\": 0, \"left-coordinate\": 1920, \"is-selected\": false}"; + const std::wstring expectedStr = L"{\"process-id\": 1, \"span-zones-across-monitors\": true, \"monitors\": [" + expectedMonitor1 + L", " + expectedMonitor2 + L"]}"; + + const auto expected = json::JsonObject::Parse(expectedStr); + const auto actual = EditorArgs::ToJson(args); + + compareJsonObjects(expected, actual); + } + }; } \ No newline at end of file From 8556a0694764a079acf60b9077567370e3c77e03 Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Tue, 22 Dec 2020 18:07:43 +0300 Subject: [PATCH 27/38] [FZ Editor] Serialize/deserialize settings fix (#8707) --- .../Utils/FancyZonesEditorIO.cs | 90 +++++++++++++------ src/modules/fancyzones/lib/FancyZones.cpp | 7 +- src/modules/fancyzones/lib/FancyZonesData.cpp | 66 +++++++++----- 3 files changed, 109 insertions(+), 54 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs index 636debcbe773..6d150c24d8ba 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs @@ -38,6 +38,8 @@ public class FancyZonesEditorIO PropertyNamingPolicy = new DashCaseNamingPolicy(), }; + private List _unusedDevices = new List(); + public string FancyZonesSettingsFile { get; private set; } public string FancyZonesEditorParamsFile { get; private set; } @@ -225,11 +227,11 @@ public static void ParseCommandLineArguments() // Span zones across monitors App.Overlay.SpanZonesAcrossMonitors = int.Parse(argsParts[(int)CmdArgs.SpanZones]) == 1; + // Target monitor id + string targetMonitorName = argsParts[(int)CmdArgs.TargetMonitorId]; + if (!App.Overlay.SpanZonesAcrossMonitors) { - // Target monitor id - string targetMonitorName = argsParts[(int)CmdArgs.TargetMonitorId]; - // Test launch with custom monitors configuration bool isCustomMonitorConfigurationMode = targetMonitorName.StartsWith("Monitor#"); if (isCustomMonitorConfigurationMode) @@ -336,6 +338,10 @@ public static void ParseCommandLineArguments() } } } + else + { + App.Overlay.Monitors[App.Overlay.CurrentDesktop].Device.Id = targetMonitorName; + } } catch (Exception) { @@ -435,6 +441,31 @@ public ParsingResult ParseParams() } } } + else + { + // Update monitors data + foreach (Monitor monitor in App.Overlay.Monitors) + { + bool matchFound = false; + foreach (NativeMonitorData nativeData in editorParams.Monitors) + { + // Can't do an exact match since the rounding algorithm used by the framework is different from ours + if (monitor.Device.UnscaledBounds.X >= (nativeData.LeftCoordinate - 1) && monitor.Device.UnscaledBounds.X <= (nativeData.LeftCoordinate + 1) && + monitor.Device.UnscaledBounds.Y >= (nativeData.TopCoordinate - 1) && monitor.Device.UnscaledBounds.Y <= (nativeData.TopCoordinate + 1)) + { + monitor.Device.Id = nativeData.MonitorId; + monitor.Device.Dpi = nativeData.Dpi; + matchFound = true; + break; + } + } + + if (matchFound == false) + { + MessageBox.Show(string.Format(Properties.Resources.Error_Monitor_Match_Not_Found, monitor.Device.UnscaledBounds.ToString())); + } + } + } } catch (Exception ex) { @@ -451,6 +482,8 @@ public ParsingResult ParseParams() public ParsingResult ParseZoneSettings() { + _unusedDevices.Clear(); + if (_fileSystem.File.Exists(FancyZonesSettingsFile)) { ZoneSettingsWrapper zoneSettings; @@ -491,7 +524,7 @@ public void SerializeZoneSettings() zoneSettings.Devices = new List(); zoneSettings.CustomZoneSets = new List(); - // Serialize devices + // Serialize used devices foreach (var monitor in App.Overlay.Monitors) { LayoutSettings zoneset = monitor.Settings; @@ -515,6 +548,12 @@ public void SerializeZoneSettings() }); } + // Serialize unused devices + foreach (var device in _unusedDevices) + { + zoneSettings.Devices.Add(device); + } + // Serialize custom zonesets foreach (LayoutModel layout in MainWindowSettingsModel.CustomModels) { @@ -634,37 +673,30 @@ private bool SetDevices(List devices) continue; } - var settings = new LayoutSettings - { - ZonesetUuid = device.ActiveZoneset.Uuid, - ShowSpacing = device.EditorShowSpacing, - Spacing = device.EditorSpacing, - Type = JsonTagToLayoutType(device.ActiveZoneset.Type), - ZoneCount = device.EditorZoneCount, - SensitivityRadius = device.EditorSensitivityRadius, - }; - - if (!App.Overlay.SpanZonesAcrossMonitors) + bool unused = true; + foreach (Monitor monitor in monitors) { - foreach (Monitor monitor in monitors) + if (monitor.Device.Id == device.DeviceId) { - if (monitor.Device.Id == device.DeviceId) + var settings = new LayoutSettings { - monitor.Settings = settings; - break; - } + ZonesetUuid = device.ActiveZoneset.Uuid, + ShowSpacing = device.EditorShowSpacing, + Spacing = device.EditorSpacing, + Type = JsonTagToLayoutType(device.ActiveZoneset.Type), + ZoneCount = device.EditorZoneCount, + SensitivityRadius = device.EditorSensitivityRadius, + }; + + monitor.Settings = settings; + unused = false; + break; } } - else + + if (unused) { - bool isLayoutMultiMonitor = device.DeviceId.StartsWith(MultiMonitorId); - if (isLayoutMultiMonitor) - { - // one zoneset for all desktops - App.Overlay.Monitors[App.Overlay.CurrentDesktop].Settings = settings; - App.Overlay.Monitors[App.Overlay.CurrentDesktop].Device.Id = device.DeviceId; - break; - } + _unusedDevices.Add(device); } } diff --git a/src/modules/fancyzones/lib/FancyZones.cpp b/src/modules/fancyzones/lib/FancyZones.cpp index fc9c93874c07..db38428e96cf 100644 --- a/src/modules/fancyzones/lib/FancyZones.cpp +++ b/src/modules/fancyzones/lib/FancyZones.cpp @@ -650,6 +650,11 @@ void FancyZones::ToggleEditor() noexcept std::vector> allMonitors; allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>(); + if (spanZonesAcrossMonitors) + { + params += FancyZonesUtils::GenerateUniqueIdAllMonitorsArea(virtualDesktopId.get()) + divider; /* Monitor id where the Editor should be opened */ + } + // device id map std::unordered_map displayDeviceIdxMap; @@ -664,7 +669,7 @@ void FancyZones::ToggleEditor() noexcept std::wstring deviceId = FancyZonesUtils::GetDisplayDeviceId(monitorInfo.szDevice, displayDeviceIdxMap); std::wstring monitorId = FancyZonesUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId.get()); - if (monitor == targetMonitor) + if (monitor == targetMonitor && !spanZonesAcrossMonitors) { params += monitorId + divider; /* Monitor id where the Editor should be opened */ } diff --git a/src/modules/fancyzones/lib/FancyZonesData.cpp b/src/modules/fancyzones/lib/FancyZonesData.cpp index a83a946f368e..9bbf76ed9060 100644 --- a/src/modules/fancyzones/lib/FancyZonesData.cpp +++ b/src/modules/fancyzones/lib/FancyZonesData.cpp @@ -513,41 +513,59 @@ void FancyZonesData::SaveFancyZonesEditorParameters(bool spanZonesAcrossMonitors argsJson.processId = GetCurrentProcessId(); /* Process id */ argsJson.spanZonesAcrossMonitors = spanZonesAcrossMonitors; /* Span zones */ - std::vector> allMonitors; - allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>(); + if (spanZonesAcrossMonitors) + { + auto monitorRect = FancyZonesUtils::GetAllMonitorsCombinedRect<&MONITORINFOEX::rcWork>(); + std::wstring monitorId = FancyZonesUtils::GenerateUniqueIdAllMonitorsArea(virtualDesktopId); - // device id map for correct device ids - std::unordered_map displayDeviceIdxMap; + JSONHelpers::MonitorInfo monitorJson; + monitorJson.id = monitorId; + monitorJson.top = monitorRect.top; + monitorJson.left = monitorRect.left; + monitorJson.isSelected = true; + monitorJson.dpi = 0; // unused - for (auto& monitorData : allMonitors) + argsJson.monitors.emplace_back(std::move(monitorJson)); /* add monitor data */ + } + else { - HMONITOR monitor = monitorData.first; - auto monitorInfo = monitorData.second; + std::vector> allMonitors; + allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>(); - JSONHelpers::MonitorInfo monitorJson; + // device id map for correct device ids + std::unordered_map displayDeviceIdxMap; - std::wstring deviceId = FancyZonesUtils::GetDisplayDeviceId(monitorInfo.szDevice, displayDeviceIdxMap); - std::wstring monitorId = FancyZonesUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId); - - if (monitor == targetMonitor) + for (auto& monitorData : allMonitors) { - monitorJson.isSelected = true; /* Is monitor selected for the main editor window opening */ - } + HMONITOR monitor = monitorData.first; + auto monitorInfo = monitorData.second; - monitorJson.id = monitorId; /* Monitor id */ + JSONHelpers::MonitorInfo monitorJson; - UINT dpiX = 0; - UINT dpiY = 0; - if (GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY) == S_OK) - { - monitorJson.dpi = dpiX; /* DPI */ - } + std::wstring deviceId = FancyZonesUtils::GetDisplayDeviceId(monitorInfo.szDevice, displayDeviceIdxMap); + std::wstring monitorId = FancyZonesUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId); - monitorJson.top = monitorInfo.rcMonitor.top; /* Top coordinate */ - monitorJson.left = monitorInfo.rcMonitor.left; /* Left coordinate */ + if (monitor == targetMonitor) + { + monitorJson.isSelected = true; /* Is monitor selected for the main editor window opening */ + } - argsJson.monitors.emplace_back(std::move(monitorJson)); /* add monitor data */ + monitorJson.id = monitorId; /* Monitor id */ + + UINT dpiX = 0; + UINT dpiY = 0; + if (GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY) == S_OK) + { + monitorJson.dpi = dpiX; /* DPI */ + } + + monitorJson.top = monitorInfo.rcMonitor.top; /* Top coordinate */ + monitorJson.left = monitorInfo.rcMonitor.left; /* Left coordinate */ + + argsJson.monitors.emplace_back(std::move(monitorJson)); /* add monitor data */ + } } + json::to_file(editorParametersFileName, JSONHelpers::EditorArgs::ToJson(argsJson)); } From 5623f8e70ed2372f9738cf33d2c5a7be070b077f Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Wed, 23 Dec 2020 13:01:00 +0300 Subject: [PATCH 28/38] [FZ Editor] Hide unsupported settings in custom layouts flyouts (#8716) --- .../LayoutModelTypeToVisibilityConverter.cs | 24 +++++++++++++++++++ .../editor/FancyZonesEditor/MainWindow.xaml | 20 +++++++++++----- 2 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs new file mode 100644 index 000000000000..a1a3c304476f --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Windows; +using System.Windows.Data; +using FancyZonesEditor.Models; + +namespace FancyZonesEditor.Converters +{ + public class LayoutModelTypeToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return value is CanvasLayoutModel ? Visibility.Collapsed : Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return null; + } + } +} diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index deac21c51515..9fad8230563c 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -26,6 +26,8 @@ ResizeMode="CanResize"> + + + IsOn="true" + Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}"/> + Foreground="{DynamicResource PrimaryForegroundBrush}" + Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}"/> + AutomationProperties.LabeledBy="{Binding ElementName=paddingValue}" + Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}"/> + IsOn="true" + Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}"/> + Foreground="{DynamicResource PrimaryForegroundBrush}" + Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}" /> + AutomationProperties.LabeledBy="{Binding ElementName=paddingValue}" + Visibility="{Binding Converter={StaticResource LayoutModelTypeToVisibilityConverter}}"/> Date: Wed, 23 Dec 2020 17:59:35 +0300 Subject: [PATCH 29/38] [FZ Editor] Duplicate custom layouts (#8718) --- .../FancyZonesEditor/MainWindow.xaml.cs | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index 6772cd60b07a..6303ffa75cde 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -140,36 +140,29 @@ private void DuplicateLayout_Click(object sender, RoutedEventArgs e) model.IsSelected = false; Hide(); - bool isPredefinedLayout = MainWindowSettingsModel.IsPredefinedLayout(model); - if (!MainWindowSettingsModel.CustomModels.Contains(model) || isPredefinedLayout) - { - if (isPredefinedLayout) - { - // make a copy - model = model.Clone(); - mainEditor.CurrentDataContext = model; - } + // make a copy + model = model.Clone(); + mainEditor.CurrentDataContext = model; - int maxCustomIndex = 0; - foreach (LayoutModel customModel in MainWindowSettingsModel.CustomModels) + int maxCustomIndex = 0; + foreach (LayoutModel customModel in MainWindowSettingsModel.CustomModels) + { + string name = customModel.Name; + if (name.StartsWith(_defaultNamePrefix)) { - string name = customModel.Name; - if (name.StartsWith(_defaultNamePrefix)) + if (int.TryParse(name.Substring(_defaultNamePrefix.Length), out int i)) { - if (int.TryParse(name.Substring(_defaultNamePrefix.Length), out int i)) + if (maxCustomIndex < i) { - if (maxCustomIndex < i) - { - maxCustomIndex = i; - } + maxCustomIndex = i; } } } - - model.Name = _defaultNamePrefix + (++maxCustomIndex); } + model.Name = _defaultNamePrefix + (++maxCustomIndex); + mainEditor.OpenEditor(model); } From 854482da9e34c47796ef5740a3a531162b1a1924 Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Thu, 24 Dec 2020 17:56:57 +0300 Subject: [PATCH 30/38] [FZ Editor] Duplicate layout behavior (#8720) --- .../FancyZonesEditor/MainWindow.xaml.cs | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index 6303ffa75cde..90abfe76536e 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -31,9 +31,6 @@ public partial class MainWindow : Window private readonly MainWindowSettingsModel _settings = ((App)Application.Current).MainWindowSettings; - // Localizable string - private static readonly string _defaultNamePrefix = "Custom Layout "; - public int WrapPanelItemSize { get; set; } = DefaultWrapPanelItemSize; public MainWindow(bool spanZonesAcrossMonitors, Rect workArea) @@ -139,31 +136,45 @@ private void DuplicateLayout_Click(object sender, RoutedEventArgs e) model.IsSelected = false; - Hide(); - // make a copy model = model.Clone(); mainEditor.CurrentDataContext = model; + string name = model.Name; + var index = name.LastIndexOf('('); + if (index != -1) + { + name = name.Remove(index); + name = name.TrimEnd(); + } + int maxCustomIndex = 0; foreach (LayoutModel customModel in MainWindowSettingsModel.CustomModels) { - string name = customModel.Name; - if (name.StartsWith(_defaultNamePrefix)) + string customModelName = customModel.Name; + if (customModelName.StartsWith(name)) { - if (int.TryParse(name.Substring(_defaultNamePrefix.Length), out int i)) + int openBraceIndex = customModelName.LastIndexOf('('); + int closeBraceIndex = customModelName.LastIndexOf(')'); + if (openBraceIndex != -1 && closeBraceIndex != -1) { - if (maxCustomIndex < i) + string indexSubstring = customModelName.Substring(openBraceIndex + 1, closeBraceIndex - openBraceIndex - 1); + + if (int.TryParse(indexSubstring, out int i)) { - maxCustomIndex = i; + if (maxCustomIndex < i) + { + maxCustomIndex = i; + } } } } } - model.Name = _defaultNamePrefix + (++maxCustomIndex); + model.Name = name + " (" + (++maxCustomIndex) + ')'; - mainEditor.OpenEditor(model); + model.Persist(); + App.FancyZonesEditorIO.SerializeZoneSettings(); } private void Apply_Click(object sender, RoutedEventArgs e) From 11c30482996a8e0e371d3743ed4a39853cdc61d0 Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Mon, 28 Dec 2020 12:50:00 +0300 Subject: [PATCH 31/38] [FZ Editor] Spacing settings in layout flyouts (#8772) --- ....cs => LayoutTypeToVisibilityConverter.cs} | 4 +- .../FancyZonesEditor/GridEditor.xaml.cs | 12 +- .../editor/FancyZonesEditor/GridZone.xaml.cs | 28 +--- .../FancyZonesEditor/LayoutPreview.xaml.cs | 7 +- .../editor/FancyZonesEditor/MainWindow.xaml | 120 ++++++++++-------- .../Models/CanvasLayoutModel.cs | 3 + .../Models/GridLayoutModel.cs | 46 +++++++ .../FancyZonesEditor/Models/LayoutModel.cs | 21 +++ .../FancyZonesEditor/Models/LayoutSettings.cs | 8 +- .../Models/MainWindowSettingsModel.cs | 74 ----------- .../Utils/FancyZonesEditorIO.cs | 20 ++- .../fancyzones/lib/FancyZonesDataTypes.h | 13 +- src/modules/fancyzones/lib/JsonHelpers.cpp | 14 ++ .../tests/UnitTests/JsonHelpers.Tests.cpp | 78 +++++++++++- 14 files changed, 277 insertions(+), 171 deletions(-) rename src/modules/fancyzones/editor/FancyZonesEditor/Converters/{LayoutModelTypeToVisibilityConverter.cs => LayoutTypeToVisibilityConverter.cs} (79%) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeToVisibilityConverter.cs similarity index 79% rename from src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs rename to src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeToVisibilityConverter.cs index a1a3c304476f..ec87012c5e13 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeToVisibilityConverter.cs @@ -9,11 +9,11 @@ namespace FancyZonesEditor.Converters { - public class LayoutModelTypeToVisibilityConverter : IValueConverter + public class LayoutTypeToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { - return value is CanvasLayoutModel ? Visibility.Collapsed : Visibility.Visible; + return (LayoutType)value == LayoutType.Custom ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml.cs index eb931ad114b0..28d6c1300863 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml.cs @@ -332,7 +332,7 @@ private int AddZone() } } - zone = new GridZone(); + zone = new GridZone(Model.ShowSpacing ? Model.Spacing : 0); zone.Split += OnSplit; zone.MergeDrag += OnMergeDrag; zone.MergeComplete += OnMergeComplete; @@ -383,9 +383,7 @@ private void ArrangeGridRects(Size arrangeSize) return; } - MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings; - - int spacing = settings.ShowSpacing ? settings.Spacing : 0; + int spacing = model.ShowSpacing ? model.Spacing : 0; _data.RecalculateZones(spacing, arrangeSize); _data.ArrangeZones(Preview.Children, spacing); @@ -411,10 +409,10 @@ private void Resizer_DragDelta(object sender, System.Windows.Controls.Primitives if (_dragHandles.HasSnappedNonAdjacentResizers(resizer)) { double spacing = 0; - MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings; - if (settings.ShowSpacing) + GridLayoutModel model = Model; + if (model.ShowSpacing) { - spacing = settings.Spacing; + spacing = model.Spacing; } _data.SplitOnDrag(resizer, delta, spacing); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml.cs index 210120cdf3d8..24765f987cd5 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml.cs @@ -59,7 +59,7 @@ public bool IsSelected set { SetValue(IsSelectedProperty, value); } } - public GridZone() + public GridZone(int spacing) { InitializeComponent(); OnSelectionChanged(); @@ -69,6 +69,9 @@ public GridZone() }; Body.Children.Add(_splitter); + Spacing = spacing; + SplitterThickness = Math.Max(spacing, 1); + ((App)Application.Current).MainWindowSettings.PropertyChanged += ZoneSettings_PropertyChanged; } @@ -104,19 +107,9 @@ private bool IsVerticalSplit } } - private int SplitterThickness - { - get - { - MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings; - if (!settings.ShowSpacing) - { - return 1; - } + private int Spacing { get; set; } - return Math.Max(settings.Spacing, 1); - } - } + private int SplitterThickness { get; set; } private void UpdateSplitter() { @@ -282,14 +275,7 @@ private void DoMergeComplete(MouseButtonEventArgs e) private void DoSplit(Orientation orientation, double offset) { - int spacing = 0; - MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings; - if (settings.ShowSpacing) - { - spacing = settings.Spacing; - } - - Split?.Invoke(this, new SplitEventArgs(orientation, offset, spacing)); + Split?.Invoke(this, new SplitEventArgs(orientation, offset, Spacing)); } private void FullSplit_Click(object sender, RoutedEventArgs e) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs index ee3ddbfea5c7..9a64488582d3 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs @@ -115,9 +115,7 @@ private void RenderActualScalePreview(GridLayoutModel grid) RowColInfo[] colInfo = (from percent in grid.ColumnPercents select new RowColInfo(percent)).ToArray(); - MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings; - - int spacing = settings.ShowSpacing ? settings.Spacing : 0; + int spacing = grid.ShowSpacing ? grid.Spacing : 0; var workArea = App.Overlay.WorkArea; double width = workArea.Width - (spacing * (cols + 1)); @@ -215,8 +213,7 @@ private void RenderSmallScalePreview(GridLayoutModel grid) Body.ColumnDefinitions.Add(def); } - MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings; - Thickness margin = new Thickness(settings.ShowSpacing ? settings.Spacing / 20 : 0); + Thickness margin = new Thickness(grid.ShowSpacing ? grid.Spacing / 20 : 0); List visited = new List(); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 9fad8230563c..35a5fa38e5cb 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -9,6 +9,7 @@ xmlns:Converters="clr-namespace:FancyZonesEditor.Converters" xmlns:props="clr-namespace:FancyZonesEditor.Properties" xmlns:local1="clr-namespace:FancyZonesEditor.ViewModels" + xmlns:models="clr-namespace:FancyZonesEditor.Models" xmlns:ui="http://schemas.modernwpf.com/2019" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:controls="clr-namespace:ModernWpf.Controls;assembly=ModernWpf" @@ -26,7 +27,7 @@ ResizeMode="CanResize"> - + - - + + + + + + - - - - - - - + + @@ -230,7 +250,8 @@ - + + + Style="{StaticResource AccentButtonStyle}" + Visibility="{Binding Type, Converter={StaticResource LayoutTypeToVisibilityConverter}}"> - - + Foreground="{DynamicResource PrimaryForegroundBrush}" + Visibility="{Binding Type, Converter={StaticResource LayoutTypeToVisibilityConverter}}" /> - + + - + IsOn="{Binding ShowSpacing}" /> + - + Foreground="{DynamicResource PrimaryForegroundBrush}" /> + - + AutomationProperties.LabeledBy="{Binding ElementName=paddingValue}" /> + - + Background="Transparent" + Visibility="{Binding Type, Converter={StaticResource LayoutTypeToVisibilityConverter}}"> diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs index f6bc3d061c92..f4a1f2cecf4c 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs @@ -70,6 +70,7 @@ public override LayoutModel Clone() layout.Zones.Add(zone); } + layout.SensitivityRadius = SensitivityRadius; return layout; } @@ -80,6 +81,8 @@ public void RestoreTo(CanvasLayoutModel other) { other.Zones.Add(zone); } + + other.SensitivityRadius = SensitivityRadius; } // PersistData diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs index ed2ff44130a5..406b0bc97c24 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs @@ -65,6 +65,48 @@ public int Columns // ColumnPercents - represents the %age width of each column in the grid public List ColumnPercents { get; set; } + // ShowSpacing - flag if free space between cells should be presented + public bool ShowSpacing + { + get + { + return _showSpacing; + } + + set + { + if (value != _showSpacing) + { + _showSpacing = value; + App.Overlay.Monitors[App.Overlay.CurrentDesktop].Settings.ShowSpacing = value; + App.FancyZonesEditorIO.SerializeZoneSettings(); + } + } + } + + private bool _showSpacing = LayoutSettings.DefaultShowSpacing; + + // Spacing - free space between cells + public int Spacing + { + get + { + return _spacing; + } + + set + { + if (value != _spacing) + { + _spacing = value; + App.Overlay.Monitors[App.Overlay.CurrentDesktop].Settings.Spacing = value; + App.FancyZonesEditorIO.SerializeZoneSettings(); + } + } + } + + private int _spacing = LayoutSettings.DefaultSpacing; + // FreeZones (not persisted) - used to keep track of child indices that are no longer in use in the CellChildMap, // making them candidates for re-use when it's needed to add another child // TODO: do I need FreeZones on the data model? - I think I do @@ -169,6 +211,10 @@ public void RestoreTo(GridLayoutModel layout) } layout.ColumnPercents = colPercents; + + layout.ShowSpacing = ShowSpacing; + layout.Spacing = Spacing; + layout.SensitivityRadius = SensitivityRadius; } // PersistData diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs index 4ace86920b15..1173b6632ffa 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs @@ -100,6 +100,7 @@ public bool IsSelected private bool _isSelected; + // IsApplied (not-persisted) - tracks whether or not this LayoutModel is applied in the picker public bool IsApplied { get @@ -119,6 +120,26 @@ public bool IsApplied private bool _isApplied; + public int SensitivityRadius + { + get + { + return _sensitivityRadius; + } + + set + { + if (value != _sensitivityRadius) + { + _sensitivityRadius = value; + App.Overlay.Monitors[App.Overlay.CurrentDesktop].Settings.SensitivityRadius = value; + App.FancyZonesEditorIO.SerializeZoneSettings(); + } + } + } + + private int _sensitivityRadius = LayoutSettings.DefaultSensitivityRadius; + // implementation of INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutSettings.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutSettings.cs index 32c5b63a7e44..81f6731bbc7d 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutSettings.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutSettings.cs @@ -9,13 +9,13 @@ namespace FancyZonesEditor { public class LayoutSettings { - public static bool DefaultShowSpacing => true; + public const bool DefaultShowSpacing = true; - public static int DefaultSpacing => 16; + public const int DefaultSpacing = 16; - public static int DefaultZoneCount => 3; + public const int DefaultZoneCount = 3; - public static int DefaultSensitivityRadius => 20; + public const int DefaultSensitivityRadius = 20; public string ZonesetUuid { get; set; } = string.Empty; diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs index 294579fe507d..7565c7e4590f 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs @@ -126,65 +126,6 @@ public int ZoneCount } } - // Spacing - how much space in between zones of the grid do you want - public int Spacing - { - get - { - return App.Overlay.CurrentLayoutSettings.Spacing; - } - - set - { - value = Math.Max(0, value); - if (App.Overlay.CurrentLayoutSettings.Spacing != value) - { - App.Overlay.CurrentLayoutSettings.Spacing = value; - UpdateTemplateLayoutModels(); - FirePropertyChanged(nameof(Spacing)); - } - } - } - - // ShowSpacing - is the Spacing value used or ignored? - public bool ShowSpacing - { - get - { - return App.Overlay.CurrentLayoutSettings.ShowSpacing; - } - - set - { - if (App.Overlay.CurrentLayoutSettings.ShowSpacing != value) - { - App.Overlay.CurrentLayoutSettings.ShowSpacing = value; - UpdateTemplateLayoutModels(); - FirePropertyChanged(nameof(ShowSpacing)); - } - } - } - - // SensitivityRadius - how much space inside the zone to highlight the adjacent zone too - public int SensitivityRadius - { - get - { - return App.Overlay.CurrentLayoutSettings.SensitivityRadius; - } - - set - { - value = Math.Max(0, value); - if (App.Overlay.CurrentLayoutSettings.SensitivityRadius != value) - { - App.Overlay.CurrentLayoutSettings.SensitivityRadius = value; - UpdateTemplateLayoutModels(); - FirePropertyChanged(nameof(SensitivityRadius)); - } - } - } - // IsShiftKeyPressed - is the shift key currently being held down public bool IsShiftKeyPressed { @@ -466,21 +407,6 @@ public void UpdateDesktopDependantProperties(LayoutSettings prevSettings) { FirePropertyChanged(nameof(ZoneCount)); } - - if (prevSettings.Spacing != Spacing) - { - FirePropertyChanged(nameof(Spacing)); - } - - if (prevSettings.ShowSpacing != ShowSpacing) - { - FirePropertyChanged(nameof(ShowSpacing)); - } - - if (prevSettings.SensitivityRadius != SensitivityRadius) - { - FirePropertyChanged(nameof(SensitivityRadius)); - } } // implementation of INotifyPropertyChanged diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs index 6d150c24d8ba..8366c2fc7aa8 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs @@ -108,7 +108,7 @@ public struct ActiveZoneSetWrapper public int EditorSensitivityRadius { get; set; } } - private struct CanvasInfoWrapper + private class CanvasInfoWrapper { public struct CanvasZoneWrapper { @@ -126,9 +126,11 @@ public struct CanvasZoneWrapper public int RefHeight { get; set; } public List Zones { get; set; } + + public int SensitivityRadius { get; set; } = LayoutSettings.DefaultSensitivityRadius; } - private struct GridInfoWrapper + private class GridInfoWrapper { public int Rows { get; set; } @@ -139,6 +141,12 @@ private struct GridInfoWrapper public List ColumnsPercentage { get; set; } public int[][] CellChildMap { get; set; } + + public bool ShowSpacing { get; set; } = LayoutSettings.DefaultShowSpacing; + + public int Spacing { get; set; } = LayoutSettings.DefaultSpacing; + + public int SensitivityRadius { get; set; } = LayoutSettings.DefaultSensitivityRadius; } private struct CustomLayoutWrapper @@ -581,6 +589,7 @@ public void SerializeZoneSettings() RefWidth = (int)canvasRect.Width, RefHeight = (int)canvasRect.Height, Zones = new List(), + SensitivityRadius = canvasLayout.SensitivityRadius, }; foreach (var zone in canvasLayout.Zones) @@ -619,6 +628,9 @@ public void SerializeZoneSettings() RowsPercentage = gridLayout.RowPercents, ColumnsPercentage = gridLayout.ColumnPercents, CellChildMap = cells, + ShowSpacing = gridLayout.ShowSpacing, + Spacing = gridLayout.Spacing, + SensitivityRadius = gridLayout.SensitivityRadius, }; string json = JsonSerializer.Serialize(wrapper, _options); @@ -728,6 +740,7 @@ private bool SetCustomLayouts(List customLayouts) } layout = new CanvasLayoutModel(zoneSet.Uuid, zoneSet.Name, LayoutType.Custom, zones, info.RefWidth, info.RefHeight); + layout.SensitivityRadius = info.SensitivityRadius; } else if (zoneSet.Type == GridLayoutModel.ModelTypeID) { @@ -743,6 +756,9 @@ private bool SetCustomLayouts(List customLayouts) } layout = new GridLayoutModel(zoneSet.Uuid, zoneSet.Name, LayoutType.Custom, info.Rows, info.Columns, info.RowsPercentage, info.ColumnsPercentage, cells); + layout.SensitivityRadius = info.SensitivityRadius; + (layout as GridLayoutModel).ShowSpacing = info.ShowSpacing; + (layout as GridLayoutModel).Spacing = info.Spacing; } else { diff --git a/src/modules/fancyzones/lib/FancyZonesDataTypes.h b/src/modules/fancyzones/lib/FancyZonesDataTypes.h index 51eccfb4c688..84103f972059 100644 --- a/src/modules/fancyzones/lib/FancyZonesDataTypes.h +++ b/src/modules/fancyzones/lib/FancyZonesDataTypes.h @@ -45,6 +45,7 @@ namespace FancyZonesDataTypes int height; }; std::vector zones; + int sensitivityRadius; }; struct GridLayoutInfo @@ -62,6 +63,9 @@ namespace FancyZonesDataTypes const std::vector& rowsPercents; const std::vector& columnsPercents; const std::vector>& cellChildMap; + bool showSpacing; + int spacing; + int sensitivityRadius; }; GridLayoutInfo(const Minimal& info); @@ -74,16 +78,23 @@ namespace FancyZonesDataTypes inline int rows() const { return m_rows; } inline int columns() const { return m_columns; } - + inline const std::vector& rowsPercents() const { return m_rowsPercents; }; inline const std::vector& columnsPercents() const { return m_columnsPercents; }; inline const std::vector>& cellChildMap() const { return m_cellChildMap; }; + inline bool showSpacing() const { return m_showSpacing; } + inline int spacing() const { return m_spacing; } + inline int sensitivityRadius() const { return m_sensitivityRadius; } + int m_rows; int m_columns; std::vector m_rowsPercents; std::vector m_columnsPercents; std::vector> m_cellChildMap; + bool m_showSpacing; + int m_spacing; + int m_sensitivityRadius; }; struct CustomZoneSetData diff --git a/src/modules/fancyzones/lib/JsonHelpers.cpp b/src/modules/fancyzones/lib/JsonHelpers.cpp index 801b1d7aebcc..833a45108fa4 100644 --- a/src/modules/fancyzones/lib/JsonHelpers.cpp +++ b/src/modules/fancyzones/lib/JsonHelpers.cpp @@ -39,6 +39,9 @@ namespace NonLocalizable const wchar_t RefWidthStr[] = L"ref-width"; const wchar_t RowsPercentageStr[] = L"rows-percentage"; const wchar_t RowsStr[] = L"rows"; + const wchar_t SensitivityRadius[] = L"sensitivity-radius"; + const wchar_t ShowSpacing[] = L"show-spacing"; + const wchar_t Spacing[] = L"spacing"; const wchar_t TypeStr[] = L"type"; const wchar_t UuidStr[] = L"uuid"; const wchar_t WidthStr[] = L"width"; @@ -137,6 +140,7 @@ namespace JSONHelpers zonesJson.Append(zoneJson); } infoJson.SetNamedValue(NonLocalizable::ZonesStr, zonesJson); + infoJson.SetNamedValue(NonLocalizable::SensitivityRadius, json::value(canvasInfo.sensitivityRadius)); return infoJson; } @@ -161,6 +165,8 @@ namespace JSONHelpers FancyZonesDataTypes::CanvasLayoutInfo::Rect zone{ x, y, width, height }; info.zones.push_back(zone); } + + info.sensitivityRadius = infoJson.GetNamedNumber(NonLocalizable::SensitivityRadius, DefaultValues::SensitivityRadius); return info; } catch (const winrt::hresult_error&) @@ -183,6 +189,10 @@ namespace JSONHelpers cellChildMapJson.Append(NumVecToJsonArray(gridInfo.m_cellChildMap[i])); } infoJson.SetNamedValue(NonLocalizable::CellChildMapStr, cellChildMapJson); + + infoJson.SetNamedValue(NonLocalizable::SensitivityRadius, json::value(gridInfo.m_sensitivityRadius)); + infoJson.SetNamedValue(NonLocalizable::ShowSpacing, json::value(gridInfo.m_showSpacing)); + infoJson.SetNamedValue(NonLocalizable::Spacing, json::value(gridInfo.m_spacing)); return infoJson; } @@ -217,6 +227,10 @@ namespace JSONHelpers info.cellChildMap().push_back(JsonArrayToNumVec(cellsArray)); } + info.m_showSpacing = infoJson.GetNamedBoolean(NonLocalizable::ShowSpacing, DefaultValues::ShowSpacing); + info.m_spacing = infoJson.GetNamedNumber(NonLocalizable::Spacing, DefaultValues::Spacing); + info.m_sensitivityRadius = infoJson.GetNamedNumber(NonLocalizable::SensitivityRadius, DefaultValues::SensitivityRadius); + return info; } catch (const winrt::hresult_error&) diff --git a/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp b/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp index 79ba6bdb54f0..4136f72fcaa8 100644 --- a/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp +++ b/src/modules/fancyzones/tests/UnitTests/JsonHelpers.Tests.cpp @@ -189,7 +189,8 @@ namespace FancyZonesUnitTests TEST_CLASS (CanvasLayoutInfoUnitTests) { - json::JsonObject m_json = json::JsonObject::Parse(L"{\"ref-width\": 123, \"ref-height\": 321, \"zones\": [{\"X\": 11, \"Y\": 22, \"width\": 33, \"height\": 44}, {\"X\": 55, \"Y\": 66, \"width\": 77, \"height\": 88}]}"); + json::JsonObject m_json = json::JsonObject::Parse(L"{\"ref-width\": 123, \"ref-height\": 321, \"zones\": [{\"X\": 11, \"Y\": 22, \"width\": 33, \"height\": 44}, {\"X\": 55, \"Y\": 66, \"width\": 77, \"height\": 88}], \"sensitivity-radius\": 50}"); + json::JsonObject m_jsonWithoutOptionalValues = json::JsonObject::Parse(L"{\"ref-width\": 123, \"ref-height\": 321, \"zones\": [{\"X\": 11, \"Y\": 22, \"width\": 33, \"height\": 44}, {\"X\": 55, \"Y\": 66, \"width\": 77, \"height\": 88}]}"); TEST_METHOD (ToJson) { @@ -197,6 +198,7 @@ namespace FancyZonesUnitTests info.lastWorkAreaWidth = 123; info.lastWorkAreaHeight = 321; info.zones = { CanvasLayoutInfo::Rect{ 11, 22, 33, 44 }, CanvasLayoutInfo::Rect{ 55, 66, 77, 88 } }; + info.sensitivityRadius = 50; auto actual = CanvasLayoutInfoJSON::ToJson(info); compareJsonObjects(m_json, actual); @@ -208,6 +210,7 @@ namespace FancyZonesUnitTests expected.lastWorkAreaWidth = 123; expected.lastWorkAreaHeight = 321; expected.zones = { CanvasLayoutInfo::Rect{ 11, 22, 33, 44 }, CanvasLayoutInfo::Rect{ 55, 66, 77, 88 } }; + expected.sensitivityRadius = 50; auto actual = CanvasLayoutInfoJSON::FromJson(m_json); Assert::IsTrue(actual.has_value()); @@ -215,6 +218,30 @@ namespace FancyZonesUnitTests Assert::AreEqual(expected.lastWorkAreaHeight, actual->lastWorkAreaHeight); Assert::AreEqual(expected.lastWorkAreaWidth, actual->lastWorkAreaWidth); Assert::AreEqual(expected.zones.size(), actual->zones.size()); + Assert::AreEqual(expected.sensitivityRadius, actual->sensitivityRadius); + for (int i = 0; i < expected.zones.size(); i++) + { + Assert::AreEqual(expected.zones[i].x, actual->zones[i].x); + Assert::AreEqual(expected.zones[i].y, actual->zones[i].y); + Assert::AreEqual(expected.zones[i].width, actual->zones[i].width); + Assert::AreEqual(expected.zones[i].height, actual->zones[i].height); + } + } + + TEST_METHOD (FromJsonWithoutOptionalValues) + { + CanvasLayoutInfo expected; + expected.lastWorkAreaWidth = 123; + expected.lastWorkAreaHeight = 321; + expected.zones = { CanvasLayoutInfo::Rect{ 11, 22, 33, 44 }, CanvasLayoutInfo::Rect{ 55, 66, 77, 88 } }; + + auto actual = CanvasLayoutInfoJSON::FromJson(m_jsonWithoutOptionalValues); + Assert::IsTrue(actual.has_value()); + + Assert::AreEqual(expected.lastWorkAreaHeight, actual->lastWorkAreaHeight); + Assert::AreEqual(expected.lastWorkAreaWidth, actual->lastWorkAreaWidth); + Assert::AreEqual(expected.zones.size(), actual->zones.size()); + Assert::AreEqual(DefaultValues::SensitivityRadius, actual->sensitivityRadius); for (int i = 0; i < expected.zones.size(); i++) { Assert::AreEqual(expected.zones[i].x, actual->zones[i].x); @@ -226,7 +253,7 @@ namespace FancyZonesUnitTests TEST_METHOD (FromJsonMissingKeys) { - CanvasLayoutInfo info{ 123, 321, { CanvasLayoutInfo::Rect{ 11, 22, 33, 44 }, CanvasLayoutInfo::Rect{ 55, 66, 77, 88 } } }; + CanvasLayoutInfo info{ 123, 321, { CanvasLayoutInfo::Rect{ 11, 22, 33, 44 }, CanvasLayoutInfo::Rect{ 55, 66, 77, 88 } }, 50 }; const auto json = CanvasLayoutInfoJSON::ToJson(info); auto iter = json.First(); @@ -234,6 +261,11 @@ namespace FancyZonesUnitTests { json::JsonObject modifiedJson = json::JsonObject::Parse(json.Stringify()); modifiedJson.Remove(iter.Current().Key()); + if (iter.Current().Key() == L"sensitivity-radius") + { + iter.MoveNext(); + continue; + } auto actual = CanvasLayoutInfoJSON::FromJson(modifiedJson); Assert::IsFalse(actual.has_value()); @@ -436,6 +468,27 @@ namespace FancyZonesUnitTests compareJsonObjects(expected, actual); } + + TEST_METHOD (ToJsonWithOptionals) + { + json::JsonObject expected = json::JsonObject(); + expected = json::JsonObject::Parse(L"{\"rows\": 3, \"columns\": 4}"); + expected.SetNamedValue(L"rows-percentage", m_rowsArray); + expected.SetNamedValue(L"columns-percentage", m_columnsArray); + expected.SetNamedValue(L"cell-child-map", m_cells); + expected.SetNamedValue(L"show-spacing", json::value(true)); + expected.SetNamedValue(L"spacing", json::value(99)); + expected.SetNamedValue(L"sensitivity-radius", json::value(55)); + + GridLayoutInfo info = m_info; + info.m_sensitivityRadius = 55; + info.m_showSpacing = true; + info.m_spacing = 99; + + auto actual = GridLayoutInfoJSON::ToJson(info); + compareJsonObjects(expected, actual); + } + TEST_METHOD (FromJson) { json::JsonObject json = json::JsonObject(m_gridJson); @@ -514,6 +567,27 @@ namespace FancyZonesUnitTests } } + TEST_METHOD(FromJsonWithOptionals) + { + json::JsonObject json = json::JsonObject(); + json = json::JsonObject::Parse(L"{\"rows\": 3, \"columns\": 4}"); + json.SetNamedValue(L"rows-percentage", m_rowsArray); + json.SetNamedValue(L"columns-percentage", m_columnsArray); + json.SetNamedValue(L"cell-child-map", m_cells); + json.SetNamedValue(L"show-spacing", json::value(true)); + json.SetNamedValue(L"spacing", json::value(99)); + json.SetNamedValue(L"sensitivity-radius", json::value(55)); + + GridLayoutInfo expected = m_info; + expected.m_sensitivityRadius = 55; + expected.m_showSpacing = true; + expected.m_spacing = 99; + + auto actual = GridLayoutInfoJSON::FromJson(json); + Assert::IsTrue(actual.has_value()); + compareGridInfos(expected, *actual); + } + TEST_METHOD (FromJsonInvalidTypes) { json::JsonObject gridJson = json::JsonObject::Parse(L"{\"rows\": \"три\", \"columns\": \"четыре\"}"); From e7c2b784bbda57fa87e131d0b130720549a0861e Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Mon, 28 Dec 2020 16:20:56 +0300 Subject: [PATCH 32/38] [FZ Editor] Do not close the editor after applying a layout in the single-monitor mode (#8776) --- .../editor/FancyZonesEditor/MainWindow.xaml.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index 90abfe76536e..a9b10605c48c 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -191,11 +191,6 @@ private void Apply() { model.Apply(); } - - if (!mainEditor.MultiMonitorMode) - { - Close(); - } } private void OnClosing(object sender, EventArgs e) @@ -266,11 +261,6 @@ private void Reset_Click(object sender, RoutedEventArgs e) overlay.CurrentDataContext = MainWindowSettingsModel.BlankModel; App.FancyZonesEditorIO.SerializeZoneSettings(); - - if (!overlay.MultiMonitorMode) - { - Close(); - } } private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog sender, ModernWpf.Controls.ContentDialogButtonClickEventArgs args) From c23b3ccd7df7f1d3729759f0208d9a96b1113acd Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Mon, 28 Dec 2020 16:21:31 +0300 Subject: [PATCH 33/38] [FZ Editor] Update layout preview after editing (#8775) --- .../editor/FancyZonesEditor/LayoutPreview.xaml.cs | 12 ++++++++++++ .../editor/FancyZonesEditor/MainWindow.xaml | 2 +- .../FancyZonesEditor/Models/GridLayoutModel.cs | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs index 9a64488582d3..e61c03f2a1a6 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs @@ -50,7 +50,14 @@ public void UpdatePreview() private void LayoutPreview_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { + if (_model != null) + { + _model.PropertyChanged -= LayoutModel_PropertyChanged; + } + _model = (LayoutModel)DataContext; + _model.PropertyChanged += LayoutModel_PropertyChanged; + RenderPreview(); } @@ -69,6 +76,11 @@ private void ZoneSettings_PropertyChanged(object sender, System.ComponentModel.P } } + private void LayoutModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + RenderPreview(); + } + public Int32Rect[] GetZoneRects() { return _zones.ToArray(); diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index 35a5fa38e5cb..f0b19903a91c 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -358,7 +358,7 @@ Foreground="{DynamicResource PrimaryForegroundBrush}" /> diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs index 406b0bc97c24..6ed73529a0aa 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs @@ -79,6 +79,8 @@ public bool ShowSpacing { _showSpacing = value; App.Overlay.Monitors[App.Overlay.CurrentDesktop].Settings.ShowSpacing = value; + + FirePropertyChanged(nameof(ShowSpacing)); App.FancyZonesEditorIO.SerializeZoneSettings(); } } @@ -100,6 +102,8 @@ public int Spacing { _spacing = value; App.Overlay.Monitors[App.Overlay.CurrentDesktop].Settings.Spacing = value; + + FirePropertyChanged(nameof(Spacing)); App.FancyZonesEditorIO.SerializeZoneSettings(); } } From f6e0e298f9448100733b6f91889b2a0b877d0a64 Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Thu, 31 Dec 2020 18:55:07 +0300 Subject: [PATCH 34/38] [FZ Editor] Disable layout preview on mouse enter (#8852) --- .../fancyzones/editor/FancyZonesEditor/MainWindow.xaml | 4 ---- .../editor/FancyZonesEditor/MainWindow.xaml.cs | 10 ---------- 2 files changed, 14 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index f0b19903a91c..b980eb252ce0 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -86,8 +86,6 @@ @@ -254,8 +252,6 @@ diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index a9b10605c48c..31935d3327b0 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -81,11 +81,6 @@ private void IncrementZones_Click(object sender, RoutedEventArgs e) } } - private void LayoutItem_MouseEnter(object sender, MouseEventArgs e) - { - Select(((Grid)sender).DataContext as LayoutModel); - } - private void LayoutItem_Click(object sender, MouseButtonEventArgs e) { Select(((Grid)sender).DataContext as LayoutModel); @@ -320,10 +315,5 @@ private void MonitorItem_MouseDown(object sender, MouseButtonEventArgs e) { monitorViewModel.SelectCommand.Execute((MonitorInfoModel)(sender as Border).DataContext); } - - private void LayoutItem_MouseLeave(object sender, MouseEventArgs e) - { - // TO DO: reset back to the applied layout - } } } From e5cb4bac7904d33e27819a46c4017adc358ce6f5 Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Thu, 14 Jan 2021 14:14:25 +0300 Subject: [PATCH 35/38] [FZ Editor] Update ModernWpf package (dialog rendering fix) (#9099) --- .../fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj index d91a91d8dc2e..886717b79006 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj +++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj @@ -66,7 +66,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 5dc231b5385794e90843e1af7f787ed8971ec800 Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Thu, 14 Jan 2021 14:15:59 +0300 Subject: [PATCH 36/38] [FZ Editor] close flyout after Duplicate or Delete button was clicked (#9086) --- .../FancyZonesEditor/MainWindow.xaml.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs index 31935d3327b0..dadd5db99945 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs @@ -7,6 +7,7 @@ using System.Windows; using System.Windows.Automation.Peers; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Media; using FancyZonesEditor.Models; @@ -123,6 +124,8 @@ private async void NewLayoutButton_Click(object sender, RoutedEventArgs e) private void DuplicateLayout_Click(object sender, RoutedEventArgs e) { + CloseFlyout((DependencyObject)sender); + var mainEditor = App.Overlay; if (!(mainEditor.CurrentDataContext is LayoutModel model)) { @@ -197,6 +200,8 @@ private void OnClosing(object sender, EventArgs e) private async void DeleteLayout_Click(object sender, RoutedEventArgs e) { + CloseFlyout((DependencyObject)sender); + var dialog = new ModernWpf.Controls.ContentDialog() { Title = FancyZonesEditor.Properties.Resources.Are_You_Sure, @@ -315,5 +320,29 @@ private void MonitorItem_MouseDown(object sender, MouseButtonEventArgs e) { monitorViewModel.SelectCommand.Execute((MonitorInfoModel)(sender as Border).DataContext); } + + private void CloseFlyout(DependencyObject closingButton) + { + try + { + var flyoutPresenter = VisualTreeHelper.GetParent(closingButton); + while (flyoutPresenter != null && !(flyoutPresenter is FlyoutPresenter)) + { + flyoutPresenter = VisualTreeHelper.GetParent(flyoutPresenter); + } + + if (flyoutPresenter != null) + { + var popup = ((FrameworkElement)flyoutPresenter).Parent as Popup; + if (popup != null) + { + popup.IsOpen = false; + } + } + } + catch (Exception) + { + } + } } } From 9f34337d28e93c619cb351d494ceadaa847f8e1e Mon Sep 17 00:00:00 2001 From: Seraphima Zykova Date: Thu, 14 Jan 2021 14:22:32 +0300 Subject: [PATCH 37/38] [FZ Editor] Move zones + and - buttons to the template layouts flyout (#9066) --- ... LayoutTypeCustomToVisibilityConverter.cs} | 2 +- ...LayoutTypeTemplateToVisibilityConverter.cs | 25 +++ .../editor/FancyZonesEditor/MainWindow.xaml | 160 ++++++++++------ .../FancyZonesEditor/MainWindow.xaml.cs | 27 +-- .../Models/CanvasLayoutModel.cs | 22 +++ .../Models/GridLayoutModel.cs | 146 +++++++++++++- .../FancyZonesEditor/Models/LayoutModel.cs | 38 ++++ .../FancyZonesEditor/Models/LayoutSettings.cs | 3 + .../Models/MainWindowSettingsModel.cs | 180 +++--------------- .../editor/FancyZonesEditor/Overlay.cs | 3 +- 10 files changed, 376 insertions(+), 230 deletions(-) rename src/modules/fancyzones/editor/FancyZonesEditor/Converters/{LayoutTypeToVisibilityConverter.cs => LayoutTypeCustomToVisibilityConverter.cs} (91%) create mode 100644 src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeTemplateToVisibilityConverter.cs diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeToVisibilityConverter.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeCustomToVisibilityConverter.cs similarity index 91% rename from src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeToVisibilityConverter.cs rename to src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeCustomToVisibilityConverter.cs index ec87012c5e13..6f254760630e 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeToVisibilityConverter.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeCustomToVisibilityConverter.cs @@ -9,7 +9,7 @@ namespace FancyZonesEditor.Converters { - public class LayoutTypeToVisibilityConverter : IValueConverter + public class LayoutTypeCustomToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeTemplateToVisibilityConverter.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeTemplateToVisibilityConverter.cs new file mode 100644 index 000000000000..e1642fce06b1 --- /dev/null +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeTemplateToVisibilityConverter.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Windows; +using System.Windows.Data; +using FancyZonesEditor.Models; + +namespace FancyZonesEditor.Converters +{ + public class LayoutTypeTemplateToVisibilityConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + var type = (LayoutType)value; + return type != LayoutType.Custom && type != LayoutType.Blank ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return null; + } + } +} diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml index b980eb252ce0..450c1df9fce2 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml +++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml @@ -27,8 +27,9 @@ ResizeMode="CanResize"> - - + + + + Visibility="{Binding Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}"> + Visibility="{Binding Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}" /> + Visibility="{Binding Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}"/> + + +