[FancyZones Editor] New UX for the FZ editor. (#9325)

* Removed MetroWindow, added theming support and modernWPF

* Rmoved MahApps refs

* Removed MahApps

* Updated canvas zones

* Updated GridEditor

* Fixes

* UI updates

* New layout type selection dialog

* New editor UI

* Updates

* Fix

* UI enhancements

* Updated UI

* Added styles to layoutpreview

* Accesibility improvements

* Accesibility and styling improvements

* Fix

* Cleaned up brushes

* Updated UX

* Updated UI

* Added no layouts description

* Fix

* UI fixes

* [FZ Editor] Serialize/deserialize settings (#8615)

* conflicts fix

* [FZ Editor] Parse json file instead of command line args (#8649)

* [FZ Editor] Serialize/deserialize settings fix (#8707)

* [FZ Editor] Hide unsupported settings in custom layouts flyouts (#8716)

* [FZ Editor] Duplicate custom layouts (#8718)

* [FZ Editor] Duplicate layout behavior (#8720)

* New UX proposal

* Updated spacing

* Switching to toggleswitches

* Revert toggleswitch

* Updated colorbrush

* Updated string for saving label

* Updated UI

* Dark theme color fixes

* Removed space

* [FZ Editor] Bind dialog properties (#9199)

* Resize editor window to fit the content in single-monitor mode (#9203)

* Editor opening fix (#9207)

* Disable "Create" button if the Name textbox is empty (#9212)

* [FZ Editor] Changed edit dialog for template layouts. (#9233)

* [FZ Editor] Small fixes and refactoring. (#9236)

* new layout creation refactoring
* "Save and apply" applies the layout
* number of zones header hide

* [FZ Editor] Empty layout template. (#9237)

* [FZ Editor] Move "Duplicate" and "Delete" buttons to the Edit dialog. (#9272)

* [FZ Editor] Preview the applied layout after editing another layout. (#9278)

* Fixed "Save and apply" button behavior (#9286)

* [FZ Editor] Save template layouts in the settings. (#9283)

* Added default custom layout name (#9291)

* close dialog before opening zones editor (#9302)

* Pressing Esc closes dialogs (#9301)

* [FZ Editor] Reset applied layout to "No layout" if it was deleted. (#9315)

* [FZ Editor] Dark theme colors (#9317)

* "Number of zones" buttons colors. (#9321)

* rebase fix

* added ModernWpf.dll

* address PR comments: updated colors

* added comments, replaced magic numbers

* refactoring

* merge zones crash fix

* removed redundant using directive

Co-authored-by: Niels Laute <niels9001@hotmail.com>
Co-authored-by: Niels Laute <niels.laute@live.nl>
This commit is contained in:
Seraphima Zykova
2021-01-27 21:33:52 +03:00
committed by GitHub
parent eb15cdde1b
commit 646d61bd4d
61 changed files with 3664 additions and 2781 deletions

View File

@@ -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">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<!-- Accent and AppTheme setting -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
<ui:ThemeResources />
<ui:XamlControlsResources />
<ResourceDictionary Source="pack://application:,,,/Styles/ButtonStyles.xaml" />
<ResourceDictionary Source="pack://application:,,,/Styles/LayoutPreviewStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<SolidColorBrush x:Key="CanvasZoneBackgroundBrush" Color="#BF333333"/>
<SolidColorBrush x:Key="GridZoneBackgroundBrush" Color="#FF1a1a1a"/>
<Style x:Key="UWPFocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border Margin="-2"
CornerRadius="4"
BorderThickness="2"
BorderBrush="{DynamicResource PrimaryForegroundBrush}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -9,6 +9,8 @@ using System.Globalization;
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 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
public static int PowerToysPID { get; set; }
private ThemeManager _themeManager;
public static bool DebugMode
{
get
@@ -67,7 +74,7 @@ namespace FancyZonesEditor
public App()
{
DebugModeCheck();
// DebugModeCheck();
FancyZonesEditorIO = new FancyZonesEditorIO();
Overlay = new Overlay();
MainWindowSettings = new MainWindowSettingsModel();
@@ -82,8 +89,61 @@ namespace FancyZonesEditor
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();

View File

@@ -1,202 +1,69 @@
<local:EditorWindow x:Class="FancyZonesEditor.CanvasEditorWindow"
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:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:local="clr-namespace:FancyZonesEditor"
xmlns:props="clr-namespace:FancyZonesEditor.Properties"
mc:Ignorable="d"
Title=""
Width="528"
SizeToContent="Height"
Background="White"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
Closed="OnClosed">
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">
<Grid>
<Grid Height="36"
Background="{DynamicResource SecondaryBackgroundBrush}"
Margin="0,-36,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Stretch">
<Border Background="{DynamicResource TitleBarSecondaryForegroundBrush}"
Width="30"
Height="3"
CornerRadius="1.5"
VerticalAlignment="Center"
Margin="0,4,0,0" />
</Grid>
<StackPanel Margin="16"
FocusManager.FocusedElement="{Binding ElementName=newZoneButton}">
<Button x:Name="newZoneButton"
AutomationProperties.LabeledBy="{Binding ElementName=newZoneName}"
HorizontalAlignment="Stretch"
Height="64"
Width="64"
ui:ControlHelper.CornerRadius="64"
Margin="0,8,0,0"
Style="{StaticResource AccentButtonStyle}"
FontFamily="Segoe MDL2 Assets"
Content="&#xE109;"
FontSize="24"
ToolTip="{x:Static props:Resources.Add_zone}"
Click="OnAddZone" />
<Window.Resources>
<Style x:Key="titleText" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="LineHeight" Value="24" />
<Setter Property="FontSize" Value="18"/>
<Setter Property="Margin" Value="16,16,0,12" />
</Style>
<Style x:Key="zoneCount" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="FontSize" Value="24"/>
<Setter Property="LineHeight" Value="24" />
<Setter Property="Margin" Value="20,0,20,0" />
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style x:Key="tabText" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="#C4C4C4"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="LineHeight" Value="20" />
<Setter Property="Margin" Value="24,20,0,0" />
<Setter Property="TextAlignment" Value="Center" />
</Style>
<Style x:Key="settingText" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="LineHeight" Value="20" />
<Setter Property="Margin" Value="5,10,0,0" />
<Setter Property="TextAlignment" Value="Left" />
</Style>
<Style x:Key="templateTitleText" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="0,20,0,0" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Height" Value="30"/>
<Setter Property="Width" Value="250"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style x:Key="customButtonFocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="1" Stroke="White" StrokeDashArray="1 2" StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="secondaryButton" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="0,5,0,5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="#767676"/>
<Setter Property="Margin" Value="16,10,0,0" />
<Setter Property="Width" Value="239"/>
<Setter Property="Height" Value="32"/>
<Setter Property="FocusVisualStyle" Value="{DynamicResource customButtonFocusVisualStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#5D5D5D"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="primaryButton" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="0,5,0,5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="#0078D7"/>
<Setter Property="Margin" Value="16,10,0,0" />
<Setter Property="Width" Value="239"/>
<Setter Property="Height" Value="32"/>
<Setter Property="FocusVisualStyle" Value="{DynamicResource customButtonFocusVisualStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#024D89"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="spinnerButton" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontSize" Value="24"/>
<Setter Property="Padding" Value="0,0,0,5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="#F2F2F2"/>
<Setter Property="Margin" Value="0,0,0,0" />
</Style>
<Style x:Key="templateBackground" TargetType="Rectangle">
<Setter Property="Fill" Value="Black"/>
<Setter Property="Opacity" Value="0.05"/>
<Setter Property="RadiusX" Value="4"/>
<Setter Property="RadiusY" Value="4"/>
</Style>
<Style x:Key="templateBackgroundSelected" TargetType="Rectangle">
<Setter Property="Fill" Value="#F2F2F2"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="RadiusX" Value="4"/>
<Setter Property="RadiusY" Value="4"/>
<Setter Property="Stroke" Value="#0078D7"/>
<Setter Property="StrokeThickness" Value="2"/>
</Style>
<Style x:Key="newZoneButton" TargetType="Button">
<Setter Property="Background" Value="#f2f2f2"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontFamily" Value="SegoeUI"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="FontSize" Value="120"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style x:Key="textLabel" TargetType="TextBlock">
<Setter Property="FontFamily" Value="SegoeUI"/>
<Setter Property="FontWeight" Value="Regular"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Margin" Value="16,12,0,0"/>
</Style>
<Style x:Key="textBox" TargetType="TextBox">
<Setter Property="BorderBrush" Value="#949494"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FontFamily" Value="SegoeUI"/>
<Setter Property="FontWeight" Value="Regular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,5,0,0"/>
<Setter Property="Padding" Value="5,5,5,5"/>
</Style>
</Window.Resources>
<StackPanel FocusManager.FocusedElement="{Binding ElementName=newZoneButton}">
<TextBlock Name="windowEditorDialogTitle" Text="{x:Static props:Resources.Custom_Layout_Creator}" Style="{StaticResource titleText}" />
<Button x:Name="newZoneButton" AutomationProperties.LabeledBy="{Binding ElementName=newZoneName}" Width="496" Height="136" Style="{StaticResource newZoneButton}" Click="OnAddZone">
<StackPanel>
<TextBlock x:Name="newZoneName" Text="{x:Static props:Resources.Add_zone}" Style="{StaticResource templateTitleText}" />
<TextBlock HorizontalAlignment="Center" Text="+" Margin="0,-40,0,0"/>
</StackPanel>
</Button>
<TextBlock x:Name="customLayoutName" Text="{x:Static props:Resources.Name}" Style="{StaticResource textLabel}" />
<TextBox Text="{Binding Name}" AutomationProperties.LabeledBy="{Binding ElementName=customLayoutName}" Width="496" Style="{StaticResource textBox}" />
<!--
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<CheckBox x:Name="showGridSetting" VerticalAlignment="Center" HorizontalAlignment="Center" IsChecked="True" Margin="16,4,0,0"/>
<TextBlock Text="Show snap grid" Style="{StaticResource settingText}" />
<TextBlock Text="Grid spacing" Style="{StaticResource settingText}" Margin="40,10,10,0" />
<TextBox x:Name="gridValue" Text="{Binding Path=Spacing,Mode=TwoWay}" Style="{StaticResource textBox}"/>
<Grid Margin="0,24,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Content="{x:Static props:Resources.Cancel}"
Style="{StaticResource DefaultButtonStyle}"
HorizontalAlignment="Stretch"
Grid.Column="2"
Click="OnCancel" />
<Button Content="{x:Static props:Resources.Save_Apply}"
Style="{StaticResource AccentButtonStyle}"
HorizontalAlignment="Stretch"
Click="OnSaveApplyTemplate" />
</Grid>
</StackPanel>
-->
<StackPanel Orientation="Horizontal" Margin="0,12,0,16">
<Button Content="{x:Static props:Resources.Cancel}" Style="{StaticResource secondaryButton}" Click="OnCancel"/>
<Button Content="{x:Static props:Resources.Save_Apply}" Style="{StaticResource primaryButton}" Click="OnSaveApplyTemplate" />
</StackPanel>
</StackPanel>
</local:EditorWindow>
</Grid>
</local:EditorWindow>

View File

@@ -8,11 +8,23 @@ using FancyZonesEditor.Models;
namespace FancyZonesEditor
{
/// <summary>
/// Interaction logic for windowEditor.xaml
/// </summary>
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 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
OnCancel(sender, null);
}
}
private int _offset = 100;
private CanvasLayoutModel _model;
private CanvasLayoutModel _stashedModel;
}
}

View File

@@ -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 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border x:Name="ThumbBorder" Opacity="0" BorderBrush="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Border x:Name="ThumbBorder" Opacity="0" BorderBrush="{DynamicResource SystemControlBackgroundAccentBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates" >
<VisualStateGroup.Transitions>
@@ -43,16 +44,27 @@
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryForegroundBrush}" />
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border x:Name="border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter"
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource SystemControlBackgroundAccentBrush}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.6"/>
@@ -67,7 +79,10 @@
</Style>
</UserControl.Resources>
<Border BorderBrush="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}" Background="{StaticResource CanvasZoneBackgroundBrush}" BorderThickness="1">
<Border BorderBrush="{DynamicResource SystemControlBackgroundAccentBrush}"
Background="{DynamicResource CanvasZoneBackgroundBrush}"
CornerRadius="4"
BorderThickness="1">
<Grid x:Name="Frame">
<Grid.RowDefinitions>
<RowDefinition Height="8"/>
@@ -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 @@
<Thumb x:Name="SWResize" Cursor="SizeNESW" BorderThickness="3,0,0,3" Grid.Row="3" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="SWResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
<Thumb x:Name="SEResize" Cursor="SizeNWSE" BorderThickness="0,0,3,3" Grid.Row="3" Grid.Column="3" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="SEResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
<Button Content="&#xE894;" BorderThickness="0" ToolTip="Delete zone" Background="Transparent" Foreground="White" FontSize="16" Padding="4" Click="OnClose" Grid.Row="2" Grid.Column="2" FontFamily="Segoe MDL2 Assets" HorizontalAlignment="Right" VerticalAlignment="Top" Style="{DynamicResource CloseButtonStyle}"/>
<Button Content="&#xE894;"
BorderThickness="0"
ToolTip="{x:Static props:Resources.Delete_Zone}"
Background="Transparent"
FontSize="16"
Padding="4"
Click="OnClose"
Grid.Row="2"
Grid.Column="2"
FontFamily="Segoe MDL2 Assets"
HorizontalAlignment="Right"
VerticalAlignment="Top" Style="{DynamicResource CloseButtonStyle}"/>
<Canvas x:Name="Body" />
</Grid>
</Border>
</UserControl>

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 @@ namespace FancyZonesEditor
}
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();

View File

@@ -65,19 +65,14 @@
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<PackageReference Include="MahApps.Metro" Version="2.3.2" />
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="ControlzEx" Version="4.4.0" />
<PackageReference Include="ModernWpfUI" Version="0.9.3" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Resource Include="images\ChromeClose.png" />
<Resource Include="images\Delete.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="images\Merge.png" />
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
</ItemGroup>
<ItemGroup>
<Resource Include="images\FancyZonesEditor.ico" />
@@ -86,6 +81,11 @@
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>

View File

@@ -7,7 +7,6 @@ using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using FancyZonesEditor.Models;
using FancyZonesEditor.Utils;
namespace FancyZonesEditor
{
@@ -120,25 +119,29 @@ namespace FancyZonesEditor
{
_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<int, int> RowColByIndex(int index)
{
int foundRow = -1;
@@ -238,6 +241,7 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
FixAccuracyError(_rowInfo, _model.RowPercents);
_model.CellChildMap = newCellChildMap;
_model.Rows++;
_model.UpdatePreview();
}
public void SplitOnDrag(GridResizer resizer, double delta, double space)
@@ -447,6 +452,8 @@ namespace FancyZonesEditor
_model.CellChildMap = newCellChildMap;
_model.Rows++;
}
_model.UpdatePreview();
}
public void RecalculateZones(int spacing, Size arrangeSize)
@@ -474,6 +481,11 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
_model.Rows = rows;
_model.Columns = cols;
_model.UpdatePreview();
}
private void FixAccuracyError(List<RowColInfo> info, List<int> percents)

View File

@@ -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">
<UserControl.Resources>
<Style TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="14" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="#F2F2F2" />
<Setter Property="Width" Value="150" />
</Style>
</UserControl.Resources>
<Viewbox Stretch="Uniform">
<Grid>
<Canvas x:Name="Preview" />
<Canvas x:Name="AdornerLayer" />
<Canvas
x:Name="MergePanel"
MouseUp="MergePanelMouseUp"
Visibility="Collapsed">
<StackPanel
x:Name="MergeButtons"
Background="Gray"
Orientation="Horizontal">
<Button
Width="134"
Height="36"
Margin="0"
Click="MergeClick">
<StackPanel Orientation="Horizontal">
<Image
Height="16"
Margin="0,0,12,0"
HorizontalAlignment="Left"
Source="images/Merge.png" />
<TextBlock Text="Merge zones" />
</StackPanel>
</Button>
<Canvas x:Name="MergePanel"
MouseUp="MergePanelMouseUp"
Visibility="Collapsed">
<Canvas.Effect>
<DropShadowEffect BlurRadius="6" Opacity="0.32" ShadowDepth="2" />
</Canvas.Effect>
<StackPanel x:Name="MergeButtons"
Orientation="Horizontal">
<Border CornerRadius="2"
Background="{DynamicResource PrimaryBackgroundBrush}">
<Button Width="134"
Height="36"
Margin="0"
Style="{StaticResource DefaultButtonStyle}"
Click="MergeClick">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE746;"
FontFamily="Segoe MDL2 Assets"
Foreground="{DynamicResource PrimaryForegroundBrush}"
Margin="0,3,8,0" />
<TextBlock Text="{x:Static props:Resources.Merge_zones}"
Foreground="{DynamicResource PrimaryForegroundBrush}"/>
</StackPanel>
</Button>
</Border>
</StackPanel>
</Canvas>
</Grid>

View File

@@ -8,7 +8,6 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using FancyZonesEditor.Models;
using FancyZonesEditor.Utils;
namespace FancyZonesEditor
{
@@ -40,27 +39,27 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
Preview.Height = workArea.Height;
GridLayoutModel model = Model;
if (model == null)
if (model == null || _data == null)
{
return;
}
@@ -383,9 +384,7 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
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);

View File

@@ -1,196 +1,62 @@
<local:EditorWindow x:Class="FancyZonesEditor.GridEditorWindow"
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:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:local="clr-namespace:FancyZonesEditor"
xmlns:props="clr-namespace:FancyZonesEditor.Properties"
mc:Ignorable="d"
Title=""
Width="528"
SizeToContent="Height"
Background="White"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
Closed="OnClosed">
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">
<Grid>
<Grid
Height="36"
Background="{DynamicResource SecondaryBackgroundBrush}"
Margin="0,-36,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Stretch">
<Window.Resources>
<Style x:Key="titleText" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="LineHeight" Value="24" />
<Setter Property="FontSize" Value="18"/>
<Setter Property="Margin" Value="0,0,0,12" />
</Style>
<Style x:Key="zoneCount" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="FontSize" Value="24"/>
<Setter Property="LineHeight" Value="24" />
<Setter Property="Margin" Value="20,0,20,0" />
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style x:Key="tabText" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="#C4C4C4"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="LineHeight" Value="20" />
<Setter Property="Margin" Value="24,20,0,0" />
<Setter Property="TextAlignment" Value="Center" />
</Style>
<Style x:Key="settingText" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="LineHeight" Value="20" />
<Setter Property="Margin" Value="5,10,0,0" />
<Setter Property="TextAlignment" Value="Left" />
</Style>
<Style x:Key="templateTitleText" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="0,20,0,0" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Height" Value="30"/>
<Setter Property="Width" Value="250"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style x:Key="customButtonFocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="1" Stroke="White" StrokeDashArray="1 2" StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="secondaryButton" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="0,5,0,5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="#767676"/>
<Setter Property="Width" Value="239"/>
<Setter Property="Height" Value="32"/>
<Setter Property="FocusVisualStyle" Value="{DynamicResource customButtonFocusVisualStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#5D5D5D"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="primaryButton" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="0,5,0,5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="#0078D7"/>
<Setter Property="Margin" Value="16,0,0,0" />
<Setter Property="Width" Value="239"/>
<Setter Property="Height" Value="32"/>
<Setter Property="FocusVisualStyle" Value="{DynamicResource customButtonFocusVisualStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#024D89"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="spinnerButton" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontSize" Value="24"/>
<Setter Property="Padding" Value="0,0,0,5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="#F2F2F2"/>
<Setter Property="Margin" Value="0,0,0,0" />
</Style>
<Style x:Key="templateBackground" TargetType="Rectangle">
<Setter Property="Fill" Value="Black"/>
<Setter Property="Opacity" Value="0.05"/>
<Setter Property="RadiusX" Value="4"/>
<Setter Property="RadiusY" Value="4"/>
</Style>
<Style x:Key="templateBackgroundSelected" TargetType="Rectangle">
<Setter Property="Fill" Value="#F2F2F2"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="RadiusX" Value="4"/>
<Setter Property="RadiusY" Value="4"/>
<Setter Property="Stroke" Value="#0078D7"/>
<Setter Property="StrokeThickness" Value="2"/>
</Style>
<Style x:Key="newZoneButton" TargetType="Button">
<Setter Property="Background" Value="#f2f2f2"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontFamily" Value="SegoeUI"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="FontSize" Value="120"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style x:Key="textLabel" TargetType="TextBlock">
<Setter Property="FontFamily" Value="SegoeUI"/>
<Setter Property="FontWeight" Value="Regular"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Margin" Value="0,12,0,0"/>
</Style>
<Style x:Key="textBox" TargetType="TextBox">
<Setter Property="BorderBrush" Value="#949494"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FontFamily" Value="SegoeUI"/>
<Setter Property="FontWeight" Value="Regular"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Padding" Value="5,5,5,5"/>
</Style>
</Window.Resources>
<StackPanel Margin="16">
<TextBlock Name="windowEditorDialogTitle" Text="{x:Static props:Resources.Custom_Table_Layout}" Style="{StaticResource titleText}" />
<TextBlock Text="{x:Static props:Resources.Note_Custom_Table}" Style="{StaticResource textLabel}" TextWrapping="Wrap" />
<TextBlock x:Name="customLayoutName" Text="{x:Static props:Resources.Name}" Style="{StaticResource textLabel}" />
<TextBox Name="customLayoutNameTextBox" Text="{Binding Name}" GotFocus="NameTextBox_GotFocus" AutomationProperties.LabeledBy="{Binding ElementName=customLayoutName}" Style="{StaticResource textBox}" />
<!--
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<CheckBox x:Name="showGridSetting" VerticalAlignment="Center" HorizontalAlignment="Center" IsChecked="True" Margin="21,4,0,0"/>
<TextBlock Text="Show snap grid" Style="{StaticResource settingText}" />
<TextBlock Text="Grid spacing" Style="{StaticResource settingText}" Margin="40,10,10,0" />
<TextBox x:Name="gridValue" Text="{Binding Path=Spacing,Mode=TwoWay}" Style="{StaticResource textBox}"/>
<Border
Background="{DynamicResource TitleBarSecondaryForegroundBrush}"
Width="30"
Height="3"
CornerRadius="1.5"
VerticalAlignment="Center"
Margin="0,4,0,0" />
</Grid>
<StackPanel Margin="16">
<TextBlock Text="{x:Static props:Resources.Note_Custom_Table}"
Foreground="{DynamicResource SecondaryForegroundBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Margin="0,8,0,0"
TextWrapping="Wrap" />
<Grid Margin="0,24,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="8"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Content="{x:Static props:Resources.Cancel}"
Style="{StaticResource DefaultButtonStyle}"
HorizontalAlignment="Stretch"
Grid.Column="2"
Click="OnCancel" />
<Button Content="{x:Static props:Resources.Save_Apply}"
Style="{StaticResource AccentButtonStyle}"
HorizontalAlignment="Stretch"
Click="OnSaveApplyTemplate" />
</Grid>
</StackPanel>
-->
<StackPanel Orientation="Horizontal" Margin="0,16,0,0">
<Button Content="{x:Static props:Resources.Cancel}" Style="{StaticResource secondaryButton}" Click="OnCancel" />
<Button Content="{x:Static props:Resources.Save_Apply}" Style="{StaticResource primaryButton}" Click="OnSaveApplyTemplate" />
</StackPanel>
</StackPanel>
</Grid>
</local:EditorWindow>

View File

@@ -5,13 +5,9 @@
using System.Windows;
using System.Windows.Input;
using FancyZonesEditor.Models;
using FancyZonesEditor.Utils;
namespace FancyZonesEditor
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class GridEditorWindow : EditorWindow
{
public GridEditorWindow()
@@ -42,15 +38,5 @@ namespace FancyZonesEditor
}
private GridLayoutModel _stashedModel;
private void NameTextBox_GotFocus(object sender, RoutedEventArgs e)
{
customLayoutNameTextBox.CaretIndex = customLayoutNameTextBox.Text.Length;
}
public System.Windows.Controls.TextBox NameTextBox()
{
return customLayoutNameTextBox;
}
}
}

View File

@@ -8,15 +8,32 @@
d:DesignHeight="300" d:DesignWidth="300">
<Thumb.Template>
<ControlTemplate>
<StackPanel x:Name="Body" Grid.Column="0" Width="48" Height="48">
<Ellipse x:Name="BackgroundEllipse" Height="48" Width="48" Fill="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}" />
<Rectangle Height="20" Width="2" Fill="White" Margin="5,-48,0,0"/>
<Rectangle Height="20" Width="2" Fill="White" Margin="-5,-48,0,0"/>
</StackPanel>
<Border x:Name="Body"
Height="48"
Width="48"
CornerRadius="48"
Background="{DynamicResource SystemControlBackgroundAccentBrush}">
<Border.Effect>
<DropShadowEffect BlurRadius="6"
Opacity="0.24"
ShadowDepth="1" />
</Border.Effect>
<Grid>
<Rectangle Height="20"
Width="2"
Fill="White"
Margin="5,0,0,0" />
<Rectangle Height="20"
Width="2"
Fill="White"
Margin="-5,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Opacity" TargetName="BackgroundEllipse" Value="0.6"/>
<Setter Property="Background"
TargetName="Body"
Value="{DynamicResource SystemAccentColorLight1Brush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

View File

@@ -45,7 +45,7 @@ namespace FancyZonesEditor
{
_orientation = value;
ApplyTemplate();
StackPanel body = (StackPanel)Template.FindName("Body", this);
Border body = (Border)Template.FindName("Body", this);
if (value == Orientation.Vertical)
{
body.RenderTransform = null;

View File

@@ -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">
<Grid x:Name="Frame">
<Canvas x:Name="Body" />
@@ -23,9 +24,9 @@
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Content="ID"
FontFamily="Segoe UI Light"
FontWeight="SemiBold"
FontSize="64"
Foreground="White" />
Foreground="{DynamicResource PrimaryForegroundBrush}" />
<!--<TextBlock Margin="2" Text="Shift Key switches direction&#13;Ctrl Key repeats"/>-->
</Grid>
</UserControl>

View File

@@ -59,7 +59,7 @@ namespace FancyZonesEditor
set { SetValue(IsSelectedProperty, value); }
}
public GridZone()
public GridZone(int spacing)
{
InitializeComponent();
OnSelectionChanged();
@@ -69,6 +69,9 @@ namespace FancyZonesEditor
};
Body.Children.Add(_splitter);
Spacing = spacing;
SplitterThickness = Math.Max(spacing, 1);
((App)Application.Current).MainWindowSettings.PropertyChanged += ZoneSettings_PropertyChanged;
}
@@ -104,19 +107,9 @@ namespace FancyZonesEditor
}
}
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 @@ namespace FancyZonesEditor
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)

View File

@@ -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"/>
Background="{DynamicResource BackdropBrush}"/>

View File

@@ -6,8 +6,12 @@
xmlns:local="clr-namespace:FancyZonesEditor"
mc:Ignorable="d"
Loaded="OnLoaded"
d:DesignHeight="450" d:DesignWidth="800">
<Grid x:Name="Body">
d:DesignHeight="450"
d:DesignWidth="800">
<Grid>
<Border CornerRadius="4"
Background="{DynamicResource LayoutPreviewBackgroundBrush}" />
<Grid x:Name="Body"
Background="Transparent" />
</Grid>
</UserControl>

View File

@@ -8,7 +8,6 @@ using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using FancyZonesEditor.Models;
namespace FancyZonesEditor
@@ -22,10 +21,11 @@ namespace FancyZonesEditor
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<Int32Rect> _zones = new List<Int32Rect>();
@@ -49,8 +49,17 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
}
}
private void LayoutModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
RenderPreview();
}
public Int32Rect[] GetZoneRects()
{
return _zones.ToArray();
@@ -114,9 +128,7 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
((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 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
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<int> visited = new List<int>();
@@ -229,7 +238,7 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
}
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 @@ namespace FancyZonesEditor
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);
}

File diff suppressed because it is too large Load Diff

View File

@@ -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
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
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 @@ namespace FancyZonesEditor
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))
{
_settings.ZoneCount--;
return;
}
if (model.TemplateZoneCount > 1)
{
model.TemplateZoneCount--;
}
}
private void IncrementZones_Click(object sender, RoutedEventArgs e)
{
if (_settings.ZoneCount < MaxZones)
var mainEditor = App.Overlay;
if (!(mainEditor.CurrentDataContext is LayoutModel model))
{
_settings.ZoneCount++;
return;
}
if (model.TemplateZoneCount < LayoutSettings.MaxZones)
{
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 @@ namespace FancyZonesEditor
private void Select(LayoutModel newSelection)
{
if (App.Overlay.CurrentDataContext is LayoutModel currentSelection)
{
currentSelection.IsSelected = false;
}
newSelection.IsSelected = true;
_settings.SetSelectedModel(newSelection);
App.Overlay.CurrentDataContext = newSelection;
}
private void EditLayout_Click(object sender, RoutedEventArgs e)
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)
{
string name = customModel.Name;
if (name.StartsWith(defaultNamePrefix))
{
if (int.TryParse(name.Substring(defaultNamePrefix.Length), out int i))
{
if (maxCustomIndex < i)
{
maxCustomIndex = i;
}
}
}
}
LayoutNameText.Text = defaultNamePrefix + " " + (++maxCustomIndex);
GridLayoutRadioButton.IsChecked = true;
GridLayoutRadioButton.Focus();
await NewLayoutDialog.ShowAsync();
}
private void DuplicateLayout_Click(object sender, RoutedEventArgs e)
{
EditLayoutDialog.Hide();
var mainEditor = App.Overlay;
if (!(mainEditor.CurrentDataContext is LayoutModel model))
{
@@ -133,26 +172,32 @@ namespace FancyZonesEditor
}
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 @@ namespace FancyZonesEditor
}
}
}
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 @@ namespace FancyZonesEditor
e.Handled = true;
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog sender, ModernWpf.Controls.ContentDialogButtonClickEventArgs args)
{
this.Close();
LayoutModel selectedLayoutModel;
if (GridLayoutRadioButton.IsChecked == true)
{
GridLayoutModel gridModel = new GridLayoutModel(LayoutNameText.Text, LayoutType.Custom)
{
Rows = 1,
RowPercents = new List<int>(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);
}
private void Reset_Click(object sender, RoutedEventArgs e)
// This is required to fix a WPF rendering bug when using custom chrome
private void OnContentRendered(object sender, EventArgs e)
{
var overlay = App.Overlay;
MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings;
InvalidateVisual();
}
if (overlay.CurrentDataContext is LayoutModel model)
private void MonitorItem_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return || e.Key == Key.Space)
{
model.IsSelected = false;
model.IsApplied = false;
monitorViewModel.SelectCommand.Execute((MonitorInfoModel)(sender as Border).DataContext);
}
}
private void MonitorItem_MouseDown(object sender, MouseButtonEventArgs e)
{
monitorViewModel.SelectCommand.Execute((MonitorInfoModel)(sender as Border).DataContext);
}
// EditLayout: Cancel changes
private void EditLayoutDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
// restore model properties from settings
_settings.RestoreSelectedModel(_backup);
_backup = null;
Select(_settings.AppliedModel);
}
// EditLayout: Save changes
private void EditLayoutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
var mainEditor = App.Overlay;
if (!(mainEditor.CurrentDataContext is LayoutModel model))
{
return;
}
overlay.CurrentLayoutSettings.ZonesetUuid = settings.BlankModel.Uuid;
overlay.CurrentLayoutSettings.Type = LayoutType.Blank;
overlay.CurrentDataContext = settings.BlankModel;
_backup = null;
App.FancyZonesEditorIO.SerializeAppliedLayouts();
if (!overlay.MultiMonitorMode)
// update current settings
if (model == _settings.AppliedModel)
{
Close();
App.Overlay.SetLayoutSettings(App.Overlay.Monitors[App.Overlay.CurrentDesktop], model);
}
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)
{
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;
}
}
}

View File

@@ -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 @@ namespace FancyZonesEditor.Models
{
}
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<Int32Rect> Zones { get; private set; } = new List<Int32Rect>();
@@ -54,6 +63,28 @@ namespace FancyZonesEditor.Models
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 @@ namespace FancyZonesEditor.Models
layout.Zones.Add(zone);
}
layout.SensitivityRadius = SensitivityRadius;
return layout;
}
@@ -81,37 +113,8 @@ namespace FancyZonesEditor.Models
{
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 @@ namespace FancyZonesEditor.Models
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<JsonElement>(jsonString));
SerializeCreatedCustomZonesets();
}
}
}

