Color Picker
Basic HSV color picker inspired by http://colorpicker.com/
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Sample.ColorPicker"
UseLayoutRounding="True">
<UserControl.Resources>
<Style x:Key="SpectrumSliderButtonStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Delay" Value="250"/>
<Setter Property="Interval" Value="100"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Background="Transparent" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="SpectrumSliderThumbTemplate" TargetType="{x:Type Thumb}">
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Path Grid.Column="0" Data="M0,0L8,5 0,10z" Fill="Black" HorizontalAlignment="Right"/>
<Path Grid.Column="2" Data="M8,0L0,5 8,10z" Fill="Black" HorizontalAlignment="Left"/>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="SpectrumSliderTemplate" TargetType="{x:Type Slider}">
<Grid>
<Rectangle StrokeThickness="1" Stroke="#000000" Width="20">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="#FFFF0000" Offset="0"/>
<GradientStop Color="#FFFF00FF" Offset="0.1666666"/>
<GradientStop Color="#FF0000FF" Offset="0.3333333"/>
<GradientStop Color="#FF00FFFF" Offset="0.5"/>
<GradientStop Color="#FF00FF00" Offset="0.6666666"/>
<GradientStop Color="#FFFFFF00" Offset="0.8333333"/>
<GradientStop Color="#FFFF0000" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Track x:Name="PART_Track">
<Track.Thumb>
<Thumb Template="{StaticResource SpectrumSliderThumbTemplate}" Margin="0,-4"/>
</Track.Thumb>
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource SpectrumSliderButtonStyle}" Command="Slider.DecreaseLarge" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource SpectrumSliderButtonStyle}" Command="Slider.IncreaseLarge" />
</Track.IncreaseRepeatButton>
</Track>
</Grid>
</ControlTemplate>
</UserControl.Resources>
<Grid Background="Gray">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Color selected -->
<Grid Grid.Row="0" Grid.ColumnSpan="2">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0">
<TextBlock x:Name="Text" FontSize="15" VerticalAlignment="Center" Width = "70"/>
<Rectangle Width="50" Height="50" Margin="10" StrokeThickness="1" Stroke="#000000">
<Rectangle.Fill>
<SolidColorBrush x:Name="Color" Color="#FF0000"/>
</Rectangle.Fill>
</Rectangle>
</StackPanel>
</Grid>
<!-- Picker -->
<Grid x:Name="HS" Grid.Row="1" Grid.Column="0">
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Color="White" Offset="0"/>
<GradientStop x:Name="Stop" Color="Red" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Stroke="#000000">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="1,0" EndPoint="0,0">
<GradientStop Offset="0" Color="#00000000"/>
<GradientStop Offset="1" Color="#FF000000"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Canvas Height="12" Width="12" RenderTransformOrigin="0.5,0.5" ClipToBounds="true">
<Canvas.RenderTransform>
<TranslateTransform x:Name="PickerTransform" X="0" Y="0"/>
</Canvas.RenderTransform>
<Grid>
<Ellipse Stroke="Black" Width="12" Height="12"/>
<Ellipse Stroke="White" Width="10" Height="10"/>
</Grid>
</Canvas>
</Grid>
<!-- Spectrum -->
<Grid Grid.Row="1" Grid.Column="1">
<Slider x:Name="Slider" Orientation="Vertical" IsMoveToPointEnabled="True" Minimum="0" Maximum="360"
Value="0" Template="{StaticResource SpectrumSliderTemplate}" Margin="5,0"/>
</Grid>
</Grid>
</UserControl>
Code: Select all
using Noesis;
using System;
namespace Sample
{
[Noesis.Extended]
[Noesis.UserControlSource("Assets/Test/ColorPicker.xaml")]
public class ColorPicker : Noesis.UserControl
{
public static DependencyProperty ColorProperty = DependencyProperty.Register("Color",
typeof(SolidColorBrush), typeof(ColorPicker), new PropertyMetadata(null));
public SolidColorBrush Color
{
get { return GetValue<SolidColorBrush>(ColorProperty); }
set { SetValue<SolidColorBrush>(ColorProperty, value); }
}
public void OnPostInit()
{
_spectrum = FindName<Slider>("Slider");
_hs = FindName<FrameworkElement>("HS");
_pickerTransform = FindName<TranslateTransform>("PickerTransform");
_text = FindName<TextBlock>("Text");
_color = FindName<SolidColorBrush>("Color");
_stop = FindName<GradientStop>("Stop");
_spectrum.ValueChanged += this.OnSpectrumChange;
_hs.MouseLeftButtonDown += this.OnMouseLeftButtonDown;
_hs.MouseLeftButtonUp += this.OnMouseLeftButtonUp;
_hs.MouseMove += this.OnMouseMove;
_hs.SizeChanged += this.OnSizeChanged;
_hue = 0.0f;
_saturation = 0.5f;
_value = 0.5f;
Update();
}
private void OnSpectrumChange(float oldValue, float newValue)
{
_hue = newValue;
_stop.SetColor(HSVToColor(_hue, 1, 1));
Update();
}
private void OnMouseLeftButtonDown(BaseComponent c, MouseButtonEventArgs args)
{
Focus();
_hs.CaptureMouse();
Noesis.Point p = _hs.PointFromScreen(args.position);
UpdatePickerPosition(p);
}
private void OnMouseLeftButtonUp(BaseComponent c, MouseButtonEventArgs args)
{
_hs.ReleaseMouseCapture();
}
private void OnMouseMove(BaseComponent c, MouseEventArgs args)
{
if (_hs.GetIsMouseCaptured())
{
Noesis.Point p = _hs.PointFromScreen(args.position);
UpdatePickerPosition(p);
}
}
private void OnSizeChanged(BaseComponent c, SizeChangedEventArgs args)
{
Noesis.Size size = args.sizeChangedInfo.newSize;
_pickerTransform.SetX(_value * size.width - 0.5f * size.width);
_pickerTransform.SetY(size.height - _saturation * size.height - 0.5f * size.height);
}
private void UpdatePickerPosition(Noesis.Point pos)
{
Noesis.Size size = _hs.GetRenderSize();
pos.x = Math.Max(0.0f, Math.Min(size.width, pos.x));
pos.y = Math.Max(0.0f, Math.Min(size.height, pos.y));
_pickerTransform.SetX(pos.x - 0.5f * size.width);
_pickerTransform.SetY(pos.y - 0.5f * size.height);
_value = pos.x / size.width;
_saturation = (size.height - pos.y) / size.height;
Update();
}
private void Update()
{
Noesis.Color color = HSVToColor(_hue, _saturation, _value);
int red = color.GetRedI();
int green = color.GetGreenI();
int blue = color.GetBlueI();
_text.SetText(String.Format("#{0:X2}{1:X2}{2:X2}", red, green, blue));
_color.SetColor(color);
Color = new SolidColorBrush(color);
}
private Noesis.Color HSVToColor(float hue, float saturation, float value)
{
float chroma = value * saturation;
float hueTag = (hue % 360) / 60;
float x = chroma * (1 - Math.Abs(hueTag % 2.0f - 1));
float m = value - chroma;
switch ((int)hueTag)
{
case 0:
{
return new Noesis.Color(chroma + m, x + m, m);
}
case 1:
{
return new Noesis.Color(x + m, chroma + m, m);
}
case 2:
{
return new Noesis.Color(m, chroma + m, x + m);
}
case 3:
{
return new Noesis.Color(m, x + m, chroma + m);
}
case 4:
{
return new Noesis.Color(x + m, m, chroma + m);
}
default:
{
return new Noesis.Color(chroma + m, m, x + m);
}
}
}
private Slider _spectrum;
private FrameworkElement _hs;
private TranslateTransform _pickerTransform;
private TextBlock _text;
private SolidColorBrush _color;
private GradientStop _stop;
private float _hue;
private float _saturation;
private float _value;
}
}
Who is online
Users browsing this forum: rjmg and 1 guest