Compare commits

...

6 Commits

Author SHA1 Message Date
Niels Laute
6220b91425 Updated brushes 2024-03-05 11:51:44 +01:00
Niels Laute
20e5bb52dc Merge branch 'main' into niels9001/fancyzones-wpfui 2024-02-14 14:49:03 +01:00
Niels Laute
aa150246e9 Moving to wpfui 2024-01-18 14:55:52 +01:00
Niels Laute
b5adf3a8cd Merge branch 'main' into niels9001/fancyzones-wpfui 2024-01-17 15:20:36 +01:00
Niels Laute
6f216a3c91 Fix 2023-12-04 15:26:11 +01:00
Niels Laute
f75a3a8ad0 Trying to port to WPfui 2023-12-04 15:25:28 +01:00
34 changed files with 3068 additions and 92 deletions

View File

@@ -90,7 +90,7 @@
<PackageVersion Include="Vanara.PInvoke.User32" Version="3.4.11" />
<PackageVersion Include="Vanara.PInvoke.Shell32" Version="3.4.11" />
<PackageVersion Include="WinUIEx" Version="2.2.0" />
<PackageVersion Include="WPF-UI" Version="3.0.0-preview.13" />
<PackageVersion Include="WPF-UI" Version="3.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(IsExperimentationLive)'!=''">
<!-- Additional dependencies used by experimentation -->

View File

@@ -2,18 +2,20 @@
x:Class="FancyZonesEditor.App"
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"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Exit="OnExit"
Startup="OnStartup">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemeResources />
<ui:XamlControlsResources />
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
<ResourceDictionary Source="pack://application:,,,/Styles/ButtonStyles.xaml" />
<ResourceDictionary Source="pack://application:,,,/Styles/GridViewStyles.xaml" />
<ResourceDictionary Source="pack://application:,,,/Styles/LayoutPreviewStyles.xaml" />
<ResourceDictionary Source="pack://application:,,,/Controls/GridView/ListView.xaml" />
<ResourceDictionary Source="pack://application:,,,/Controls/GridView/GridView.xaml" />
<ResourceDictionary Source="pack://application:,,,/Controls/ContentDialog/ContentDialog.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="HeadingTextBlock" TargetType="TextBlock" />

View File

@@ -0,0 +1,378 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FancyZonesEditor.Controls"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019">
<sys:Double x:Key="ContentDialogMinWidth">320</sys:Double>
<sys:Double x:Key="ContentDialogMaxWidth">548</sys:Double>
<sys:Double x:Key="ContentDialogMinHeight">184</sys:Double>
<sys:Double x:Key="ContentDialogMaxHeight">756</sys:Double>
<GridLength x:Key="ContentDialogButtonSpacing">8</GridLength>
<Thickness x:Key="ContentDialogTitleMargin">0,0,0,12</Thickness>
<Thickness x:Key="ContentDialogPadding">24</Thickness>
<Thickness x:Key="ContentDialogSeparatorThickness">0,0,0,1</Thickness>
<KeySpline x:Key="ControlFastOutSlowInKeySpline">0,0,0,1</KeySpline>
<KeyTime x:Key="ControlNormalAnimationDuration">00:00:00.250</KeyTime>
<KeyTime x:Key="ControlFastAnimationDuration">00:00:00.167</KeyTime>
<KeyTime x:Key="ControlFastAnimationAfterDuration">00:00:00.168</KeyTime>
<KeyTime x:Key="ControlFasterAnimationDuration">00:00:00.083</KeyTime>
<Style TargetType="local:ContentDialog">
<Setter Property="Foreground" Value="{DynamicResource ContentDialogForeground}" />
<Setter Property="Background" Value="{DynamicResource ContentDialogBackground}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{DynamicResource ContentDialogBorderBrush}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="IsShadowEnabled" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ContentDialog">
<Border x:Name="Container">
<VisualStateManager.CustomVisualStateManager>
<ui:SimpleVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<Grid
x:Name="LayoutRoot"
SnapsToDevicePixels="True"
Visibility="Collapsed">
<Rectangle x:Name="SmokeLayerBackground" Fill="{DynamicResource ContentDialogSmokeFill}" />
<Grid
x:Name="BackgroundElement"
MinWidth="320"
MinHeight="184"
MaxWidth="548"
MaxHeight="756"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FlowDirection="{TemplateBinding FlowDirection}"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<ScaleTransform x:Name="ScaleTransform" />
</Grid.RenderTransform>
<ui:ThemeShadowChrome
x:Name="Shdw"
Margin="1"
CornerRadius="{TemplateBinding CornerRadius}"
IsShadowEnabled="{TemplateBinding IsShadowEnabled}" />
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
ClipToBounds="True"
CornerRadius="{TemplateBinding CornerRadius}">
<Border x:Name="DialogSpace">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer
x:Name="ContentScrollViewer"
HorizontalScrollBarVisibility="Disabled"
IsTabStop="False"
VerticalScrollBarVisibility="Disabled">
<Border
Padding="24"
Background="{DynamicResource ContentDialogTopOverlay}"
BorderBrush="{DynamicResource ContentDialogSeparatorBorderBrush}"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl
x:Name="Title"
Margin="{StaticResource ContentDialogTitleMargin}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="{TemplateBinding Title}"
ContentTemplate="{TemplateBinding TitleTemplate}"
FontSize="20"
FontWeight="Normal"
Foreground="{TemplateBinding Foreground}"
IsTabStop="False"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
<ContentPresenter
x:Name="Content"
Grid.Row="1"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</Border>
</ScrollViewer>
<Grid
x:Name="CommandSpace"
Grid.Row="1"
Margin="{StaticResource ContentDialogPadding}"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Background="{TemplateBinding Background}"
KeyboardNavigation.DirectionalNavigation="Contained">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="PrimaryColumn" Width="*" />
<ColumnDefinition x:Name="FirstSpacer" Width="0" />
<ColumnDefinition x:Name="SecondaryColumn" Width="0" />
<ColumnDefinition x:Name="SecondSpacer" Width="8" />
<ColumnDefinition x:Name="CloseColumn" Width="*" />
</Grid.ColumnDefinitions>
<Button
x:Name="PrimaryButton"
HorizontalAlignment="Stretch"
Content="{TemplateBinding PrimaryButtonText}"
IsEnabled="{TemplateBinding IsPrimaryButtonEnabled}"
Style="{TemplateBinding PrimaryButtonStyle}" />
<Button
x:Name="SecondaryButton"
HorizontalAlignment="Stretch"
Content="{TemplateBinding SecondaryButtonText}"
IsEnabled="{TemplateBinding IsSecondaryButtonEnabled}"
Style="{TemplateBinding SecondaryButtonStyle}" />
<Button
x:Name="CloseButton"
Grid.Column="4"
HorizontalAlignment="Stretch"
Content="{TemplateBinding CloseButtonText}"
Style="{TemplateBinding CloseButtonStyle}" />
</Grid>
</Grid>
</Border>
</Border>
</Grid>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DialogShowingStates">
<VisualStateGroup.Transitions>
<VisualTransition To="DialogHidden">
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="SnapsToDevicePixels">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" />
</BooleanAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="IsHitTestVisible">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" />
</BooleanAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ScaleTransform" Storyboard.TargetProperty="ScaleX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
<SplineDoubleKeyFrame
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
KeyTime="{StaticResource ControlFastAnimationDuration}"
Value="1.05" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ScaleTransform" Storyboard.TargetProperty="ScaleY">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
<SplineDoubleKeyFrame
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
KeyTime="{StaticResource ControlFasterAnimationDuration}"
Value="1.05" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Opacity">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="0.0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition To="DialogShowing">
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="SnapsToDevicePixels">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False" />
</BooleanAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ScaleTransform" Storyboard.TargetProperty="ScaleX">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.05" />
<SplineDoubleKeyFrame
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
KeyTime="{StaticResource ControlNormalAnimationDuration}"
Value="1.0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ScaleTransform" Storyboard.TargetProperty="ScaleY">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.05" />
<SplineDoubleKeyFrame
KeySpline="{StaticResource ControlFastOutSlowInKeySpline}"
KeyTime="{StaticResource ControlNormalAnimationDuration}"
Value="1.0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Opacity">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="0.0" />
<LinearDoubleKeyFrame KeyTime="{StaticResource ControlFasterAnimationDuration}" Value="1.0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="DialogHidden" />
<VisualState x:Name="DialogShowing">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="(KeyboardNavigation.TabNavigation)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static KeyboardNavigationMode.Cycle}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="DialogShowingWithoutSmokeLayer">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Null}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DialogSizingStates">
<VisualState x:Name="DefaultDialogSizing" />
<VisualState x:Name="FullDialogSizing">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="VerticalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static VerticalAlignment.Stretch}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ButtonsVisibilityStates">
<VisualState x:Name="AllVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FirstSpacer" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource ContentDialogButtonSpacing}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SecondaryColumn" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<GridLength>*</GridLength>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<Int32AnimationUsingKeyFrames Storyboard.TargetName="SecondaryButton" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteInt32KeyFrame KeyTime="0:0:0" Value="2" />
</Int32AnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="NoneVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CommandSpace" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PrimaryVisible">
<Storyboard>
<Int32AnimationUsingKeyFrames Storyboard.TargetName="PrimaryButton" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteInt32KeyFrame KeyTime="0:0:0" Value="4" />
</Int32AnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SecondaryButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CloseButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="SecondaryVisible">
<Storyboard>
<Int32AnimationUsingKeyFrames Storyboard.TargetName="SecondaryButton" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteInt32KeyFrame KeyTime="0:0:0" Value="4" />
</Int32AnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PrimaryButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CloseButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="CloseVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PrimaryButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SecondaryButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PrimaryAndSecondaryVisible">
<Storyboard>
<Int32AnimationUsingKeyFrames Storyboard.TargetName="SecondaryButton" Storyboard.TargetProperty="(Grid.Column)">
<DiscreteInt32KeyFrame KeyTime="0:0:0" Value="4" />
</Int32AnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CloseButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PrimaryAndCloseVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SecondaryButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="SecondaryAndCloseVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PrimaryButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DefaultButtonStates">
<VisualState x:Name="NoDefaultButton" />
<VisualState x:Name="PrimaryAsDefaultButton" />
<VisualState x:Name="SecondaryAsDefaultButton" />
<VisualState x:Name="CloseAsDefaultButton" />
</VisualStateGroup>
<VisualStateGroup x:Name="DialogBorderStates">
<VisualState x:Name="NoBorder" />
<VisualState x:Name="AccentColorBorder">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Red" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsShadowEnabled" Value="False">
<Setter TargetName="Shdw" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="DefaultButton" Value="Primary">
<!--<Setter TargetName="PrimaryButton" Property="Style" Value="{DynamicResource AccentButtonStyle}" />-->
</Trigger>
<Trigger Property="DefaultButton" Value="Secondary">
<!--<Setter TargetName="SecondaryButton" Property="Style" Value="{DynamicResource AccentButtonStyle}" />-->
</Trigger>
<Trigger Property="DefaultButton" Value="Close">
<!--<Setter TargetName="CloseButton" Property="Style" Value="{DynamicResource AccentButtonStyle}" />-->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,14 @@
// 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.
namespace FancyZonesEditor.Controls
{
public enum ContentDialogButton
{
None = 0,
Primary = 1,
Secondary = 2,
Close = 3,
}
}