View File

@@ -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 @@ namespace FancyZonesEditor.Models
if (_rows != value)
{
_rows = value;
FirePropertyChanged();
}
}
}
@@ -49,7 +63,6 @@ namespace FancyZonesEditor.Models
if (_cols != value)
{
_cols = value;
FirePropertyChanged();
}
}
}
@@ -62,10 +75,50 @@ namespace FancyZonesEditor.Models
public int[,] CellChildMap { get; set; }
// RowPercents - represents the %age height of each row in the grid
public List<int> RowPercents { get; set; }
public List<int> RowPercents { get; set; } = new List<int>();
// ColumnPercents - represents the %age width of each column in the grid
public List<int> ColumnPercents { get; set; }
public List<int> ColumnPercents { get; set; } = new List<int>();
// 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 @@ namespace FancyZonesEditor.Models
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<int>(Rows);
for (int row = 0; row < Rows; row++)
@@ -125,6 +211,8 @@ namespace FancyZonesEditor.Models
CellChildMap[row, col] = data[i++];
}
}
FirePropertyChanged();
}
// Clone
@@ -171,30 +259,36 @@ namespace FancyZonesEditor.Models
}
layout.ColumnPercents = colPercents;
layout.ShowSpacing = ShowSpacing;
layout.Spacing = Spacing;
layout.SensitivityRadius = SensitivityRadius;
}
private struct GridLayoutInfo
// InitTemplateZones
// Creates zones based on template zones count
public override void InitTemplateZones()
{
public int Rows { get; set; }
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;
}
public int Columns { get; set; }
public List<int> RowsPercentage { get; set; }
public List<int> ColumnsPercentage { get; set; }
public int[][] CellChildMap { get; set; }
}
private struct GridLayoutJson
{
public string Uuid { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public GridLayoutInfo Info { get; set; }
FirePropertyChanged();
}
// PersistData
@@ -202,40 +296,105 @@ namespace FancyZonesEditor.Models
protected override void PersistData()
{
AddCustomLayout(this);
}
GridLayoutInfo layoutInfo = new GridLayoutInfo
{
Rows = Rows,
Columns = Columns,
RowsPercentage = RowPercents,
ColumnsPercentage = ColumnPercents,
CellChildMap = new int[Rows][],
};
private void InitRows()
{
CellChildMap = new int[TemplateZoneCount, 1];
RowPercents = new List<int>(TemplateZoneCount);
for (int row = 0; row < Rows; row++)
for (int i = 0; i < TemplateZoneCount; i++)
{
layoutInfo.CellChildMap[row] = new int[Columns];
for (int col = 0; col < Columns; col++)
CellChildMap[i, 0] = i;
// 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));
}
_rows = TemplateZoneCount;
}
private void InitColumns()
{
CellChildMap = new int[1, TemplateZoneCount];
ColumnPercents = new List<int>(TemplateZoneCount);
for (int i = 0; i < TemplateZoneCount; i++)
{
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).
ColumnPercents.Add(((GridMultiplier * (i + 1)) / TemplateZoneCount) - ((GridMultiplier * i) / TemplateZoneCount));
}
_cols = TemplateZoneCount;
}
private void InitGrid()
{
int rows = 1;
while (TemplateZoneCount / rows >= rows)
{
rows++;
}
rows--;
int cols = TemplateZoneCount / rows;
if (TemplateZoneCount % rows == 0)
{
// even grid
}
else
{
cols++;
}
RowPercents = new List<int>(rows);
ColumnPercents = new List<int>(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++)
{
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
{
Uuid = Uuid,
Name = Name,
Type = ModelTypeID,
Info = layoutInfo,
};
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new DashCaseNamingPolicy(),
};
_rows = rows;
_cols = cols;
}
string jsonString = JsonSerializer.Serialize(jsonObj, options);
AddCustomLayoutJson(JsonSerializer.Deserialize<JsonElement>(jsonString));
SerializeCreatedCustomZonesets();
private void InitPriorityGrid()
{
if (TemplateZoneCount <= _priorityData.Length)
{
Reload(_priorityData[TemplateZoneCount - 1]);
}
else
{
// same as grid;
InitGrid();
}
}
}
}

