mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 11:17:53 +01:00
[ColorPicker] CMYK, HSV and HSL color format (#6975)
* Add HSL and HSV color formats + cleanup + docu * Fix build problem (lang version) * Add CYMK color + replace float with double values * ups - fix cmyk text format * fix wrong settings text + doc typo fix * Address feedback * Address feedback + fix to small window size * adress feedback + more cleanup * typo fix * Avoid possible division by zero + unit test * Address feedback - move all represenation to own helper class + UnitTest * Address feedback -> switch to mstest framework
This commit is contained in:
@@ -269,6 +269,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Calculator
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Folder.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj", "{4FA206A5-F69F-4193-BF8F-F6EEB496734C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest-ColorPickerUI", "UnitTest-ColorPickerUI\UnitTest-ColorPickerUI.csproj", "{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logging", "src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}"
|
||||
EndProject
|
||||
Global
|
||||
@@ -545,6 +547,10 @@ Global
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|x64.Build.0 = Debug|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.ActiveCfg = Release|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.Build.0 = Release|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|x64.ActiveCfg = Release|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|x64.Build.0 = Release|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.Build.0 = Debug|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.ActiveCfg = Release|x64
|
||||
@@ -627,6 +633,7 @@ Global
|
||||
{0F85E674-34AE-443D-954C-8321EB8B93B1} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
|
||||
187
UnitTest-ColorPickerUI/Helpers/ColorHelperTest.cs
Normal file
187
UnitTest-ColorPickerUI/Helpers/ColorHelperTest.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using ColorPicker.Helpers;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace UnitTest_ColorPickerUI.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Test class to test <see cref="ColorConverter"/>
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class ColorConverterTest
|
||||
{
|
||||
// test values taken from https://de.wikipedia.org/wiki/HSV-Farbraum
|
||||
[TestMethod]
|
||||
[DataRow(000, 000, 000, 000, 000, 000)] // Black
|
||||
[DataRow(000, 000, 100, 100, 100, 100)] // White
|
||||
[DataRow(000, 100, 050, 100, 000, 000)] // Red
|
||||
[DataRow(015, 100, 050, 100, 025, 000)] // Vermilion/Cinnabar
|
||||
[DataRow(020, 060, 022.5, 036, 018, 009)] // Brown
|
||||
[DataRow(030, 100, 050, 100, 050, 000)] // Orange
|
||||
[DataRow(045, 100, 050, 100, 075, 000)] // Saffron
|
||||
[DataRow(060, 100, 050, 100, 100, 000)] // Yellow
|
||||
[DataRow(075, 100, 050, 075, 100, 000)] // Light green-yellow
|
||||
[DataRow(090, 100, 050, 050, 100, 000)] // Green-yellow
|
||||
[DataRow(105, 100, 050, 025, 100, 000)] // Lime
|
||||
[DataRow(120, 100, 025, 000, 050, 000)] // Dark green
|
||||
[DataRow(120, 100, 050, 000, 100, 000)] // Green
|
||||
[DataRow(135, 100, 050, 000, 100, 025)] // Light blue-green
|
||||
[DataRow(150, 100, 050, 000, 100, 050)] // Blue-green
|
||||
[DataRow(165, 100, 050, 000, 100, 075)] // Green-cyan
|
||||
[DataRow(180, 100, 050, 000, 100, 100)] // Cyan
|
||||
[DataRow(195, 100, 050, 000, 075, 100)] // Blue-cyan
|
||||
[DataRow(210, 100, 050, 000, 050, 100)] // Green-blue
|
||||
[DataRow(225, 100, 050, 000, 025, 100)] // Light green-blue
|
||||
[DataRow(240, 100, 050, 000, 000, 100)] // Blue
|
||||
[DataRow(255, 100, 050, 025, 000, 100)] // Indigo
|
||||
[DataRow(270, 100, 050, 050, 000, 100)] // Purple
|
||||
[DataRow(285, 100, 050, 075, 000, 100)] // Blue-magenta
|
||||
[DataRow(300, 100, 050, 100, 000, 100)] // Magenta
|
||||
[DataRow(315, 100, 050, 100, 000, 075)] // Red-magenta
|
||||
[DataRow(330, 100, 050, 100, 000, 050)] // Blue-red
|
||||
[DataRow(345, 100, 050, 100, 000, 025)] // Light blue-red
|
||||
public void ColorRGBtoHSL(double hue, double saturation, double lightness, int red, int green, int blue)
|
||||
{
|
||||
red = Convert.ToInt32(Math.Round(255d / 100d * red)); // [0%..100%] to [0..255]
|
||||
green = Convert.ToInt32(Math.Round(255d / 100d * green)); // [0%..100%] to [0..255]
|
||||
blue = Convert.ToInt32(Math.Round(255d / 100d * blue)); // [0%..100%] to [0..255]
|
||||
|
||||
var color = Color.FromArgb(255, red, green, blue);
|
||||
var result = ColorHelper.ConvertToHSLColor(color);
|
||||
|
||||
// hue[0<>..360<EFBFBD>]
|
||||
Assert.AreEqual(result.hue, hue, 0.2d);
|
||||
|
||||
// saturation[0..1]
|
||||
Assert.AreEqual(result.saturation * 100d, saturation, 0.2d);
|
||||
|
||||
// lightness[0..1]
|
||||
Assert.AreEqual(result.lightness * 100d, lightness, 0.2d);
|
||||
}
|
||||
|
||||
// test values taken from https://de.wikipedia.org/wiki/HSV-Farbraum
|
||||
[TestMethod]
|
||||
[DataRow(000, 000, 000, 000, 000, 000)] // Black
|
||||
[DataRow(000, 000, 100, 100, 100, 100)] // White
|
||||
[DataRow(000, 100, 100, 100, 000, 000)] // Red
|
||||
[DataRow(015, 100, 100, 100, 025, 000)] // Vermilion/Cinnabar
|
||||
[DataRow(020, 075, 036, 036, 018, 009)] // Brown
|
||||
[DataRow(030, 100, 100, 100, 050, 000)] // Orange
|
||||
[DataRow(045, 100, 100, 100, 075, 000)] // Saffron
|
||||
[DataRow(060, 100, 100, 100, 100, 000)] // Yellow
|
||||
[DataRow(075, 100, 100, 075, 100, 000)] // Light green-yellow
|
||||
[DataRow(090, 100, 100, 050, 100, 000)] // Green-yellow
|
||||
[DataRow(105, 100, 100, 025, 100, 000)] // Lime
|
||||
[DataRow(120, 100, 050, 000, 050, 000)] // Dark green
|
||||
[DataRow(120, 100, 100, 000, 100, 000)] // Green
|
||||
[DataRow(135, 100, 100, 000, 100, 025)] // Light blue-green
|
||||
[DataRow(150, 100, 100, 000, 100, 050)] // Blue-green
|
||||
[DataRow(165, 100, 100, 000, 100, 075)] // Green-cyan
|
||||
[DataRow(180, 100, 100, 000, 100, 100)] // Cyan
|
||||
[DataRow(195, 100, 100, 000, 075, 100)] // Blue-cyan
|
||||
[DataRow(210, 100, 100, 000, 050, 100)] // Green-blue
|
||||
[DataRow(225, 100, 100, 000, 025, 100)] // Light green-blue
|
||||
[DataRow(240, 100, 100, 000, 000, 100)] // Blue
|
||||
[DataRow(255, 100, 100, 025, 000, 100)] // Indigo
|
||||
[DataRow(270, 100, 100, 050, 000, 100)] // Purple
|
||||
[DataRow(285, 100, 100, 075, 000, 100)] // Blue-magenta
|
||||
[DataRow(300, 100, 100, 100, 000, 100)] // Magenta
|
||||
[DataRow(315, 100, 100, 100, 000, 075)] // Red-magenta
|
||||
[DataRow(330, 100, 100, 100, 000, 050)] // Blue-red
|
||||
[DataRow(345, 100, 100, 100, 000, 025)] // Light blue-red
|
||||
public void ColorRGBtoHSV(double hue, double saturation, double value, int red, int green, int blue)
|
||||
{
|
||||
red = Convert.ToInt32(Math.Round(255d / 100d * red)); // [0%..100%] to [0..255]
|
||||
green = Convert.ToInt32(Math.Round(255d / 100d * green)); // [0%..100%] to [0..255]
|
||||
blue = Convert.ToInt32(Math.Round(255d / 100d * blue)); // [0%..100%] to [0..255]
|
||||
|
||||
var color = Color.FromArgb(255, red, green, blue);
|
||||
var result = ColorHelper.ConvertToHSVColor(color);
|
||||
|
||||
// hue [0<>..360<EFBFBD>]
|
||||
Assert.AreEqual(result.hue, hue, 0.2d);
|
||||
|
||||
// saturation[0..1]
|
||||
Assert.AreEqual(result.saturation * 100d, saturation, 0.2d);
|
||||
|
||||
// value[0..1]
|
||||
Assert.AreEqual(result.value * 100d, value, 0.2d);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[DataRow(000, 000, 000, 100, 000, 000, 000)] // Black
|
||||
[DataRow(000, 000, 000, 000, 255, 255, 255)] // White
|
||||
[DataRow(000, 100, 100, 000, 255, 000, 000)] // Red
|
||||
[DataRow(000, 075, 100, 000, 255, 064, 000)] // Vermilion/Cinnabar
|
||||
[DataRow(000, 050, 075, 064, 092, 046, 023)] // Brown
|
||||
[DataRow(000, 050, 100, 000, 255, 128, 000)] // Orange
|
||||
[DataRow(000, 025, 100, 000, 255, 192, 000)] // Saffron
|
||||
[DataRow(000, 000, 100, 000, 255, 255, 000)] // Yellow
|
||||
[DataRow(025, 000, 100, 000, 192, 255, 000)] // Light green-yellow
|
||||
[DataRow(050, 000, 100, 000, 128, 255, 000)] // Green-yellow
|
||||
[DataRow(075, 000, 100, 000, 064, 255, 000)] // Lime
|
||||
[DataRow(100, 000, 100, 050, 000, 128, 000)] // Dark green
|
||||
[DataRow(100, 000, 100, 000, 000, 255, 000)] // Green
|
||||
[DataRow(100, 000, 075, 000, 000, 255, 064)] // Light blue-green
|
||||
[DataRow(100, 000, 050, 000, 000, 255, 128)] // Blue-green
|
||||
[DataRow(100, 000, 025, 000, 000, 255, 192)] // Green-cyan
|
||||
[DataRow(100, 000, 000, 000, 000, 255, 255)] // Cyan
|
||||
[DataRow(100, 025, 000, 000, 000, 192, 255)] // Blue-cyan
|
||||
[DataRow(100, 050, 000, 000, 000, 128, 255)] // Green-blue
|
||||
[DataRow(100, 075, 000, 000, 000, 064, 255)] // Light green-blue
|
||||
[DataRow(100, 100, 000, 000, 000, 000, 255)] // Blue
|
||||
[DataRow(075, 100, 000, 000, 064, 000, 255)] // Indigo
|
||||
[DataRow(050, 100, 000, 000, 128, 000, 255)] // Purple
|
||||
[DataRow(025, 100, 000, 000, 192, 000, 255)] // Blue-magenta
|
||||
[DataRow(000, 100, 000, 000, 255, 000, 255)] // Magenta
|
||||
[DataRow(000, 100, 025, 000, 255, 000, 192)] // Red-magenta
|
||||
[DataRow(000, 100, 050, 000, 255, 000, 128)] // Blue-red
|
||||
[DataRow(000, 100, 075, 000, 255, 000, 064)] // Light blue-red
|
||||
public void ColorRGBtoCMYK(int cyan, int magenta, int yellow, int blackKey, int red, int green, int blue)
|
||||
{
|
||||
var color = Color.FromArgb(255, red, green, blue);
|
||||
var result = ColorHelper.ConvertToCMYKColor(color);
|
||||
|
||||
// cyan[0..1]
|
||||
Assert.AreEqual(result.cyan * 100d, cyan, 0.5d);
|
||||
|
||||
// magenta[0..1]
|
||||
Assert.AreEqual(result.magenta * 100d, magenta, 0.5d);
|
||||
|
||||
// yellow[0..1]
|
||||
Assert.AreEqual(result.yellow * 100d, yellow, 0.5d);
|
||||
|
||||
// black[0..1]
|
||||
Assert.AreEqual(result.blackKey * 100d, blackKey, 0.5d);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ColorRGBtoCMYKZeroDiv()
|
||||
{
|
||||
for(var red = 0; red < 256; red++)
|
||||
{
|
||||
for(var blue = 0; blue < 256; blue++)
|
||||
{
|
||||
for(var green = 0; green < 256; green++)
|
||||
{
|
||||
var color = Color.FromArgb(red, green, blue);
|
||||
|
||||
Exception? exception = null;
|
||||
|
||||
try
|
||||
{
|
||||
_ = ColorHelper.ConvertToCMYKColor(color);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
|
||||
Assert.IsNull(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using ColorPicker.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.Drawing;
|
||||
|
||||
namespace UnitTest_ColorPickerUI.Helpers
|
||||
{
|
||||
[TestClass]
|
||||
public class ColorRepresentationHelperTest
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow(ColorRepresentationType.CMYK, "cmyk(0%, 0%, 0%, 100%)")]
|
||||
[DataRow(ColorRepresentationType.HEX, "#000000")]
|
||||
[DataRow(ColorRepresentationType.HSL, "hsl(0, 0%, 0%)")]
|
||||
[DataRow(ColorRepresentationType.HSV, "hsv(0, 0%, 0%)")]
|
||||
[DataRow(ColorRepresentationType.RGB, "rgb(0, 0, 0)")]
|
||||
|
||||
public void ColorRGBtoCMYKZeroDiv(ColorRepresentationType type, string expected)
|
||||
{
|
||||
var result = ColorRepresentationHelper.GetStringRepresentation(Color.Black, type);
|
||||
Assert.AreEqual(result, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj
Normal file
35
UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj
Normal file
@@ -0,0 +1,35 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>UnitTest_ColorPickerUI</RootNamespace>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.3.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\src\core\Microsoft.PowerToys.Settings.UI.Lib\Microsoft.PowerToys.Settings.UI.Lib.csproj" />
|
||||
<ProjectReference Include="..\src\modules\colorPicker\ColorPickerUI\ColorPickerUI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -9,8 +9,30 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
{
|
||||
public enum ColorRepresentationType
|
||||
{
|
||||
/// <summary>
|
||||
/// Color presentation as hexadecimal color value without the alpha-value (e.g. #0055FF)
|
||||
/// </summary>
|
||||
HEX = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Color presentation as RGB color value (red[0..255], green[0..255], blue[0..255])
|
||||
/// </summary>
|
||||
RGB = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Color presentation as CMYK color value (cyan[0%..100%], magenta[0%..100%], yellow[0%..100%], black key[0%..100%])
|
||||
/// </summary>
|
||||
CMYK = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Color presentation as HSL color value (hue[0°..360°], saturation[0..100%], lightness[0%..100%])
|
||||
/// </summary>
|
||||
HSL = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Color presentation as HSV color value (hue[0°..360°], saturation[0%..100%], value[0%..100%])
|
||||
/// </summary>
|
||||
HSV = 4,
|
||||
}
|
||||
|
||||
public class ColorPickerProperties
|
||||
@@ -31,8 +53,6 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
||||
public ColorRepresentationType CopiedColorRepresentation { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
}
|
||||
=> JsonSerializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,10 @@
|
||||
Width="240"
|
||||
IsEnabled="{Binding IsEnabled}">
|
||||
<ComboBoxItem Content="HEX - #FFAA00"/>
|
||||
<ComboBoxItem Content="RGB - RGB(100, 50, 75)"/>
|
||||
<ComboBoxItem Content="RGB - rgb(100, 50, 75)"/>
|
||||
<ComboBoxItem Content="CMYK - cmyk(100%, 50%, 75%, 0%)"/>
|
||||
<ComboBoxItem Content="HSL - hsl(100, 50%, 75%)"/>
|
||||
<ComboBoxItem Content="HSV - hsv(100, 50%, 75%)"/>
|
||||
</ComboBox>
|
||||
|
||||
<!--
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Interactivity;
|
||||
using System.Windows.Media.Animation;
|
||||
using ColorPicker.Constants;
|
||||
|
||||
namespace ColorPicker.Behaviors
|
||||
{
|
||||
@@ -37,21 +38,31 @@ namespace ColorPicker.Behaviors
|
||||
|
||||
private void Appear()
|
||||
{
|
||||
var opacityAppear = new DoubleAnimation(0, 1.0, new Duration(TimeSpan.FromMilliseconds(250)));
|
||||
opacityAppear.EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseOut };
|
||||
var duration = new Duration(TimeSpan.FromMilliseconds(250));
|
||||
|
||||
var resize = new DoubleAnimation(0, 180, new Duration(TimeSpan.FromMilliseconds(250)));
|
||||
resize.EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut };
|
||||
AssociatedObject.BeginAnimation(Window.OpacityProperty, opacityAppear);
|
||||
AssociatedObject.BeginAnimation(Window.WidthProperty, resize);
|
||||
var opacityAppear = new DoubleAnimation(0d, 1d, duration)
|
||||
{
|
||||
EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseOut },
|
||||
};
|
||||
|
||||
var resize = new DoubleAnimation(0d, WindowConstant.PickerWindowWidth, duration)
|
||||
{
|
||||
EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },
|
||||
};
|
||||
|
||||
AssociatedObject.BeginAnimation(UIElement.OpacityProperty, opacityAppear);
|
||||
AssociatedObject.BeginAnimation(FrameworkElement.WidthProperty, resize);
|
||||
}
|
||||
|
||||
private void Hide()
|
||||
{
|
||||
var opacityAppear = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(1)));
|
||||
var resize = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(1)));
|
||||
AssociatedObject.BeginAnimation(Window.OpacityProperty, opacityAppear);
|
||||
AssociatedObject.BeginAnimation(Window.WidthProperty, resize);
|
||||
var duration = new Duration(TimeSpan.FromMilliseconds(1));
|
||||
|
||||
var opacityAppear = new DoubleAnimation(0d, duration);
|
||||
var resize = new DoubleAnimation(0d, duration);
|
||||
|
||||
AssociatedObject.BeginAnimation(UIElement.OpacityProperty, opacityAppear);
|
||||
AssociatedObject.BeginAnimation(FrameworkElement.WidthProperty, resize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
using System.ComponentModel.Composition;
|
||||
using System.ComponentModel.Composition.Hosting;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("UnitTest-ColorPickerUI")]
|
||||
|
||||
namespace ColorPicker
|
||||
{
|
||||
@@ -21,8 +24,6 @@ namespace ColorPicker
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
Container.Dispose();
|
||||
}
|
||||
=> Container.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
@@ -73,7 +73,7 @@
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
@@ -107,6 +107,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Behaviors\GridEffectBehavior.cs" />
|
||||
<Compile Include="Constants\WindowConstant.cs" />
|
||||
<Compile Include="Helpers\ColorHelper.cs" />
|
||||
<Compile Include="Helpers\ColorRepresentationHelper.cs" />
|
||||
<Compile Include="Helpers\IThrottledActionInvoker.cs" />
|
||||
<Compile Include="Helpers\ThrottledActionInvoker.cs" />
|
||||
<Compile Include="NativeMethods.cs" />
|
||||
|
||||
@@ -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 ColorPicker.Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains all assembly wide constants for windows and views
|
||||
/// </summary>
|
||||
public static class WindowConstant
|
||||
{
|
||||
/// <summary>
|
||||
/// The width of the color picker window
|
||||
/// </summary>
|
||||
public const double PickerWindowWidth = 240d;
|
||||
}
|
||||
}
|
||||
84
src/modules/colorPicker/ColorPickerUI/Helpers/ColorHelper.cs
Normal file
84
src/modules/colorPicker/ColorPickerUI/Helpers/ColorHelper.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
// 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.Drawing;
|
||||
|
||||
namespace ColorPicker.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to easier work with colors
|
||||
/// </summary>
|
||||
internal static class ColorHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert a given <see cref="Color"/> color to a HSL color (hue, saturation, lightness)
|
||||
/// </summary>
|
||||
/// <param name="color">The <see cref="Color"/> to convert</param>
|
||||
/// <returns>The hue [0°..360°], saturation [0..1] and lightness [0..1] values of the converted color</returns>
|
||||
internal static (double hue, double saturation, double lightness) ConvertToHSLColor(Color color)
|
||||
{
|
||||
var min = Math.Min(Math.Min(color.R, color.G), color.B) / 255d;
|
||||
var max = Math.Max(Math.Max(color.R, color.G), color.B) / 255d;
|
||||
|
||||
var lightness = (max + min) / 2d;
|
||||
|
||||
if (lightness == 0d || min == max)
|
||||
{
|
||||
return (color.GetHue(), 0d, lightness);
|
||||
}
|
||||
else if (lightness is > 0d and <= 0.5d)
|
||||
{
|
||||
return (color.GetHue(), (max - min) / (max + min), lightness);
|
||||
}
|
||||
|
||||
return (color.GetHue(), (max - min) / (2d - (max + min)), lightness);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a given <see cref="Color"/> color to a HSV color (hue, saturation, value)
|
||||
/// </summary>
|
||||
/// <param name="color">The <see cref="Color"/> to convert</param>
|
||||
/// <returns>The hue [0°..360°], saturation [0..1] and value [0..1] of the converted color</returns>
|
||||
internal static (double hue, double saturation, double value) ConvertToHSVColor(Color color)
|
||||
{
|
||||
var min = Math.Min(Math.Min(color.R, color.G), color.B) / 255d;
|
||||
var max = Math.Max(Math.Max(color.R, color.G), color.B) / 255d;
|
||||
|
||||
return (color.GetHue(), max == 0d ? 0d : (max - min) / max, max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a given <see cref="Color"/> color to a CYMK color (cyan, magenta, yellow, black key)
|
||||
/// </summary>
|
||||
/// <param name="color">The <see cref="Color"/> to convert</param>
|
||||
/// <returns>The cyan[0..1], magenta[0..1], yellow[0..1] and black key[0..1] of the converted color</returns>
|
||||
internal static (double cyan, double magenta, double yellow, double blackKey) ConvertToCMYKColor(Color color)
|
||||
{
|
||||
// special case for black (avoid division by zero)
|
||||
if (color.R == 0 && color.G == 0 && color.B == 0)
|
||||
{
|
||||
return (0d, 0d, 0d, 1d);
|
||||
}
|
||||
|
||||
var red = color.R / 255d;
|
||||
var green = color.G / 255d;
|
||||
var blue = color.B / 255d;
|
||||
|
||||
var blackKey = 1d - Math.Max(Math.Max(red, green), blue);
|
||||
|
||||
// special case for black (avoid division by zero)
|
||||
if (1d - blackKey == 0d)
|
||||
{
|
||||
return (0d, 0d, 0d, 1d);
|
||||
}
|
||||
|
||||
var cyan = (1d - red - blackKey) / (1d - blackKey);
|
||||
var magenta = (1d - green - blackKey) / (1d - blackKey);
|
||||
var yellow = (1d - blue - blackKey) / (1d - blackKey);
|
||||
|
||||
return (cyan, magenta, yellow, blackKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// 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.Drawing;
|
||||
using System.Globalization;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
|
||||
namespace ColorPicker.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to easier work with color represantation
|
||||
/// </summary>
|
||||
internal static class ColorRepresentationHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Return a <see cref="string"/> representation of a given <see cref="Color"/>
|
||||
/// </summary>
|
||||
/// <param name="color">The <see cref="Color"/> for the presentation</param>
|
||||
/// <param name="colorRepresentationType">The type of the representation</param>
|
||||
/// <returns>A <see cref="string"/> representation of a color</returns>
|
||||
internal static string GetStringRepresentation(Color color, ColorRepresentationType colorRepresentationType)
|
||||
=> colorRepresentationType switch
|
||||
{
|
||||
ColorRepresentationType.CMYK => ColorToCYMK(color),
|
||||
ColorRepresentationType.HEX => ColorToHex(color),
|
||||
ColorRepresentationType.HSL => ColorToHSL(color),
|
||||
ColorRepresentationType.HSV => ColorToHSV(color),
|
||||
ColorRepresentationType.RGB => ColorToRGB(color),
|
||||
|
||||
// Fall-back value, when "_userSettings.CopiedColorRepresentation.Value" is incorrect
|
||||
_ => ColorToHex(color),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Return a hexadecimal <see cref="string"/> representation of a RGB color
|
||||
/// </summary>
|
||||
/// <param name="color">The see cref="Color"/> for the hexadecimal presentation</param>
|
||||
/// <returns>A hexadecimal <see cref="string"/> representation of a RGB color</returns>
|
||||
private static string ColorToHex(Color color)
|
||||
=> $"#{color.R.ToString("X2", CultureInfo.InvariantCulture)}"
|
||||
+ $"{color.G.ToString("X2", CultureInfo.InvariantCulture)}"
|
||||
+ $"{color.B.ToString("X2", CultureInfo.InvariantCulture)}";
|
||||
|
||||
/// <summary>
|
||||
/// Return a <see cref="string"/> representation of a RGB color
|
||||
/// </summary>
|
||||
/// <param name="color">The see cref="Color"/> for the RGB color presentation</param>
|
||||
/// <returns>A <see cref="string"/> representation of a RGB color</returns>
|
||||
private static string ColorToRGB(Color color)
|
||||
=> $"rgb({color.R.ToString(CultureInfo.InvariantCulture)}"
|
||||
+ $", {color.G.ToString(CultureInfo.InvariantCulture)}"
|
||||
+ $", {color.B.ToString(CultureInfo.InvariantCulture)})";
|
||||
|
||||
/// <summary>
|
||||
/// Return a <see cref="string"/> representation of a HSL color
|
||||
/// </summary>
|
||||
/// <param name="color">The see cref="Color"/> for the HSL color presentation</param>
|
||||
/// <returns>A <see cref="string"/> representation of a HSL color</returns>
|
||||
private static string ColorToHSL(Color color)
|
||||
{
|
||||
var (hue, saturation, lightness) = ColorHelper.ConvertToHSLColor(color);
|
||||
|
||||
hue = Math.Round(hue);
|
||||
saturation = Math.Round(saturation * 100);
|
||||
lightness = Math.Round(lightness * 100);
|
||||
|
||||
return $"hsl({hue.ToString(CultureInfo.InvariantCulture)}"
|
||||
+ $", {saturation.ToString(CultureInfo.InvariantCulture)}%"
|
||||
+ $", {lightness.ToString(CultureInfo.InvariantCulture)}%)";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a <see cref="string"/> representation of a HSV color
|
||||
/// </summary>
|
||||
/// <param name="color">The see cref="Color"/> for the HSV color presentation</param>
|
||||
/// <returns>A <see cref="string"/> representation of a HSV color</returns>
|
||||
private static string ColorToHSV(Color color)
|
||||
{
|
||||
var (hue, saturation, value) = ColorHelper.ConvertToHSVColor(color);
|
||||
|
||||
hue = Math.Round(hue);
|
||||
saturation = Math.Round(saturation * 100);
|
||||
value = Math.Round(value * 100);
|
||||
|
||||
return $"hsv({hue.ToString(CultureInfo.InvariantCulture)}"
|
||||
+ $", {saturation.ToString(CultureInfo.InvariantCulture)}%"
|
||||
+ $", {value.ToString(CultureInfo.InvariantCulture)}%)";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a <see cref="string"/> representation of a HSV color
|
||||
/// </summary>
|
||||
/// <param name="color">The see cref="Color"/> for the HSV color presentation</param>
|
||||
/// <returns>A <see cref="string"/> representation of a HSV color</returns>
|
||||
private static string ColorToCYMK(Color color)
|
||||
{
|
||||
var (cyan, magenta, yellow, blackKey) = ColorHelper.ConvertToCMYKColor(color);
|
||||
|
||||
cyan = Math.Round(cyan * 100);
|
||||
magenta = Math.Round(magenta * 100);
|
||||
yellow = Math.Round(yellow * 100);
|
||||
blackKey = Math.Round(blackKey * 100);
|
||||
|
||||
return $"cmyk({cyan.ToString(CultureInfo.InvariantCulture)}%"
|
||||
+ $", {magenta.ToString(CultureInfo.InvariantCulture)}%"
|
||||
+ $", {yellow.ToString(CultureInfo.InvariantCulture)}%"
|
||||
+ $", {blackKey.ToString(CultureInfo.InvariantCulture)}%)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,11 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:ColorPickerUI"
|
||||
xmlns:constants="clr-namespace:ColorPicker.Constants"
|
||||
mc:Ignorable="d"
|
||||
xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity"
|
||||
xmlns:behaviors="clr-namespace:ColorPicker.Behaviors"
|
||||
Title="Color Picker" Height="50" Width="180" WindowStyle="None" Opacity="0.01" ShowInTaskbar="False" ResizeMode="NoResize" Topmost="True" Background="Transparent" AllowsTransparency="True">
|
||||
Title="Color Picker" Height="50" Width="{x:Static constants:WindowConstant.PickerWindowWidth}" WindowStyle="None" Opacity="0.01" ShowInTaskbar="False" ResizeMode="NoResize" Topmost="True" Background="Transparent" AllowsTransparency="True">
|
||||
<e:Interaction.Behaviors>
|
||||
<behaviors:ChangeWindowPositionBehavior/>
|
||||
<behaviors:AppearAnimationBehavior/>
|
||||
|
||||
@@ -8,10 +8,14 @@ namespace ColorPicker.ViewModelContracts
|
||||
{
|
||||
public interface IMainViewModel
|
||||
{
|
||||
string HexColor { get; }
|
||||
|
||||
string RgbColor { get; }
|
||||
/// <summary>
|
||||
/// Gets the text representation of the selected color value
|
||||
/// </summary>
|
||||
string ColorText { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current selected color as a <see cref="Brush"/>
|
||||
/// </summary>
|
||||
Brush ColorBrush { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using ColorPicker.Common;
|
||||
@@ -23,11 +23,23 @@ namespace ColorPicker.ViewModels
|
||||
[Export(typeof(IMainViewModel))]
|
||||
public class MainViewModel : ViewModelBase, IMainViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Defined error code for "clipboard can't open"
|
||||
/// </summary>
|
||||
private const uint ErrorCodeClipboardCantOpen = 0x800401D0;
|
||||
|
||||
private readonly ZoomWindowHelper _zoomWindowHelper;
|
||||
private readonly AppStateHandler _appStateHandler;
|
||||
private readonly IUserSettings _userSettings;
|
||||
private string _hexColor;
|
||||
private string _rgbColor;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="OtherColor"/>
|
||||
/// </summary>
|
||||
private string _colorText;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="ColorBrush"/>
|
||||
/// </summary>
|
||||
private Brush _colorBrush;
|
||||
|
||||
[ImportingConstructor]
|
||||
@@ -52,41 +64,12 @@ namespace ColorPicker.ViewModels
|
||||
keyboardMonitor?.Start();
|
||||
}
|
||||
|
||||
public string HexColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return _hexColor;
|
||||
}
|
||||
|
||||
private set
|
||||
{
|
||||
_hexColor = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string RgbColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return _rgbColor;
|
||||
}
|
||||
|
||||
private set
|
||||
{
|
||||
_rgbColor = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current selected color as a <see cref="Brush"/>
|
||||
/// </summary>
|
||||
public Brush ColorBrush
|
||||
{
|
||||
get
|
||||
{
|
||||
return _colorBrush;
|
||||
}
|
||||
|
||||
get => _colorBrush;
|
||||
private set
|
||||
{
|
||||
_colorBrush = value;
|
||||
@@ -94,74 +77,80 @@ namespace ColorPicker.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private void Mouse_ColorChanged(object sender, System.Drawing.Color color)
|
||||
/// <summary>
|
||||
/// Gets the text representation of the selected color value
|
||||
/// </summary>
|
||||
public string ColorText
|
||||
{
|
||||
HexColor = ColorToHex(color);
|
||||
RgbColor = ColorToRGB(color);
|
||||
ColorBrush = new SolidColorBrush(Color.FromArgb(color.A, color.R, color.G, color.B));
|
||||
get => _colorText;
|
||||
private set
|
||||
{
|
||||
_colorText = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell the color picker that the color on the position of the mouse cursor have changed
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="color">The new <see cref="Color"/> under the mouse cursor</param>
|
||||
private void Mouse_ColorChanged(object sender, System.Drawing.Color color)
|
||||
{
|
||||
ColorBrush = new SolidColorBrush(Color.FromArgb(color.A, color.R, color.G, color.B));
|
||||
ColorText = ColorRepresentationHelper.GetStringRepresentation(color, _userSettings.CopiedColorRepresentation.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell the color picker that the user have press a mouse button (after release the button)
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="p">The current <see cref="System.Drawing.Point"/> of the mouse cursor</param>
|
||||
private void MouseInfoProvider_OnMouseDown(object sender, System.Drawing.Point p)
|
||||
{
|
||||
string colorRepresentationToCopy = string.Empty;
|
||||
|
||||
switch (_userSettings.CopiedColorRepresentation.Value)
|
||||
{
|
||||
case ColorRepresentationType.HEX:
|
||||
colorRepresentationToCopy = HexColor;
|
||||
break;
|
||||
case ColorRepresentationType.RGB:
|
||||
colorRepresentationToCopy = RgbColor;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CopyToClipboard(colorRepresentationToCopy);
|
||||
CopyToClipboard(ColorText);
|
||||
|
||||
_appStateHandler.HideColorPicker();
|
||||
PowerToysTelemetry.Log.WriteEvent(new ColorPickerShowEvent());
|
||||
}
|
||||
|
||||
private static void CopyToClipboard(string colorRepresentationToCopy)
|
||||
/// <summary>
|
||||
/// Copy the given text to the Windows clipboard
|
||||
/// </summary>
|
||||
/// <param name="text">The text to copy to the Windows clipboard</param>
|
||||
private static void CopyToClipboard(string text)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(colorRepresentationToCopy))
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
// nasty hack - sometimes clipboard can be in use and it will raise and exception
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(colorRepresentationToCopy);
|
||||
break;
|
||||
}
|
||||
catch (COMException ex)
|
||||
{
|
||||
const uint CLIPBRD_E_CANT_OPEN = 0x800401D0;
|
||||
if ((uint)ex.ErrorCode != CLIPBRD_E_CANT_OPEN)
|
||||
{
|
||||
Logger.LogError("Failed to set text into clipboard", ex);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(10);
|
||||
// nasty hack - sometimes clipboard can be in use and it will raise and exception
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(text);
|
||||
break;
|
||||
}
|
||||
catch (COMException ex)
|
||||
{
|
||||
if ((uint)ex.ErrorCode != ErrorCodeClipboardCantOpen)
|
||||
{
|
||||
Logger.LogError("Failed to set text into clipboard", ex);
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell the color picker that the user have used the mouse wheel
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender of this event</param>
|
||||
/// <param name="e">The new values for the zoom</param>
|
||||
private void MouseInfoProvider_OnMouseWheel(object sender, Tuple<Point, bool> e)
|
||||
{
|
||||
_zoomWindowHelper.Zoom(e.Item1, e.Item2);
|
||||
}
|
||||
|
||||
private static string ColorToHex(System.Drawing.Color c)
|
||||
{
|
||||
return "#" + c.R.ToString("X2", CultureInfo.InvariantCulture) + c.G.ToString("X2", CultureInfo.InvariantCulture) + c.B.ToString("X2", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private static string ColorToRGB(System.Drawing.Color c)
|
||||
{
|
||||
return "RGB(" + c.R.ToString(CultureInfo.InvariantCulture) + "," + c.G.ToString(CultureInfo.InvariantCulture) + "," + c.B.ToString(CultureInfo.InvariantCulture) + ")";
|
||||
}
|
||||
=> _zoomWindowHelper.Zoom(e.Item1, e.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,55 @@
|
||||
<UserControl x:Class="ColorPicker.Views.MainView"
|
||||
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:local="clr-namespace:ColorPicker.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:viewModel="clr-namespace:ColorPicker.ViewModels"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="50" d:DesignWidth="180"
|
||||
d:DataContext="{d:DesignInstance viewModel:MainViewModel, IsDesignTimeCreatable=True}">
|
||||
xmlns:constants="clr-namespace:ColorPicker.Constants"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="50"
|
||||
d:DesignWidth="{x:Static constants:WindowConstant.PickerWindowWidth}"
|
||||
d:DataContext="{d:DesignInstance viewModel:MainViewModel, IsDesignTimeCreatable=True}" >
|
||||
|
||||
<Grid Background="Transparent" >
|
||||
<Grid>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="20"/>
|
||||
<ColumnDefinition Width="50"/>
|
||||
<ColumnDefinition Width="20" />
|
||||
<ColumnDefinition Width="50" />
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<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 Grid.Column="2"
|
||||
Margin="0,1,1,1"
|
||||
Background="#202020"
|
||||
BorderBrush="#505050"
|
||||
BorderThickness="3,0,3,0"
|
||||
CornerRadius="0" />
|
||||
|
||||
<Border Grid.Column="1"
|
||||
Background="{Binding ColorBrush}"
|
||||
BorderBrush="Black"
|
||||
BorderThickness="1"
|
||||
CornerRadius="2,0,0,2" />
|
||||
|
||||
<Border Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
Background="Transparent"
|
||||
BorderThickness="1"
|
||||
BorderBrush="Black"
|
||||
CornerRadius="2" />
|
||||
|
||||
<TextBlock Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Margin="7,0,0,0"
|
||||
Foreground="White"
|
||||
Text="{Binding ColorText}" />
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace ColorPicker.Views
|
||||
public partial class MainView : UserControl
|
||||
{
|
||||
public MainView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
=> InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,39 @@
|
||||
<UserControl x:Class="ColorPicker.Views.ZoomView"
|
||||
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:local="clr-namespace:ColorPicker.Views"
|
||||
mc:Ignorable="d"
|
||||
xmlns:shaders="clr-namespace:ColorPicker.Shaders"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:behaviors="clr-namespace:ColorPicker.Behaviors"
|
||||
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}">
|
||||
xmlns:shaders="clr-namespace:ColorPicker.Shaders"
|
||||
Background="Transparent"
|
||||
Focusable="False"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d" >
|
||||
|
||||
<Border BorderBrush="#FF2B2B2B"
|
||||
BorderThickness="2"
|
||||
ClipToBounds="True"
|
||||
CornerRadius="2" >
|
||||
|
||||
<Image Source="{Binding ZoomArea}"
|
||||
Height="{Binding Height, Mode=TwoWay}"
|
||||
Width="{Binding Width, Mode=TwoWay}"
|
||||
RenderOptions.BitmapScalingMode="NearestNeighbor"
|
||||
Stretch="Fill" >
|
||||
|
||||
<e:Interaction.Behaviors>
|
||||
<behaviors:ResizeBehavior Width="{Binding DesiredWidth}" Height="{Binding DesiredHeight}"/>
|
||||
<behaviors:GridEffectBehavior Effect="{Binding ElementName=gridEffect}" ZoomFactor="{Binding ZoomFactor}"/>
|
||||
<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"/>
|
||||
<shaders:GridShaderEffect x:Name="gridEffect" />
|
||||
</Image.Effect>
|
||||
|
||||
</Image>
|
||||
|
||||
</Border>
|
||||
|
||||
</UserControl>
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace ColorPicker.Views
|
||||
public partial class ZoomView : UserControl
|
||||
{
|
||||
public ZoomView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
=> InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user