View File

@@ -0,0 +1,23 @@
// 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;
namespace FancyZonesEditor.Controls
{
public sealed class ContentDialogButtonClickDeferral
{
private readonly Action _handler;
internal ContentDialogButtonClickDeferral(Action handler)
{
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
public void Complete()
{
_handler();
}
}
}

View File

@@ -0,0 +1,50 @@
// 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.Diagnostics;
namespace FancyZonesEditor.Controls
{
public class ContentDialogButtonClickEventArgs : EventArgs
{
private ContentDialogButtonClickDeferral _deferral;
private int _deferralCount;
internal ContentDialogButtonClickEventArgs()
{
}
public bool Cancel { get; set; }
public ContentDialogButtonClickDeferral GetDeferral()
{
_deferralCount++;
return new ContentDialogButtonClickDeferral(() =>
{
DecrementDeferralCount();
});
}
internal void SetDeferral(ContentDialogButtonClickDeferral deferral)
{
_deferral = deferral;
}
internal void DecrementDeferralCount()
{
_deferralCount--;
if (_deferralCount == 0)
{
_deferral.Complete();
}
}
internal void IncrementDeferralCount()
{
_deferralCount++;
}
}
}

View File

@@ -0,0 +1,18 @@
// 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;
namespace FancyZonesEditor.Controls
{
public class ContentDialogClosedEventArgs : EventArgs
{
internal ContentDialogClosedEventArgs(ContentDialogResult result)
{
Result = result;
}
public ContentDialogResult Result { get; }
}
}

View File

@@ -0,0 +1,23 @@
// 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;
namespace FancyZonesEditor.Controls
{
public sealed class ContentDialogClosingDeferral
{
private readonly Action _handler;
internal ContentDialogClosingDeferral(Action handler)
{
_handler = handler ?? throw new ArgumentNullException(nameof(handler));
}
public void Complete()
{
_handler();
}
}
}

View File

@@ -0,0 +1,53 @@
// 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.Diagnostics;
namespace FancyZonesEditor.Controls
{
public sealed class ContentDialogClosingEventArgs : EventArgs
{
private ContentDialogClosingDeferral _deferral;
private int _deferralCount;
internal ContentDialogClosingEventArgs(ContentDialogResult result)
{
Result = result;
}
public bool Cancel { get; set; }
public ContentDialogResult Result { get; }
public ContentDialogClosingDeferral GetDeferral()
{
_deferralCount++;
return new ContentDialogClosingDeferral(() =>
{
DecrementDeferralCount();
});
}
internal void SetDeferral(ContentDialogClosingDeferral deferral)
{
_deferral = deferral;
}
internal void DecrementDeferralCount()
{
_deferralCount--;
if (_deferralCount == 0)
{
_deferral.Complete();
}
}
internal void IncrementDeferralCount()
{
_deferralCount++;
}
}
}

View File

@@ -0,0 +1,15 @@
// 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;
namespace FancyZonesEditor.Controls
{
public class ContentDialogOpenedEventArgs : EventArgs
{
internal ContentDialogOpenedEventArgs()
{
}
}
}

View File

@@ -0,0 +1,12 @@
// 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.
namespace FancyZonesEditor.Controls
{
public enum ContentDialogPlacement
{
Popup = 0,
InPlace = 1,
}
}

View File

@@ -0,0 +1,13 @@
// 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.
namespace FancyZonesEditor.Controls
{
public enum ContentDialogResult
{
None = 0,
Primary = 1,
Secondary = 2,
}
}

View File

@@ -0,0 +1,17 @@
// 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.
namespace FancyZonesEditor.Controls
{
#pragma warning disable SA1622 // Generic type parameter documentation should have text
/// <summary>
/// Represents a method that handles general events.
/// </summary>
/// <typeparam name="TSender"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="sender">The event source.</param>
/// <param name="args">The event data. If there is no event data, this parameter will be null.</param>
public delegate void TypedEventHandler<TSender, TResult>(TSender sender, TResult args);
#pragma warning restore SA1622 // Generic type parameter documentation should have text
}

View File

@@ -0,0 +1,230 @@
// 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.Windows;
using System.Windows.Media;
namespace FancyZonesEditor.Controls
{
/// <summary>
/// Defines a collection of extensions methods for UI.
/// </summary>
public static class VisualTree
{
/// <summary>
/// Find descendant <see cref="FrameworkElement"/> control using its name.
/// </summary>
/// <param name="element">Parent element.</param>
/// <param name="name">Name of the control to find</param>
/// <returns>Descendant control or null if not found.</returns>
public static FrameworkElement FindDescendantByName(this DependencyObject element, string name)
{
if (element == null || string.IsNullOrWhiteSpace(name))
{
return null;
}
if (name.Equals((element as FrameworkElement)?.Name, StringComparison.OrdinalIgnoreCase))
{
return element as FrameworkElement;
}
var childCount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < childCount; i++)
{
var result = VisualTreeHelper.GetChild(element, i).FindDescendantByName(name);
if (result != null)
{
return result;
}
}
return null;
}
/// <summary>
/// Find first descendant control of a specified type.
/// </summary>
/// <typeparam name="T">Type to search for.</typeparam>
/// <param name="element">Parent element.</param>
/// <returns>Descendant control or null if not found.</returns>
public static T FindDescendant<T>(this DependencyObject element)
where T : DependencyObject
{
T retValue = null;
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
for (var i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(element, i);
var type = child as T;
if (type != null)
{
retValue = type;
break;
}
retValue = child.FindDescendant<T>();
if (retValue != null)
{
break;
}
}
return retValue;
}
/// <summary>
/// Find first descendant control of a specified type.
/// </summary>
/// <param name="element">Parent element.</param>
/// <param name="type">Type of descendant.</param>
/// <returns>Descendant control or null if not found.</returns>
public static object FindDescendant(this DependencyObject element, Type type)
{
object retValue = null;
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
for (var i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(element, i);
if (child.GetType() == type)
{
retValue = child;
break;
}
retValue = child.FindDescendant(type);
if (retValue != null)
{
break;
}
}
return retValue;
}
/// <summary>
/// Find all descendant controls of the specified type.
/// </summary>
/// <typeparam name="T">Type to search for.</typeparam>
/// <param name="element">Parent element.</param>
/// <returns>Descendant controls or empty if not found.</returns>
public static IEnumerable<T> FindDescendants<T>(this DependencyObject element)
where T : DependencyObject
{
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
for (var i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(element, i);
var type = child as T;
if (type != null)
{
yield return type;
}
foreach (T childofChild in child.FindDescendants<T>())
{
yield return childofChild;
}
}
}
/// <summary>
/// Find visual ascendant <see cref="FrameworkElement"/> control using its name.
/// </summary>
/// <param name="element">Parent element.</param>
/// <param name="name">Name of the control to find</param>
/// <returns>Descendant control or null if not found.</returns>
public static FrameworkElement FindAscendantByName(this DependencyObject element, string name)
{
if (element == null || string.IsNullOrWhiteSpace(name))
{
return null;
}
var parent = VisualTreeHelper.GetParent(element);
if (parent == null)
{
return null;
}
if (name.Equals((parent as FrameworkElement)?.Name, StringComparison.OrdinalIgnoreCase))
{
return parent as FrameworkElement;
}
return parent.FindAscendantByName(name);
}
/// <summary>
/// Find first visual ascendant control of a specified type.
/// </summary>
/// <typeparam name="T">Type to search for.</typeparam>
/// <param name="element">Child element.</param>
/// <returns>Ascendant control or null if not found.</returns>
public static T FindAscendant<T>(this DependencyObject element)
where T : DependencyObject
{
var parent = VisualTreeHelper.GetParent(element);
if (parent == null)
{
return null;
}
if (parent is T)
{
return parent as T;
}
return parent.FindAscendant<T>();
}
/// <summary>
/// Find first visual ascendant control of a specified type.
/// </summary>
/// <param name="element">Child element.</param>
/// <param name="type">Type of ascendant to look for.</param>
/// <returns>Ascendant control or null if not found.</returns>
public static object FindAscendant(this DependencyObject element, Type type)
{
var parent = VisualTreeHelper.GetParent(element);
if (parent == null)
{
return null;
}
if (parent.GetType() == type)
{
return parent;
}
return parent.FindAscendant(type);
}
/// <summary>
/// Find all visual ascendants for the element.
/// </summary>
/// <param name="element">Child element.</param>
/// <returns>A collection of parent elements or null if none found.</returns>
public static IEnumerable<DependencyObject> FindAscendants(this DependencyObject element)
{
var parent = VisualTreeHelper.GetParent(element);
while (parent != null)
{
yield return parent;
parent = VisualTreeHelper.GetParent(parent);
}
}
}
}