View File

@@ -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 @@ namespace FancyZonesEditor.Models
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 @@ namespace FancyZonesEditor.Models
if (_name != value)
{
_name = value;
FirePropertyChanged();
FirePropertyChanged(nameof(Name));
}
}
}
@@ -82,6 +90,14 @@ namespace FancyZonesEditor.Models
}
}
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 @@ namespace FancyZonesEditor.Models
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 @@ namespace FancyZonesEditor.Models
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 @@ namespace FancyZonesEditor.Models
// 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 @@ namespace FancyZonesEditor.Models
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<LayoutModel> LoadCustomModels()
{
_customModels = new ObservableCollection<LayoutModel>();
App.FancyZonesEditorIO.ParseLayouts(ref _customModels, ref _deletedCustomModels);
return _customModels;
}
private static ObservableCollection<LayoutModel> _customModels;
private static List<string> _deletedCustomModels = new List<string>();
private static List<JsonElement> _createdCustomLayouts = new List<JsonElement>();
// 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 @@ namespace FancyZonesEditor.Models
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();
}
}
}

View File

@@ -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;

View File

@@ -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 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
public MainWindowSettingsModel()
{
// Initialize the five default layout models: Focus, Columns, Rows, Grid, and PriorityGrid
DefaultModels = new List<LayoutModel>(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<int>(1) { _multiplier },
RowPercents = new List<int>(1) { GridLayoutModel.GridMultiplier },
};
_columnsModel.InitTemplateZones();
DefaultModels.Add(_columnsModel);
_rowsModel = new GridLayoutModel(Properties.Resources.Template_Layout_Rows, LayoutType.Rows)
{
Columns = 1,
ColumnPercents = new List<int>(1) { _multiplier },
ColumnPercents = new List<int>(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,138 +129,7 @@ namespace FancyZonesEditor
private bool _isCtrlKeyPressed;
// UpdateLayoutModels
// Update the five default layouts based on the new ZoneCount
private void UpdateTemplateLayoutModels()
{
// 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<int>(ZoneCount);
for (int i = 0; i < ZoneCount; i++)
{
_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));
}
// Update the "Grid" Default Layout
int rows = 1;
while (ZoneCount / rows >= rows)
{
rows++;
}
rows--;
int cols = ZoneCount / rows;
if (ZoneCount % rows == 0)
{
// even grid
}
else
{
cols++;
}
_gridModel.Rows = rows;
_gridModel.Columns = cols;
_gridModel.RowPercents = new List<int>(rows);
_gridModel.ColumnPercents = new List<int>(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));
}
for (int col = 0; col < cols; col++)
{
_gridModel.ColumnPercents.Add(((_multiplier * (col + 1)) / cols) - ((_multiplier * col) / cols));
}
int index = 0;
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
_gridModel.CellChildMap[row, col] = index++;
if (index == ZoneCount)
{
index--;
}
}
}
// 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<LayoutModel> DefaultModels { get; }
public static ObservableCollection<LayoutModel> CustomModels
{
get
{
if (_customModels == null)
{
_customModels = LayoutModel.LoadCustomModels();
_customModels.Insert(0, _blankCustomModel);
}
return _customModels;
}
}
private static ObservableCollection<LayoutModel> _customModels;
public CanvasLayoutModel BlankModel
public LayoutModel BlankModel
{
get
{
@@ -367,7 +137,55 @@ namespace FancyZonesEditor
}
}
private CanvasLayoutModel _blankModel = new CanvasLayoutModel(string.Empty, LayoutType.Blank);
public static IList<LayoutModel> DefaultModels { get; } = new List<LayoutModel>(6);
public static ObservableCollection<LayoutModel> CustomModels
{
get
{
return _customModels;
}
}
private static ObservableCollection<LayoutModel> _customModels = new ObservableCollection<LayoutModel>();
public LayoutModel SelectedModel
{
get
{
return _selectedModel;
}
private set
{
if (_selectedModel != value)
{
_selectedModel = value;
FirePropertyChanged(nameof(SelectedModel));
}
}
}
private LayoutModel _selectedModel = null;
public LayoutModel AppliedModel
{
get
{
return _appliedModel;
}
private set
{
if (_appliedModel != value)
{
_appliedModel = value;
FirePropertyChanged(nameof(AppliedModel));
}
}
}
private LayoutModel _appliedModel = null;
public static bool IsPredefinedLayout(LayoutModel model)
{
@@ -376,21 +194,13 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
{
// 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 @@ namespace FancyZonesEditor
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();
}
}
}

