diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index 6017c2aa9add..3eee435af6da 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -2374,6 +2374,7 @@ Whichdoes
whitespaces
WIC
Wifi
+wifstream
wih
wiki
wikipedia
diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs
index b3b41e9320ae..483d1e6aae2c 100644
--- a/installer/PowerToysSetup/Product.wxs
+++ b/installer/PowerToysSetup/Product.wxs
@@ -374,8 +374,9 @@
-
+
+
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml
index 8baea2aed95a..c372a74c8bb0 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/App.xaml
@@ -2,20 +2,29 @@
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..ba939028d57d 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; }
@@ -49,6 +54,8 @@ public partial class App : Application
public static int PowerToysPID { get; set; }
+ private ThemeManager _themeManager;
+
public static bool DebugMode
{
get
@@ -67,7 +74,7 @@ private void DebugModeCheck()
public App()
{
- DebugModeCheck();
+ // DebugModeCheck();
FancyZonesEditorIO = new FancyZonesEditorIO();
Overlay = new Overlay();
MainWindowSettings = new MainWindowSettingsModel();
@@ -82,8 +89,61 @@ private void OnStartup(object sender, StartupEventArgs e)
Environment.Exit(0);
});
- FancyZonesEditorIO.ParseCommandLineArguments();
- FancyZonesEditorIO.ParseDeviceInfoData();
+ _themeManager = new ThemeManager(this);
+
+ if (!FancyZonesEditorIO.ParseParams().Result)
+ {
+ FancyZonesEditorIO.ParseCommandLineArguments();
+ }
+
+ 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/CanvasEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml
index a7eb95c12efb..2cc908d9adb8 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml
@@ -1,202 +1,69 @@
+ AutomationProperties.Name="{x:Static props:Resources.Canvas_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="320"
+ BorderThickness="0"
+ xmlns:ui="http://schemas.modernwpf.com/2019"
+ ui:WindowHelper.UseModernWindowStyle="True"
+ ui:TitleBar.IsIconVisible="True"
+ SizeToContent="Height"
+ Background="{DynamicResource PrimaryBackgroundBrush}"
+ ResizeMode="NoResize"
+ WindowStartupLocation="CenterOwner"
+ Closed="OnClosed">
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml.cs
index 994f1a54d494..a6959a8ecbfa 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml.cs
@@ -8,11 +8,23 @@
namespace FancyZonesEditor
{
- ///
- /// Interaction logic for windowEditor.xaml
- ///
public partial class CanvasEditorWindow : EditorWindow
{
+ // Default distance from the top and left borders to the zone.
+ private const int DefaultOffset = 100;
+
+ // Next created zone will be by OffsetShift value below and to the right of the previous.
+ private const int OffsetShift = 50;
+
+ // Zone size depends on the work area size multiplied by ZoneSizeMultiplier value.
+ private const double ZoneSizeMultiplier = 0.4;
+
+ // Distance from the top and left borders to the zone.
+ private int _offset = DefaultOffset;
+
+ private CanvasLayoutModel _model;
+ private CanvasLayoutModel _stashedModel;
+
public CanvasEditorWindow()
{
InitializeComponent();
@@ -28,19 +40,19 @@ private void OnAddZone(object sender, RoutedEventArgs e)
Rect workingArea = App.Overlay.WorkArea;
int offset = (int)App.Overlay.ScaleCoordinateWithCurrentMonitorDpi(_offset);
- if (offset + (int)(workingArea.Width * 0.4) < (int)workingArea.Width
- && offset + (int)(workingArea.Height * 0.4) < (int)workingArea.Height)
+ if (offset + (int)(workingArea.Width * ZoneSizeMultiplier) < (int)workingArea.Width
+ && offset + (int)(workingArea.Height * ZoneSizeMultiplier) < (int)workingArea.Height)
{
- _model.AddZone(new Int32Rect(offset, offset, (int)(workingArea.Width * 0.4), (int)(workingArea.Height * 0.4)));
+ _model.AddZone(new Int32Rect(offset, offset, (int)(workingArea.Width * ZoneSizeMultiplier), (int)(workingArea.Height * ZoneSizeMultiplier)));
}
else
{
- _offset = 100;
+ _offset = DefaultOffset;
offset = (int)App.Overlay.ScaleCoordinateWithCurrentMonitorDpi(_offset);
- _model.AddZone(new Int32Rect(offset, offset, (int)(workingArea.Width * 0.4), (int)(workingArea.Height * 0.4)));
+ _model.AddZone(new Int32Rect(offset, offset, (int)(workingArea.Width * ZoneSizeMultiplier), (int)(workingArea.Height * ZoneSizeMultiplier)));
}
- _offset += 50; // TODO: replace hardcoded numbers
+ _offset += OffsetShift;
}
protected new void OnCancel(object sender, RoutedEventArgs e)
@@ -56,9 +68,5 @@ private void CanvasEditorWindow_KeyUp(object sender, KeyEventArgs e)
OnCancel(sender, null);
}
}
-
- private int _offset = 100;
- private CanvasLayoutModel _model;
- private CanvasLayoutModel _stashedModel;
}
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml
index ec036867a0c1..58082fab50ba 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml
@@ -2,7 +2,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:props="clr-namespace:FancyZonesEditor.Properties"
xmlns:local="clr-namespace:FancyZonesEditor"
mc:Ignorable="d"
Background="Transparent"
@@ -15,7 +16,7 @@
-
+
@@ -43,16 +44,27 @@
+
-
-
+
+
-
+
@@ -67,7 +79,10 @@
-
+
@@ -89,8 +104,8 @@
Canvas.Left="10"
Canvas.Bottom="10"
FontSize="64"
- FontFamily="Segoe UI Light"
- Foreground="White"
+ FontWeight="SemiBold"
+ Foreground="{DynamicResource PrimaryForegroundBrush}"
Grid.Column="2"
Grid.Row="2"
VerticalContentAlignment="Center"
@@ -108,10 +123,20 @@
-
+
-
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeBlankToVisibilityConverter.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeBlankToVisibilityConverter.cs
new file mode 100644
index 000000000000..6dea0953668d
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeBlankToVisibilityConverter.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.Globalization;
+using System.Windows;
+using System.Windows.Data;
+using FancyZonesEditor.Models;
+
+namespace FancyZonesEditor.Converters
+{
+ public class LayoutModelTypeBlankToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return (LayoutType)value == LayoutType.Blank ? Visibility.Collapsed : Visibility.Visible;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return null;
+ }
+ }
+}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/BooleanToBrushConverter.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs
similarity index 57%
rename from src/modules/fancyzones/editor/FancyZonesEditor/Converters/BooleanToBrushConverter.xaml.cs
rename to src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs
index 3443c0480991..a1a3c304476f 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/BooleanToBrushConverter.xaml.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutModelTypeToVisibilityConverter.cs
@@ -3,24 +3,22 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Windows;
using System.Windows.Data;
-using System.Windows.Media;
+using FancyZonesEditor.Models;
namespace FancyZonesEditor.Converters
{
- public class BooleanToBrushConverter : IValueConverter
+ public class LayoutModelTypeToVisibilityConverter : 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));
-
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
- return ((bool)value) ? _selectedBrush : _normalBrush;
+ return value is CanvasLayoutModel ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
- return value == _selectedBrush;
+ return null;
}
}
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeCustomToVisibilityConverter.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeCustomToVisibilityConverter.cs
new file mode 100644
index 000000000000..67f685de71b2
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Converters/LayoutTypeCustomToVisibilityConverter.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.Globalization;
+using System.Windows;
+using System.Windows.Data;
+using FancyZonesEditor.Models;
+
+namespace FancyZonesEditor.Converters
+{
+ public class LayoutTypeCustomToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return (LayoutType)value == LayoutType.Custom ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return null;
+ }
+ }
+}
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..c525f2a11f58
--- /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.Globalization;
+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, CultureInfo culture)
+ {
+ return (LayoutType)value != LayoutType.Custom ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return null;
+ }
+ }
+}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs b/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs
index 50cd45798060..367264549879 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)
{
@@ -24,9 +23,13 @@ protected void OnSaveApplyTemplate(object sender, RoutedEventArgs e)
}
model.Persist();
+
+ MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings;
+ settings.SetAppliedModel(model);
+ App.Overlay.SetLayoutSettings(App.Overlay.Monitors[App.Overlay.CurrentDesktop], model);
}
- LayoutModel.SerializeDeletedCustomZoneSets();
+ App.FancyZonesEditorIO.SerializeZoneSettings();
_backToLayoutPicker = false;
Close();
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj
index f1c5ebc635f4..c173f1a29e66 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj
@@ -65,19 +65,14 @@
-
-
-
+
+
all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
+
+
@@ -86,6 +81,11 @@
+
+ True
+ True
+ Resources.resx
+
True
True
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridData.cs b/src/modules/fancyzones/editor/FancyZonesEditor/GridData.cs
index 8aecf1201540..2fed5c8276a1 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/GridData.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridData.cs
@@ -7,7 +7,6 @@
using System.Windows;
using System.Windows.Controls;
using FancyZonesEditor.Models;
-using FancyZonesEditor.Utils;
namespace FancyZonesEditor
{
@@ -120,25 +119,29 @@ public GridData(GridLayoutModel model)
{
_colInfo.Add(new RowColInfo(model.ColumnPercents[col]));
}
+
+ int maxIndex = 0;
+ for (int row = 0; row < _model.Rows; row++)
+ {
+ for (int col = 0; col < _model.Columns; col++)
+ {
+ maxIndex = Math.Max(maxIndex, _model.CellChildMap[row, col]);
+ }
+ }
+
+ _zoneCount = maxIndex + 1;
}
public int ZoneCount
{
get
{
- int maxIndex = 0;
- for (int row = 0; row < _model.Rows; row++)
- {
- for (int col = 0; col < _model.Columns; col++)
- {
- maxIndex = Math.Max(maxIndex, _model.CellChildMap[row, col]);
- }
- }
-
- return maxIndex;
+ return _zoneCount;
}
}
+ private int _zoneCount;
+
public Tuple RowColByIndex(int index)
{
int foundRow = -1;
@@ -238,6 +241,7 @@ public void SplitColumn(int foundCol, int spliteeIndex, int newChildIndex, doubl
FixAccuracyError(_colInfo, _model.ColumnPercents);
_model.CellChildMap = newCellChildMap;
_model.Columns++;
+ _model.UpdatePreview();
}
public void SplitRow(int foundRow, int spliteeIndex, int newChildIndex, double space, double offset, double actualHeight)
@@ -289,6 +293,7 @@ public void SplitRow(int foundRow, int spliteeIndex, int newChildIndex, double s
FixAccuracyError(_rowInfo, _model.RowPercents);
_model.CellChildMap = newCellChildMap;
_model.Rows++;
+ _model.UpdatePreview();
}
public void SplitOnDrag(GridResizer resizer, double delta, double space)
@@ -447,6 +452,8 @@ public void SplitOnDrag(GridResizer resizer, double delta, double space)
_model.CellChildMap = newCellChildMap;
_model.Rows++;
}
+
+ _model.UpdatePreview();
}
public void RecalculateZones(int spacing, Size arrangeSize)
@@ -474,6 +481,11 @@ public void RecalculateZones(int spacing, Size arrangeSize)
public void ArrangeZones(UIElementCollection zones, int spacing)
{
+ if (zones.Count == 0)
+ {
+ return;
+ }
+
int rows = _model.Rows;
int cols = _model.Columns;
int[,] cells = _model.CellChildMap;
@@ -1029,6 +1041,7 @@ private void CollapseIndices()
_model.Rows = rows;
_model.Columns = cols;
+ _model.UpdatePreview();
}
private void FixAccuracyError(List info, List percents)
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml
index 09a039c1160d..6d6eb917b1cf 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml
@@ -5,47 +5,40 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FancyZonesEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:props="clr-namespace:FancyZonesEditor.Properties"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
-
-
-
-
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml.cs
index eb931ad114b0..6c5f6475a4b7 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditor.xaml.cs
@@ -8,7 +8,6 @@
using System.Windows.Controls;
using System.Windows.Input;
using FancyZonesEditor.Models;
-using FancyZonesEditor.Utils;
namespace FancyZonesEditor
{
@@ -40,27 +39,27 @@ public GridEditor()
private void GridEditor_Loaded(object sender, RoutedEventArgs e)
{
GridLayoutModel model = (GridLayoutModel)DataContext;
- if (model != null)
+ if (model == null)
{
- _data = new GridData(model);
- _dragHandles = new GridDragHandles(AdornerLayer.Children, Resizer_DragDelta, Resizer_DragCompleted);
-
- int zoneCount = _data.ZoneCount;
- for (int i = 0; i <= zoneCount; i++)
- {
- AddZone();
- }
+ return;
}
+ _data = new GridData(model);
+ _dragHandles = new GridDragHandles(AdornerLayer.Children, Resizer_DragDelta, Resizer_DragCompleted);
+ _dragHandles.InitDragHandles(model);
+
Model = model;
- if (Model == null)
+ Model.PropertyChanged += OnGridDimensionsChanged;
+
+ int zoneCount = _data.ZoneCount;
+ for (int i = 0; i < zoneCount; i++)
{
- Model = new GridLayoutModel();
- DataContext = Model;
+ AddZone();
}
- Model.PropertyChanged += OnGridDimensionsChanged;
- _dragHandles.InitDragHandles(model);
+ Rect workingArea = App.Overlay.WorkArea;
+ Size actualSize = new Size(workingArea.Width, workingArea.Height);
+ ArrangeGridRects(actualSize);
}
private void GridEditor_Unloaded(object sender, RoutedEventArgs e)
@@ -330,15 +329,17 @@ private int AddZone()
zone.Visibility = Visibility.Visible;
return freeIndex;
}
+
+ zone = new GridZone(Model.ShowSpacing ? Model.Spacing : 0);
+ zone.Split += OnSplit;
+ zone.MergeDrag += OnMergeDrag;
+ zone.MergeComplete += OnMergeComplete;
+ zone.FullSplit += OnFullSplit;
+ Preview.Children.Add(zone);
+ return Preview.Children.Count - 1;
}
- zone = new GridZone();
- zone.Split += OnSplit;
- zone.MergeDrag += OnMergeDrag;
- zone.MergeComplete += OnMergeComplete;
- zone.FullSplit += OnFullSplit;
- Preview.Children.Add(zone);
- return Preview.Children.Count - 1;
+ return 0;
}
private void OnGridDimensionsChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
@@ -372,7 +373,7 @@ private void ArrangeGridRects(Size arrangeSize)
Preview.Height = workArea.Height;
GridLayoutModel model = Model;
- if (model == null)
+ if (model == null || _data == null)
{
return;
}
@@ -383,9 +384,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 +410,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/GridEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml
index 5a35cf349b8a..eba84aadcc84 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml
@@ -1,196 +1,62 @@
+ 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="320"
+ BorderThickness="0"
+ xmlns:ui="http://schemas.modernwpf.com/2019"
+ ui:WindowHelper.UseModernWindowStyle="True"
+ ui:TitleBar.IsIconVisible="True"
+ SizeToContent="Height"
+ Background="{DynamicResource PrimaryBackgroundBrush}"
+ ResizeMode="NoResize"
+ WindowStartupLocation="CenterOwner"
+ Closed="OnClosed">
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml.cs
index a8fb06e15462..df3b8edf9a58 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml.cs
@@ -5,13 +5,9 @@
using System.Windows;
using System.Windows.Input;
using FancyZonesEditor.Models;
-using FancyZonesEditor.Utils;
namespace FancyZonesEditor
{
- ///
- /// Interaction logic for Window2.xaml
- ///
public partial class GridEditorWindow : EditorWindow
{
public GridEditorWindow()
@@ -42,15 +38,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;
- }
}
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml
index 1ed08b38e85a..de499119fc4a 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridResizer.xaml
@@ -8,15 +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/GridZone.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml
index a8cb63dc12a8..491c8e0caf99 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridZone.xaml
@@ -4,13 +4,14 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FancyZonesEditor"
+ xmlns:props="clr-namespace:FancyZonesEditor.Properties"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
- Background="{StaticResource GridZoneBackgroundBrush}"
- BorderBrush="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}"
+ Background="{DynamicResource GridZoneBackgroundBrush}"
+ BorderBrush="{DynamicResource SystemControlBackgroundAccentBrush}"
BorderThickness="1"
- Opacity="0.8"
+ Opacity="1"
mc:Ignorable="d">
@@ -23,9 +24,9 @@
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Content="ID"
- FontFamily="Segoe UI Light"
+ FontWeight="SemiBold"
FontSize="64"
- Foreground="White" />
+ Foreground="{DynamicResource PrimaryForegroundBrush}" />
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/LayoutOverlayWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutOverlayWindow.xaml
index 2ccd224aa26f..4710403e7ce2 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutOverlayWindow.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutOverlayWindow.xaml
@@ -5,9 +5,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FancyZonesEditor"
mc:Ignorable="d"
- Title="FancyZones Layout" Height="450" Width="800"
+ Title="FancyZones Layout"
+ Height="450"
+ Width="800"
ShowInTaskbar="False"
ResizeMode="NoResize"
WindowStyle="None"
AllowsTransparency="True"
- Background="Transparent"/>
\ No newline at end of file
+ Background="{DynamicResource BackdropBrush}"/>
\ No newline at end of file
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml
index e871f7935be5..601d08450706 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml
@@ -6,8 +6,12 @@
xmlns:local="clr-namespace:FancyZonesEditor"
mc:Ignorable="d"
Loaded="OnLoaded"
- d:DesignHeight="450" d:DesignWidth="800">
-
-
+ 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..1780ec7e9254 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/LayoutPreview.xaml.cs
@@ -8,7 +8,6 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
-using System.Windows.Shapes;
using FancyZonesEditor.Models;
namespace FancyZonesEditor
@@ -22,10 +21,11 @@ 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));
-
private LayoutModel _model;
private List _zones = new List();
@@ -49,8 +49,17 @@ public void UpdatePreview()
private void LayoutPreview_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
+ if (_model != null)
+ {
+ _model.PropertyChanged -= LayoutModel_PropertyChanged;
+ }
+
_model = (LayoutModel)DataContext;
- RenderPreview();
+ if (_model != null)
+ {
+ _model.PropertyChanged += LayoutModel_PropertyChanged;
+ RenderPreview();
+ }
}
private void ZoneSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
@@ -68,6 +77,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();
@@ -114,9 +128,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));
@@ -157,7 +169,7 @@ private void RenderActualScalePreview(GridLayoutModel grid)
((col == 0) || (grid.CellChildMap[row, col - 1] != childIndex)))
{
// this is not a continuation of a span
- Rectangle rect = new Rectangle();
+ Border rect = new Border();
left = colInfo[col].Start;
top = rowInfo[row].Start;
Canvas.SetTop(rect, top);
@@ -177,9 +189,7 @@ 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.Style = (Style)FindResource("GridLayoutPreviewActualSizeStyle");
frame.Children.Add(rect);
_zones.Add(new Int32Rect(
(int)left, (int)top, (int)rect.Width, (int)rect.Height));
@@ -216,8 +226,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();
@@ -229,7 +238,7 @@ private void RenderSmallScalePreview(GridLayoutModel grid)
if (!visited.Contains(childIndex))
{
visited.Add(childIndex);
- Rectangle rect = new Rectangle();
+ Border rect = new Border();
Grid.SetRow(rect, row);
Grid.SetColumn(rect, col);
int span = 1;
@@ -251,11 +260,8 @@ private void RenderSmallScalePreview(GridLayoutModel grid)
}
Grid.SetColumnSpan(rect, span);
-
rect.Margin = margin;
- rect.StrokeThickness = 1;
- rect.Stroke = Brushes.DarkGray;
- rect.Fill = Brushes.LightGray;
+ rect.Style = (Style)FindResource("GridLayoutPreviewStyle");
Body.Children.Add(rect);
}
}
@@ -296,14 +302,21 @@ private void RenderCanvasPreview(CanvasLayoutModel canvas)
foreach (Int32Rect zone in canvas.Zones)
{
- Rectangle rect = new Rectangle();
+ Border rect = new Border();
Canvas.SetTop(rect, zone.Y);
Canvas.SetLeft(rect, zone.X);
rect.MinWidth = zone.Width;
rect.MinHeight = zone.Height;
- rect.StrokeThickness = 5;
- rect.Stroke = Brushes.DarkGray;
- rect.Fill = Brushes.LightGray;
+
+ if (IsActualSize)
+ {
+ rect.Style = (Style)FindResource("CanvasLayoutPreviewActualSizeStyle");
+ }
+ else
+ {
+ rect.Style = (Style)FindResource("CanvasLayoutPreviewStyle");
+ }
+
frame.Children.Add(rect);
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml
index 88c87e3e1f66..e63e472fd478 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml
@@ -1,465 +1,666 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 82e363dd324b..2326e21d0c63 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs
@@ -3,40 +3,32 @@
// 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;
using FancyZonesEditor.Models;
-using MahApps.Metro.Controls;
+using FancyZonesEditor.Utils;
+using ModernWpf.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;
- private const int DefaultWrapPanelItemSize = 262;
- private const int SmallWrapPanelItemSize = 180;
+ private const int DefaultWrapPanelItemSize = 164;
+ private const int SmallWrapPanelItemSize = 164;
private const int MinimalForDefaultWrapPanelsHeight = 900;
private readonly MainWindowSettingsModel _settings = ((App)Application.Current).MainWindowSettings;
+ private LayoutModel _backup = null;
- // Localizable string
- private static readonly string _defaultNamePrefix = "Custom Layout ";
+ private ContentDialog _openedDialog = null;
public int WrapPanelItemSize { get; set; } = DefaultWrapPanelItemSize;
- public double SettingsTextMaxWidth
- {
- get
- {
- return (Width / 2) - 60;
- }
- }
-
public MainWindow(bool spanZonesAcrossMonitors, Rect workArea)
{
InitializeComponent();
@@ -51,59 +43,84 @@ public MainWindow(bool spanZonesAcrossMonitors, Rect workArea)
if (workArea.Height < MinimalForDefaultWrapPanelsHeight || App.Overlay.MultiMonitorMode)
{
- SizeToContent = SizeToContent.WidthAndHeight;
WrapPanelItemSize = SmallWrapPanelItemSize;
}
+
+ SizeToContent = SizeToContent.WidthAndHeight;
}
public void Update()
{
DataContext = _settings;
- SetSelectedItem();
}
private void MainWindow_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
- OnClosing(sender, null);
+ if (_openedDialog != null)
+ {
+ _openedDialog.Hide();
+ }
+ else
+ {
+ OnClosing(sender, null);
+ }
}
}
private void DecrementZones_Click(object sender, RoutedEventArgs e)
{
- if (_settings.ZoneCount > 1)
+ var mainEditor = App.Overlay;
+ if (!(mainEditor.CurrentDataContext is LayoutModel model))
+ {
+ return;
+ }
+
+ if (model.TemplateZoneCount > 1)
{
- _settings.ZoneCount--;
+ model.TemplateZoneCount--;
}
}
private void IncrementZones_Click(object sender, RoutedEventArgs e)
{
- if (_settings.ZoneCount < MaxZones)
+ var mainEditor = App.Overlay;
+ if (!(mainEditor.CurrentDataContext is LayoutModel model))
+ {
+ return;
+ }
+
+ if (model.TemplateZoneCount < LayoutSettings.MaxZones)
{
- _settings.ZoneCount++;
+ model.TemplateZoneCount++;
}
}
- private void NewCustomLayoutButton_Click(object sender, RoutedEventArgs e)
+ private void LayoutItem_MouseEnter(object sender, MouseEventArgs e)
{
- WindowLayout window = new WindowLayout();
- window.Show();
- Hide();
+ // Select(((Grid)sender).DataContext as LayoutModel);
}
private void LayoutItem_Click(object sender, MouseButtonEventArgs e)
{
- Select(((Border)sender).DataContext as LayoutModel);
+ LayoutModel selectedLayoutModel = ((Grid)sender).DataContext as LayoutModel;
+ Select(selectedLayoutModel);
+ Apply();
}
private void LayoutItem_Focused(object sender, RoutedEventArgs e)
{
+ // Ignore focus on Edit button click
+ if (e.Source is Button)
+ {
+ return;
+ }
+
Select(((Border)sender).DataContext as LayoutModel);
}
- private void LayoutItem_Apply(object sender, KeyEventArgs e)
+ private void LayoutItem_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return || e.Key == Key.Space)
{
@@ -115,17 +132,39 @@ private void LayoutItem_Apply(object sender, KeyEventArgs e)
private void Select(LayoutModel newSelection)
{
- if (App.Overlay.CurrentDataContext is LayoutModel currentSelection)
+ _settings.SetSelectedModel(newSelection);
+ App.Overlay.CurrentDataContext = newSelection;
+ }
+
+ private async void NewLayoutButton_Click(object sender, RoutedEventArgs e)
+ {
+ string defaultNamePrefix = FancyZonesEditor.Properties.Resources.Default_Custom_Layout_Name;
+ int maxCustomIndex = 0;
+ foreach (LayoutModel customModel in MainWindowSettingsModel.CustomModels)
{
- currentSelection.IsSelected = false;
+ string name = customModel.Name;
+ if (name.StartsWith(defaultNamePrefix))
+ {
+ if (int.TryParse(name.Substring(defaultNamePrefix.Length), out int i))
+ {
+ if (maxCustomIndex < i)
+ {
+ maxCustomIndex = i;
+ }
+ }
+ }
}
- newSelection.IsSelected = true;
- App.Overlay.CurrentDataContext = newSelection;
+ LayoutNameText.Text = defaultNamePrefix + " " + (++maxCustomIndex);
+ GridLayoutRadioButton.IsChecked = true;
+ GridLayoutRadioButton.Focus();
+ await NewLayoutDialog.ShowAsync();
}
- private void EditLayout_Click(object sender, RoutedEventArgs e)
+ private void DuplicateLayout_Click(object sender, RoutedEventArgs e)
{
+ EditLayoutDialog.Hide();
+
var mainEditor = App.Overlay;
if (!(mainEditor.CurrentDataContext is LayoutModel model))
{
@@ -133,26 +172,32 @@ private void EditLayout_Click(object sender, RoutedEventArgs e)
}
model.IsSelected = false;
- Hide();
- bool isPredefinedLayout = MainWindowSettingsModel.IsPredefinedLayout(model);
+ // make a copy
+ model = model.Clone();
+ mainEditor.CurrentDataContext = model;
- if (!MainWindowSettingsModel.CustomModels.Contains(model) || isPredefinedLayout)
+ string name = model.Name;
+ var index = name.LastIndexOf('(');
+ if (index != -1)
{
- if (isPredefinedLayout)
- {
- // make a copy
- model = model.Clone();
- mainEditor.CurrentDataContext = model;
- }
+ name = name.Remove(index);
+ name = name.TrimEnd();
+ }
- int maxCustomIndex = 0;
- foreach (LayoutModel customModel in MainWindowSettingsModel.CustomModels)
+ int maxCustomIndex = 0;
+ foreach (LayoutModel customModel in MainWindowSettingsModel.CustomModels)
+ {
+ string customModelName = customModel.Name;
+ if (customModelName.StartsWith(name))
{
- string name = customModel.Name;
- if (name.StartsWith(_defaultNamePrefix))
+ int openBraceIndex = customModelName.LastIndexOf('(');
+ int closeBraceIndex = customModelName.LastIndexOf(')');
+ if (openBraceIndex != -1 && closeBraceIndex != -1)
{
- if (int.TryParse(name.Substring(_defaultNamePrefix.Length), out int i))
+ string indexSubstring = customModelName.Substring(openBraceIndex + 1, closeBraceIndex - openBraceIndex - 1);
+
+ if (int.TryParse(indexSubstring, out int i))
{
if (maxCustomIndex < i)
{
@@ -161,67 +206,70 @@ private void EditLayout_Click(object sender, RoutedEventArgs e)
}
}
}
-
- model.Name = _defaultNamePrefix + (++maxCustomIndex);
}
- mainEditor.OpenEditor(model);
- }
+ model.Name = name + " (" + (++maxCustomIndex) + ')';
- private void Apply_Click(object sender, RoutedEventArgs e)
- {
- Apply();
+ model.Persist();
+
+ App.Overlay.SetLayoutSettings(App.Overlay.Monitors[App.Overlay.CurrentDesktop], model);
+ App.FancyZonesEditorIO.SerializeZoneSettings();
}
private void Apply()
{
- ((App)Application.Current).MainWindowSettings.ResetAppliedModel();
-
var mainEditor = App.Overlay;
if (mainEditor.CurrentDataContext is LayoutModel model)
{
- model.Apply();
- }
-
- if (!mainEditor.MultiMonitorMode)
- {
- Close();
+ _settings.SetAppliedModel(model);
+ App.Overlay.SetLayoutSettings(App.Overlay.Monitors[App.Overlay.CurrentDesktop], model);
+ App.FancyZonesEditorIO.SerializeZoneSettings();
}
}
private void OnClosing(object sender, EventArgs e)
{
- LayoutModel.SerializeDeletedCustomZoneSets();
+ App.FancyZonesEditorIO.SerializeZoneSettings();
App.Overlay.CloseLayoutWindow();
App.Current.Shutdown();
}
- private void OnInitialized(object sender, EventArgs e)
+ private void DeleteLayout_Click(object sender, RoutedEventArgs e)
{
- SetSelectedItem();
+ EditLayoutDialog.Hide();
+ DeleteLayout((FrameworkElement)sender);
}
- private void SetSelectedItem()
+ private async void EditLayout_Click(object sender, RoutedEventArgs e)
{
- foreach (LayoutModel model in MainWindowSettingsModel.CustomModels)
+ var dataContext = ((FrameworkElement)sender).DataContext;
+ Select((LayoutModel)dataContext);
+
+ if (_settings.SelectedModel is GridLayoutModel grid)
{
- if (model.IsSelected)
- {
- TemplateTab.SelectedItem = model;
- return;
- }
+ _backup = new GridLayoutModel(grid);
}
+ else if (_settings.SelectedModel is CanvasLayoutModel canvas)
+ {
+ _backup = new CanvasLayoutModel(canvas);
+ }
+
+ await EditLayoutDialog.ShowAsync();
}
- private void OnDelete(object sender, RoutedEventArgs e)
+ private void EditZones_Click(object sender, RoutedEventArgs e)
{
- LayoutModel model = ((FrameworkElement)sender).DataContext as LayoutModel;
- if (model.IsSelected)
+ EditLayoutDialog.Hide();
+ var mainEditor = App.Overlay;
+ if (!(mainEditor.CurrentDataContext is LayoutModel model))
{
- SetSelectedItem();
+ return;
}
- model.Delete();
+ _settings.SetSelectedModel(model);
+
+ Hide();
+ mainEditor.OpenEditor(model);
}
private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
@@ -239,32 +287,129 @@ private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e
e.Handled = true;
}
- private void CloseButton_Click(object sender, RoutedEventArgs e)
+ private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog sender, ModernWpf.Controls.ContentDialogButtonClickEventArgs args)
+ {
+ LayoutModel selectedLayoutModel;
+
+ if (GridLayoutRadioButton.IsChecked == true)
+ {
+ GridLayoutModel gridModel = new GridLayoutModel(LayoutNameText.Text, LayoutType.Custom)
+ {
+ Rows = 1,
+ RowPercents = new List(1) { GridLayoutModel.GridMultiplier },
+ };
+ selectedLayoutModel = gridModel;
+ }
+ else
+ {
+ selectedLayoutModel = new CanvasLayoutModel(LayoutNameText.Text, LayoutType.Custom)
+ {
+ TemplateZoneCount = 0,
+ };
+ }
+
+ selectedLayoutModel.InitTemplateZones();
+
+ App.Overlay.CurrentDataContext = selectedLayoutModel;
+ var mainEditor = App.Overlay;
+ Hide();
+ mainEditor.OpenEditor(selectedLayoutModel);
+ }
+
+ // This is required to fix a WPF rendering bug when using custom chrome
+ private void OnContentRendered(object sender, EventArgs e)
+ {
+ InvalidateVisual();
+ }
+
+ private void MonitorItem_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Return || e.Key == Key.Space)
+ {
+ monitorViewModel.SelectCommand.Execute((MonitorInfoModel)(sender as Border).DataContext);
+ }
+ }
+
+ private void MonitorItem_MouseDown(object sender, MouseButtonEventArgs e)
{
- this.Close();
+ monitorViewModel.SelectCommand.Execute((MonitorInfoModel)(sender as Border).DataContext);
}
- private void Reset_Click(object sender, RoutedEventArgs e)
+ // EditLayout: Cancel changes
+ private void EditLayoutDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
- var overlay = App.Overlay;
- MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings;
+ // restore model properties from settings
+ _settings.RestoreSelectedModel(_backup);
+ _backup = null;
+
+ Select(_settings.AppliedModel);
+ }
- if (overlay.CurrentDataContext is LayoutModel model)
+ // EditLayout: Save changes
+ private void EditLayoutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
+ {
+ var mainEditor = App.Overlay;
+ if (!(mainEditor.CurrentDataContext is LayoutModel model))
{
- model.IsSelected = false;
- model.IsApplied = false;
+ return;
}
- overlay.CurrentLayoutSettings.ZonesetUuid = settings.BlankModel.Uuid;
- overlay.CurrentLayoutSettings.Type = LayoutType.Blank;
- overlay.CurrentDataContext = settings.BlankModel;
+ _backup = null;
- App.FancyZonesEditorIO.SerializeAppliedLayouts();
+ // update current settings
+ if (model == _settings.AppliedModel)
+ {
+ App.Overlay.SetLayoutSettings(App.Overlay.Monitors[App.Overlay.CurrentDesktop], model);
+ }
- if (!overlay.MultiMonitorMode)
+ App.FancyZonesEditorIO.SerializeZoneSettings();
+
+ // reset selected model
+ Select(_settings.AppliedModel);
+ }
+
+ private async void DeleteLayout(FrameworkElement element)
+ {
+ var dialog = new ModernWpf.Controls.ContentDialog()
+ {
+ Title = FancyZonesEditor.Properties.Resources.Are_You_Sure,
+ Content = FancyZonesEditor.Properties.Resources.Are_You_Sure_Description,
+ PrimaryButtonText = FancyZonesEditor.Properties.Resources.Delete,
+ SecondaryButtonText = FancyZonesEditor.Properties.Resources.Cancel,
+ };
+
+ var result = await dialog.ShowAsync();
+ if (result == ContentDialogResult.Primary)
{
- Close();
+ LayoutModel model = element.DataContext as LayoutModel;
+
+ if (model == _settings.AppliedModel)
+ {
+ _settings.SetAppliedModel(_settings.BlankModel);
+ Select(_settings.BlankModel);
+ }
+
+ foreach (var monitor in App.Overlay.Monitors)
+ {
+ if (monitor.Settings.ZonesetUuid == model.Uuid)
+ {
+ App.Overlay.SetLayoutSettings(monitor, _settings.BlankModel);
+ }
+ }
+
+ App.FancyZonesEditorIO.SerializeZoneSettings();
+ model.Delete();
}
}
+
+ private void Dialog_Opened(ContentDialog sender, ContentDialogOpenedEventArgs args)
+ {
+ _openedDialog = sender;
+ }
+
+ private void Dialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs args)
+ {
+ _openedDialog = null;
+ }
}
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs
index 03ac60aaaaa3..49cc928ac020 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/CanvasLayoutModel.cs
@@ -2,9 +2,7 @@
// 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.Collections.Generic;
-using System.Text.Json;
using System.Windows;
namespace FancyZonesEditor.Models
@@ -14,7 +12,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; }
@@ -35,6 +33,17 @@ public CanvasLayoutModel(string name)
{
}
+ public CanvasLayoutModel(CanvasLayoutModel other)
+ : base(other)
+ {
+ CanvasRect = new Rect(other.CanvasRect.X, other.CanvasRect.Y, other.CanvasRect.Width, other.CanvasRect.Height);
+
+ foreach (Int32Rect zone in other.Zones)
+ {
+ Zones.Add(zone);
+ }
+ }
+
// Zones - the list of all zones in this layout, described as independent rectangles
public IList Zones { get; private set; } = new List();
@@ -54,6 +63,28 @@ public void AddZone(Int32Rect zone)
UpdateLayout();
}
+ // InitTemplateZones
+ // Creates zones based on template zones count
+ public override void InitTemplateZones()
+ {
+ Zones.Clear();
+
+ var workingArea = App.Overlay.WorkArea;
+ int topLeftCoordinate = (int)App.Overlay.ScaleCoordinateWithCurrentMonitorDpi(100); // TODO: replace magic numbers
+ int width = (int)(workingArea.Width * 0.4);
+ int height = (int)(workingArea.Height * 0.4);
+ Int32Rect focusZoneRect = new Int32Rect(topLeftCoordinate, topLeftCoordinate, width, height);
+ int focusRectXIncrement = (TemplateZoneCount <= 1) ? 0 : (int)App.Overlay.ScaleCoordinateWithCurrentMonitorDpi(50); // TODO: replace magic numbers
+ int focusRectYIncrement = (TemplateZoneCount <= 1) ? 0 : (int)App.Overlay.ScaleCoordinateWithCurrentMonitorDpi(50); // TODO: replace magic numbers
+
+ for (int i = 0; i < TemplateZoneCount; i++)
+ {
+ Zones.Add(focusZoneRect);
+ focusZoneRect.X += focusRectXIncrement;
+ focusZoneRect.Y += focusRectYIncrement;
+ }
+ }
+
private void UpdateLayout()
{
FirePropertyChanged();
@@ -71,6 +102,7 @@ public override LayoutModel Clone()
layout.Zones.Add(zone);
}
+ layout.SensitivityRadius = SensitivityRadius;
return layout;
}
@@ -81,37 +113,8 @@ public void RestoreTo(CanvasLayoutModel other)
{
other.Zones.Add(zone);
}
- }
-
- 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; }
+ other.SensitivityRadius = SensitivityRadius;
}
// PersistData
@@ -119,48 +122,6 @@ private struct CanvasLayoutJson
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..cfc2792871a9 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/GridLayoutModel.cs
@@ -1,11 +1,8 @@
-// Copyright (c) Microsoft Corporation
+// 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.Collections.Generic;
-using System.Text.Json;
-using System.Windows;
namespace FancyZonesEditor.Models
{
@@ -14,7 +11,25 @@ namespace FancyZonesEditor.Models
public class GridLayoutModel : LayoutModel
{
// Non-localizable strings
- private const string ModelTypeID = "grid";
+ public const string ModelTypeID = "grid";
+
+ public const int GridMultiplier = 10000;
+
+ // hard coded data for all the "Priority Grid" configurations that are unique to "Grid"
+ private static readonly byte[][] _priorityData = new byte[][]
+ {
+ new byte[] { 0, 0, 0, 0, 0, 1, 1, 39, 16, 39, 16, 0 },
+ new byte[] { 0, 0, 0, 0, 0, 1, 2, 39, 16, 26, 11, 13, 5, 0, 1 },
+ new byte[] { 0, 0, 0, 0, 0, 1, 3, 39, 16, 9, 196, 19, 136, 9, 196, 0, 1, 2 },
+ new byte[] { 0, 0, 0, 0, 0, 2, 3, 19, 136, 19, 136, 9, 196, 19, 136, 9, 196, 0, 1, 2, 0, 1, 3 },
+ new byte[] { 0, 0, 0, 0, 0, 2, 3, 19, 136, 19, 136, 9, 196, 19, 136, 9, 196, 0, 1, 2, 3, 1, 4 },
+ new byte[] { 0, 0, 0, 0, 0, 3, 3, 13, 5, 13, 6, 13, 5, 9, 196, 19, 136, 9, 196, 0, 1, 2, 0, 1, 3, 4, 1, 5 },
+ new byte[] { 0, 0, 0, 0, 0, 3, 3, 13, 5, 13, 6, 13, 5, 9, 196, 19, 136, 9, 196, 0, 1, 2, 3, 1, 4, 5, 1, 6 },
+ new byte[] { 0, 0, 0, 0, 0, 3, 4, 13, 5, 13, 6, 13, 5, 9, 196, 9, 196, 9, 196, 9, 196, 0, 1, 2, 3, 4, 1, 2, 5, 6, 1, 2, 7 },
+ new byte[] { 0, 0, 0, 0, 0, 3, 4, 13, 5, 13, 6, 13, 5, 9, 196, 9, 196, 9, 196, 9, 196, 0, 1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8 },
+ new byte[] { 0, 0, 0, 0, 0, 3, 4, 13, 5, 13, 6, 13, 5, 9, 196, 9, 196, 9, 196, 9, 196, 0, 1, 2, 3, 4, 1, 5, 6, 7, 1, 8, 9 },
+ new byte[] { 0, 0, 0, 0, 0, 3, 4, 13, 5, 13, 6, 13, 5, 9, 196, 9, 196, 9, 196, 9, 196, 0, 1, 2, 3, 4, 1, 5, 6, 7, 8, 9, 10 },
+ };
// Rows - number of rows in the Grid
public int Rows
@@ -29,7 +44,6 @@ public int Rows
if (_rows != value)
{
_rows = value;
- FirePropertyChanged();
}
}
}
@@ -49,7 +63,6 @@ public int Columns
if (_cols != value)
{
_cols = value;
- FirePropertyChanged();
}
}
}
@@ -62,10 +75,50 @@ public int Columns
public int[,] CellChildMap { get; set; }
// RowPercents - represents the %age height of each row in the grid
- public List RowPercents { get; set; }
+ public List RowPercents { get; set; } = new List();
// ColumnPercents - represents the %age width of each column in the grid
- public List ColumnPercents { get; set; }
+ public List ColumnPercents { get; set; } = new List();
+
+ // ShowSpacing - flag if free space between cells should be presented
+ public bool ShowSpacing
+ {
+ get
+ {
+ return _showSpacing;
+ }
+
+ set
+ {
+ if (value != _showSpacing)
+ {
+ _showSpacing = value;
+ FirePropertyChanged(nameof(ShowSpacing));
+ }
+ }
+ }
+
+ private bool _showSpacing = LayoutSettings.DefaultShowSpacing;
+
+ // Spacing - free space between cells
+ public int Spacing
+ {
+ get
+ {
+ return _spacing;
+ }
+
+ set
+ {
+ if (value != _spacing)
+ {
+ _spacing = value;
+ FirePropertyChanged(nameof(Spacing));
+ }
+ }
+ }
+
+ 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
@@ -97,13 +150,46 @@ public GridLayoutModel(string uuid, string name, LayoutType type, int rows, int
CellChildMap = cellChildMap;
}
+ public GridLayoutModel(GridLayoutModel other)
+ : base(other)
+ {
+ _rows = other._rows;
+ _cols = other._cols;
+ _showSpacing = other._showSpacing;
+ _spacing = other._spacing;
+
+ CellChildMap = new int[_rows, _cols];
+ for (int row = 0; row < _rows; row++)
+ {
+ for (int col = 0; col < _cols; col++)
+ {
+ CellChildMap[row, col] = other.CellChildMap[row, col];
+ }
+ }
+
+ for (int row = 0; row < _rows; row++)
+ {
+ RowPercents.Add(other.RowPercents[row]);
+ }
+
+ for (int col = 0; col < _cols; col++)
+ {
+ ColumnPercents.Add(other.ColumnPercents[col]);
+ }
+ }
+
+ public void UpdatePreview()
+ {
+ FirePropertyChanged();
+ }
+
public void Reload(byte[] data)
{
// Skip version (2 bytes), id (2 bytes), and type (1 bytes)
int i = 5;
- Rows = data[i++];
- Columns = data[i++];
+ _rows = data[i++];
+ _cols = data[i++];
RowPercents = new List(Rows);
for (int row = 0; row < Rows; row++)
@@ -125,6 +211,8 @@ public void Reload(byte[] data)
CellChildMap[row, col] = data[i++];
}
}
+
+ FirePropertyChanged();
}
// Clone
@@ -171,71 +259,142 @@ public void RestoreTo(GridLayoutModel layout)
}
layout.ColumnPercents = colPercents;
+
+ layout.ShowSpacing = ShowSpacing;
+ layout.Spacing = Spacing;
+ layout.SensitivityRadius = SensitivityRadius;
+ }
+
+ // InitTemplateZones
+ // Creates zones based on template zones count
+ public override void InitTemplateZones()
+ {
+ switch (Type)
+ {
+ case LayoutType.Rows:
+ InitRows();
+ break;
+ case LayoutType.Columns:
+ InitColumns();
+ break;
+ case LayoutType.Grid:
+ InitGrid();
+ break;
+ case LayoutType.PriorityGrid:
+ InitPriorityGrid();
+ break;
+ case LayoutType.Custom:
+ InitColumns(); // Custom is initialized with columns
+ break;
+ }
+
+ FirePropertyChanged();
}
- private struct GridLayoutInfo
+ // PersistData
+ // Implements the LayoutModel.PersistData abstract method
+ protected override void PersistData()
{
- public int Rows { get; set; }
+ AddCustomLayout(this);
+ }
- public int Columns { get; set; }
+ private void InitRows()
+ {
+ CellChildMap = new int[TemplateZoneCount, 1];
+ RowPercents = new List(TemplateZoneCount);
- public List RowsPercentage { get; set; }
+ for (int i = 0; i < TemplateZoneCount; i++)
+ {
+ CellChildMap[i, 0] = i;
- public List ColumnsPercentage { get; set; }
+ // Note: This is NOT equal to _multiplier / ZoneCount and is done like this to make
+ // the sum of all RowPercents exactly (_multiplier).
+ RowPercents.Add(((GridMultiplier * (i + 1)) / TemplateZoneCount) - ((GridMultiplier * i) / TemplateZoneCount));
+ }
- public int[][] CellChildMap { get; set; }
+ _rows = TemplateZoneCount;
}
- private struct GridLayoutJson
+ private void InitColumns()
{
- public string Uuid { get; set; }
+ CellChildMap = new int[1, TemplateZoneCount];
+ ColumnPercents = new List(TemplateZoneCount);
- public string Name { get; set; }
+ for (int i = 0; i < TemplateZoneCount; i++)
+ {
+ CellChildMap[0, i] = i;
- public string Type { get; set; }
+ // Note: This is NOT equal to _multiplier / ZoneCount and is done like this to make
+ // the sum of all RowPercents exactly (_multiplier).
+ ColumnPercents.Add(((GridMultiplier * (i + 1)) / TemplateZoneCount) - ((GridMultiplier * i) / TemplateZoneCount));
+ }
- public GridLayoutInfo Info { get; set; }
+ _cols = TemplateZoneCount;
}
- // PersistData
- // Implements the LayoutModel.PersistData abstract method
- protected override void PersistData()
+ private void InitGrid()
{
- AddCustomLayout(this);
+ int rows = 1;
+ while (TemplateZoneCount / rows >= rows)
+ {
+ rows++;
+ }
- GridLayoutInfo layoutInfo = new GridLayoutInfo
+ rows--;
+ int cols = TemplateZoneCount / rows;
+ if (TemplateZoneCount % rows == 0)
{
- Rows = Rows,
- Columns = Columns,
- RowsPercentage = RowPercents,
- ColumnsPercentage = ColumnPercents,
- CellChildMap = new int[Rows][],
- };
+ // even grid
+ }
+ else
+ {
+ cols++;
+ }
- for (int row = 0; row < Rows; row++)
+ RowPercents = new List(rows);
+ ColumnPercents = new List(cols);
+ CellChildMap = new int[rows, cols];
+
+ // Note: The following are NOT equal to _multiplier divided by rows or columns and is
+ // done like this to make the sum of all RowPercents exactly (_multiplier).
+ for (int row = 0; row < rows; row++)
{
- layoutInfo.CellChildMap[row] = new int[Columns];
- for (int col = 0; col < Columns; col++)
+ RowPercents.Add(((GridMultiplier * (row + 1)) / rows) - ((GridMultiplier * row) / rows));
+ }
+
+ for (int col = 0; col < cols; col++)
+ {
+ ColumnPercents.Add(((GridMultiplier * (col + 1)) / cols) - ((GridMultiplier * col) / cols));
+ }
+
+ int index = 0;
+ for (int row = 0; row < rows; row++)
+ {
+ for (int col = 0; col < cols; col++)
{
- layoutInfo.CellChildMap[row][col] = CellChildMap[row, col];
+ CellChildMap[row, col] = index++;
+ if (index == TemplateZoneCount)
+ {
+ index--;
+ }
}
}
- GridLayoutJson jsonObj = new GridLayoutJson
+ _rows = rows;
+ _cols = cols;
+ }
+
+ private void InitPriorityGrid()
+ {
+ if (TemplateZoneCount <= _priorityData.Length)
{
- Uuid = Uuid,
- Name = Name,
- Type = ModelTypeID,
- Info = layoutInfo,
- };
- JsonSerializerOptions options = new JsonSerializerOptions
+ Reload(_priorityData[TemplateZoneCount - 1]);
+ }
+ else
{
- PropertyNamingPolicy = new DashCaseNamingPolicy(),
- };
-
- string jsonString = JsonSerializer.Serialize(jsonObj, options);
- AddCustomLayoutJson(JsonSerializer.Deserialize(jsonString));
- SerializeCreatedCustomZonesets();
+ // same as grid;
+ InitGrid();
+ }
}
}
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs
index 61d3ac76bdae..ea66005b22ac 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
{
@@ -42,6 +39,17 @@ protected LayoutModel(string name, LayoutType type)
Type = type;
}
+ protected LayoutModel(LayoutModel other)
+ {
+ _guid = other._guid;
+ _name = other._name;
+ Type = other.Type;
+ _isSelected = other._isSelected;
+ _isApplied = other._isApplied;
+ _sensitivityRadius = other._sensitivityRadius;
+ _zoneCount = other._zoneCount;
+ }
+
// Name - the display name for this layout model - is also used as the key in the registry
public string Name
{
@@ -55,7 +63,7 @@ public string Name
if (_name != value)
{
_name = value;
- FirePropertyChanged();
+ FirePropertyChanged(nameof(Name));
}
}
}
@@ -82,6 +90,14 @@ public string Uuid
}
}
+ public bool IsCustom
+ {
+ get
+ {
+ return Type == LayoutType.Custom;
+ }
+ }
+
// IsSelected (not-persisted) - tracks whether or not this LayoutModel is selected in the picker
// TODO: once we switch to a picker per monitor, we need to move this state to the view
public bool IsSelected
@@ -96,13 +112,14 @@ public bool IsSelected
if (_isSelected != value)
{
_isSelected = value;
- FirePropertyChanged();
+ FirePropertyChanged(nameof(IsSelected));
}
}
}
private bool _isSelected;
+ // IsApplied (not-persisted) - tracks whether or not this LayoutModel is applied in the picker
public bool IsApplied
{
get
@@ -115,13 +132,53 @@ public bool IsApplied
if (_isApplied != value)
{
_isApplied = value;
- FirePropertyChanged();
+ FirePropertyChanged(nameof(IsApplied));
}
}
}
private bool _isApplied;
+ public int SensitivityRadius
+ {
+ get
+ {
+ return _sensitivityRadius;
+ }
+
+ set
+ {
+ if (value != _sensitivityRadius)
+ {
+ _sensitivityRadius = value;
+ FirePropertyChanged(nameof(SensitivityRadius));
+ }
+ }
+ }
+
+ private int _sensitivityRadius = LayoutSettings.DefaultSensitivityRadius;
+
+ // TemplateZoneCount - number of zones selected in the picker window for template layouts
+ public int TemplateZoneCount
+ {
+ get
+ {
+ return _zoneCount;
+ }
+
+ set
+ {
+ if (value != _zoneCount)
+ {
+ _zoneCount = value;
+ InitTemplateZones();
+ FirePropertyChanged(nameof(TemplateZoneCount));
+ }
+ }
+ }
+
+ private int _zoneCount = LayoutSettings.DefaultZoneCount;
+
// implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
@@ -134,11 +191,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,48 +203,25 @@ 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;
- }
-
- private static ObservableCollection _customModels;
- private static List _deletedCustomModels = new List();
- private static List _createdCustomLayouts = new List();
+ // InitTemplateZones
+ // Creates zones based on template zones count
+ public abstract void InitTemplateZones();
// Callbacks that the base LayoutModel makes to derived types
protected abstract void PersistData();
@@ -197,21 +231,6 @@ public static ObservableCollection LoadCustomModels()
public void Persist()
{
PersistData();
- Apply();
- }
-
- public void Apply()
- {
- MainWindowSettingsModel settings = ((App)App.Current).MainWindowSettings;
- settings.ResetAppliedModel();
- IsApplied = true;
-
- // update settings
- App.Overlay.CurrentLayoutSettings.ZonesetUuid = Uuid;
- App.Overlay.CurrentLayoutSettings.Type = Type;
-
- // update temp file
- App.FancyZonesEditorIO.SerializeAppliedLayouts();
}
}
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutSettings.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutSettings.cs
index 32c5b63a7e44..3b8487a6353a 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutSettings.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutSettings.cs
@@ -9,13 +9,16 @@ namespace FancyZonesEditor
{
public class LayoutSettings
{
- public static bool DefaultShowSpacing => true;
+ // TODO: share the constants b/w C# Editor and FancyZoneLib
+ 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 const int MaxZones = 40;
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 c48b371d56dd..a23e1d8fd8c3 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs
@@ -2,12 +2,10 @@
// 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.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
-using System.Windows;
using FancyZonesEditor.Models;
namespace FancyZonesEditor
@@ -25,43 +23,17 @@ private enum DeviceIdParts
VirtualDesktopId,
}
- private static CanvasLayoutModel _blankCustomModel;
+ private readonly CanvasLayoutModel _blankModel;
private readonly CanvasLayoutModel _focusModel;
private readonly GridLayoutModel _rowsModel;
private readonly GridLayoutModel _columnsModel;
private readonly GridLayoutModel _gridModel;
private readonly GridLayoutModel _priorityGridModel;
- public const ushort _focusModelId = 0xFFFF;
- public const ushort _rowsModelId = 0xFFFE;
- public const ushort _columnsModelId = 0xFFFD;
- public const ushort _gridModelId = 0xFFFC;
- public const ushort _priorityGridModelId = 0xFFFB;
- public const ushort _blankCustomModelId = 0xFFFA;
- public const ushort _lastDefinedId = _blankCustomModelId;
-
// Non-localizable strings
public static readonly string RegistryPath = "SOFTWARE\\SuperFancyZones";
public static readonly string FullRegistryPath = "HKEY_CURRENT_USER\\" + RegistryPath;
- // hard coded data for all the "Priority Grid" configurations that are unique to "Grid"
- private static readonly byte[][] _priorityData = new byte[][]
- {
- new byte[] { 0, 0, 0, 0, 0, 1, 1, 39, 16, 39, 16, 0 },
- new byte[] { 0, 0, 0, 0, 0, 1, 2, 39, 16, 26, 11, 13, 5, 0, 1 },
- new byte[] { 0, 0, 0, 0, 0, 1, 3, 39, 16, 9, 196, 19, 136, 9, 196, 0, 1, 2 },
- new byte[] { 0, 0, 0, 0, 0, 2, 3, 19, 136, 19, 136, 9, 196, 19, 136, 9, 196, 0, 1, 2, 0, 1, 3 },
- new byte[] { 0, 0, 0, 0, 0, 2, 3, 19, 136, 19, 136, 9, 196, 19, 136, 9, 196, 0, 1, 2, 3, 1, 4 },
- new byte[] { 0, 0, 0, 0, 0, 3, 3, 13, 5, 13, 6, 13, 5, 9, 196, 19, 136, 9, 196, 0, 1, 2, 0, 1, 3, 4, 1, 5 },
- new byte[] { 0, 0, 0, 0, 0, 3, 3, 13, 5, 13, 6, 13, 5, 9, 196, 19, 136, 9, 196, 0, 1, 2, 3, 1, 4, 5, 1, 6 },
- new byte[] { 0, 0, 0, 0, 0, 3, 4, 13, 5, 13, 6, 13, 5, 9, 196, 9, 196, 9, 196, 9, 196, 0, 1, 2, 3, 4, 1, 2, 5, 6, 1, 2, 7 },
- new byte[] { 0, 0, 0, 0, 0, 3, 4, 13, 5, 13, 6, 13, 5, 9, 196, 9, 196, 9, 196, 9, 196, 0, 1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8 },
- new byte[] { 0, 0, 0, 0, 0, 3, 4, 13, 5, 13, 6, 13, 5, 9, 196, 9, 196, 9, 196, 9, 196, 0, 1, 2, 3, 4, 1, 5, 6, 7, 1, 8, 9 },
- new byte[] { 0, 0, 0, 0, 0, 3, 4, 13, 5, 13, 6, 13, 5, 9, 196, 9, 196, 9, 196, 9, 196, 0, 1, 2, 3, 4, 1, 5, 6, 7, 8, 9, 10 },
- };
-
- private const int _multiplier = 10000;
-
public bool IsCustomLayoutActive
{
get
@@ -80,112 +52,41 @@ public bool IsCustomLayoutActive
public MainWindowSettingsModel()
{
- // Initialize the five default layout models: Focus, Columns, Rows, Grid, and PriorityGrid
- DefaultModels = new List(5);
+ // Initialize default layout models: Blank, Focus, Columns, Rows, Grid, and PriorityGrid
+ _blankModel = new CanvasLayoutModel(Properties.Resources.Template_Layout_Blank, LayoutType.Blank)
+ {
+ TemplateZoneCount = 0,
+ SensitivityRadius = 0,
+ };
+ DefaultModels.Add(_blankModel);
+
_focusModel = new CanvasLayoutModel(Properties.Resources.Template_Layout_Focus, LayoutType.Focus);
+ _focusModel.InitTemplateZones();
DefaultModels.Add(_focusModel);
_columnsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Columns, LayoutType.Columns)
{
Rows = 1,
- RowPercents = new List(1) { _multiplier },
+ RowPercents = new List(1) { GridLayoutModel.GridMultiplier },
};
+ _columnsModel.InitTemplateZones();
DefaultModels.Add(_columnsModel);
_rowsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Rows, LayoutType.Rows)
{
Columns = 1,
- ColumnPercents = new List(1) { _multiplier },
+ ColumnPercents = new List(1) { GridLayoutModel.GridMultiplier },
};
+ _rowsModel.InitTemplateZones();
DefaultModels.Add(_rowsModel);
_gridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Grid, LayoutType.Grid);
+ _gridModel.InitTemplateZones();
DefaultModels.Add(_gridModel);
_priorityGridModel = new GridLayoutModel(Properties.Resources.Template_Layout_Priority_Grid, LayoutType.PriorityGrid);
+ _priorityGridModel.InitTemplateZones();
DefaultModels.Add(_priorityGridModel);
-
- _blankCustomModel = new CanvasLayoutModel(Properties.Resources.Custom_Layout_Create_New, LayoutType.Blank);
-
- UpdateTemplateLayoutModels();
- }
-
- // ZoneCount - number of zones selected in the picker window
- public int ZoneCount
- {
- get
- {
- return App.Overlay.CurrentLayoutSettings.ZoneCount;
- }
-
- set
- {
- if (App.Overlay.CurrentLayoutSettings.ZoneCount != value)
- {
- App.Overlay.CurrentLayoutSettings.ZoneCount = value;
- UpdateTemplateLayoutModels();
- FirePropertyChanged(nameof(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
@@ -228,146 +129,63 @@ public bool IsCtrlKeyPressed
private bool _isCtrlKeyPressed;
- // UpdateLayoutModels
- // Update the five default layouts based on the new ZoneCount
- private void UpdateTemplateLayoutModels()
+ public LayoutModel BlankModel
{
- // Update the "Focus" Default Layout
- _focusModel.Zones.Clear();
-
- // Sanity check for imported settings that may have invalid data
- if (ZoneCount < 1)
- {
- ZoneCount = 3;
- }
-
- // If changing focus layout zones size and/or increment,
- // same change should be applied in ZoneSet.cpp (ZoneSet::CalculateFocusLayout)
- var workingArea = App.Overlay.WorkArea;
- int topLeftCoordinate = (int)App.Overlay.ScaleCoordinateWithCurrentMonitorDpi(100); // TODO: replace magic numbers
- int width = (int)(workingArea.Width * 0.4);
- int height = (int)(workingArea.Height * 0.4);
- Int32Rect focusZoneRect = new Int32Rect(topLeftCoordinate, topLeftCoordinate, width, height);
- int focusRectXIncrement = (ZoneCount <= 1) ? 0 : (int)App.Overlay.ScaleCoordinateWithCurrentMonitorDpi(50);
- int focusRectYIncrement = (ZoneCount <= 1) ? 0 : (int)App.Overlay.ScaleCoordinateWithCurrentMonitorDpi(50);
-
- for (int i = 0; i < ZoneCount; i++)
- {
- _focusModel.Zones.Add(focusZoneRect);
- focusZoneRect.X += focusRectXIncrement;
- focusZoneRect.Y += focusRectYIncrement;
- }
-
- // Update the "Rows" and "Columns" Default Layouts
- // They can share their model, just transposed
- _rowsModel.CellChildMap = new int[ZoneCount, 1];
- _columnsModel.CellChildMap = new int[1, ZoneCount];
- _rowsModel.Rows = _columnsModel.Columns = ZoneCount;
- _rowsModel.RowPercents = _columnsModel.ColumnPercents = new List(ZoneCount);
-
- for (int i = 0; i < ZoneCount; i++)
+ get
{
- _rowsModel.CellChildMap[i, 0] = i;
- _columnsModel.CellChildMap[0, i] = i;
-
- // Note: This is NOT equal to _multiplier / ZoneCount and is done like this to make
- // the sum of all RowPercents exactly (_multiplier).
- // _columnsModel is sharing the same array
- _rowsModel.RowPercents.Add(((_multiplier * (i + 1)) / ZoneCount) - ((_multiplier * i) / ZoneCount));
+ return _blankModel;
}
+ }
- // Update the "Grid" Default Layout
- int rows = 1;
- while (ZoneCount / rows >= rows)
- {
- rows++;
- }
+ public static IList DefaultModels { get; } = new List(6);
- rows--;
- int cols = ZoneCount / rows;
- if (ZoneCount % rows == 0)
- {
- // even grid
- }
- else
+ public static ObservableCollection CustomModels
+ {
+ get
{
- cols++;
+ return _customModels;
}
+ }
- _gridModel.Rows = rows;
- _gridModel.Columns = cols;
- _gridModel.RowPercents = new List(rows);
- _gridModel.ColumnPercents = new List(cols);
- _gridModel.CellChildMap = new int[rows, cols];
-
- // Note: The following are NOT equal to _multiplier divided by rows or columns and is
- // done like this to make the sum of all RowPercents exactly (_multiplier).
- for (int row = 0; row < rows; row++)
- {
- _gridModel.RowPercents.Add(((_multiplier * (row + 1)) / rows) - ((_multiplier * row) / rows));
- }
+ private static ObservableCollection _customModels = new ObservableCollection();
- for (int col = 0; col < cols; col++)
+ public LayoutModel SelectedModel
+ {
+ get
{
- _gridModel.ColumnPercents.Add(((_multiplier * (col + 1)) / cols) - ((_multiplier * col) / cols));
+ return _selectedModel;
}
- int index = 0;
- for (int row = 0; row < rows; row++)
+ private set
{
- for (int col = 0; col < cols; col++)
+ if (_selectedModel != value)
{
- _gridModel.CellChildMap[row, col] = index++;
- if (index == ZoneCount)
- {
- index--;
- }
+ _selectedModel = value;
+ FirePropertyChanged(nameof(SelectedModel));
}
}
-
- // Update the "Priority Grid" Default Layout
- if (ZoneCount <= _priorityData.Length)
- {
- _priorityGridModel.Reload(_priorityData[ZoneCount - 1]);
- }
- else
- {
- // same as grid;
- _priorityGridModel.Rows = _gridModel.Rows;
- _priorityGridModel.Columns = _gridModel.Columns;
- _priorityGridModel.RowPercents = _gridModel.RowPercents;
- _priorityGridModel.ColumnPercents = _gridModel.ColumnPercents;
- _priorityGridModel.CellChildMap = _gridModel.CellChildMap;
- }
}
- public IList DefaultModels { get; }
+ private LayoutModel _selectedModel = null;
- public static ObservableCollection CustomModels
+ public LayoutModel AppliedModel
{
get
{
- if (_customModels == null)
- {
- _customModels = LayoutModel.LoadCustomModels();
- _customModels.Insert(0, _blankCustomModel);
- }
-
- return _customModels;
+ return _appliedModel;
}
- }
-
- private static ObservableCollection _customModels;
- public CanvasLayoutModel BlankModel
- {
- get
+ private set
{
- return _blankModel;
+ if (_appliedModel != value)
+ {
+ _appliedModel = value;
+ FirePropertyChanged(nameof(AppliedModel));
+ }
}
}
- private CanvasLayoutModel _blankModel = new CanvasLayoutModel(string.Empty, LayoutType.Blank);
+ private LayoutModel _appliedModel = null;
public static bool IsPredefinedLayout(LayoutModel model)
{
@@ -376,21 +194,13 @@ public static bool IsPredefinedLayout(LayoutModel model)
public LayoutModel UpdateSelectedLayoutModel()
{
- UpdateTemplateLayoutModels();
- ResetAppliedModel();
- ResetSelectedModel();
-
LayoutModel foundModel = null;
LayoutSettings currentApplied = App.Overlay.CurrentLayoutSettings;
// set new layout
- if (currentApplied.Type == LayoutType.Blank)
+ if (currentApplied.Type == LayoutType.Custom)
{
- foundModel = BlankModel;
- }
- else if (currentApplied.Type == LayoutType.Custom)
- {
- foreach (LayoutModel model in MainWindowSettingsModel.CustomModels)
+ foreach (LayoutModel model in CustomModels)
{
if ("{" + model.Guid.ToString().ToUpperInvariant() + "}" == currentApplied.ZonesetUuid.ToUpperInvariant())
{
@@ -408,6 +218,15 @@ public LayoutModel UpdateSelectedLayoutModel()
{
// found match
foundModel = model;
+ foundModel.TemplateZoneCount = currentApplied.ZoneCount;
+ foundModel.SensitivityRadius = currentApplied.SensitivityRadius;
+ if (foundModel is GridLayoutModel grid)
+ {
+ grid.ShowSpacing = currentApplied.ShowSpacing;
+ grid.Spacing = currentApplied.Spacing;
+ }
+
+ foundModel.InitTemplateZones();
break;
}
}
@@ -415,80 +234,74 @@ public LayoutModel UpdateSelectedLayoutModel()
if (foundModel == null)
{
- foundModel = DefaultModels[4]; // PriorityGrid
+ foundModel = _priorityGridModel;
}
- foundModel.IsSelected = true;
- foundModel.IsApplied = true;
-
+ SetSelectedModel(foundModel);
+ SetAppliedModel(foundModel);
FirePropertyChanged(nameof(IsCustomLayoutActive));
return foundModel;
}
- public void ResetSelectedModel()
+ public void RestoreSelectedModel(LayoutModel model)
{
- foreach (LayoutModel model in CustomModels)
+ if (SelectedModel == null || model == null)
{
- if (model.IsSelected)
- {
- model.IsSelected = false;
- break;
- }
+ return;
}
- foreach (LayoutModel model in DefaultModels)
+ SelectedModel.SensitivityRadius = model.SensitivityRadius;
+ SelectedModel.TemplateZoneCount = model.TemplateZoneCount;
+ SelectedModel.IsSelected = model.IsSelected;
+ SelectedModel.IsApplied = model.IsApplied;
+ SelectedModel.Name = model.Name;
+
+ if (model is GridLayoutModel grid)
{
- if (model.IsSelected)
- {
- model.IsSelected = false;
- break;
- }
+ ((GridLayoutModel)SelectedModel).Spacing = grid.Spacing;
+ ((GridLayoutModel)SelectedModel).ShowSpacing = grid.ShowSpacing;
}
}
- public void ResetAppliedModel()
+ public void SetSelectedModel(LayoutModel model)
{
- foreach (LayoutModel model in CustomModels)
+ if (_selectedModel != null)
{
- if (model.IsApplied)
- {
- model.IsApplied = false;
- break;
- }
+ _selectedModel.IsSelected = false;
}
- foreach (LayoutModel model in DefaultModels)
+ if (model != null)
{
- if (model.IsApplied)
- {
- model.IsApplied = false;
- break;
- }
+ model.IsSelected = true;
}
+
+ SelectedModel = model;
}
- public void UpdateDesktopDependantProperties(LayoutSettings prevSettings)
+ public void SetAppliedModel(LayoutModel model)
{
- UpdateTemplateLayoutModels();
-
- if (prevSettings.ZoneCount != ZoneCount)
+ if (_appliedModel != null)
{
- FirePropertyChanged(nameof(ZoneCount));
+ _appliedModel.IsApplied = false;
}
- if (prevSettings.Spacing != Spacing)
+ if (model != null)
{
- FirePropertyChanged(nameof(Spacing));
+ model.IsApplied = true;
}
- if (prevSettings.ShowSpacing != ShowSpacing)
- {
- FirePropertyChanged(nameof(ShowSpacing));
- }
+ AppliedModel = model;
+ }
- if (prevSettings.SensitivityRadius != SensitivityRadius)
+ public void UpdateDefaultModels()
+ {
+ foreach (LayoutModel model in DefaultModels)
{
- FirePropertyChanged(nameof(SensitivityRadius));
+ if (App.Overlay.CurrentLayoutSettings.Type == model.Type && App.Overlay.CurrentLayoutSettings.ZoneCount != model.TemplateZoneCount)
+ {
+ model.TemplateZoneCount = App.Overlay.CurrentLayoutSettings.ZoneCount;
+ model.InitTemplateZones();
+ }
}
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/Monitor.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/Monitor.cs
index 4290d6b1d5ff..f81aab8d3cc3 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/Monitor.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/Monitor.cs
@@ -5,7 +5,6 @@
using System;
using System.Reflection;
using System.Windows;
-using System.Windows.Input;
using System.Windows.Media;
using FancyZonesEditor.Utils;
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs
index be527fa5e8fd..ec0f2d2ab079 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Overlay.cs
@@ -13,7 +13,6 @@ namespace FancyZonesEditor
public class Overlay
{
private MainWindow _mainWindow;
-
private LayoutPreview _layoutPreview;
private UserControl _editor;
@@ -28,7 +27,7 @@ public Rect WorkArea
return Monitors[CurrentDesktop].Device.WorkAreaRect;
}
- return default(Rect);
+ return default;
}
}
@@ -54,7 +53,7 @@ public Window CurrentLayoutWindow
return Monitors[CurrentDesktop].Window;
}
- return default(Window);
+ return default;
}
}
@@ -100,14 +99,13 @@ public int CurrentDesktop
return;
}
- var prevSettings = CurrentLayoutSettings;
_currentDesktop = value;
MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings;
if (settings != null)
{
- settings.ResetAppliedModel();
- settings.UpdateDesktopDependantProperties(prevSettings);
+ settings.SetAppliedModel(null);
+ settings.UpdateDefaultModels();
}
Update();
@@ -130,8 +128,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)
{
@@ -174,7 +172,7 @@ public void Show()
_layoutPreview = new LayoutPreview
{
IsActualSize = true,
- Opacity = 0.5,
+ Opacity = 1,
};
ShowLayout();
@@ -201,6 +199,30 @@ public void ShowLayout()
}
}
+ public void SetLayoutSettings(Monitor monitor, LayoutModel model)
+ {
+ if (model == null)
+ {
+ return;
+ }
+
+ monitor.Settings.ZonesetUuid = model.Uuid;
+ monitor.Settings.Type = model.Type;
+ monitor.Settings.SensitivityRadius = model.SensitivityRadius;
+ monitor.Settings.ZoneCount = model.TemplateZoneCount;
+
+ if (model is GridLayoutModel grid)
+ {
+ monitor.Settings.ShowSpacing = grid.ShowSpacing;
+ monitor.Settings.Spacing = grid.Spacing;
+ }
+ else
+ {
+ monitor.Settings.ShowSpacing = false;
+ monitor.Settings.Spacing = 0;
+ }
+ }
+
public void OpenEditor(LayoutModel model)
{
_layoutPreview = null;
@@ -216,11 +238,10 @@ public void OpenEditor(LayoutModel model)
CurrentLayoutWindow.Content = _editor;
EditorWindow window;
- bool isGrid = false;
+
if (model is GridLayoutModel)
{
window = new GridEditorWindow();
- isGrid = true;
}
else
{
@@ -230,14 +251,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();
- }
-
- window.LeftWindowCommands = null;
- window.RightWindowCommands = null;
}
public void CloseEditor()
@@ -246,7 +259,7 @@ public void CloseEditor()
_layoutPreview = new LayoutPreview
{
IsActualSize = true,
- Opacity = 0.5,
+ Opacity = 1,
};
CurrentLayoutWindow.Content = _layoutPreview;
@@ -318,8 +331,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/Properties/Resources.Designer.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs
index e9ee173e4d79..161d9db94e44 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.Designer.cs
@@ -78,6 +78,33 @@ public static string Apply {
}
}
+ ///
+ /// Looks up a localized string similar to Apply layout.
+ ///
+ public static string Apply_Layout {
+ get {
+ return ResourceManager.GetString("Apply_Layout", resourceCulture);
+ }
+ }
+
+ ///
+ /// 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.
///
@@ -97,7 +124,7 @@ public static string Canvas_Layout_Editor {
}
///
- /// Looks up a localized string similar to Choose your layout for this desktop.
+ /// Looks up a localized string similar to Choose the layout for this desktop.
///
public static string Choose_Layout {
get {
@@ -105,6 +132,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 +168,33 @@ 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 custom layout.
+ ///
+ public static string Create_Custom_From_Template {
+ get {
+ return ResourceManager.GetString("Create_Custom_From_Template", 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.
///
@@ -142,7 +205,7 @@ public static string Custom {
}
///
- /// Looks up a localized string similar to Create new custom.
+ /// Looks up a localized string similar to Custom layout.
///
public static string Custom_Layout_Create_New {
get {
@@ -160,20 +223,29 @@ public static string Custom_Layout_Creator {
}
///
- /// Looks up a localized string similar to Delete custom layout.
+ /// Looks up a localized string similar to Custom layout.
+ ///
+ public static string Default_Custom_Layout_Name {
+ get {
+ return ResourceManager.GetString("Default_Custom_Layout_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Delete.
///
- public static string Custom_Layout_Delete_Button {
+ public static string Delete {
get {
- return ResourceManager.GetString("Custom_Layout_Delete_Button", resourceCulture);
+ return ResourceManager.GetString("Delete", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Custom table layout creator.
+ /// Looks up a localized string similar to Delete zone.
///
- public static string Custom_Table_Layout {
+ public static string Delete_Zone {
get {
- return ResourceManager.GetString("Custom_Table_Layout", resourceCulture);
+ return ResourceManager.GetString("Delete_Zone", resourceCulture);
}
}
@@ -187,11 +259,38 @@ public static string Distance_adjacent_zones {
}
///
- /// Looks up a localized string similar to Edit selected layout.
+ /// 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 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);
}
}
@@ -276,6 +375,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.
///
@@ -330,6 +456,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 +520,17 @@ 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 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"..
///
public static string Note_Custom_Table {
get {
@@ -348,6 +538,15 @@ public static string Note_Custom_Table {
}
}
+ ///
+ /// Looks up a localized string similar to Number of zones.
+ ///
+ public static string NumberOfZones {
+ get {
+ return ResourceManager.GetString("NumberOfZones", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Reset layout.
///
@@ -358,7 +557,16 @@ public static string Reset_Layout {
}
///
- /// Looks up a localized string similar to Save and apply.
+ /// Looks up a localized string similar to Save.
+ ///
+ public static string Save {
+ get {
+ return ResourceManager.GetString("Save", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Save & apply.
///
public static string Save_Apply {
get {
@@ -367,38 +575,38 @@ public static string Save_Apply {
}
///
- /// Looks up a localized string similar to Show space around zones.
+ /// Looks up a localized string similar to Template settings.
///
- public static string Show_Space_Zones {
+ public static string Settings {
get {
- return ResourceManager.GetString("Show_Space_Zones", resourceCulture);
+ return ResourceManager.GetString("Settings", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Space around zones.
+ /// Looks up a localized string similar to Show space around zones.
///
- public static string Space_Around_Zones {
+ public static string Show_Space_Zones {
get {
- return ResourceManager.GetString("Space_Around_Zones", resourceCulture);
+ return ResourceManager.GetString("Show_Space_Zones", 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 Space around zones.
///
- public static string Tab_Item_Custom {
+ public static string Space_Around_Zones {
get {
- return ResourceManager.GetString("Tab_Item_Custom", resourceCulture);
+ return ResourceManager.GetString("Space_Around_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 No layout.
///
- public static string Tab_Item_Templates {
+ public static string Template_Layout_Blank {
get {
- return ResourceManager.GetString("Tab_Item_Templates", resourceCulture);
+ return ResourceManager.GetString("Template_Layout_Blank", resourceCulture);
}
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx b/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx
index 20203c17cf41..bd45e1ca4b5d 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
@@ -147,14 +144,11 @@
Custom layout creator
-
- Custom table layout creator
-
Distance to highlight adjacent zones
-
- Edit selected layout
+
+ Edit layout
FancyZones Editor
@@ -166,10 +160,11 @@
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 and apply
+ Save & apply
Show space around zones
@@ -186,13 +181,6 @@
Increment number of zones in template layout
-
- Delete custom layout
-
-
- Create new custom
- As in Create new custom layout
-
FancyZones Editor arguments are invalid.
@@ -220,12 +208,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 +239,99 @@
Reset layout
as in Reset to a blank value
+
+ Choose the 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
+
+
+ Custom layout
+
+
+ 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
+
+
+ Template settings
+
+
+ Are you sure?
+
+
+ Are you sure you want to delete this layout?
+
+
+ Edit zones
+
+
+ Create or duplicate a layout to get started
+
+
+ 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.
+
+
+ Apply layout
+
+
+ Save
+
+
+ Number of zones
+
+
+ No layout
+
+
+ Create custom layout
+
+
+ Custom layout
+
\ 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
new file mode 100644
index 000000000000..a0d8b7e1d484
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Styles/ButtonStyles.xaml
@@ -0,0 +1,93 @@
+
+
+
+
\ 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..583398fcdbe1
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Styles/LayoutPreviewStyles.xaml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
\ 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
new file mode 100644
index 000000000000..4ace93266dfa
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Dark.xaml
@@ -0,0 +1,27 @@
+
+
+
+ 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..4ad21a8ea6f4
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast1.xaml
@@ -0,0 +1,27 @@
+
+
+
+ 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..6bdb2991a611
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrast2.xaml
@@ -0,0 +1,27 @@
+
+
+
+ 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..957683e13686
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastBlack.xaml
@@ -0,0 +1,27 @@
+
+
+
+ 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..eefee53fe033
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/HighContrastWhite.xaml
@@ -0,0 +1,27 @@
+
+
+
+ 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..8b5d37109414
--- /dev/null
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Themes/Light.xaml
@@ -0,0 +1,27 @@
+
+
+
+ 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/FancyZonesEditorIO.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/FancyZonesEditorIO.cs
index 8f092cd55f12..816308b365a9 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,45 +24,27 @@ 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";
+ private const string ParamsFile = "\\Microsoft\\PowerToys\\FancyZones\\editor-parameters.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(),
+ WriteIndented = true,
};
- public string ActiveZoneSetTmpFile { get; private set; }
-
- public string AppliedZoneSetTmpFile { get; private set; }
-
- public string DeletedCustomZoneSetsTmpFile { get; private set; }
+ private List _unusedDevices = new List();
public string FancyZonesSettingsFile { get; private set; }
+ public string FancyZonesEditorParamsFile { get; private set; }
+
private enum CmdArgs
{
PowerToysPID = 0,
@@ -89,41 +59,43 @@ 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 Y { get; set; }
+ public int TopCoordinate { 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();
}
}
- 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,31 +109,110 @@ private struct AppliedZoneSet
public int EditorSensitivityRadius { get; set; }
}
- private struct AppliedZonesetsToDesktops
+ private class 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; }
+
+ public int SensitivityRadius { get; set; } = LayoutSettings.DefaultSensitivityRadius;
}
- private struct DeletedCustomZoneSetsWrapper
+ private class 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; }
+
+ public bool ShowSpacing { get; set; } = LayoutSettings.DefaultShowSpacing;
+
+ public int Spacing { get; set; } = LayoutSettings.DefaultSpacing;
+
+ public int SensitivityRadius { get; set; } = LayoutSettings.DefaultSensitivityRadius;
}
- 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 TemplateLayoutWrapper
{
- string tmpDirPath = _fileSystem.Path.GetTempPath();
+ public string Type { get; set; }
+
+ public bool ShowSpacing { get; set; }
+
+ public int Spacing { get; set; }
- ActiveZoneSetTmpFile = tmpDirPath + ActiveZoneSetsTmpFileName;
- AppliedZoneSetTmpFile = tmpDirPath + AppliedZoneSetsTmpFileName;
- DeletedCustomZoneSetsTmpFile = tmpDirPath + DeletedCustomZoneSetsTmpFileName;
+ public int ZoneCount { get; set; }
+ public int SensitivityRadius { get; set; }
+ }
+
+ private struct ZoneSettingsWrapper
+ {
+ public List Devices { get; set; }
+
+ public List CustomZoneSets { get; set; }
+
+ public List Templates { 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; }
+
+ public string Message { get; }
+
+ public string MalformedData { get; }
+
+ 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;
+ FancyZonesEditorParamsFile = localAppDataDir + ParamsFile;
}
// All strings in this function shouldn't be localized.
@@ -200,14 +251,21 @@ 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)
+ {
+ App.Overlay.Monitors.Clear();
+ }
// Monitors count
int count = int.Parse(argsParts[(int)CmdArgs.MonitorsCount]);
- if (count != App.Overlay.DesktopsCount)
+ if (count != App.Overlay.DesktopsCount && !isCustomMonitorConfigurationMode)
{
MessageBox.Show(Properties.Resources.Error_Invalid_Arguments, Properties.Resources.Error_Message_Box_Title);
((App)Application.Current).Shutdown();
@@ -222,13 +280,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;
}
@@ -244,30 +303,51 @@ public static void ParseCommandLineArguments()
double scaleFactor = 96f / primaryMonitorDPI;
// Update monitors data
- foreach (Monitor monitor in monitors)
+ if (isCustomMonitorConfigurationMode)
{
- bool matchFound = false;
- monitor.Scale(scaleFactor);
+ foreach (NativeMonitorData nativeData in nativeMonitorData)
+ {
+ var splittedId = nativeData.MonitorId.Split('_');
+ int width = int.Parse(splittedId[1]);
+ int height = int.Parse(splittedId[2]);
- double scaledBoundX = (int)(monitor.Device.UnscaledBounds.X * identifyScaleFactor);
- double scaledBoundY = (int)(monitor.Device.UnscaledBounds.Y * identifyScaleFactor);
+ Rect bounds = new Rect(nativeData.LeftCoordinate, nativeData.TopCoordinate, width, height);
+ bool isPrimary = nativeData.LeftCoordinate == 0 && nativeData.TopCoordinate == 0;
- foreach (NativeMonitorData nativeData in nativeMonitorData)
+ Monitor monitor = new Monitor(bounds, bounds, isPrimary);
+ monitor.Device.Id = nativeData.MonitorId;
+ monitor.Device.Dpi = nativeData.Dpi;
+
+ monitors.Add(monitor);
+ }
+ }
+ else
+ {
+ foreach (Monitor monitor in monitors)
{
- // 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))
+ 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 nativeMonitorData)
{
- monitor.Device.Id = nativeData.Id;
- monitor.Device.Dpi = nativeData.Dpi;
- matchFound = true;
- break;
+ // 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()));
+ if (matchFound == false)
+ {
+ MessageBox.Show(string.Format(Properties.Resources.Error_Monitor_Match_Not_Found, monitor.Device.UnscaledBounds.ToString()));
+ }
}
}
@@ -282,6 +362,10 @@ public static void ParseCommandLineArguments()
}
}
}
+ else
+ {
+ App.Overlay.Monitors[App.Overlay.CurrentDesktop].Device.Id = targetMonitorName;
+ }
}
catch (Exception)
{
@@ -290,230 +374,183 @@ public static void ParseCommandLineArguments()
}
}
- public void ParseDeviceInfoData()
+ public ParsingResult ParseParams()
{
- try
+ if (_fileSystem.File.Exists(FancyZonesEditorParamsFile))
{
- JsonElement jsonObject = default(JsonElement);
+ string data = 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();
+ data = ReadFile(FancyZonesEditorParamsFile);
+ EditorParams editorParams = JsonSerializer.Deserialize(data, _options);
- JsonElement json = jsonObject.GetProperty(AppliedZonesetsJsonTag);
+ // Process ID
+ App.PowerToysPID = editorParams.ProcessId;
- int layoutId = 0;
- for (int i = 0; i < json.GetArrayLength() && layoutId < App.Overlay.DesktopsCount; i++)
- {
- var zonesetData = json[i];
+ // Span zones across monitors
+ App.Overlay.SpanZonesAcrossMonitors = editorParams.SpanZonesAcrossMonitors;
- string deviceId = zonesetData.GetProperty(DeviceIdJsonTag).GetString();
+ 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 currentLayoutType = zonesetData.GetProperty(ActiveZoneSetJsonTag).GetProperty(TypeJsonTag).GetString();
- LayoutType type = JsonTagToLayoutType(currentLayoutType);
+ string targetMonitorName = string.Empty;
- if (!App.Overlay.SpanZonesAcrossMonitors)
+ double primaryMonitorDPI = 96f;
+ double minimalUsedMonitorDPI = double.MaxValue;
+ foreach (NativeMonitorData nativeData in editorParams.Monitors)
{
- var monitors = App.Overlay.Monitors;
- for (int monitorIndex = 0; monitorIndex < monitors.Count; monitorIndex++)
+ if (nativeData.LeftCoordinate == 0 && nativeData.TopCoordinate == 0)
{
- 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;
- }
+ primaryMonitorDPI = nativeData.Dpi;
}
- }
- 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;
+ if (minimalUsedMonitorDPI > nativeData.Dpi)
+ {
+ minimalUsedMonitorDPI = nativeData.Dpi;
+ }
- break;
+ if (nativeData.IsSelected)
+ {
+ targetMonitorName = nativeData.MonitorId;
}
}
- }
- }
- }
- catch (Exception ex)
- {
- App.ShowExceptionMessageBox(Properties.Resources.Error_Parsing_Device_Info, ex);
- }
- }
- public void ParseLayouts(ref ObservableCollection custom, ref List deleted)
- {
- try
- {
- Stream inputStream = _fileSystem.File.Open(FancyZonesSettingsFile, FileMode.Open);
- JsonDocument jsonObject = JsonDocument.Parse(inputStream, options: default);
- JsonElement.ArrayEnumerator customZoneSetsEnumerator = jsonObject.RootElement.GetProperty(CustomZoneSetsJsonTag).EnumerateArray();
+ var monitors = App.Overlay.Monitors;
+ double identifyScaleFactor = minimalUsedMonitorDPI / primaryMonitorDPI;
+ double scaleFactor = 96f / primaryMonitorDPI;
- while (customZoneSetsEnumerator.MoveNext())
- {
- 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);
-
- if (type.Equals(GridJsonTag, StringComparison.OrdinalIgnoreCase))
- {
- 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)
+ // Update monitors data
+ foreach (Monitor monitor in monitors)
{
- error = true;
- }
+ bool matchFound = false;
+ monitor.Scale(scaleFactor);
- while (!error && rowsPercentageEnumerator.MoveNext())
- {
- int percentage = rowsPercentageEnumerator.Current.GetInt32();
- if (percentage <= 0)
+ double scaledBoundX = (int)(monitor.Device.UnscaledBounds.X * identifyScaleFactor);
+ double scaledBoundY = (int)(monitor.Device.UnscaledBounds.Y * identifyScaleFactor);
+
+ foreach (NativeMonitorData nativeData in editorParams.Monitors)
{
- error = true;
- break;
+ // 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;
+ }
}
- rowsPercentage.Add(percentage);
+ if (matchFound == false)
+ {
+ MessageBox.Show(string.Format(Properties.Resources.Error_Monitor_Match_Not_Found, monitor.Device.UnscaledBounds.ToString()));
+ }
}
- while (!error && columnsPercentageEnumerator.MoveNext())
+ // Set active desktop
+ for (int i = 0; i < monitors.Count; i++)
{
- int percentage = columnsPercentageEnumerator.Current.GetInt32();
- if (percentage <= 0)
+ var monitor = monitors[i];
+ if (monitor.Device.Id == targetMonitorName)
{
- error = true;
+ App.Overlay.CurrentDesktop = i;
break;
}
-
- columnsPercentage.Add(percentage);
- }
-
- int i = 0;
- JsonElement.ArrayEnumerator cellChildMapRows = info.GetProperty(CellChildMapJsonTag).EnumerateArray();
- int[,] cellChildMap = new int[rows, columns];
-
- if (cellChildMapRows.Count() != rows)
- {
- error = true;
}
-
- while (!error && cellChildMapRows.MoveNext())
+ }
+ else
+ {
+ // Update monitors data
+ foreach (Monitor monitor in App.Overlay.Monitors)
{
- int j = 0;
- JsonElement.ArrayEnumerator cellChildMapRowElems = cellChildMapRows.Current.EnumerateArray();
- if (cellChildMapRowElems.Count() != columns)
+ bool matchFound = false;
+ foreach (NativeMonitorData nativeData in editorParams.Monitors)
{
- error = true;
- break;
+ // 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;
+ }
}
- while (cellChildMapRowElems.MoveNext())
+ if (matchFound == false)
{
- cellChildMap[i, j++] = cellChildMapRowElems.Current.GetInt32();
+ MessageBox.Show(string.Format(Properties.Resources.Error_Monitor_Match_Not_Found, monitor.Device.UnscaledBounds.ToString()));
}
-
- i++;
}
-
- if (error)
- {
- 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));
}
- 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;
+ }
+ catch (Exception ex)
+ {
+ return new ParsingResult(false, ex.Message, data);
+ }
- if (workAreaWidth <= 0 || workAreaHeight <= 0)
- {
- error = true;
- }
+ return new ParsingResult(true);
+ }
+ else
+ {
+ return new ParsingResult(false);
+ }
+ }
- 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();
+ public ParsingResult ParseZoneSettings()
+ {
+ _unusedDevices.Clear();
- if (width <= 0 || height <= 0)
- {
- error = true;
- break;
- }
+ if (_fileSystem.File.Exists(FancyZonesSettingsFile))
+ {
+ ZoneSettingsWrapper zoneSettings;
+ string settingsString = string.Empty;
- zones.Add(new Int32Rect(x, y, width, height));
- }
+ try
+ {
+ settingsString = ReadFile(FancyZonesSettingsFile);
+ zoneSettings = JsonSerializer.Deserialize(settingsString, _options);
+ }
+ catch (Exception ex)
+ {
+ return new ParsingResult(false, ex.Message, settingsString);
+ }
- if (error)
- {
- App.ShowExceptionMessageBox(string.Format(Properties.Resources.Error_Layout_Malformed_Data, name));
- deleted.Add(Guid.Parse(uuid).ToString().ToUpperInvariant());
- continue;
- }
+ try
+ {
+ bool devicesParsingResult = SetDevices(zoneSettings.Devices);
+ bool customZonesParsingResult = SetCustomLayouts(zoneSettings.CustomZoneSets);
+ bool templatesParsingResult = SetTemplateLayouts(zoneSettings.Templates);
- custom.Add(new CanvasLayoutModel(uuid, name, LayoutType.Custom, zones, workAreaWidth, workAreaHeight));
+ if (!devicesParsingResult || !customZonesParsingResult)
+ {
+ return new ParsingResult(false, Properties.Resources.Error_Parsing_Zones_Settings_Malformed_Data, settingsString);
}
}
-
- inputStream.Close();
- }
- catch (Exception ex)
- {
- App.ShowExceptionMessageBox(Properties.Resources.Error_Loading_Custom_Layouts, ex);
+ catch (Exception ex)
+ {
+ return new ParsingResult(false, ex.Message, settingsString);
+ }
}
+
+ return new ParsingResult(true);
}
- public void SerializeAppliedLayouts()
+ public void SerializeZoneSettings()
{
- AppliedZonesetsToDesktops applied = new AppliedZonesetsToDesktops { };
- applied.AppliedZonesets = new List();
+ ZoneSettingsWrapper zoneSettings = new ZoneSettingsWrapper { };
+ zoneSettings.Devices = new List();
+ zoneSettings.CustomZoneSets = new List();
+ zoneSettings.Templates = new List();
+ // Serialize used devices
foreach (var monitor in App.Overlay.Monitors)
{
LayoutSettings zoneset = monitor.Settings;
@@ -522,17 +559,14 @@ public void SerializeAppliedLayouts()
continue;
}
- ActiveZoneSetWrapper activeZoneSet = new ActiveZoneSetWrapper
- {
- Uuid = zoneset.ZonesetUuid,
- };
-
- activeZoneSet.Type = LayoutTypeToJsonTag(zoneset.Type);
-
- applied.AppliedZonesets.Add(new AppliedZoneSet
+ zoneSettings.Devices.Add(new DeviceWrapper
{
DeviceId = monitor.Device.Id,
- ActiveZoneset = activeZoneSet,
+ ActiveZoneset = new DeviceWrapper.ActiveZoneSetWrapper
+ {
+ Uuid = zoneset.ZonesetUuid,
+ Type = LayoutTypeToJsonTag(zoneset.Type),
+ },
EditorShowSpacing = zoneset.ShowSpacing,
EditorSpacing = zoneset.Spacing,
EditorZoneCount = zoneset.ZoneCount,
@@ -540,10 +574,121 @@ public void SerializeAppliedLayouts()
});
}
+ // Serialize unused devices
+ foreach (var device in _unusedDevices)
+ {
+ zoneSettings.Devices.Add(device);
+ }
+
+ // Serialize custom zonesets
+ foreach (LayoutModel layout in MainWindowSettingsModel.CustomModels)
+ {
+ JsonElement info;
+ string type;
+
+ if (layout is CanvasLayoutModel)
+ {
+ type = CanvasLayoutModel.ModelTypeID;
+ var canvasLayout = layout as CanvasLayoutModel;
+
+ var canvasRect = canvasLayout.CanvasRect;
+ if (canvasRect.Width == 0 || canvasRect.Height == 0)
+ {
+ canvasRect = App.Overlay.WorkArea;
+ }
+
+ var wrapper = new CanvasInfoWrapper
+ {
+ RefWidth = (int)canvasRect.Width,
+ RefHeight = (int)canvasRect.Height,
+ Zones = new List(),
+ SensitivityRadius = canvasLayout.SensitivityRadius,
+ };
+
+ foreach (var zone in canvasLayout.Zones)
+ {
+ wrapper.Zones.Add(new CanvasInfoWrapper.CanvasZoneWrapper
+ {
+ X = zone.X,
+ Y = zone.Y,
+ Width = zone.Width,
+ Height = zone.Height,
+ });
+ }
+
+ string json = JsonSerializer.Serialize(wrapper, _options);
+ info = JsonSerializer.Deserialize(json);
+ }
+ else if (layout is GridLayoutModel)
+ {
+ type = GridLayoutModel.ModelTypeID;
+ var gridLayout = layout as GridLayoutModel;
+
+ 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++)
+ {
+ cells[row][column] = gridLayout.CellChildMap[row, column];
+ }
+ }
+
+ var wrapper = new GridInfoWrapper
+ {
+ Rows = gridLayout.Rows,
+ Columns = gridLayout.Columns,
+ RowsPercentage = gridLayout.RowPercents,
+ ColumnsPercentage = gridLayout.ColumnPercents,
+ CellChildMap = cells,
+ ShowSpacing = gridLayout.ShowSpacing,
+ Spacing = gridLayout.Spacing,
+ SensitivityRadius = gridLayout.SensitivityRadius,
+ };
+
+ string json = JsonSerializer.Serialize(wrapper, _options);
+ info = JsonSerializer.Deserialize(json);
+ }
+ else
+ {
+ // Error
+ continue;
+ }
+
+ CustomLayoutWrapper customLayout = new CustomLayoutWrapper
+ {
+ Uuid = layout.Uuid,
+ Name = layout.Name,
+ Type = type,
+ Info = info,
+ };
+
+ zoneSettings.CustomZoneSets.Add(customLayout);
+ }
+
+ // Serialize template layouts
+ foreach (LayoutModel layout in MainWindowSettingsModel.DefaultModels)
+ {
+ TemplateLayoutWrapper wrapper = new TemplateLayoutWrapper
+ {
+ Type = LayoutTypeToJsonTag(layout.Type),
+ SensitivityRadius = layout.SensitivityRadius,
+ ZoneCount = layout.TemplateZoneCount,
+ };
+
+ if (layout is GridLayoutModel grid)
+ {
+ wrapper.ShowSpacing = grid.ShowSpacing;
+ wrapper.Spacing = grid.Spacing;
+ }
+
+ zoneSettings.Templates.Add(wrapper);
+ }
+
try
{
- string jsonString = JsonSerializer.Serialize(applied, _options);
- _fileSystem.File.WriteAllText(ActiveZoneSetTmpFile, jsonString);
+ string jsonString = JsonSerializer.Serialize(zoneSettings, _options);
+ _fileSystem.File.WriteAllText(FancyZonesSettingsFile, jsonString);
}
catch (Exception ex)
{
@@ -551,68 +696,177 @@ public void SerializeAppliedLayouts()
}
}
- public void SerializeDeletedCustomZoneSets(List models)
+ private string ReadFile(string fileName)
{
- DeletedCustomZoneSetsWrapper deletedLayouts = new DeletedCustomZoneSetsWrapper
- {
- DeletedCustomZoneSets = models,
- };
+ Stream inputStream = _fileSystem.File.Open(fileName, FileMode.Open);
+ StreamReader reader = new StreamReader(inputStream);
+ string data = reader.ReadToEnd();
+ inputStream.Close();
+ return data;
+ }
- try
+ private bool SetDevices(List devices)
+ {
+ if (devices == null)
{
- string jsonString = JsonSerializer.Serialize(deletedLayouts, _options);
- _fileSystem.File.WriteAllText(DeletedCustomZoneSetsTmpFile, jsonString);
+ return false;
}
- catch (Exception ex)
+
+ bool result = true;
+ var monitors = App.Overlay.Monitors;
+ foreach (var device in devices)
{
- App.ShowExceptionMessageBox(Properties.Resources.Error_Serializing_Deleted_Layouts, ex);
+ if (device.DeviceId == null || device.DeviceId.Length == 0 || device.ActiveZoneset.Uuid == null || device.ActiveZoneset.Uuid.Length == 0)
+ {
+ result = false;
+ continue;
+ }
+
+ bool unused = true;
+ foreach (Monitor monitor in monitors)
+ {
+ if (monitor.Device.Id == device.DeviceId)
+ {
+ 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,
+ };
+
+ monitor.Settings = settings;
+ unused = false;
+ break;
+ }
+ }
+
+ if (unused)
+ {
+ _unusedDevices.Add(device);
+ }
}
+
+ return result;
}
- public void SerializeCreatedCustomZonesets(List models)
+ private bool SetCustomLayouts(List customLayouts)
{
- CreatedCustomZoneSetsWrapper layouts = new CreatedCustomZoneSetsWrapper
+ if (customLayouts == null)
{
- CreatedCustomZoneSets = models,
- };
+ return false;
+ }
- try
+ MainWindowSettingsModel.CustomModels.Clear();
+ bool result = true;
+
+ foreach (var zoneSet in customLayouts)
{
- string jsonString = JsonSerializer.Serialize(layouts, _options);
- _fileSystem.File.WriteAllText(AppliedZoneSetTmpFile, jsonString);
+ if (zoneSet.Uuid == null || zoneSet.Uuid.Length == 0)
+ {
+ result = false;
+ continue;
+ }
+
+ LayoutModel layout;
+ if (zoneSet.Type == CanvasLayoutModel.ModelTypeID)
+ {
+ var info = JsonSerializer.Deserialize(zoneSet.Info.GetRawText(), _options);
+
+ 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);
+ layout.SensitivityRadius = info.SensitivityRadius;
+ }
+ 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);
+ layout.SensitivityRadius = info.SensitivityRadius;
+ (layout as GridLayoutModel).ShowSpacing = info.ShowSpacing;
+ (layout as GridLayoutModel).Spacing = info.Spacing;
+ }
+ else
+ {
+ result = false;
+ continue;
+ }
+
+ MainWindowSettingsModel.CustomModels.Add(layout);
}
- catch (Exception ex)
+
+ return result;
+ }
+
+ private bool SetTemplateLayouts(List templateLayouts)
+ {
+ if (templateLayouts == null)
{
- App.ShowExceptionMessageBox(Properties.Resources.Error_Persisting_Custom_Layout, ex);
+ return false;
}
+
+ foreach (var wrapper in templateLayouts)
+ {
+ var type = JsonTagToLayoutType(wrapper.Type);
+
+ foreach (var layout in MainWindowSettingsModel.DefaultModels)
+ {
+ if (layout.Type == type)
+ {
+ layout.SensitivityRadius = wrapper.SensitivityRadius;
+ layout.TemplateZoneCount = wrapper.ZoneCount;
+
+ if (layout is GridLayoutModel grid)
+ {
+ grid.ShowSpacing = wrapper.ShowSpacing;
+ grid.Spacing = wrapper.Spacing;
+ }
+
+ layout.InitTemplateZones();
+ }
+ }
+ }
+
+ return true;
}
private LayoutType JsonTagToLayoutType(string tag)
{
- LayoutType type = LayoutType.Blank;
switch (tag)
{
+ case BlankJsonTag:
+ return LayoutType.Blank;
case FocusJsonTag:
- type = LayoutType.Focus;
- break;
+ return LayoutType.Focus;
case ColumnsJsonTag:
- type = LayoutType.Columns;
- break;
+ return LayoutType.Columns;
case RowsJsonTag:
- type = LayoutType.Rows;
- break;
+ return LayoutType.Rows;
case GridJsonTag:
- type = LayoutType.Grid;
- break;
+ return LayoutType.Grid;
case PriorityGridJsonTag:
- type = LayoutType.PriorityGrid;
- break;
+ return LayoutType.PriorityGrid;
case CustomJsonTag:
- type = LayoutType.Custom;
- break;
+ return LayoutType.Custom;
}
- return type;
+ return LayoutType.Blank;
}
private string LayoutTypeToJsonTag(LayoutType type)
@@ -623,19 +877,19 @@ private string LayoutTypeToJsonTag(LayoutType type)
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/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,
+ }
+}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs
index 080b6b509ff9..eff99c9aa1f9 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/ViewModels/MonitorViewModel.cs
@@ -4,7 +4,6 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
-using System.Windows;
using FancyZonesEditor.Utils;
namespace FancyZonesEditor.ViewModels
@@ -22,14 +21,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; }
@@ -57,7 +48,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)
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/WindowLayout.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/WindowLayout.xaml
index 8601aa0a5c1c..1fd306a0afe5 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/WindowLayout.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/WindowLayout.xaml
@@ -4,7 +4,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
- Title="Window1" Height="450" Width="800"
+ Title="Window1" Height="450"
+ Width="800"
WindowState="Maximized"
ShowInTaskbar="False"
ResizeMode="NoResize"
@@ -16,7 +17,7 @@
-
+
@@ -25,7 +26,7 @@
-->
-
+