View File

@@ -0,0 +1,30 @@
// 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.Windows;
namespace FancyZonesEditor.Controls
{
public class GridView : ListViewBase
{
static GridView()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridView), new FrameworkPropertyMetadata(typeof(GridView)));
}
public GridView()
{
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is GridViewItem;
}
protected override DependencyObject GetContainerForItemOverride()
{
return new GridViewItem();
}
}
}

View File

@@ -0,0 +1,183 @@
<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.Controls">
<Style TargetType="local:GridViewItem">
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="{DynamicResource GridViewItemBackground}" />
<Setter Property="Foreground" Value="{DynamicResource GridViewItemForeground}" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="Local" />
<!--<Setter Property="IsHoldingEnabled" Value="True" />-->
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,4,4" />
<Setter Property="MinWidth" Value="{DynamicResource GridViewItemMinWidth}" />
<Setter Property="MinHeight" Value="{DynamicResource GridViewItemMinHeight}" />
<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-2" />
<Setter Property="FocusVisualPrimaryBrush" Value="{DynamicResource GridViewItemFocusVisualPrimaryBrush}" />
<Setter Property="FocusVisualPrimaryThickness" Value="2" />
<Setter Property="FocusVisualSecondaryBrush" Value="{DynamicResource GridViewItemFocusVisualSecondaryBrush}" />
<Setter Property="FocusVisualSecondaryThickness" Value="1" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:GridViewItem">
<ControlTemplate.Resources>
<StreamGeometry x:Key="CheckMark">M 17.939453 5.439453 L 7.5 15.888672 L 2.060547 10.439453 L 2.939453 9.560547 L 7.5 14.111328 L 17.060547 4.560547 Z</StreamGeometry>
</ControlTemplate.Resources>
<Border
x:Name="ContentBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<VisualStateManager.CustomVisualStateManager>
<ui:SimpleVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<Grid>
<ContentPresenter
x:Name="ContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Rectangle
x:Name="BorderRectangle"
IsHitTestVisible="False"
Stroke="{DynamicResource SystemControlHighlightListAccentLowBrush}"
StrokeThickness="2"
Opacity="0" />
<Border
x:Name="MultiSelectSquare"
Background="{DynamicResource GridViewItemCheckBoxBrush}"
Width="20"
Height="20"
Margin="0,2,2,0"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Visibility="Collapsed">
<!--<ui:FontIconFallback
x:Name="MultiSelectCheck"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
Data="{StaticResource CheckMark}"
FontSize="16"
Foreground="{DynamicResource GridViewItemCheckBrush}"
Opacity="0" />-->
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<!-- Focused -->
<!--<Trigger Property="ui:FocusVisualHelper.ShowFocusVisual" Value="True">
<Setter TargetName="BorderRectangle" Property="Visibility" Value="Collapsed" />
</Trigger>-->
<!-- PointerOver -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="BorderRectangle" Property="Opacity" Value="1" />
<Setter TargetName="BorderRectangle" Property="Stroke" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource GridViewItemForegroundPointerOver}" />
<Setter Property="FocusVisualSecondaryBrush" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
<Setter Property="FocusVisualSecondaryThickness" Value="2" />
</MultiTrigger>
<!-- Selected -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="BorderRectangle" Property="Opacity" Value="1" />
<Setter TargetName="BorderRectangle" Property="Stroke" Value="{DynamicResource SystemControlHighlightAccentBrush}" />
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource GridViewItemForegroundSelected}" />
<Setter Property="FocusVisualSecondaryBrush" Value="{DynamicResource SystemControlHighlightAccentBrush}" />
<Setter Property="FocusVisualSecondaryThickness" Value="2" />
<Setter TargetName="MultiSelectSquare" Property="Background" Value="{DynamicResource SystemControlHighlightAccentBrush}" />
</MultiTrigger>
<!-- PointerOverSelected -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="BorderRectangle" Property="Opacity" Value="1" />
<Setter TargetName="BorderRectangle" Property="Stroke" Value="{DynamicResource SystemControlHighlightListAccentMediumBrush}" />
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource GridViewItemForegroundSelected}" />
<Setter Property="FocusVisualSecondaryBrush" Value="{DynamicResource SystemControlHighlightListAccentMediumBrush}" />
<Setter Property="FocusVisualSecondaryThickness" Value="2" />
<Setter TargetName="MultiSelectSquare" Property="Background" Value="{DynamicResource SystemControlHighlightAccentBrush}" />
</MultiTrigger>
<!-- Disabled -->
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="ContentBorder" Property="Opacity" Value="{DynamicResource ListViewItemDisabledThemeOpacity}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:GridView">
<Setter Property="Padding" Value="0,0,0,10" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="Once" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-2" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:GridView">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
SnapsToDevicePixels="True">
<ScrollViewer
x:Name="ScrollViewer"
KeyboardNavigation.TabNavigation="{TemplateBinding KeyboardNavigation.TabNavigation}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
Focusable="false">
<ItemsPresenter
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,16 @@
// 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.Windows;
namespace FancyZonesEditor.Controls
{
public class GridViewItem : ListViewBaseItem
{
static GridViewItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridViewItem), new FrameworkPropertyMetadata(typeof(GridViewItem)));
}
}
}