View File

@@ -5,7 +5,6 @@
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using FancyZonesEditor.Utils;

View File

@@ -13,7 +13,6 @@ namespace FancyZonesEditor
public class Overlay
{
private MainWindow _mainWindow;
private LayoutPreview _layoutPreview;
private UserControl _editor;
@@ -28,7 +27,7 @@ namespace FancyZonesEditor
return Monitors[CurrentDesktop].Device.WorkAreaRect;
}
return default(Rect);
return default;
}
}
@@ -54,7 +53,7 @@ namespace FancyZonesEditor
return Monitors[CurrentDesktop].Window;
}
return default(Window);
return default;
}
}
@@ -100,14 +99,13 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
_layoutPreview = new LayoutPreview
{
IsActualSize = true,
Opacity = 0.5,
Opacity = 1,
};
ShowLayout();
@@ -201,6 +199,30 @@ namespace FancyZonesEditor
}
}
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 @@ namespace FancyZonesEditor
CurrentLayoutWindow.Content = _editor;
EditorWindow window;
bool isGrid = false;
if (model is GridLayoutModel)
{
window = new GridEditorWindow();
isGrid = true;
}
else
{
@@ -230,14 +251,6 @@ namespace FancyZonesEditor
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 @@ namespace FancyZonesEditor
_layoutPreview = new LayoutPreview
{
IsActualSize = true,
Opacity = 0.5,
Opacity = 1,
};
CurrentLayoutWindow.Content = _layoutPreview;
@@ -318,8 +331,6 @@ namespace FancyZonesEditor
_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

View File

@@ -78,6 +78,33 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Apply layout.
/// </summary>
public static string Apply_Layout {
get {
return ResourceManager.GetString("Apply_Layout", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Are you sure?.
/// </summary>
public static string Are_You_Sure {
get {
return ResourceManager.GetString("Are_You_Sure", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Are you sure you want to delete this layout?.
/// </summary>
public static string Are_You_Sure_Description {
get {
return ResourceManager.GetString("Are_You_Sure_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cancel.
/// </summary>
@@ -97,7 +124,7 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// 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.
/// </summary>
public static string Choose_Layout {
get {
@@ -105,6 +132,15 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Choose layout type.
/// </summary>
public static string Choose_layout_type {
get {
return ResourceManager.GetString("Choose_layout_type", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Close.
/// </summary>
@@ -132,6 +168,33 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Create.
/// </summary>
public static string Create {
get {
return ResourceManager.GetString("Create", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Create custom layout.
/// </summary>
public static string Create_Custom_From_Template {
get {
return ResourceManager.GetString("Create_Custom_From_Template", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Create new layout.
/// </summary>
public static string Create_new_layout {
get {
return ResourceManager.GetString("Create_new_layout", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Custom.
/// </summary>
@@ -142,7 +205,7 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// Looks up a localized string similar to Create new custom.
/// Looks up a localized string similar to Custom layout.
/// </summary>
public static string Custom_Layout_Create_New {
get {
@@ -160,20 +223,29 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// Looks up a localized string similar to Delete custom layout.
/// Looks up a localized string similar to Custom layout.
/// </summary>
public static string Custom_Layout_Delete_Button {
public static string Default_Custom_Layout_Name {
get {
return ResourceManager.GetString("Custom_Layout_Delete_Button", resourceCulture);
return ResourceManager.GetString("Default_Custom_Layout_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Custom table layout creator.
/// Looks up a localized string similar to Delete.
/// </summary>
public static string Custom_Table_Layout {
public static string Delete {
get {
return ResourceManager.GetString("Custom_Table_Layout", resourceCulture);
return ResourceManager.GetString("Delete", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Delete zone.
/// </summary>
public static string Delete_Zone {
get {
return ResourceManager.GetString("Delete_Zone", resourceCulture);
}
}
@@ -187,11 +259,38 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// Looks up a localized string similar to Edit selected layout.
/// Looks up a localized string similar to Duplicate.
/// </summary>
public static string Edit_Selected_Layout {
public static string Duplicate {
get {
return ResourceManager.GetString("Edit_Selected_Layout", resourceCulture);
return ResourceManager.GetString("Duplicate", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Edit.
/// </summary>
public static string Edit {
get {
return ResourceManager.GetString("Edit", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Edit layout.
/// </summary>
public static string Edit_Layout {
get {
return ResourceManager.GetString("Edit_Layout", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Edit zones.
/// </summary>
public static string Edit_zones {
get {
return ResourceManager.GetString("Edit_zones", resourceCulture);
}
}
@@ -276,6 +375,33 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to &apos;zones-settings.json&apos; contains malformed data..
/// </summary>
public static string Error_Parsing_Zones_Settings_Malformed_Data {
get {
return ResourceManager.GetString("Error_Parsing_Zones_Settings_Malformed_Data", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Editor settings parsing error..
/// </summary>
public static string Error_Parsing_Zones_Settings_Title {
get {
return ResourceManager.GetString("Error_Parsing_Zones_Settings_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Would you like to continue? Malformed data will be lost..
/// </summary>
public static string Error_Parsing_Zones_Settings_User_Choice {
get {
return ResourceManager.GetString("Error_Parsing_Zones_Settings_User_Choice", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error persisting custom layout.
/// </summary>
@@ -330,6 +456,60 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Create layouts that have overlapping zones.
/// </summary>
public static string Layout_Canvas_Description {
get {
return ResourceManager.GetString("Layout_Canvas_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Canvas.
/// </summary>
public static string Layout_Canvas_Title {
get {
return ResourceManager.GetString("Layout_Canvas_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Create layouts that are horizontally or vertically stacked.
/// </summary>
public static string Layout_Grid_Description {
get {
return ResourceManager.GetString("Layout_Grid_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Grid.
/// </summary>
public static string Layout_Grid_Title {
get {
return ResourceManager.GetString("Layout_Grid_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Merge zones.
/// </summary>
public static string Merge_zones {
get {
return ResourceManager.GetString("Merge_zones", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Monitor.
/// </summary>
public static string Monitor {
get {
return ResourceManager.GetString("Monitor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Name.
/// </summary>
@@ -340,7 +520,17 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// 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 &quot;merge&quot;..
/// Looks up a localized string similar to Create or duplicate a layout to get started.
/// </summary>
public static string No_Custom_Layouts_Message {
get {
return ResourceManager.GetString("No_Custom_Layouts_Message", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Hold down Shift key to change orientation of splitter.
///To merge zones, select the zones and click &quot;merge&quot;..
/// </summary>
public static string Note_Custom_Table {
get {
@@ -348,6 +538,15 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Number of zones.
/// </summary>
public static string NumberOfZones {
get {
return ResourceManager.GetString("NumberOfZones", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reset layout.
/// </summary>
@@ -358,7 +557,16 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// Looks up a localized string similar to Save and apply.
/// Looks up a localized string similar to Save.
/// </summary>
public static string Save {
get {
return ResourceManager.GetString("Save", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save &amp; apply.
/// </summary>
public static string Save_Apply {
get {
@@ -366,6 +574,15 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Template settings.
/// </summary>
public static string Settings {
get {
return ResourceManager.GetString("Settings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show space around zones.
/// </summary>
@@ -385,20 +602,11 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// Looks up a localized string similar to Custom tab selected, press ctrl + tab to switch to Templates.
/// Looks up a localized string similar to No layout.
/// </summary>
public static string Tab_Item_Custom {
public static string Template_Layout_Blank {
get {
return ResourceManager.GetString("Tab_Item_Custom", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Templates tab selected, press ctrl + tab to switch to Custom.
/// </summary>
public static string Tab_Item_Templates {
get {
return ResourceManager.GetString("Tab_Item_Templates", resourceCulture);
return ResourceManager.GetString("Template_Layout_Blank", resourceCulture);
}
}

View File

@@ -132,9 +132,6 @@
<data name="Grid_Layout_Editor" xml:space="preserve">
<value>Grid layout editor</value>
</data>
<data name="Choose_Layout" xml:space="preserve">
<value>Choose your layout for this desktop</value>
</data>
<data name="Crash_Report_Message_Box_Text_Part1" xml:space="preserve">
<value>Error logged to </value>
</data>
@@ -147,14 +144,11 @@
<data name="Custom_Layout_Creator" xml:space="preserve">
<value>Custom layout creator</value>
</data>
<data name="Custom_Table_Layout" xml:space="preserve">
<value>Custom table layout creator</value>
</data>
<data name="Distance_adjacent_zones" xml:space="preserve">
<value>Distance to highlight adjacent zones</value>
</data>
<data name="Edit_Selected_Layout" xml:space="preserve">
<value>Edit selected layout</value>
<data name="Edit_Layout" xml:space="preserve">
<value>Edit layout</value>
</data>
<data name="Fancy_Zones_Editor_App_Title" xml:space="preserve">
<value>FancyZones Editor</value>
@@ -166,10 +160,11 @@
<value>Name</value>
</data>
<data name="Note_Custom_Table" xml:space="preserve">
<value>Note: Hold down Shift Key to change orientation of splitter. To merge zones, select the zones and click "merge".</value>
<value>Hold down Shift key to change orientation of splitter.
To merge zones, select the zones and click "merge".</value>
</data>
<data name="Save_Apply" xml:space="preserve">
<value>Save and apply</value>
<value>Save &amp; apply</value>
</data>
<data name="Show_Space_Zones" xml:space="preserve">
<value>Show space around zones</value>
@@ -186,13 +181,6 @@
<data name="Zone_Count_Increment" xml:space="preserve">
<value>Increment number of zones in template layout</value>
</data>
<data name="Custom_Layout_Delete_Button" xml:space="preserve">
<value>Delete custom layout</value>
</data>
<data name="Custom_Layout_Create_New" xml:space="preserve">
<value>Create new custom</value>
<comment>As in Create new custom layout</comment>
</data>
<data name="Error_Invalid_Arguments" xml:space="preserve">
<value>FancyZones Editor arguments are invalid.</value>
</data>
@@ -220,12 +208,6 @@
<data name="Template_Layout_Rows" xml:space="preserve">
<value>Rows</value>
</data>
<data name="Tab_Item_Custom" xml:space="preserve">
<value>Custom tab selected, press ctrl + tab to switch to Templates</value>
</data>
<data name="Tab_Item_Templates" xml:space="preserve">
<value>Templates tab selected, press ctrl + tab to switch to Custom</value>
</data>
<data name="Close" xml:space="preserve">
<value>Close</value>
</data>
@@ -257,4 +239,99 @@
<value>Reset layout</value>
<comment>as in Reset to a blank value</comment>
</data>
<data name="Choose_Layout" xml:space="preserve">
<value>Choose the layout for this desktop</value>
</data>
<data name="Choose_layout_type" xml:space="preserve">
<value>Choose layout type</value>
<comment>Dialog header that allows the user to select a specific layout type</comment>
</data>
<data name="Create" xml:space="preserve">
<value>Create</value>
<comment>Button label that creates a new layout</comment>
</data>
<data name="Create_new_layout" xml:space="preserve">
<value>Create new layout</value>
<comment>Button label that allows the user to create a new layout</comment>
</data>
<data name="Custom_Layout_Create_New" xml:space="preserve">
<value>Custom layout</value>
</data>
<data name="Delete" xml:space="preserve">
<value>Delete</value>
<comment>Context menu label that allows the user duplicate a layout</comment>
</data>
<data name="Duplicate" xml:space="preserve">
<value>Duplicate</value>
<comment>Context menu label that allows the user duplicate a layout</comment>
</data>
<data name="Edit" xml:space="preserve">
<value>Edit</value>
<comment>Context menu label that allows the user edit a layout</comment>
</data>
<data name="Layout_Canvas_Description" xml:space="preserve">
<value>Create layouts that have overlapping zones</value>
</data>
<data name="Layout_Canvas_Title" xml:space="preserve">
<value>Canvas</value>
</data>
<data name="Layout_Grid_Description" xml:space="preserve">
<value>Create layouts that are horizontally or vertically stacked</value>
</data>
<data name="Layout_Grid_Title" xml:space="preserve">
<value>Grid</value>
</data>
<data name="Merge_zones" xml:space="preserve">
<value>Merge zones</value>
<comment>Button label that allows the user to merge 2 or more zones together</comment>
</data>
<data name="Monitor" xml:space="preserve">
<value>Monitor</value>
</data>
<data name="Settings" xml:space="preserve">
<value>Template settings</value>
</data>
<data name="Are_You_Sure" xml:space="preserve">
<value>Are you sure?</value>
</data>
<data name="Are_You_Sure_Description" xml:space="preserve">
<value>Are you sure you want to delete this layout?</value>
</data>
<data name="Edit_zones" xml:space="preserve">
<value>Edit zones</value>
</data>
<data name="No_Custom_Layouts_Message" xml:space="preserve">
<value>Create or duplicate a layout to get started</value>
</data>
<data name="Delete_Zone" xml:space="preserve">
<value>Delete zone</value>
<comment>A tooltip on a button that allows the user to delete a zone</comment>
</data>
<data name="Error_Parsing_Zones_Settings_Malformed_Data" xml:space="preserve">
<value>'zones-settings.json' contains malformed data.</value>
</data>
<data name="Error_Parsing_Zones_Settings_Title" xml:space="preserve">
<value>Editor settings parsing error.</value>
</data>
<data name="Error_Parsing_Zones_Settings_User_Choice" xml:space="preserve">
<value>Would you like to continue? Malformed data will be lost.</value>
</data>
<data name="Apply_Layout" xml:space="preserve">
<value>Apply layout</value>
</data>
<data name="Save" xml:space="preserve">
<value>Save</value>
</data>
<data name="NumberOfZones" xml:space="preserve">
<value>Number of zones</value>
</data>
<data name="Template_Layout_Blank" xml:space="preserve">
<value>No layout</value>
</data>
<data name="Create_Custom_From_Template" xml:space="preserve">
<value>Create custom layout</value>
</data>
<data name="Default_Custom_Layout_Name" xml:space="preserve">
<value>Custom layout</value>
</data>
</root>

View File

@@ -0,0 +1,93 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:local="clr-namespace:FancyZonesEditor.Styles">
<Style x:Key="LayoutTypeRadioButtonStyle" TargetType="RadioButton">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Background" Value="{DynamicResource RadioButtonBackground}" />
<Setter Property="Foreground" Value="{DynamicResource RadioButtonForeground}" />
<Setter Property="BorderBrush" Value="{DynamicResource RadioButtonBorderBrush}" />
<Setter Property="Padding" Value="12" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="ui:FocusVisualHelper.UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="ui:FocusVisualHelper.FocusVisualMargin" Value="0" />
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border
x:Name="RootGrid"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="2"
SnapsToDevicePixels="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Border x:Name="CheckGlyph"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
UseLayoutRounding="False"
Opacity="0"
CornerRadius="2"
BorderThickness="2"
BorderBrush="{DynamicResource SystemControlBackgroundAccentBrush}" />
<ui:ContentPresenterEx x:Name="ContentPresenter"
TextElement.Foreground="{TemplateBinding Foreground}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Grid.Column="1"
TextWrapping="Wrap"
Focusable="False"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ContentPresenter"
Property="Foreground"
Value="{DynamicResource RadioButtonForegroundPointerOver}" />
<Setter TargetName="CheckGlyph" Property="Opacity" Value="0.6" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="ContentPresenter" Property="Foreground" Value="{DynamicResource RadioButtonForegroundPressed}" />
<Setter TargetName="RootGrid" Property="Background" Value="{DynamicResource RadioButtonBackgroundPressed}" />
<Setter TargetName="RootGrid" Property="BorderBrush" Value="{DynamicResource RadioButtonBorderBrushPressed}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="ContentPresenter" Property="Foreground" Value="{DynamicResource RadioButtonForegroundDisabled}" />
<Setter TargetName="RootGrid" Property="Background" Value="{DynamicResource RadioButtonBackgroundDisabled}" />
<Setter TargetName="RootGrid" Property="BorderBrush" Value="{DynamicResource RadioButtonBorderBrushDisabled}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,41 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:local="clr-namespace:FancyZonesEditor.Styles">
<Style x:Key="GridLayoutPreviewStyle" TargetType="Border">
<Setter Property="Background" Value="{DynamicResource LayoutPreviewZoneBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource LayoutItemBackgroundBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="4" />
</Style>
<Style x:Key="GridLayoutPreviewActualSizeStyle"
TargetType="Border">
<Setter Property="Background" Value="{DynamicResource LayoutPreviewZoneBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource LayoutPreviewZoneBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius"
Value="4" />
</Style>
<Style x:Key="CanvasLayoutPreviewStyle"
TargetType="Border">
<Setter Property="Background" Value="{DynamicResource LayoutPreviewZoneBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource LayoutItemBackgroundBrush}" />
<Setter Property="BorderThickness" Value="10" />
<Setter Property="CornerRadius" Value="4" />
</Style>
<Style x:Key="CanvasLayoutPreviewActualSizeStyle"
TargetType="Border">
<Setter Property="Background" Value="{DynamicResource LayoutPreviewZoneBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource LayoutPreviewZoneBorderBrush}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="CornerRadius"
Value="4" />
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,27 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime">
<!-- Metadata -->
<system:String x:Key="Theme.Name">Dark.Accent1</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>
<system:String x:Key="Theme.DisplayName">Accent1 (Dark)</system:String>
<system:String x:Key="Theme.BaseColorScheme">Dark</system:String>
<system:String x:Key="Theme.ColorScheme">Accent1</system:String>
<Color x:Key="Theme.PrimaryAccentColor">Black</Color>
<SolidColorBrush x:Key="PrimaryBackgroundBrush" Color="#FF242424" />
<SolidColorBrush x:Key="SecondaryBackgroundBrush" Color="#FF1c1c1c" />
<SolidColorBrush x:Key="TertiaryBackgroundBrush" Color="#FF202020" />
<SolidColorBrush x:Key="PrimaryForegroundBrush" Color="#FFFFFFFF" />
<SolidColorBrush x:Key="SecondaryForegroundBrush" Color="#FF9a9a9a" />
<SolidColorBrush x:Key="BackdropBrush" Color="#88000000" />
<SolidColorBrush x:Key="TitleBarSecondaryForegroundBrush" Color="#FF9a9a9a" />
<SolidColorBrush x:Key="LayoutItemBackgroundBrush" Color="#FF3A3A3A" />
<SolidColorBrush x:Key="LayoutItemBackgroundPointerOverBrush" Color="#FF333333" />
<SolidColorBrush x:Key="LayoutPreviewZoneBackgroundBrush" Color="#BF1b1b1b" />
<SolidColorBrush x:Key="LayoutPreviewBackgroundBrush" Color="#331B1B1B" />
<SolidColorBrush x:Key="LayoutPreviewZoneBorderBrush" Color="#FF5a5a5a" />
<SolidColorBrush x:Key="CanvasZoneBackgroundBrush" Color="#BF1b1b1b"/>
<SolidColorBrush x:Key="GridZoneBackgroundBrush" Color="#E51b1b1b" />
</ResourceDictionary>

View File

@@ -0,0 +1,27 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime">
<!-- Metadata -->
<system:String x:Key="Theme.Name">HighContrast.Accent2</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>
<system:String x:Key="Theme.DisplayName">Accent2 (HighContrast)</system:String>
<system:String x:Key="Theme.BaseColorScheme">HighContrast</system:String>
<system:String x:Key="Theme.ColorScheme">Accent2</system:String>
<Color x:Key="Theme.PrimaryAccentColor">White</Color>
<SolidColorBrush x:Key="PrimaryBackgroundBrush" Color="#FF242424" />
<SolidColorBrush x:Key="SecondaryBackgroundBrush" Color="#FF1c1c1c" />
<SolidColorBrush x:Key="TertiaryBackgroundBrush" Color="#FF202020" />
<SolidColorBrush x:Key="PrimaryForegroundBrush" Color="#FFffff00" />
<SolidColorBrush x:Key="SecondaryForegroundBrush" Color="#FF00ff00" />
<SolidColorBrush x:Key="BackdropBrush" Color="#88000000" />
<SolidColorBrush x:Key="TitleBarSecondaryForegroundBrush" Color="#FF9a9a9a" />
<SolidColorBrush x:Key="LayoutItemBackgroundBrush" Color="#FF2b2b2b" />
<SolidColorBrush x:Key="LayoutItemBackgroundPointerOverBrush" Color="#FF333333" />
<SolidColorBrush x:Key="LayoutPreviewZoneBackgroundBrush" Color="#BF1b1b1b" />
<SolidColorBrush x:Key="LayoutPreviewBackgroundBrush" Color="#331B1B1B" />
<SolidColorBrush x:Key="LayoutPreviewZoneBorderBrush" Color="#FF1b1b1b" />
<SolidColorBrush x:Key="CanvasZoneBackgroundBrush" Color="#BF1b1b1b" />
<SolidColorBrush x:Key="GridZoneBackgroundBrush" Color="#E51b1b1b" />
</ResourceDictionary>

View File

@@ -0,0 +1,27 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime">
<!-- Metadata -->
<system:String x:Key="Theme.Name">HighContrast.Accent3</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>
<system:String x:Key="Theme.DisplayName">Accent3 (HighContrast)</system:String>
<system:String x:Key="Theme.BaseColorScheme">HighContrast</system:String>
<system:String x:Key="Theme.ColorScheme">Accent3</system:String>
<Color x:Key="Theme.PrimaryAccentColor">White</Color>
<SolidColorBrush x:Key="PrimaryBackgroundBrush" Color="#FF242424" />
<SolidColorBrush x:Key="SecondaryBackgroundBrush" Color="#FF1c1c1c" />
<SolidColorBrush x:Key="TertiaryBackgroundBrush" Color="#FF202020" />
<SolidColorBrush x:Key="PrimaryForegroundBrush" Color="#FFffff00" />
<SolidColorBrush x:Key="SecondaryForegroundBrush" Color="#FFc0c0c0" />
<SolidColorBrush x:Key="BackdropBrush" Color="#88000000" />
<SolidColorBrush x:Key="TitleBarSecondaryForegroundBrush" Color="#FF9a9a9a" />
<SolidColorBrush x:Key="LayoutItemBackgroundBrush" Color="#FF2b2b2b" />
<SolidColorBrush x:Key="LayoutItemBackgroundPointerOverBrush" Color="#FF333333" />
<SolidColorBrush x:Key="LayoutPreviewZoneBackgroundBrush" Color="#BF1b1b1b" />
<SolidColorBrush x:Key="LayoutPreviewBackgroundBrush" Color="#331B1B1B" />
<SolidColorBrush x:Key="LayoutPreviewZoneBorderBrush" Color="#FF1b1b1b" />
<SolidColorBrush x:Key="CanvasZoneBackgroundBrush" Color="#BF1b1b1b" />
<SolidColorBrush x:Key="GridZoneBackgroundBrush" Color="#E51b1b1b" />
</ResourceDictionary>

View File

@@ -0,0 +1,27 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime">
<!-- Metadata -->
<system:String x:Key="Theme.Name">HighContrast.Accent4</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>
<system:String x:Key="Theme.DisplayName">Accent4 (HighContrast)</system:String>
<system:String x:Key="Theme.BaseColorScheme">HighContrast</system:String>
<system:String x:Key="Theme.ColorScheme">Accent4</system:String>
<Color x:Key="Theme.PrimaryAccentColor">White</Color>
<SolidColorBrush x:Key="PrimaryBackgroundBrush" Color="#FF242424" />
<SolidColorBrush x:Key="SecondaryBackgroundBrush" Color="#FF1c1c1c" />
<SolidColorBrush x:Key="TertiaryBackgroundBrush" Color="#FF202020" />
<SolidColorBrush x:Key="PrimaryForegroundBrush" Color="#FFffffff" />
<SolidColorBrush x:Key="SecondaryForegroundBrush" Color="#FF1aebff" />
<SolidColorBrush x:Key="BackdropBrush" Color="#88000000" />
<SolidColorBrush x:Key="TitleBarSecondaryForegroundBrush" Color="#FF9a9a9a" />
<SolidColorBrush x:Key="LayoutItemBackgroundBrush" Color="#FF3A3A3A" />
<SolidColorBrush x:Key="LayoutItemBackgroundPointerOverBrush" Color="#FF333333" />
<SolidColorBrush x:Key="LayoutPreviewZoneBackgroundBrush" Color="#BF1b1b1b" />
<SolidColorBrush x:Key="LayoutPreviewBackgroundBrush" Color="#331B1B1B" />
<SolidColorBrush x:Key="LayoutPreviewZoneBorderBrush" Color="#FF5a5a5a" />
<SolidColorBrush x:Key="CanvasZoneBackgroundBrush" Color="#BF1b1b1b" />
<SolidColorBrush x:Key="GridZoneBackgroundBrush" Color="#E51b1b1b" />
</ResourceDictionary>

View File

@@ -0,0 +1,27 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime">
<!-- Metadata -->
<system:String x:Key="Theme.Name">HighContrast.Accent5</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>
<system:String x:Key="Theme.DisplayName">Accent5 (HighContrast)</system:String>
<system:String x:Key="Theme.BaseColorScheme">HighContrast</system:String>
<system:String x:Key="Theme.ColorScheme">Accent5</system:String>
<Color x:Key="Theme.PrimaryAccentColor">White</Color>
<SolidColorBrush x:Key="PrimaryBackgroundBrush" Color="#FFf9f9f9" />
<SolidColorBrush x:Key="SecondaryBackgroundBrush" Color="#FFeeeeee" />
<SolidColorBrush x:Key="TertiaryBackgroundBrush" Color="#FFF3F3F3" />
<SolidColorBrush x:Key="PrimaryForegroundBrush" Color="#FF000000" />
<SolidColorBrush x:Key="SecondaryForegroundBrush" Color="#FF37006e" />
<SolidColorBrush x:Key="BackdropBrush" Color="#88FFFFFF" />
<SolidColorBrush x:Key="TitleBarSecondaryForegroundBrush" Color="#FF949494" />
<SolidColorBrush x:Key="LayoutItemBackgroundBrush" Color="#FFffffff" />
<SolidColorBrush x:Key="LayoutItemBackgroundPointerOverBrush" Color="#FFf2f2f2" />
<SolidColorBrush x:Key="LayoutPreviewZoneBackgroundBrush" Color="#88cccccc" />
<SolidColorBrush x:Key="LayoutPreviewBackgroundBrush" Color="#19949494" />
<SolidColorBrush x:Key="LayoutPreviewZoneBorderBrush" Color="#9c9c9c" />
<SolidColorBrush x:Key="CanvasZoneBackgroundBrush" Color="#BFffffff" />
<SolidColorBrush x:Key="GridZoneBackgroundBrush" Color="#E5ffffff" />
</ResourceDictionary>

View File

@@ -0,0 +1,27 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=System.Runtime">
<!-- Metadata -->
<system:String x:Key="Theme.Name">Light.Accent1</system:String>
<system:String x:Key="Theme.Origin">PowerToysRun</system:String>
<system:String x:Key="Theme.DisplayName">Accent1 (Light)</system:String>
<system:String x:Key="Theme.BaseColorScheme">Light</system:String>
<system:String x:Key="Theme.ColorScheme">Accent1</system:String>
<Color x:Key="Theme.PrimaryAccentColor">White</Color>
<SolidColorBrush x:Key="PrimaryBackgroundBrush" Color="#FFF9F9F9" />
<SolidColorBrush x:Key="SecondaryBackgroundBrush" Color="#FFeeeeee" />
<SolidColorBrush x:Key="TertiaryBackgroundBrush" Color="#FFF3F3F3" />
<SolidColorBrush x:Key="PrimaryForegroundBrush" Color="#FF000000" />
<SolidColorBrush x:Key="SecondaryForegroundBrush" Color="#FF949494" />
<SolidColorBrush x:Key="BackdropBrush" Color="#88FFFFFF" />
<SolidColorBrush x:Key="TitleBarSecondaryForegroundBrush" Color="#FF949494" />
<SolidColorBrush x:Key="LayoutItemBackgroundBrush" Color="#FFffffff"/>
<SolidColorBrush x:Key="LayoutItemBackgroundPointerOverBrush" Color="#FFf2f2f2" />
<SolidColorBrush x:Key="LayoutPreviewZoneBackgroundBrush" Color="#88cccccc"/>
<SolidColorBrush x:Key="LayoutPreviewBackgroundBrush" Color="#19949494" />
<SolidColorBrush x:Key="LayoutPreviewZoneBorderBrush" Color="#9c9c9c" />
<SolidColorBrush x:Key="CanvasZoneBackgroundBrush" Color="#BFffffff"/>
<SolidColorBrush x:Key="GridZoneBackgroundBrush" Color="#E5ffffff" />
</ResourceDictionary>

View File

@@ -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)
{
}
/// <inheritdoc />
public override void FillColorSchemeValues(Dictionary<string, string> values, RuntimeThemeColorValues colorValues)
{
}
}
}

View File

@@ -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,
}
}

View File

@@ -4,7 +4,6 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using FancyZonesEditor.Utils;
namespace FancyZonesEditor.ViewModels
@@ -22,14 +21,6 @@ namespace FancyZonesEditor.ViewModels
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 @@ namespace FancyZonesEditor.ViewModels
double maxMultiplier = MaxPreviewDisplaySize / maxDimension;
double minMultiplier = MinPreviewDisplaySize / minDimension;
DesktopPreviewMultiplier = (minMultiplier + maxMultiplier) / 2;
DesktopPreviewMultiplier = (minMultiplier + maxMultiplier) / 3.5;
}
private void RaisePropertyChanged(string propertyName)

View File

@@ -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 @@
<Grid x:Name="Body">
<Rectangle Fill="White" Opacity="0.5"/>
<Rectangle Fill="White" Opacity="1"/>
<Grid x:Name="Window1" >
<Border BorderThickness="2" BorderBrush="Black">
@@ -25,7 +26,7 @@
<Thumb Background="Red" Height="36" VerticalAlignment="Top"/>
<Button Height="36" Width="36" VerticalAlignment="Top" Background="Red" FontFamily="Segoe UI Symbol" FontSize="16" Content="✖" HorizontalAlignment="Right"/>
-->
<Rectangle Fill="Black" Opacity="0.2"/>
<Rectangle Fill="Black" Opacity="1"/>
<!--
<Grid Width="24" Height="24" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,0,0">
<Grid.ColumnDefinitions>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B