[ColorPicker] Improving keyboard navigation (#11384)

* Fix keyboard navigation

* Fix button

* HIerarchy

* Place flyout at the bottom

Co-authored-by: Niels Laute <niels9001@hotmail.com>
This commit is contained in:
Niels Laute 2021-05-21 15:57:57 +02:00 committed by GitHub
parent 756c9ff935
commit b84e9da005
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 486 additions and 384 deletions

View file

@ -1,22 +1,18 @@
<UserControl x:Class="ColorPicker.Controls.ColorFormatControl"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:p="clr-namespace:ColorPicker.Properties"
xmlns:ui="http://schemas.modernwpf.com/2019"
mc:Ignorable="d">
<UserControl.Resources>
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
Color="Transparent" />
</UserControl.Resources>
<Border x:Name="MainBorder"
Margin="12,16,12,0"
Width="308"
Height="36"
CornerRadius="2"
HorizontalAlignment="Stretch"
Background="{DynamicResource ColorControlBackgroundBrush}">
Margin="12,16,12,0"
Width="308"
Height="36"
CornerRadius="2"
HorizontalAlignment="Stretch"
Background="{DynamicResource ColorControlBackgroundBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="64"/>
@ -42,32 +38,22 @@
IsReadOnly="True"
VerticalAlignment="Center"
Padding="8"
AutomationProperties.LabeledBy="{Binding FormatNameTextBlock}"
AutomationProperties.LabeledBy="{Binding ElementName=FormatNameTextBlock, Path=Text}"
/>
<Button x:Name="CopyToClipboardButton"
ToolTipService.ToolTip="{x:Static p:Resources.Copy_to_clipboard}"
Background="{DynamicResource ColorControlBackgroundBrush}"
Foreground="{DynamicResource SecondaryForegroundBrush}"
Height="36"
Width="36"
Grid.Column="2"
AutomationProperties.HelpText="{Binding ElementName=FormatNameTextBlock, Path=Text}"
AutomationProperties.Name="{x:Static p:Resources.Copy_to_clipboard}">
<Button.Content>
<TextBlock FontFamily="Segoe MDL2 Assets"
Text="&#xE16F;"
FontSize="12" />
</Button.Content>
<Button.Resources>
<Style TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsMouseOver, ElementName=MainBorder}" Value="False">
<Setter Property="Opacity" Value="0"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Resources>
</Button>
AutomationProperties.Name="{x:Static p:Resources.Copy_to_clipboard}"
FontSize="12"
Style="{StaticResource DefaultButtonStyle}"
FontFamily="Segoe MDL2 Assets"
Content="&#xE16F;" />
</Grid>
<Border.Effect>
<DropShadowEffect BlurRadius="6" Opacity="0.24" ShadowDepth="1" />

View file