View File

@@ -0,0 +1,21 @@
// 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.Windows;
namespace FancyZonesEditor.Controls
{
public delegate void ItemClickEventHandler(object sender, ItemClickEventArgs e);
#pragma warning disable SA1649 // File name should match first type name
public sealed class ItemClickEventArgs : RoutedEventArgs
#pragma warning restore SA1649 // File name should match first type name
{
public ItemClickEventArgs()
{
}
public object ClickedItem { get; internal set; }
}
}

View File

@@ -0,0 +1,30 @@
// 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.Windows;
namespace FancyZonesEditor.Controls
{
public class ListView : ListViewBase
{
static ListView()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(typeof(ListView)));
}
public ListView()
{
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is ListViewItem;
}
protected override DependencyObject GetContainerForItemOverride()
{
return new ListViewItem();
}
}
}

View File

@@ -0,0 +1,181 @@
<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.Controls">
<Style TargetType="local:ListViewItem">
<Setter Property="FontFamily" Value="{DynamicResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="Local" />
<!--<Setter Property="IsHoldingEnabled" Value="True" />-->
<Setter Property="Padding" Value="12,0,12,0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="MinWidth" Value="{DynamicResource ListViewItemMinWidth}" />
<Setter Property="MinHeight" Value="{DynamicResource ListViewItemMinHeight}" />
<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="0" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ListViewItem">
<Border
x:Name="ContentBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
SnapsToDevicePixels="True">
<VisualStateManager.CustomVisualStateManager>
<ui:SimpleVisualStateManager />
</VisualStateManager.CustomVisualStateManager>
<Grid>
<Rectangle
x:Name="BorderBackground"
IsHitTestVisible="False"
Fill="{DynamicResource ListViewItemBorderBackground}"
Opacity="0" />
<Grid
x:Name="ContentPresenterGrid"
Background="Transparent"
Margin="0,0,0,0">
<Grid.RenderTransform>
<TranslateTransform x:Name="ContentPresenterTranslateTransform" />
</Grid.RenderTransform>
<ContentPresenter
x:Name="ContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
<Border
x:Name="MultiSelectSquare"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumHighBrush}"
BorderThickness="2"
Width="20"
Height="20"
Margin="12,0,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Visibility="Collapsed">
<Border.Clip>
<RectangleGeometry Rect="0,0,20,20">
<RectangleGeometry.Transform>
<TranslateTransform x:Name="MultiSelectClipTransform" />
</RectangleGeometry.Transform>
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<TranslateTransform x:Name="MultiSelectCheckBoxTransform" />
</Border.RenderTransform>
<!--<ui:FontIconFallback
x:Name="MultiSelectCheck"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
Data="{StaticResource CheckMark}"
FontSize="16"
Foreground="{DynamicResource ListViewItemCheckBrush}"
Visibility="Collapsed"
Opacity="0" />-->
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="BorderBackground" Property="Opacity" Value="1" />
<Setter TargetName="BorderBackground" Property="Fill" Value="{DynamicResource SystemControlHighlightListLowBrush}" />
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource SystemControlHighlightAltBaseHighBrush}" />
<Setter TargetName="MultiSelectSquare" Property="BorderBrush" Value="{DynamicResource SystemControlHighlightAltBaseHighBrush}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="BorderBackground" Property="Opacity" Value="1" />
<Setter TargetName="BorderBackground" Property="Fill" Value="{DynamicResource SystemControlHighlightListAccentLowBrush}" />
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource SystemControlHighlightAltBaseHighBrush}" />
<Setter TargetName="MultiSelectSquare" Property="BorderBrush" Value="{DynamicResource SystemControlHighlightAltBaseHighBrush}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="BorderBackground" Property="Opacity" Value="1" />
<Setter TargetName="BorderBackground" Property="Fill" Value="{DynamicResource SystemControlHighlightListAccentMediumBrush}" />
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource SystemControlHighlightAltBaseHighBrush}" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="ContentBorder" Property="Opacity" Value="{DynamicResource ListViewItemDisabledThemeOpacity}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:ListView">
<Setter Property="Padding" Value="0,0,0,10" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="Once" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ListView">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
SnapsToDevicePixels="True">
<ScrollViewer
x:Name="ScrollViewer"
KeyboardNavigation.TabNavigation="{TemplateBinding KeyboardNavigation.TabNavigation}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
Focusable="false">
<ItemsPresenter
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,183 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Windows;
using System.Windows.Controls;
using ModernWpf.Controls.Primitives;
namespace FancyZonesEditor.Controls
{
public class ListViewBase : ListBox
{
static ListViewBase()
{
SelectionModeProperty.OverrideMetadata(typeof(ListViewBase), new FrameworkPropertyMetadata(OnSelectionModePropertyChanged));
}
protected ListViewBase()
{
UpdateMultiSelectEnabled();
}
public static readonly DependencyProperty IsItemClickEnabledProperty =
DependencyProperty.Register(
nameof(IsItemClickEnabled),
typeof(bool),
typeof(ListViewBase),
new PropertyMetadata(false));
public bool IsItemClickEnabled
{
get => (bool)GetValue(IsItemClickEnabledProperty);
set => SetValue(IsItemClickEnabledProperty, value);
}
public static readonly DependencyProperty IsSelectionEnabledProperty =
DependencyProperty.Register(
nameof(IsSelectionEnabled),
typeof(bool),
typeof(ListViewBase),
new PropertyMetadata(true, OnIsSelectionEnabledChanged));
public bool IsSelectionEnabled
{
get => (bool)GetValue(IsSelectionEnabledProperty);
set => SetValue(IsSelectionEnabledProperty, value);
}
private static void OnIsSelectionEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var lvb = (ListViewBase)d;
lvb.UpdateMultiSelectEnabled();
if (!(bool)e.NewValue)
{
if (lvb.SelectedItems.Count > 0)
{
lvb.UnselectAll();
}
}
}
public static readonly DependencyProperty IsMultiSelectCheckBoxEnabledProperty =
DependencyProperty.Register(
nameof(IsMultiSelectCheckBoxEnabled),
typeof(bool),
typeof(ListViewBase),
new PropertyMetadata(true, OnIsMultiSelectCheckBoxEnabledChanged));
public bool IsMultiSelectCheckBoxEnabled
{
get => (bool)GetValue(IsMultiSelectCheckBoxEnabledProperty);
set => SetValue(IsMultiSelectCheckBoxEnabledProperty, value);
}
private static void OnIsMultiSelectCheckBoxEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ListViewBase)d).UpdateMultiSelectEnabled();
}
public static readonly DependencyProperty UseSystemFocusVisualsProperty =
FocusVisualHelper.UseSystemFocusVisualsProperty.AddOwner(typeof(ListViewBase));
public bool UseSystemFocusVisuals
{
get => (bool)GetValue(UseSystemFocusVisualsProperty);
set => SetValue(UseSystemFocusVisualsProperty, value);
}
public static readonly DependencyProperty FocusVisualMarginProperty =
FocusVisualHelper.FocusVisualMarginProperty.AddOwner(typeof(ListViewBase));
public Thickness FocusVisualMargin
{
get => (Thickness)GetValue(FocusVisualMarginProperty);
set => SetValue(FocusVisualMarginProperty, value);
}
public static readonly DependencyProperty CornerRadiusProperty =
ControlHelper.CornerRadiusProperty.AddOwner(typeof(ListViewBase));
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
internal bool MultiSelectEnabled
{
get => multiSelectEnabled;
set
{
if (multiSelectEnabled != value)
{
multiSelectEnabled = value;
MultiSelectEnabledChanged?.Invoke(this, EventArgs.Empty);
}
}
}
public event ItemClickEventHandler ItemClick;
internal event EventHandler MultiSelectEnabledChanged;
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
if (element is ListViewBaseItem lvi)
{
lvi.SubscribeToMultiSelectEnabledChanged(this);
}
}
protected override void ClearContainerForItemOverride(DependencyObject element, object item)
{
base.ClearContainerForItemOverride(element, item);
if (element is ListViewBaseItem lvi)
{
lvi.UnsubscribeFromMultiSelectEnabledChanged(this);
}
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
if (IsSelectionEnabled)
{
base.OnSelectionChanged(e);
}
else
{
if (SelectedItems.Count > 0)
{
UnselectAll();
}
}
}
internal void NotifyListItemClicked(ListViewBaseItem item)
{
if (IsItemClickEnabled)
{
var clickedItem = ItemContainerGenerator.ItemFromContainer(item);
ItemClick?.Invoke(this, new ItemClickEventArgs { ClickedItem = clickedItem });
}
}
private static void OnSelectionModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ListViewBase)d).UpdateMultiSelectEnabled();
}
private void UpdateMultiSelectEnabled()
{
MultiSelectEnabled = IsSelectionEnabled &&
SelectionMode == SelectionMode.Multiple &&
IsMultiSelectCheckBoxEnabled;
}
private bool multiSelectEnabled;
}
}

