mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-23 19:49:43 +01:00
Added pixel reveal effect, increased max zoom level to 4, added rounded corners to main and zoom window (#6242)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
// 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;
|
||||
using System.Windows.Interactivity;
|
||||
using ColorPicker.Shaders;
|
||||
|
||||
namespace ColorPicker.Behaviors
|
||||
{
|
||||
public class GridEffectBehavior : Behavior<FrameworkElement>
|
||||
{
|
||||
private static double baseZoomImageSizeInPx = 50;
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-security#:~:text=Dependency%20properties%20should%20generally%20be%20considered%20to%20be,make%20security%20guarantees%20about%20a%20dependency%20property%20value.")]
|
||||
public static DependencyProperty EffectProperty = DependencyProperty.Register("Effect", typeof(GridShaderEffect), typeof(GridEffectBehavior));
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-security#:~:text=Dependency%20properties%20should%20generally%20be%20considered%20to%20be,make%20security%20guarantees%20about%20a%20dependency%20property%20value.")]
|
||||
public static DependencyProperty ZoomFactorProperty = DependencyProperty.Register("ZoomFactor", typeof(double), typeof(GridEffectBehavior));
|
||||
|
||||
public GridShaderEffect Effect
|
||||
{
|
||||
get { return (GridShaderEffect)GetValue(EffectProperty); }
|
||||
set { SetValue(EffectProperty, value); }
|
||||
}
|
||||
|
||||
public double ZoomFactor
|
||||
{
|
||||
get { return (double)GetValue(ZoomFactorProperty); }
|
||||
set { SetValue(ZoomFactorProperty, value); }
|
||||
}
|
||||
|
||||
protected override void OnAttached()
|
||||
{
|
||||
AssociatedObject.Loaded += AssociatedObject_Loaded;
|
||||
}
|
||||
|
||||
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AssociatedObject.MouseMove += AssociatedObject_MouseMove;
|
||||
}
|
||||
|
||||
private void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
|
||||
{
|
||||
var position = e.GetPosition(AssociatedObject);
|
||||
|
||||
var relativeX = position.X / AssociatedObject.ActualWidth;
|
||||
var relativeY = position.Y / AssociatedObject.Height;
|
||||
Effect.MousePosition = new Point(relativeX, relativeY);
|
||||
if (ZoomFactor >= 4)
|
||||
{
|
||||
Effect.Radius = 0.04;
|
||||
Effect.SquareSize = ZoomFactor;
|
||||
Effect.TextureSize = baseZoomImageSizeInPx * ZoomFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't show grid, too small pixels
|
||||
Effect.Radius = 0.0;
|
||||
Effect.SquareSize = 0;
|
||||
Effect.TextureSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,6 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
@@ -107,11 +106,14 @@
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Behaviors\GridEffectBehavior.cs" />
|
||||
<Compile Include="Helpers\IThrottledActionInvoker.cs" />
|
||||
<Compile Include="Helpers\ThrottledActionInvoker.cs" />
|
||||
<Compile Include="Settings\IUserSettings.cs" />
|
||||
<Compile Include="Settings\SettingItem`1.cs" />
|
||||
<Compile Include="Settings\UserSettings.cs" />
|
||||
<Compile Include="Shaders\Global.cs" />
|
||||
<Compile Include="Shaders\GridShaderEffect.cs" />
|
||||
<Compile Include="Telemetry\ColorPickerCancelledEvent.cs" />
|
||||
<Compile Include="Telemetry\ColorPickerShowEvent.cs" />
|
||||
<Compile Include="Telemetry\ColorPickerZoomOpenedEvent.cs" />
|
||||
@@ -208,6 +210,7 @@
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Resource Include="Shaders\GridShader.cso" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
@@ -254,5 +257,8 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Shaders\GridShader.fx" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -21,7 +21,7 @@ namespace ColorPicker.Helpers
|
||||
private const int ZoomWindowChangeDelayInMS = 50;
|
||||
private const int ZoomFactor = 2;
|
||||
private const int BaseZoomImageSize = 50;
|
||||
private const int MaxZoomLevel = 3;
|
||||
private const int MaxZoomLevel = 4;
|
||||
private const int MinZoomLevel = 0;
|
||||
|
||||
private readonly IZoomViewModel _zoomViewModel;
|
||||
|
||||
39
src/modules/colorPicker/ColorPickerUI/Shaders/Global.cs
Normal file
39
src/modules/colorPicker/ColorPickerUI/Shaders/Global.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 ColorPicker.Shaders
|
||||
{
|
||||
internal static class Global
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper method for generating a "pack://" URI for a given relative file based on the
|
||||
/// assembly that this class is in.
|
||||
/// </summary>
|
||||
public static Uri MakePackUri(string relativeFile)
|
||||
{
|
||||
string uriString = "pack://application:,,,/" + AssemblyShortName + ";component/Shaders/" + relativeFile;
|
||||
return new Uri(uriString);
|
||||
}
|
||||
|
||||
private static string AssemblyShortName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_assemblyShortName == null)
|
||||
{
|
||||
var assembly = typeof(Global).Assembly;
|
||||
|
||||
// Pull out the short name.
|
||||
_assemblyShortName = assembly.ToString().Split(',')[0];
|
||||
}
|
||||
|
||||
return _assemblyShortName;
|
||||
}
|
||||
}
|
||||
|
||||
private static string _assemblyShortName;
|
||||
}
|
||||
}
|
||||
BIN
src/modules/colorPicker/ColorPickerUI/Shaders/GridShader.cso
Normal file
BIN
src/modules/colorPicker/ColorPickerUI/Shaders/GridShader.cso
Normal file
Binary file not shown.
81
src/modules/colorPicker/ColorPickerUI/Shaders/GridShader.fx
Normal file
81
src/modules/colorPicker/ColorPickerUI/Shaders/GridShader.fx
Normal file
@@ -0,0 +1,81 @@
|
||||
float2 mousePosition : register(C1);
|
||||
float radius : register(C2);
|
||||
float squareSize : register(c3);
|
||||
float textureSize : register(c4);
|
||||
|
||||
sampler2D inputSampler : register(S0);
|
||||
|
||||
float4 main(float2 uv : TEXCOORD) : COLOR
|
||||
{
|
||||
// do not draw grid where the mouse is
|
||||
if (uv.x == mousePosition.y && uv.y == mousePosition.y)
|
||||
{
|
||||
return tex2D(inputSampler, uv);
|
||||
}
|
||||
|
||||
float gridColor = 1.0f;
|
||||
float mainRectangleColor = 1.0f;
|
||||
|
||||
float4 originalColor = tex2D(inputSampler, uv);
|
||||
float4 colorAtMousePosition = tex2D(inputSampler, mousePosition);
|
||||
|
||||
if (originalColor.r > 0.8 && originalColor.g > 0.8 && originalColor.b > 0.8)
|
||||
{
|
||||
gridColor = 0.0f;
|
||||
}
|
||||
|
||||
if (colorAtMousePosition.r > 0.8 && colorAtMousePosition.g > 0.8 && colorAtMousePosition.b > 0.8)
|
||||
{
|
||||
mainRectangleColor = 0.0f;
|
||||
}
|
||||
|
||||
float4 color = tex2D(inputSampler, uv);
|
||||
float distanceFromMouse = length(mousePosition - uv);
|
||||
float distanceFactor;
|
||||
|
||||
int pixelPositionX = textureSize * uv.x;
|
||||
int pixelPositionY = textureSize * uv.y;
|
||||
|
||||
int mousePositionX = mousePosition.x * textureSize;
|
||||
int mousePositionY = mousePosition.y * textureSize;
|
||||
|
||||
int2 topLeftRectangle = int2(mousePositionX - (mousePositionX % squareSize) - 1, mousePositionY - (mousePositionY % squareSize) - 1);
|
||||
|
||||
// do not draw grid inside square even when grid (avoid drawing grid in that area later
|
||||
if (((pixelPositionX >= topLeftRectangle.x + 1 && pixelPositionX <= topLeftRectangle.x + squareSize) && (pixelPositionY == topLeftRectangle.y + 1 || pixelPositionY == topLeftRectangle.y + squareSize)) ||
|
||||
((pixelPositionY >= topLeftRectangle.y + 1 && pixelPositionY <= topLeftRectangle.y + squareSize) && (pixelPositionX == topLeftRectangle.x + 1 || pixelPositionX == topLeftRectangle.x + squareSize)))
|
||||
{
|
||||
return originalColor;
|
||||
}
|
||||
|
||||
if (distanceFromMouse <= radius)
|
||||
{
|
||||
// draw grid
|
||||
if (pixelPositionX % squareSize == 0 || pixelPositionY % squareSize == 0)
|
||||
{
|
||||
if (gridColor == 1.0f)
|
||||
{
|
||||
color.r = color.r + ((1.0 - color.r) * (1.0 - (distanceFromMouse / radius)));
|
||||
color.g = color.g + ((1.0 - color.g) * (1.0 - (distanceFromMouse / radius)));
|
||||
color.b = color.b + ((1.0 - color.b) * (1.0 - (distanceFromMouse / radius)));
|
||||
}
|
||||
else
|
||||
{
|
||||
color.r = color.r * (distanceFromMouse / radius);
|
||||
color.g = color.g * (distanceFromMouse / radius);
|
||||
color.b = color.b * (distanceFromMouse / radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (((pixelPositionX >= topLeftRectangle.x && pixelPositionX <= topLeftRectangle.x + squareSize + 2) && (pixelPositionY == topLeftRectangle.y || pixelPositionY == topLeftRectangle.y + squareSize + 2)) ||
|
||||
((pixelPositionY >= topLeftRectangle.y && pixelPositionY <= topLeftRectangle.y + squareSize + 2) && (pixelPositionX == topLeftRectangle.x || pixelPositionX == topLeftRectangle.x + squareSize + 2)))
|
||||
{
|
||||
originalColor.r = mainRectangleColor;
|
||||
originalColor.g = mainRectangleColor;
|
||||
originalColor.b = mainRectangleColor;
|
||||
return originalColor;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// 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;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Effects;
|
||||
|
||||
namespace ColorPicker.Shaders
|
||||
{
|
||||
public class GridShaderEffect : ShaderEffect
|
||||
{
|
||||
private static readonly PixelShader Shader =
|
||||
new PixelShader()
|
||||
{
|
||||
UriSource = Global.MakePackUri("GridShader.cso"),
|
||||
};
|
||||
|
||||
public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(GridShaderEffect), 0);
|
||||
public static readonly DependencyProperty MousePositionProperty = DependencyProperty.Register("MousePosition", typeof(Point), typeof(GridShaderEffect), new UIPropertyMetadata(new Point(0D, 0D), PixelShaderConstantCallback(1)));
|
||||
public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(GridShaderEffect), new UIPropertyMetadata((double)0D, PixelShaderConstantCallback(2)));
|
||||
public static readonly DependencyProperty SquareSizeProperty = DependencyProperty.Register("SquareSize", typeof(double), typeof(GridShaderEffect), new UIPropertyMetadata((double)0D, PixelShaderConstantCallback(3)));
|
||||
public static readonly DependencyProperty TextureSizeProperty = DependencyProperty.Register("TextureSize", typeof(double), typeof(GridShaderEffect), new UIPropertyMetadata((double)0D, PixelShaderConstantCallback(4)));
|
||||
|
||||
public GridShaderEffect()
|
||||
{
|
||||
PixelShader = Shader;
|
||||
|
||||
UpdateShaderValue(InputProperty);
|
||||
UpdateShaderValue(MousePositionProperty);
|
||||
UpdateShaderValue(RadiusProperty);
|
||||
UpdateShaderValue(SquareSizeProperty);
|
||||
UpdateShaderValue(TextureSizeProperty);
|
||||
}
|
||||
|
||||
public Brush Input
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Brush)GetValue(InputProperty);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetValue(InputProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Point MousePosition
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Point)GetValue(MousePositionProperty);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetValue(MousePositionProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public double Radius
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)GetValue(RadiusProperty);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetValue(RadiusProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public double SquareSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)GetValue(SquareSizeProperty);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetValue(SquareSizeProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public double TextureSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)GetValue(TextureSizeProperty);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
SetValue(TextureSizeProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,12 @@
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.RowSpan="2" Grid.ColumnSpan="2" Grid.Column="1" Background="#202020" BorderThickness="1" BorderBrush="Black" />
|
||||
<Border Background="{Binding ColorBrush}" BorderBrush="Black" Grid.Column="1" BorderThickness="1" Grid.RowSpan="2" x:Name="ColorBorder"/>
|
||||
<Border BorderBrush="#505050" Grid.Column="2" Margin="0,1,1,1" Grid.RowSpan="2" BorderThickness="3,0,3,0" Background="#202020" CornerRadius="0" />
|
||||
<Border Background="{Binding ColorBrush}" BorderBrush="Black" Grid.Column="1" BorderThickness="1" Grid.RowSpan="2" x:Name="ColorBorder" CornerRadius="2,0,0,2"/>
|
||||
<Border Grid.RowSpan="2" Grid.ColumnSpan="2" Grid.Column="1" Background="Transparent" BorderThickness="1" BorderBrush="Black" CornerRadius="2"/>
|
||||
|
||||
<TextBlock Margin="7,5,5,5" Foreground="White" Grid.Row="0" Grid.Column="2" Text="{Binding HexColor}"/>
|
||||
<TextBlock Margin="7,0,0,0" Foreground="White" Grid.Row="1" Grid.Column="2" Text="{Binding RgbColor}"/>
|
||||
|
||||
|
||||
<Border BorderBrush="#505050" Grid.Column="2" Margin="0,1,1,1" Grid.RowSpan="2" BorderThickness="3,0,3,0" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -5,12 +5,20 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ColorPicker.Views"
|
||||
mc:Ignorable="d"
|
||||
xmlns:shaders="clr-namespace:ColorPicker.Shaders"
|
||||
xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity"
|
||||
xmlns:behaviors="clr-namespace:ColorPicker.Behaviors"
|
||||
d:DesignHeight="450" d:DesignWidth="800" BorderBrush="Black" BorderThickness="2" Focusable="False">
|
||||
<Image Source="{Binding ZoomArea}" RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Fill" Width="{Binding Width, Mode=TwoWay}" Height="{Binding Height, Mode=TwoWay}">
|
||||
<e:Interaction.Behaviors>
|
||||
<behaviors:ResizeBehavior Width="{Binding DesiredWidth}" Height="{Binding DesiredHeight}"/>
|
||||
</e:Interaction.Behaviors>
|
||||
</Image>
|
||||
d:DesignHeight="450" d:DesignWidth="800" Background="Transparent" Focusable="False">
|
||||
<Border BorderBrush="#FF2B2B2B" ClipToBounds="True" BorderThickness="2" CornerRadius="2">
|
||||
<Image Source="{Binding ZoomArea}" RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Fill" Width="{Binding Width, Mode=TwoWay}" Height="{Binding Height, Mode=TwoWay}">
|
||||
<e:Interaction.Behaviors>
|
||||
<behaviors:ResizeBehavior Width="{Binding DesiredWidth}" Height="{Binding DesiredHeight}"/>
|
||||
<behaviors:GridEffectBehavior Effect="{Binding ElementName=gridEffect}" ZoomFactor="{Binding ZoomFactor}"/>
|
||||
</e:Interaction.Behaviors>
|
||||
|
||||
<Image.Effect>
|
||||
<shaders:GridShaderEffect x:Name="gridEffect"/>
|
||||
</Image.Effect>
|
||||
</Image>
|
||||
</Border>
|
||||
</UserControl>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity"
|
||||
xmlns:behaviors="clr-namespace:ColorPicker.Behaviors"
|
||||
mc:Ignorable="d"
|
||||
Title="Zoom window" WindowStyle="None" SizeToContent="WidthAndHeight" Topmost="True" ShowInTaskbar="False" ResizeMode="NoResize" Focusable="False">
|
||||
Title="Zoom window" WindowStyle="None" SizeToContent="WidthAndHeight" Topmost="True" AllowsTransparency="True" Background="Transparent" ShowInTaskbar="False" ResizeMode="NoResize" Focusable="False">
|
||||
<e:Interaction.Behaviors>
|
||||
<behaviors:CloseZoomWindowBehavior/>
|
||||
<behaviors:MoveWindowBehavior Left="{Binding DesiredLeft, Mode=TwoWay}" Top="{Binding DesiredTop}"/>
|
||||
|
||||
Reference in New Issue
Block a user