@ -7,66 +7,283 @@
xmlns:p="clr-namespace:ColorPicker.Properties"
xmlns:ui="http://schemas.modernwpf.com/2019"
mc:Ignorable="d"
Height="350"
Width="333">
<StackPanel x:Name="PickerPanel"
Orientation="Vertical"
Background="{x:Null}" >
<!--Top panel-->
<Grid HorizontalAlignment="Stretch" Margin="12,0,12,0">
TabIndex="3"
FocusManager.IsFocusScope="True"
KeyboardNavigation.TabNavigation="Once"
>
<UserControl.Resources>
<Style TargetType="Thumb"
x:Key="SliderThumbStyle">
<Setter Property="BorderThickness"
Value="4" />
<Setter Property="Background"
Value="{DynamicResource SliderThumbBackground}" />
<Setter Property="IsTabStop"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Border Background="Transparent"
BorderBrush="{DynamicResource PrimaryForegroundBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{DynamicResource SliderThumbCornerRadius}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="SliderHorizontal"
TargetType="Slider">
<Grid Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="SliderContainer"
Grid.Row="1"
Background="Transparent"
ui:FocusVisualHelper.IsTemplateFocusTarget="True">
<Border Background="{TemplateBinding Background}"
Margin="1,0,1,0"
CornerRadius="6"
VerticalAlignment="Center"
Height="12">
<Border.Effect>
<DropShadowEffect BlurRadius="6"
Opacity="0.32"
ShadowDepth="2" />
</Border.Effect>
</Border>
<Grid x:Name="HorizontalTemplate"
MinHeight="{DynamicResource SliderHorizontalHeight}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle x:Name="HorizontalTrackRect"
Fill="Transparent"
Height="{DynamicResource SliderTrackThemeHeight}"
Grid.Row="1"
Grid.ColumnSpan="3" />
<Rectangle x:Name="HorizontalDecreaseRect"
Width="{Binding ActualWidth, ElementName=HorizontalDecrease}"
Fill="Transparent"
Grid.Row="1" />
<TickBar x:Name="TopTickBar"
Placement="Top"
Visibility="Collapsed"
Fill="{DynamicResource SliderTickBarFill}"
Height="{DynamicResource SliderOutsideTickBarThemeHeight}"
VerticalAlignment="Bottom"
Margin="0,0,0,4"
Grid.ColumnSpan="3" />
<TickBar x:Name="BottomTickBar"
Placement="Bottom"
Visibility="Collapsed"
Fill="{DynamicResource SliderTickBarFill}"
Height="{DynamicResource SliderOutsideTickBarThemeHeight}"
VerticalAlignment="Top"
Margin="0,4,0,0"
Grid.Row="2"
Grid.ColumnSpan="3" />
<Track x:Name="PART_Track"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="0"
Grid.ColumnSpan="3">
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="HorizontalDecrease"
Command="{x:Static Slider.DecreaseLarge}"
Style="{StaticResource RepeatButtonTransparent}" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static Slider.IncreaseLarge}"
Style="{StaticResource RepeatButtonTransparent}" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb x:Name="HorizontalThumb"
Style="{StaticResource SliderThumbStyle}"
DataContext="{TemplateBinding Value}"
Height="20"
VerticalAlignment="Center"
Margin="0,0,0,0"
Width="20"
ui:FocusVisualHelper.FocusVisualMargin="-14,-6,-14,-6">
<Thumb.Resources>
<Style TargetType="ToolTip"
BasedOn="{StaticResource SliderAutoToolTipStyle}" />
</Thumb.Resources>
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TickPlacement"
Value="TopLeft">
<Setter TargetName="TopTickBar"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="TickPlacement"
Value="BottomRight">
<Setter TargetName="BottomTickBar"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="TickPlacement"
Value="Both">
<Setter TargetName="TopTickBar"
Property="Visibility"
Value="Visible" />
<Setter TargetName="BottomTickBar"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="HorizontalThumb"
Property="Opacity"
Value="0.8" />
</Trigger>
<Trigger SourceName="HorizontalThumb"
Property="IsDragging"
Value="True">
<Setter TargetName="HorizontalThumb"
Property="Opacity"
Value="0.6" />
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter TargetName="HorizontalDecreaseRect"
Property="Fill"
Value="{DynamicResource SliderTrackValueFillDisabled}" />
<Setter TargetName="HorizontalTrackRect"
Property="Fill"
Value="{DynamicResource SliderTrackFillDisabled}" />
<Setter TargetName="HorizontalThumb"
Property="Background"
Value="{DynamicResource SliderThumbBackgroundDisabled}" />
<Setter TargetName="TopTickBar"
Property="Fill"
Value="{DynamicResource SliderTickBarFillDisabled}" />
<Setter TargetName="BottomTickBar"
Property="Fill"
Value="{DynamicResource SliderTickBarFillDisabled}" />
<Setter TargetName="SliderContainer"
Property="Background"
Value="{DynamicResource SliderContainerBackgroundDisabled}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="CustomSLiderStyle"
TargetType="Slider">
<Setter Property="OverridesDefaultStyle"
Value="True" />
<Setter Property="Stylus.IsPressAndHoldEnabled"
Value="false" />
<Setter Property="Background"
Value="{DynamicResource SliderTrackFill}" />
<Setter Property="BorderThickness"
Value="{DynamicResource SliderBorderThemeThickness}" />
<Setter Property="Foreground"
Value="{DynamicResource SliderTrackValueFill}" />
<Setter Property="FontFamily"
Value="{DynamicResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize"
Value="{DynamicResource ControlContentThemeFontSize}" />
<!--<Setter Property="ManipulationMode" Value="None" />-->
<Setter Property="FocusVisualStyle"
Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="ui:FocusVisualHelper.UseSystemFocusVisuals"
Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="ui:FocusVisualHelper.FocusVisualMargin"
Value="-7,0,-7,0" />
<Setter Property="ui:ControlHelper.CornerRadius"
Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Template"
Value="{StaticResource SliderHorizontal}" />
<Style.Triggers>
<Trigger Property="Orientation"
Value="Vertical">
<Setter Property="Template"
Value="{StaticResource SliderVertical}" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid x:Name="PickerPanel"
HorizontalAlignment="Stretch"
Margin="12,2,12,2">
<Grid.Effect>
<DropShadowEffect BlurRadius="6" Opacity="0.32" ShadowDepth="2" />
<DropShadowEffect BlurRadius="6"
Opacity="0.32"
ShadowDepth="2" />
</Grid.Effect>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="36"/>
<ColumnDefinition Width="36"/>
<ColumnDefinition Width="165"/>
<ColumnDefinition Width="36"/>
<ColumnDefinition Width="36"/>
<ColumnDefinition Width="36" />
<ColumnDefinition Width="36" />
<ColumnDefinition Width="165" />
<ColumnDefinition Width="36" />
<ColumnDefinition Width="36" />
</Grid.ColumnDefinitions>
<Button x:Name="colorVariation1Button"
Grid.Column="0"
TabIndex="4"
TabIndex="3"
ui:ControlHelper.CornerRadius="2,0,0,2"
Background="LightPink"
Click="ColorVariationButton_Click"
AutomationProperties.Name="Color shade 1"
Style="{DynamicResource ColorShadeButtonStyle}"
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}"/>
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}" />
<Button x:Name="colorVariation2Button"
Grid.Column="1"
ui:ControlHelper.CornerRadius="0"
TabIndex="5"
Background="LightPink"
Click="ColorVariationButton_Click"
AutomationProperties.Name="Color shade 2"
Style="{DynamicResource ColorShadeButtonStyle}"
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}"/>
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}" />
<Button x:Name="colorVariation3Button"
Grid.Column="3"
TabIndex="7"
ui:ControlHelper.CornerRadius="0"
Background="LightPink"
Click="ColorVariationButton_Click"
AutomationProperties.Name="Color shade 3"
Style="{DynamicResource ColorShadeButtonStyle}"
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}"/>
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}" />
<Button x:Name="colorVariation4Button"
Grid.Column="4"
TabIndex="8"
ui:ControlHelper.CornerRadius="0,2,2,0"
Background="LightPink"
Click="ColorVariationButton_Click"
AutomationProperties.Name="Color shade 5"
Style="{DynamicResource ColorShadeButtonStyle}"
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}"/>
ToolTipService.ToolTip="{x:Static p:Resources.Select_color}" />
<Button x:Name="CurrentColorButton"
HorizontalAlignment="Left"
Grid.Column="0"
TabIndex="6"
Grid.ColumnSpan="5"
Opacity="1"
ui:ControlHelper.CornerRadius="0"
Background="Red"
Width="165"
@ -77,221 +294,161 @@
ToolTipService.ToolTip="{x:Static p:Resources.Selected_color_tooltip}"
Click="CurrentColorButton_Click"
Style="{DynamicResource ColorShadeButtonStyle}">
<ui:FlyoutService.Flyout>
<ui:Flyout x:Name="DetailsFlyout"
Placement="Bottom"
Closed="DetailsFlyout_Closed">
<Grid Margin="0,4,0,12"
KeyboardNavigation.TabNavigation="Contained"
x:Name="detailsGrid">
<StackPanel x:Name="detailsStackPanel">
<StackPanel Orientation="Horizontal">
<TextBlock Text="H"
Width="38"
FontWeight="SemiBold"
TextAlignment="Center"
VerticalAlignment="Center" />
<Slider x:Name="HueGradientSlider"
Width="214"
IsMoveToPointEnabled="True"
AutomationProperties.Name="{x:Static p:Resources.Hue_slider}"
Style="{StaticResource CustomSLiderStyle}"
ValueChanged="HueGradientSlider_ValueChanged"
VerticalAlignment="Center"
Grid.Column="1"
Minimum="0"
Maximum="289" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="S"
Grid.Row="1"
Width="38"
TextAlignment="Center"
FontWeight="SemiBold"
VerticalAlignment="Center" />
<Slider x:Name="SaturationGradientSlider"
AutomationProperties.Name="{x:Static p:Resources.Saturation_slider}"
Style="{StaticResource CustomSLiderStyle}"
ValueChanged="SaturationGradientSlider_ValueChanged"
Grid.Column="1"
Width="214"
IsMoveToPointEnabled="True"
Grid.Row="1"
Minimum="0"
Maximum="289">
<Slider.Background>
<LinearGradientBrush EndPoint="1,0.5"
StartPoint="0, 0.5">
<GradientStop x:Name="SaturationStartColor"
Color="Black" />
<GradientStop x:Name="SaturationStopColor"
Color="Red"
Offset="1" />
</LinearGradientBrush>
</Slider.Background>
</Slider>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="V"
Grid.Row="2"
Width="38"
TextAlignment="Center"
FontWeight="SemiBold"
VerticalAlignment="Center" />
<Slider x:Name="ValueGradientSlider"
AutomationProperties.Name="{x:Static p:Resources.Value_slider}"
Style="{StaticResource CustomSLiderStyle}"
ValueChanged="ValueGradientSlider_ValueChanged"
Grid.Column="1"
IsMoveToPointEnabled="True"
Grid.Row="2"
Width="214"
Minimum="0"
Maximum="289">
<Slider.Background>
<LinearGradientBrush EndPoint="1,0.5"
StartPoint="0, 0.5">
<GradientStop x:Name="ValueStartColor"
Color="Black" />
<GradientStop x:Name="ValueStopColor"
Color="Red"
Offset="1" />
</LinearGradientBrush>
</Slider.Background>
</Slider>
</StackPanel>
<StackPanel Orientation="Horizontal"
Margin="0,16,0,0">
<TextBlock Text="RGB"
Width="38"
FontWeight="SemiBold"
TextAlignment="Center"
VerticalAlignment="Center" />
<ui:NumberBox x:Name="RNumberBox"
Height="32"
Width="72"
ui:ControlHelper.CornerRadius="2,0,0,2"
AutomationProperties.Name="{x:Static p:Resources.Red_value}"
ValueChanged="RGBNumberBox_ValueChanged"
Minimum="0"
Maximum="255" />
<ui:NumberBox x:Name="GNumberBox"
Height="32"
Margin="-1,0,0,0"
Width="72"
ui:ControlHelper.CornerRadius="0"
AutomationProperties.Name="{x:Static p:Resources.Green_value}"
ValueChanged="RGBNumberBox_ValueChanged"
Minimum="0"
Maximum="255" />
<ui:NumberBox x:Name="BNumberBox"
Height="32"
Width="72"
Margin="-1,0,0,0"
ui:ControlHelper.CornerRadius="0,2,2,0"
AutomationProperties.Name="{x:Static p:Resources.Blue_value}"
ValueChanged="RGBNumberBox_ValueChanged"
Minimum="0"
Maximum="255" />
</StackPanel>
<StackPanel Orientation="Horizontal"
Margin="0,16,0,0">
<TextBlock Text="HEX"
Width="38"
TextAlignment="Center"
FontWeight="SemiBold"
VerticalAlignment="Center" />
<TextBox x:Name="HexCode"
Height="32"
Width="214"
AutomationProperties.Name="{x:Static p:Resources.Hex_value}"
GotKeyboardFocus="HexCode_GotKeyboardFocus"
TextChanged="HexCode_TextChanged"
TextWrapping="Wrap" />
</StackPanel>
<Button Margin="0,32,0,0"
x:Name="OKButton"
Click="OKButton_Click"
Style="{StaticResource AccentButtonStyle}"
AutomationProperties.Name="{x:Static p:Resources.Select}"
Content="{x:Static p:Resources.Select}"
HorizontalAlignment="Stretch" />
</StackPanel>
</Grid>
</ui:Flyout>
</ui:FlyoutService.Flyout>
</Button>
</Grid>
<!--Details panel-->
<Grid Margin="0,4,0,12"
Height="0"
Visibility="Collapsed"
x:Name="detailsGrid">
<Border Background="{DynamicResource PrimaryBackgroundBrush}"/>
<StackPanel x:Name="detailsStackPanel"
Opacity="0">
<Grid Margin="12,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="36"/>
<RowDefinition Height="36"/>
<RowDefinition Height="36"/>
</Grid.RowDefinitions>
<TextBlock Text="H"
FontWeight="SemiBold"
Margin="0,10,0,0"
VerticalAlignment="Center"/>
<Border Grid.Column="1"
Margin="0,12,12,0"
x:Name="HueGradientGrid"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Height="24"
AutomationProperties.Name="{x:Static p:Resources.Hue_slider}"
Width="289"
CornerRadius="2"
MouseLeftButtonDown="HueGradientGrid_MouseLeftButtonDown"
MouseMove="HueGradientGrid_MouseMove">
<Border.Effect>
<DropShadowEffect BlurRadius="6" Opacity="0.32" ShadowDepth="2" />
</Border.Effect>
<Border VerticalAlignment="Stretch"
Width="6"
x:Name="hueGradientPointer"
Margin="154,0,0,0"
Background="#88FFFFFF"
BorderBrush="Black"
CornerRadius="2"
BorderThickness="1"
HorizontalAlignment="Left"/>
</Border>
<TextBlock Text="S"
Grid.Row="1"
Margin="0,10,0,0"
FontWeight="SemiBold"
VerticalAlignment="Center"/>
<Border HorizontalAlignment="Left"
Grid.Column="1"
Grid.Row="1"
Margin="0,12,12,0"
VerticalAlignment="Center"
Height="24"
AutomationProperties.Name="{x:Static p:Resources.Saturation_slider}"
x:Name="SaturationGradientGrid"
Width="289"
CornerRadius="2"
MouseLeftButtonDown="SaturationGradientGrid_MouseLeftButtonDown"
MouseMove="SaturationGradientGrid_MouseMove">
<Border.Effect>
<DropShadowEffect BlurRadius="6" Opacity="0.32" ShadowDepth="2" />
</Border.Effect>
<Border.Background>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0, 0.5">
<GradientStop x:Name="SaturationStartColor" Color="Black"/>
<GradientStop x:Name="SaturationStopColor" Color="Red" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Border HorizontalAlignment="Left"
x:Name="saturationGradientPointer"
BorderBrush="Black"
BorderThickness="1"
Margin="154,0,0,0"
CornerRadius="2"
Width="6"
VerticalAlignment="Stretch"
Background="#88FFFFFF"/>
</Border>
<TextBlock Text="V"
Grid.Row="2"
Margin="0,10,0,0"
FontWeight="SemiBold"
VerticalAlignment="Center"/>
<Border HorizontalAlignment="Left"
Grid.Column="1"
Grid.Row="2"
Margin="0,12,12,0"
Height="24"
VerticalAlignment="Center"
CornerRadius="2"
x:Name="ValueGradientGrid"
Width="289"
AutomationProperties.Name="{x:Static p:Resources.Value_slider}"
MouseLeftButtonDown="ValueGradientGrid_MouseLeftButtonDown"
MouseMove="ValueGradientGrid_MouseMove">
<Border.Effect>
<DropShadowEffect BlurRadius="6" Opacity="0.32" ShadowDepth="2" />
</Border.Effect>
<Border.Background>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0, 0.5">
<GradientStop x:Name="ValueStartColor" Color="Red"/>
<GradientStop x:Name="ValueStopColor" Color="White" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Border HorizontalAlignment="Left"
x:Name="valueGradientPointer"
BorderBrush="Black"
BorderThickness="1"
Margin="154,0,0,0"
Width="6"
CornerRadius="2"
VerticalAlignment="Stretch"
Background="#88FFFFFF"/>
</Border>
</Grid>
<Grid HorizontalAlignment="Stretch"
Margin="12,16,12,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="86" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="36" />
<RowDefinition Height="36" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<TextBlock Text="R"
FontWeight="SemiBold"
VerticalAlignment="Center" />
<ui:NumberBox x:Name="RNumberBox"
Grid.Column="1"
Height="32"
AutomationProperties.Name="{x:Static p:Resources.Red_value}"
ValueChanged="RGBNumberBox_ValueChanged"
Minimum="0"
Maximum="255" />
<TextBlock Text="G"
FontWeight="SemiBold"
Grid.Row="1"
VerticalAlignment="Center" />
<ui:NumberBox x:Name="GNumberBox"
Height="32"
Grid.Row="1"
Grid.Column="1"
AutomationProperties.Name="{x:Static p:Resources.Green_value}"
ValueChanged="RGBNumberBox_ValueChanged"
Minimum="0"
Maximum="255" />
<TextBlock Text="B"
FontWeight="SemiBold"
Grid.Row="2"
VerticalAlignment="Center" />
<ui:NumberBox x:Name="BNumberBox"
Height="32"
Grid.Column="1"
Grid.Row="2"
AutomationProperties.Name="{x:Static p:Resources.Blue_value}"
ValueChanged="RGBNumberBox_ValueChanged"
Minimum="0"
Maximum="255" />
<TextBlock Text="HEX"
Grid.Column="2"
HorizontalAlignment="Right"
FontWeight="SemiBold"
VerticalAlignment="Center" />
<TextBox x:Name="HexCode"
HorizontalAlignment="Stretch"
Margin="8,0,0,0"
Height="32"
Grid.Column="3"
AutomationProperties.Name="{x:Static p:Resources.Hex_value}"
GotKeyboardFocus="HexCode_GotKeyboardFocus"
TextChanged="HexCode_TextChanged"
TextWrapping="Wrap" />
</Grid>
<WrapPanel HorizontalAlignment="Right"
Margin="0,0,0,0"
VerticalAlignment="Top">
<Button x:Name="CancelButton"
Click="CancelButton_Click"
AutomationProperties.Name="{x:Static p:Resources.Cancel}"
Content="{x:Static p:Resources.Cancel}"
Width="80"/>
<Button Margin="12,0,12,0"
x:Name="OKButton"
Click="OKButton_Click"
Style="{StaticResource AccentButtonStyle}"
AutomationProperties.Name="{x:Static p:Resources.OK}"
Content="{x:Static p:Resources.OK}"
Width="80"/>
</WrapPanel>
</StackPanel>
</Grid>
</StackPanel>
</UserControl>