View File

@@ -0,0 +1,181 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using ModernWpf.Controls.Primitives;
namespace FancyZonesEditor.Controls
{
public class ListViewBaseItem : ListBoxItem
{
protected ListViewBaseItem()
{
}
public static readonly DependencyProperty UseSystemFocusVisualsProperty =
FocusVisualHelper.UseSystemFocusVisualsProperty.AddOwner(typeof(ListViewBaseItem));
public bool UseSystemFocusVisuals
{
get => (bool)GetValue(UseSystemFocusVisualsProperty);
set => SetValue(UseSystemFocusVisualsProperty, value);
}
public static readonly DependencyProperty FocusVisualMarginProperty =
FocusVisualHelper.FocusVisualMarginProperty.AddOwner(typeof(ListViewBaseItem));
public Thickness FocusVisualMargin
{
get => (Thickness)GetValue(FocusVisualMarginProperty);
set => SetValue(FocusVisualMarginProperty, value);
}
public static readonly DependencyProperty FocusVisualPrimaryBrushProperty =
FocusVisualHelper.FocusVisualPrimaryBrushProperty.AddOwner(typeof(ListViewBaseItem));
public Thickness FocusVisualPrimaryBrush
{
get => (Thickness)GetValue(FocusVisualPrimaryBrushProperty);
set => SetValue(FocusVisualPrimaryBrushProperty, value);
}
public static readonly DependencyProperty FocusVisualPrimaryThicknessProperty =
FocusVisualHelper.FocusVisualPrimaryThicknessProperty.AddOwner(typeof(ListViewBaseItem));
public Thickness FocusVisualPrimaryThickness
{
get => (Thickness)GetValue(FocusVisualPrimaryThicknessProperty);
set => SetValue(FocusVisualPrimaryThicknessProperty, value);
}
public static readonly DependencyProperty FocusVisualSecondaryBrushProperty =
FocusVisualHelper.FocusVisualSecondaryBrushProperty.AddOwner(typeof(ListViewBaseItem));
public Thickness FocusVisualSecondaryBrush
{
get => (Thickness)GetValue(FocusVisualSecondaryBrushProperty);
set => SetValue(FocusVisualSecondaryBrushProperty, value);
}
public static readonly DependencyProperty FocusVisualSecondaryThicknessProperty =
FocusVisualHelper.FocusVisualSecondaryThicknessProperty.AddOwner(typeof(ListViewBaseItem));
public Thickness FocusVisualSecondaryThickness
{
get => (Thickness)GetValue(FocusVisualSecondaryThicknessProperty);
set => SetValue(FocusVisualSecondaryThicknessProperty, value);
}
public static readonly DependencyProperty CornerRadiusProperty =
ControlHelper.CornerRadiusProperty.AddOwner(typeof(ListViewBaseItem));
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
UpdateMultiSelectStates(ParentListViewBase, false);
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (!e.Handled)
{
isPressed = true;
}
base.OnMouseLeftButtonDown(e);
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
if (!e.Handled)
{
HandleMouseUp(e);
isPressed = false;
}
base.OnMouseLeftButtonUp(e);
}
protected override void OnMouseLeave(MouseEventArgs e)
{
if (!e.Handled)
{
isPressed = false;
}
base.OnMouseLeave(e);
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Enter)
{
OnClick();
e.Handled = true;
}
}
internal void SubscribeToMultiSelectEnabledChanged(ListViewBase parent)
{
parent.MultiSelectEnabledChanged += OnMultiSelectEnabledChanged;
UpdateMultiSelectStates(parent);
}
internal void UnsubscribeFromMultiSelectEnabledChanged(ListViewBase parent)
{
parent.MultiSelectEnabledChanged -= OnMultiSelectEnabledChanged;
UpdateMultiSelectStates(parent);
}
private void OnMultiSelectEnabledChanged(object sender, EventArgs e)
{
UpdateMultiSelectStates((ListViewBase)sender);
}
private void UpdateMultiSelectStates(ListViewBase parent, bool useTransitions = true)
{
if (parent != null)
{
bool enabled = parent.MultiSelectEnabled && parent.IsMultiSelectCheckBoxEnabled;
VisualStateManager.GoToState(this, enabled ? "MultiSelectEnabled" : "MultiSelectDisabled", useTransitions);
}
}
private void HandleMouseUp(MouseButtonEventArgs e)
{
if (isPressed)
{
#pragma warning disable SA1129 // Do not use default value type constructor
Rect r = new Rect(new Point(), RenderSize);
#pragma warning restore SA1129 // Do not use default value type constructor
if (r.Contains(e.GetPosition(this)))
{
OnClick();
}
}
}
private void OnClick()
{
ParentListViewBase?.NotifyListItemClicked(this);
}
private ListViewBase ParentListViewBase => ItemsControl.ItemsControlFromItemContainer(this) as ListViewBase;
private bool isPressed;
}
}

View File

@@ -0,0 +1,16 @@
// 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.Windows;
namespace FancyZonesEditor.Controls
{
public class ListViewItem : ListViewBaseItem
{
static ListViewItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ListViewItem), new FrameworkPropertyMetadata(typeof(ListViewItem)));
}
}
}

View File

@@ -0,0 +1,17 @@
// 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.Linq;
using System.Windows;
namespace FancyZonesEditor.Controls
{
internal static class SharedHelpers
{
public static Window GetActiveWindow()
{
return Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
}
}
}

View File

@@ -0,0 +1,91 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<AssemblyTitle>PowerToys.FancyZonesEditor</AssemblyTitle>
<AssemblyDescription>PowerToys FancyZones Editor</AssemblyDescription>
<Description>PowerToys FancyZones Editor</Description>
<Version>$(Version).0</Version>
<OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<OutputPath>..\..\..\..\..\$(Platform)\$(Configuration)</OutputPath>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<ProjectGuid>{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}</ProjectGuid>
<TargetFramework>net8.0-windows10.0.20348.0</TargetFramework>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<Optimize>false</Optimize>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>images\FancyZonesEditor.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AssemblyName>PowerToys.FancyZonesEditor</AssemblyName>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="app.manifest" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" />
<PackageReference Include="ModernWpfUI" />
<PackageReference Include="System.IO.Abstractions" />
</ItemGroup>
<ItemGroup>
<Resource Include="images\FancyZonesEditor.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\GPOWrapperProjection\GPOWrapperProjection.csproj" />
<ProjectReference Include="..\..\..\..\common\interop\PowerToys.Interop.vcxproj" />
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\..\..\common\Common.UI\Common.UI.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>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

View File

@@ -59,6 +59,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" />
<PackageReference Include="ModernWpfUI" />
<PackageReference Include="WPF-UI" />
<PackageReference Include="System.IO.Abstractions" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,4 +1,5 @@
<Window
<ui:FluentWindow
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
x:Class="FancyZonesEditor.LayoutOverlayWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -9,7 +10,7 @@
Width="800"
Height="450"
AllowsTransparency="True"
Background="{DynamicResource BackdropBrush}"
Background="#85F0F0F0"
Loaded="Window_Loaded"
ResizeMode="NoResize"
ShowInTaskbar="False"

View File

@@ -3,13 +3,14 @@
// See the LICENSE file in the project root for more information.
using System.Windows;
using Wpf.Ui.Controls;
namespace FancyZonesEditor
{
/// <summary>
/// Interaction logic for LayoutOverlayWindow.xaml
/// </summary>
public partial class LayoutOverlayWindow : Window
public partial class LayoutOverlayWindow : FluentWindow
{
public LayoutOverlayWindow()
{
@@ -18,7 +19,7 @@ namespace FancyZonesEditor
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Utils.NativeMethods.SetWindowStyleToolWindow(this);
// Utils.NativeMethods.SetWindowStyleToolWindow(this);
}
}
}

View File

@@ -10,7 +10,7 @@
Loaded="OnLoaded"
mc:Ignorable="d">
<Grid>
<Border Background="{DynamicResource LayoutPreviewBackgroundBrush}" CornerRadius="4" />
<Border Background="Transparent" CornerRadius="4" />
<Grid x:Name="Body" Background="Transparent" />
</Grid>
</UserControl>

View File