View file

@ -20,7 +20,6 @@ namespace ColorPicker.Controls
/// </summary>
public partial class ColorPickerControl : UserControl
{
private const int GradientPointerHalfWidth = 3;
private double _currH = 360;
private double _currS = 1;
private double _currV = 1;
@ -93,7 +92,7 @@ namespace ColorPicker.Controls
gradientBrush.GradientStops.Add(stop);
}
HueGradientGrid.Background = gradientBrush;
HueGradientSlider.Background = gradientBrush;
}
private static void SetColorVariationsForCurrentColor(DependencyObject d, (double hue, double saturation, double value) hsv)
@ -122,9 +121,9 @@ namespace ColorPicker.Controls
private void UpdateValueColorGradient(double posX)
{
valueGradientPointer.Margin = new Thickness(posX - GradientPointerHalfWidth, 0, 0, 0);
ValueGradientSlider.Value = posX;
_currV = posX / ValueGradientGrid.Width;
_currV = posX / ValueGradientSlider.Maximum;
UpdateHueGradient(_currS, _currV);
@ -134,9 +133,9 @@ namespace ColorPicker.Controls
private void UpdateSaturationColorGradient(double posX)
{
saturationGradientPointer.Margin = new Thickness(posX - GradientPointerHalfWidth, 0, 0, 0);
SaturationGradientSlider.Value = posX;
_currS = posX / SaturationGradientGrid.Width;
_currS = posX / HueGradientSlider.Maximum;
UpdateHueGradient(_currS, _currV);
@ -146,9 +145,8 @@ namespace ColorPicker.Controls
private void UpdateHueColorGradient(double posX)
{
hueGradientPointer.Margin = new Thickness(posX - GradientPointerHalfWidth, 0, 0, 0);
_currH = posX / HueGradientGrid.Width * 360;
HueGradientSlider.Value = posX;
_currH = posX / HueGradientSlider.Maximum * 360;
SaturationStartColor.Color = HSVColor.RGBFromHSV(_currH, 0f, _currV);
SaturationStopColor.Color = HSVColor.RGBFromHSV(_currH, 1f, _currV);
@ -184,7 +182,6 @@ namespace ColorPicker.Controls
{
if (_isCollapsed)
{
detailsGrid.Visibility = Visibility.Visible;
_isCollapsed = false;
var opacityAppear = new DoubleAnimation(1.0, new Duration(TimeSpan.FromMilliseconds(300)));
@ -202,8 +199,6 @@ namespace ColorPicker.Controls
ControlHelper.SetCornerRadius(CurrentColorButton, new CornerRadius(2));
CurrentColorButton.BeginAnimation(Button.WidthProperty, resizeColor);
CurrentColorButton.BeginAnimation(Button.MarginProperty, moveColor);
detailsStackPanel.BeginAnimation(StackPanel.OpacityProperty, opacityAppear);
detailsGrid.BeginAnimation(Grid.HeightProperty, resize);
CurrentColorButton.IsEnabled = false;
SessionEventHelper.Event.EditorAdjustColorOpened = true;
}
@ -230,9 +225,6 @@ namespace ColorPicker.Controls
ControlHelper.SetCornerRadius(CurrentColorButton, new CornerRadius(0));
CurrentColorButton.BeginAnimation(Button.WidthProperty, resizeColor);
CurrentColorButton.BeginAnimation(Button.MarginProperty, moveColor);
detailsStackPanel.BeginAnimation(Window.OpacityProperty, opacityAppear);
detailsGrid.BeginAnimation(Grid.HeightProperty, resize);
detailsGrid.Visibility = Visibility.Collapsed;
CurrentColorButton.IsEnabled = true;
}
}
@ -242,9 +234,12 @@ namespace ColorPicker.Controls
HideDetails();
SelectedColorChangedCommand.Execute(_currentColor);
SessionEventHelper.Event.EditorColorAdjusted = true;
DetailsFlyout.Hide();
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
#pragma warning disable CA1801 // Review unused parameters
private void DetailsFlyout_Closed(object sender, object e)
#pragma warning restore CA1801 // Review unused parameters
{
HideDetails();
@ -262,69 +257,30 @@ namespace ColorPicker.Controls
SessionEventHelper.Event.EditorSimilarColorPicked = true;
}
private void ValueGradientGrid_MouseMove(object sender, MouseEventArgs e)
private void SaturationGradientSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var pos = GetMousePositionWithinGrid(sender as Border);
UpdateValueColorGradient(pos.X);
_ignoreGradientsChanges = true;
UpdateTextBoxesAndCurrentColor(HSVColor.RGBFromHSV(_currH, _currS, _currV));
_ignoreGradientsChanges = false;
}
}
private void ValueGradientGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var pos = GetMousePositionWithinGrid(sender as Border);
UpdateValueColorGradient(pos.X);
UpdateSaturationColorGradient((sender as Slider).Value);
_ignoreGradientsChanges = true;
UpdateTextBoxesAndCurrentColor(HSVColor.RGBFromHSV(_currH, _currS, _currV));
_ignoreGradientsChanges = false;
}
private void SaturationGradientGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
private void HueGradientSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
var pos = GetMousePositionWithinGrid(sender as Border);
UpdateSaturationColorGradient(pos.X);
UpdateHueColorGradient((sender as Slider).Value);
_ignoreGradientsChanges = true;
UpdateTextBoxesAndCurrentColor(HSVColor.RGBFromHSV(_currH, _currS, _currV));
_ignoreGradientsChanges = false;
}
private void SaturationGradientGrid_MouseMove(object sender, MouseEventArgs e)
private void ValueGradientSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var pos = GetMousePositionWithinGrid(sender as Border);
UpdateSaturationColorGradient(pos.X);
_ignoreGradientsChanges = true;
UpdateTextBoxesAndCurrentColor(HSVColor.RGBFromHSV(_currH, _currS, _currV));
_ignoreGradientsChanges = false;
}
}
private void HueGradientGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var pos = GetMousePositionWithinGrid(sender as Border);
UpdateHueColorGradient(pos.X);
UpdateValueColorGradient((sender as Slider).Value);
_ignoreGradientsChanges = true;
UpdateTextBoxesAndCurrentColor(HSVColor.RGBFromHSV(_currH, _currS, _currV));
_ignoreGradientsChanges = false;
}
private void HueGradientGrid_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var pos = GetMousePositionWithinGrid(sender as Border);
UpdateHueColorGradient(pos.X);
_ignoreGradientsChanges = true;
UpdateTextBoxesAndCurrentColor(HSVColor.RGBFromHSV(_currH, _currS, _currV));
_ignoreGradientsChanges = false;
}
}
private static Point GetMousePositionWithinGrid(Border border)
{
var pos = System.Windows.Input.Mouse.GetPosition(border);
@ -385,9 +341,9 @@ namespace ColorPicker.Controls
{
var hsv = ColorHelper.ConvertToHSVColor(color);
var huePosition = (hsv.hue / 360) * HueGradientGrid.Width;
var saturationPosition = hsv.saturation * SaturationGradientGrid.Width;
var valuePosition = hsv.value * ValueGradientGrid.Width;
var huePosition = (hsv.hue / 360) * HueGradientSlider.Maximum;
var saturationPosition = hsv.saturation * SaturationGradientSlider.Maximum;
var valuePosition = hsv.value * ValueGradientSlider.Maximum;
UpdateHueColorGradient(huePosition);
UpdateSaturationColorGradient(saturationPosition);
UpdateValueColorGradient(valuePosition);
@ -403,7 +359,7 @@ namespace ColorPicker.Controls
private void HexCode_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
(sender as TextBox).SelectAll();
(sender as System.Windows.Controls.TextBox).SelectAll();
}
}
}