@@ -1,4 +1,4 @@
<Window
<ui:FluentWindow
x:Class="FancyZonesEditor.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -11,22 +11,18 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:props="clr-namespace:FancyZonesEditor.Properties"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
x:Name="MainWindow1"
Title="{x:Static props:Resources.Fancy_Zones_Editor_App_Title}"
MinWidth="360"
ui:TitleBar.Background="{DynamicResource TertiaryBackgroundBrush}"
ui:TitleBar.InactiveBackground="{DynamicResource TertiaryBackgroundBrush}"
ui:TitleBar.IsIconVisible="True"
ui:WindowHelper.UseModernWindowStyle="True"
ui:ExtendsContentIntoTitleBar="True"
AutomationProperties.Name="{x:Static props:Resources.Fancy_Zones_Main_Editor}"
Background="{DynamicResource PrimaryBackgroundBrush}"
Closing="OnClosing"
ContentRendered="OnContentRendered"
ResizeMode="CanResize"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d">
<Window.Resources>
<ui:FluentWindow.Resources>
<Thickness x:Key="ContentDialogPadding">24,16,0,24</Thickness>
<Thickness x:Key="ContentDialogCommandSpaceMargin">0,24,24,0</Thickness>
<Converters:LayoutModelTypeToVisibilityConverter x:Key="LayoutModelTypeToVisibilityConverter" />
@@ -46,7 +42,7 @@
Header="{x:Static props:Resources.Edit_zones}"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}">
<MenuItem.Icon>
<ui:FontIcon Glyph="&#xED35;" />
<ui:SymbolIcon Symbol="Edit24" />
</MenuItem.Icon>
</MenuItem>
@@ -150,7 +146,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
<Button
<ui:Button
x:Name="EditLayoutButton"
Grid.RowSpan="4"
Width="36"
@@ -159,29 +155,27 @@
Padding="0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
ui:ControlHelper.CornerRadius="36"
Appearance="Primary"
AutomationProperties.HelpText="{x:Static props:Resources.Edit}"
AutomationProperties.Name="{Binding Name}"
Background="Transparent"
BorderBrush="Transparent"
Click="EditLayout_Click"
Foreground="{Binding (TextElement.Foreground), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}}"
Style="{StaticResource AccentButtonStyle}"
ToolTip="{x:Static props:Resources.Edit}"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutModelTypeBlankToVisibilityConverter}}">
<Button.Content>
<TextBlock
<ui:FontIcon
AutomationProperties.Name="{x:Static props:Resources.Edit}"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontSize="16"
Text="&#xE70F;" />
Glyph="&#xE70F;" />
</Button.Content>
</Button>
</ui:Button>
</Grid>
</DataTemplate>
<Style BasedOn="{StaticResource {x:Type Slider}}" TargetType="{x:Type fancyZonesControls:CustomSlider}" />
</Window.Resources>
</ui:FluentWindow.Resources>
<Grid>
<Grid.RowDefinitions>
@@ -207,7 +201,7 @@
FontWeight="SemiBold"
Text="{x:Static props:Resources.Templates}" />
<ui:GridView
<fancyZonesControls:GridView
Grid.Row="1"
Margin="-8,8,-8,0"
AutomationProperties.LabeledBy="{Binding ElementName=TemplatesHeaderBlock}"
@@ -219,12 +213,12 @@
MouseDoubleClick="LayoutItem_MouseDoubleClick"
SelectionMode="Single"
TabIndex="1">
<ui:GridView.ItemContainerStyle>
<Style BasedOn="{StaticResource LayoutItemContainerStyle}" TargetType="ui:GridViewItem">
<fancyZonesControls:GridView.ItemContainerStyle>
<Style BasedOn="{StaticResource LayoutItemContainerStyle}" TargetType="fancyZonesControls:GridViewItem">
<Setter Property="ContextMenu" Value="{StaticResource LayoutContextMenu}" />
</Style>
</ui:GridView.ItemContainerStyle>
</ui:GridView>
</fancyZonesControls:GridView.ItemContainerStyle>
</fancyZonesControls:GridView>
<local:HeadingTextBlock
x:Name="CustomHeaderBlock"
@@ -263,7 +257,7 @@
Foreground="{DynamicResource SecondaryForegroundBrush}"
Text="{x:Static props:Resources.No_Custom_Layouts_Message}" />
</StackPanel>
<ui:GridView
<fancyZonesControls:GridView
Grid.Row="4"
Margin="-8,8,-8,0"
AutomationProperties.LabeledBy="{Binding ElementName=CustomHeaderBlock}"
@@ -275,18 +269,18 @@
MouseDoubleClick="LayoutItem_MouseDoubleClick"
SelectionMode="Single"
TabIndex="2">
<ui:GridView.ItemContainerStyle>
<Style BasedOn="{StaticResource LayoutItemContainerStyle}" TargetType="ui:GridViewItem">
<fancyZonesControls:GridView.ItemContainerStyle>
<Style BasedOn="{StaticResource LayoutItemContainerStyle}" TargetType="fancyZonesControls:GridViewItem">
<Setter Property="ContextMenu" Value="{StaticResource LayoutContextMenu}" />
</Style>
</ui:GridView.ItemContainerStyle>
</ui:GridView>
</fancyZonesControls:GridView.ItemContainerStyle>
</fancyZonesControls:GridView>
</Grid>
</ScrollViewer>
<Button
<ui:Button
x:Name="NewLayoutButton"
Grid.Row="3"
Height="36"
@@ -294,9 +288,9 @@
Padding="0"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Appearance="Primary"
AutomationProperties.Name="{x:Static props:Resources.Create_new_layout}"
Click="NewLayoutButton_Click"
Style="{StaticResource AccentButtonStyle}"
TabIndex="3">
<StackPanel Margin="8" Orientation="Horizontal">
<TextBlock
@@ -309,13 +303,7 @@
Foreground="{DynamicResource AccentButtonForeground}"
Text="{x:Static props:Resources.Create_new_layout}" />
</StackPanel>
<Button.Effect>
<DropShadowEffect
BlurRadius="6"
Opacity="0.32"
ShadowDepth="1" />
</Button.Effect>
</Button>
</ui:Button>
</Grid>
<Grid Background="{DynamicResource TertiaryBackgroundBrush}">
@@ -336,7 +324,7 @@
<local1:MonitorViewModel x:Name="monitorViewModel" />
</ScrollViewer.DataContext>
<Grid>
<ui:GridView
<fancyZonesControls:GridView
HorizontalAlignment="Center"
IsItemClickEnabled="True"
IsSelectionEnabled="True"
@@ -371,19 +359,18 @@
-->
</Grid>
<ui:ContentDialog
<fancyZonesControls:ContentDialog
x:Name="EditLayoutDialog"
MaxWidth="320"
Background="{DynamicResource PrimaryBackgroundBrush}"
Closed="Dialog_Closed"
Opened="Dialog_Opened"
PrimaryButtonClick="EditLayoutDialog_PrimaryButtonClick"
PrimaryButtonStyle="{StaticResource AccentButtonStyle}"
PrimaryButtonText="{x:Static props:Resources.Save}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SecondaryButtonClick="EditLayoutDialog_SecondaryButtonClick"
SecondaryButtonText="{x:Static props:Resources.Cancel}">
<ui:ContentDialog.Title>
<fancyZonesControls:ContentDialog.Title>
<local:HeadingTextBlock
x:Name="EditLayoutDialogTitle"
MaxWidth="320"
@@ -391,7 +378,7 @@
AutomationProperties.HeadingLevel="Level1"
Loaded="EditLayoutDialogTitle_Loaded"
Style="{StaticResource HeadingTextBlock}" />
</ui:ContentDialog.Title>
</fancyZonesControls:ContentDialog.Title>
<Grid Margin="4,4,24,32" DataContext="{Binding SelectedModel}">
<StackPanel
@@ -470,12 +457,13 @@
MaxWidth="286"
Margin="12,0,0,0"
HorizontalAlignment="Stretch"
ui:ControlHelper.Header="{x:Static props:Resources.Name}"
ui:ControlHelper.PlaceholderText="{x:Static props:Resources.Name}"
AutomationProperties.Name="{x:Static props:Resources.Name}"
GotKeyboardFocus="TextBox_GotKeyboardFocus"
Text="{Binding Name}" />
<!--
ui:ControlHelper.Header="{x:Static props:Resources.Name}"
ui:ControlHelper.PlaceholderText="{x:Static props:Resources.Name}"
-->
</StackPanel>
@@ -529,21 +517,20 @@
HorizontalAlignment="Left">
<local:LayoutPreview />
<Button
<ui:Button
x:Name="editZoneLayoutButton"
Width="36"
Height="36"
Padding="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ui:ControlHelper.CornerRadius="36"
Appearance="Primary"
AutomationProperties.Name="{x:Static props:Resources.Edit_zones}"
BorderBrush="Transparent"
Click="EditZones_Click"
Content="&#xE70F;"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontSize="16"
Style="{StaticResource AccentButtonStyle}"
ToolTip="{x:Static props:Resources.Edit_zones}"
Visibility="{Binding Path=Type, Converter={StaticResource LayoutTypeCustomToVisibilityConverter}}" />
@@ -660,16 +647,14 @@
x:Name="spaceAroundSetting"
Margin="12,0,0,0"
VerticalAlignment="Center"
ui:FocusVisualHelper.FocusVisualMargin="-3,-3,8,-3"
AutomationProperties.Name="{x:Static props:Resources.Show_Space_Zones}"
IsOn="{Binding ShowSpacing}"
OffContent=""
OnContent="">
<ui:ToggleSwitch.Resources>
<sys:Double x:Key="ToggleSwitchThemeMinWidth">0</sys:Double>
</ui:ToggleSwitch.Resources>
</ui:ToggleSwitch>
<!-- IsOn="{Binding ShowSpacing}" -->
</StackPanel>
</StackPanel>
@@ -787,26 +772,25 @@
</StackPanel>
</StackPanel>
</Grid>
</ui:ContentDialog>
</fancyZonesControls:ContentDialog>
<ui:ContentDialog
<fancyZonesControls:ContentDialog
x:Name="NewLayoutDialog"
Background="{DynamicResource PrimaryBackgroundBrush}"
Closed="Dialog_Closed"
IsPrimaryButtonEnabled="{Binding ElementName=LayoutNameText, Path=Text.Length}"
Opened="Dialog_Opened"
PrimaryButtonClick="NewLayoutDialog_PrimaryButtonClick"
PrimaryButtonStyle="{StaticResource AccentButtonStyle}"
PrimaryButtonText="{x:Static props:Resources.Create}"
SecondaryButtonText="{x:Static props:Resources.Cancel}">
<ui:ContentDialog.TitleTemplate>
<fancyZonesControls:ContentDialog.TitleTemplate>
<DataTemplate>
<local:HeadingTextBlock
AutomationProperties.HeadingLevel="Level1"
Style="{StaticResource HeadingTextBlock}"
Text="{x:Static props:Resources.Choose_layout_type}" />
</DataTemplate>
</ui:ContentDialog.TitleTemplate>
</fancyZonesControls:ContentDialog.TitleTemplate>
<StackPanel Margin="0,16,24,0">
<TextBlock x:Name="NameHeaderText" Text="{x:Static props:Resources.Name}" />
<TextBox
@@ -833,7 +817,7 @@
AutomationProperties.Name="{x:Static props:Resources.Layout_Grid_Title}"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontSize="16"
Foreground="{DynamicResource SystemControlBackgroundAccentBrush}"
Foreground="Green"
Text="&#xF0E2;" />
<StackPanel Grid.Column="1" Orientation="Vertical">
<TextBlock
@@ -843,7 +827,7 @@
TextWrapping="Wrap" />
<TextBlock
Margin="0,4,0,0"
Foreground="{DynamicResource SecondaryForegroundBrush}"
Foreground="Red"
Text="{x:Static props:Resources.Layout_Grid_Description}"
TextWrapping="Wrap" />
</StackPanel>
@@ -871,7 +855,7 @@
AutomationProperties.Name="{x:Static props:Resources.Layout_Canvas_Title}"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontSize="16"
Foreground="{DynamicResource SystemControlBackgroundAccentBrush}"
Foreground="Green"
Text="&#xF5ED;" />
<StackPanel Grid.Column="1" Orientation="Vertical">
<TextBlock
@@ -881,7 +865,7 @@
TextWrapping="Wrap" />
<TextBlock
Margin="0,4,0,0"
Foreground="{DynamicResource SecondaryForegroundBrush}"
Foreground="Red"
Text="{x:Static props:Resources.Layout_Canvas_Description}"
TextWrapping="Wrap" />
</StackPanel>
@@ -889,6 +873,6 @@
</RadioButton.Content>
</RadioButton>
</StackPanel>
</ui:ContentDialog>
</fancyZonesControls:ContentDialog>
</Grid>
</Window>
</ui:FluentWindow>