View file

@ -141,15 +141,6 @@ namespace ColorPicker.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to OK.
/// </summary>
public static string OK {
get {
return ResourceManager.GetString("OK", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open settings.
/// </summary>
@ -195,6 +186,15 @@ namespace ColorPicker.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Select.
/// </summary>
public static string Select {
get {
return ResourceManager.GetString("Select", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Select color.
/// </summary>

View file

@ -153,9 +153,9 @@
<value>Press the Color Picker icon to capture a color from your screen.</value>
<comment>Message that shows when the user launches the window for the first time or when no colors have been selected</comment>
</data>
<data name="OK" xml:space="preserve">
<value>OK</value>
<comment>OK button content</comment>
<data name="Select" xml:space="preserve">
<value>Select</value>
<comment>Select button content</comment>
</data>
<data name="Open_settings" xml:space="preserve">
<value>Open settings</value>

View file

@ -8,33 +8,23 @@
<converters:ColorToBrushConverter x:Key="colorToBrushConverter"/>
<converters:ColorToStringConverter x:Key="colorToStringConverter"/>
<converters:NumberToVisibilityConverter x:Key="numberToVisibilityConverter"/>
<converters:NumberToInvertedVisibilityConverter x:Key="numberToInvertedVisibilityConverter"/>
<converters:NumberToInvertedVisibilityConverter x:Key="numberToInvertedVisibilityConverter" />
<Style x:Key="ColorHistoryListViewStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="MinWidth"
Value="0" />
<Setter Property="ui:FocusVisualHelper.FocusVisualMargin"
Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<Border x:Name="Bd" Width="64" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="0" SnapsToDevicePixels="True">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
@ -83,7 +73,7 @@
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="ui:FocusVisualHelper.UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="ui:FocusVisualHelper.FocusVisualMargin" Value="-3" />
<Setter Property="ui:FocusVisualHelper.FocusVisualMargin" Value="-2" />
<Setter Property="ui:ControlHelper.CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="False" />
<Setter Property="Template">
@ -105,7 +95,7 @@
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Focusable="False"
Opacity="0"
Visibility="Collapsed"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
@ -114,12 +104,13 @@
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Background" Property="Opacity" Value="0.8" />
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource ButtonBorderBrushPointerOver}" />
<Setter TargetName="ContentPresenter" Property="Opacity" Value="1" />
<Setter TargetName="ContentPresenter"
Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Background" Property="Opacity" Value="0.9" />
<Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource ButtonBorderBrushPressed}" />
<Setter TargetName="ContentPresenter" Property="Opacity" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

View file

@ -1,16 +1,15 @@
<UserControl x:Class="ColorPicker.Views.ColorEditorView"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:p="clr-namespace:ColorPicker.Properties"
mc:Ignorable="d"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:e="http://schemas.microsoft.com/xaml/behaviors"
xmlns:controls="clr-namespace:ColorPicker.Controls"
xmlns:behaviors="clr-namespace:ColorPicker.Behaviors"
WindowChrome.IsHitTestVisibleInChrome="True"
WindowChrome.IsHitTestVisibleInChrome="True"
x:Name="colorEditorControl">
<Grid>
<Grid.ColumnDefinitions>
@ -24,7 +23,10 @@
Margin="0,48,0,0"
Grid.Row="1"
Padding="0"
TabIndex="3"
TabIndex="2"
Width="64"
HorizontalAlignment="Center"
ui:FocusVisualHelper.UseSystemFocusVisuals="True"
ItemsSource="{Binding ColorsHistory}"
SelectedIndex="{Binding SelectedColorIndex}"
ItemContainerStyle="{DynamicResource ColorHistoryListViewStyle}"
@ -93,20 +95,28 @@
<Button Width="64"
Height="32"
TabIndex="1"
TabIndex="0"
Content="&#xEF3C;"
Command="{Binding OpenColorPickerCommand}"
Background="Transparent"
FontFamily="Segoe MDL2 Assets"
ui:FocusVisualHelper.FocusVisualMargin="-1"
ToolTipService.ToolTip="{x:Static p:Resources.Pick_color}"
AutomationProperties.Name="{x:Static p:Resources.Pick_color}"/>
</Grid>
<!-- Main grid -->
<Grid Grid.Column="1" Visibility="{Binding ColorsHistory.Count, Converter={StaticResource numberToVisibilityConverter}}">
<ScrollViewer Grid.Column="1" Margin="0,90,0,0">
<Grid Grid.Column="1"
Visibility="{Binding ColorsHistory.Count, Converter={StaticResource numberToVisibilityConverter}}">
<ScrollViewer IsTabStop="False"
Margin="0,90,0,0">
<StackPanel>
<ItemsControl ItemsSource="{Binding ColorRepresentations}">
<ItemsControl IsTabStop="False"
TabIndex="4"
FocusManager.IsFocusScope="True"
KeyboardNavigation.TabNavigation="Once"
ItemsSource="{Binding ColorRepresentations}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:ColorFormatControl
@ -126,17 +136,19 @@
</StackPanel>
</ScrollViewer>
<controls:ColorPickerControl
HorizontalAlignment="Left"
Margin="0,44,0,0"
SelectedColor="{Binding SelectedColor}"
SelectedColorChangedCommand="{Binding SelectedColorChangedCommand}"
Grid.Column="1"
VerticalAlignment="Top"/>
<controls:ColorPickerControl HorizontalAlignment="Left"
Margin="0,44,0,0"
Visibility="{Binding ColorsHistory.Count, Converter={StaticResource numberToVisibilityConverter}}"
IsTabStop="True"
TabIndex="2"
SelectedColor="{Binding SelectedColor}"
SelectedColorChangedCommand="{Binding SelectedColorChangedCommand}"
Grid.Column="1"
VerticalAlignment="Top" />
</Grid>
<!-- Empty history -->
<StackPanel Grid.Column="1" Margin="12" VerticalAlignment="Center" Orientation="Vertical" Visibility="{Binding ColorsHistory.Count, Converter={StaticResource numberToInvertedVisibilityConverter}}">
<StackPanel Grid.Column="1" Margin="24, 12" VerticalAlignment="Center" Orientation="Vertical" Visibility="{Binding ColorsHistory.Count, Converter={StaticResource numberToInvertedVisibilityConverter}}">
<TextBlock Text="&#xEF3C;"
FontFamily="Segoe MDL2 Assets"
FontSize="44"