View File

@@ -14,17 +14,24 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using Common.UI;
using FancyZonesEditor.Controls;
using FancyZonesEditor.Models;
using FancyZonesEditor.Utils;
using ManagedCommon;
using ModernWpf.Controls;
using Wpf.Ui.Controls;
using Button = System.Windows.Controls.Button;
using ContentDialog = FancyZonesEditor.Controls.ContentDialog;
using ContentDialogButtonClickEventArgs = FancyZonesEditor.Controls.ContentDialogButtonClickEventArgs;
using ContentDialogClosedEventArgs = FancyZonesEditor.Controls.ContentDialogClosedEventArgs;
using TextBlock = System.Windows.Controls.TextBlock;
using TextBox = System.Windows.Controls.TextBox;
namespace FancyZonesEditor
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
public partial class MainWindow : FluentWindow
{
private const int DefaultWrapPanelItemSize = 164;
private const int SmallWrapPanelItemSize = 164;
@@ -46,6 +53,18 @@ namespace FancyZonesEditor
public MainWindow(bool spanZonesAcrossMonitors, Rect workArea)
{
InitializeComponent();
if (OSVersionHelper.IsWindows11())
{
WindowBackdropType = WindowBackdropType.Mica;
}
else
{
WindowBackdropType = WindowBackdropType.None;
}
Wpf.Ui.Appearance.SystemThemeWatcher.Watch(this, WindowBackdropType);
_createLayoutAnnounce = (TextBlock)FindName("LayoutCreationAnnounce");
DataContext = _settings;
@@ -369,7 +388,7 @@ namespace FancyZonesEditor
e.Handled = true;
}
private void NewLayoutDialog_PrimaryButtonClick(ModernWpf.Controls.ContentDialog sender, ModernWpf.Controls.ContentDialogButtonClickEventArgs args)
private void NewLayoutDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
Logger.LogTrace();
@@ -453,8 +472,8 @@ namespace FancyZonesEditor
private async void DeleteLayout(FrameworkElement element)
{
Logger.LogTrace();
var dialog = new ContentDialog()
Wpf.Ui.Controls.ContentDialog x = new Wpf.Ui.Controls.ContentDialog(new ContentPresenter());
var dialog = new Wpf.Ui.Controls.ContentDialog(new ContentPresenter())
{
Title = Properties.Resources.Are_You_Sure,
Content = Properties.Resources.Are_You_Sure_Description,
@@ -465,7 +484,7 @@ namespace FancyZonesEditor
Announce(FancyZonesEditor.Properties.Resources.Delete_Layout_Dialog_Announce, dialog.Content.ToString());
var result = await dialog.ShowAsync();
if (result == ContentDialogResult.Primary)
if (result == Wpf.Ui.Controls.ContentDialogResult.Primary)
{
LayoutModel model = element.DataContext as LayoutModel;
MainWindowSettingsModel.DefaultLayouts.Reset(model.Uuid);
@@ -511,13 +530,13 @@ namespace FancyZonesEditor
}
}
private void Layout_ItemClick(object sender, ItemClickEventArgs e)
private void Layout_ItemClick(object sender, Controls.ItemClickEventArgs e)
{
Select(e.ClickedItem as LayoutModel);
Apply();
}
private void Monitor_ItemClick(object sender, ItemClickEventArgs e)
private void Monitor_ItemClick(object sender, FancyZonesEditor.Controls.ItemClickEventArgs e)
{
monitorViewModel.SelectCommand.Execute(e.ClickedItem as MonitorInfoModel);
}

View File

@@ -330,6 +330,7 @@ namespace FancyZonesEditor
}
// reset main window owner to keep it on the top
CurrentLayoutWindow.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Transparent);
_mainWindow.Owner = CurrentLayoutWindow;
_mainWindow.ShowActivated = true;
_mainWindow.Topmost = true;

View File

@@ -1,6 +1,7 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:FancyZonesEditor.Controls"
xmlns:ui="http://schemas.modernwpf.com/2019">
<Style x:Key="UWPFocusVisualStyle">
@@ -23,7 +24,7 @@
Opacity="0.24"
ShadowDepth="1" />
<Style x:Key="MonitorItemContainerStyle" TargetType="ui:GridViewItem">
<Style x:Key="MonitorItemContainerStyle" TargetType="controls:GridViewItem">
<Setter Property="Background" Value="{DynamicResource LayoutItemBackgroundBrush}" />
<Setter Property="IsSelected" Value="{Binding Selected, Mode=OneWay}" />
<Setter Property="AutomationProperties.Name" Value="{Binding Index}" />
@@ -31,14 +32,14 @@
<Setter Property="MinWidth" Value="0" />
<Setter Property="MinHeight" Value="0" />
<!--<Setter Property="IsHoldingEnabled" Value="True" />-->
<Setter Property="CornerRadius" Value="4" />
<!--<Setter Property="CornerRadius" Value="4" />-->
<Setter Property="Margin" Value="8" />
<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-2" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource UWPFocusVisualStyle}" />
<!--<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />-->
<!--<Setter Property="FocusVisualMargin" Value="-2" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource UWPFocusVisualStyle}" />-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ui:GridViewItem">
<ControlTemplate TargetType="controls:GridViewItem">
<Border
x:Name="ContentBorder"
Width="{Binding DisplayWidth}"
@@ -46,7 +47,6 @@
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Effect="{StaticResource CardDropShadow}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<VisualStateManager.CustomVisualStateManager>
@@ -141,26 +141,25 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="LayoutItemContainerStyle" TargetType="ui:GridViewItem">
<Style x:Key="LayoutItemContainerStyle" TargetType="controls:GridViewItem">
<Setter Property="Background" Value="{DynamicResource LayoutItemBackgroundBrush}" />
<Setter Property="IsSelected" Value="{Binding IsApplied, Mode=OneWay}" />
<Setter Property="AutomationProperties.Name" Value="{Binding Name}" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="Local" />
<!--<Setter Property="IsHoldingEnabled" Value="True" />-->
<Setter Property="CornerRadius" Value="4" />
<!--<Setter Property="CornerRadius" Value="4" />-->
<Setter Property="Margin" Value="8" />
<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<!--<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-2" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource UWPFocusVisualStyle}" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource UWPFocusVisualStyle}" />-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ui:GridViewItem">
<ControlTemplate TargetType="controls:GridViewItem">
<Border
x:Name="ContentBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
Effect="{StaticResource CardDropShadow}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<VisualStateManager.CustomVisualStateManager>