Archive Browser
Download CmykRgbColorConversion.zip, last updated 15/07/2018 (19.21 KB)
Download- md5: 1258961adc735c8388f9b35d867df7c6
- sha1: 1e01eb8723aac6632f1c0fff5fb57f524116329c
- sha256: cfc2141a0f0820962621bc35e10882e648c95496751b65ded610a0009faae5a6
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
/* Finding nearest colors using Euclidean distance
* http://www.cyotek.com/blog/finding-nearest-colors-using-euclidean-distance
*
* Copyright © 2017 Cyotek Ltd.
*/
namespace Cyotek.Demo.CmykRgbColorConversion
{
[DefaultProperty(nameof(Color))]
[DefaultEvent(nameof(ColorChanged))]
internal class ColorBox : Control, IButtonControl
{
#region Constants
private static readonly object _eventColorChanged = new object();
private static readonly object _eventShowNameChanged = new object();
private static readonly object _eventTextAlignChanged = new object();
#endregion
#region Fields
private Color _color;
private DialogResult _dialogResult;
private bool _showName;
private ContentAlignment _textAlign;
#endregion
#region Constructors
public ColorBox()
{
base.DoubleBuffered = true;
_color = Color.White;
_textAlign = ContentAlignment.BottomRight;
}
#endregion
#region Events
/// <summary>
/// Occurs when the Color property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler ColorChanged
{
add { this.Events.AddHandler(_eventColorChanged, value); }
remove { this.Events.RemoveHandler(_eventColorChanged, value); }
}
/// <summary>
/// Occurs when the ShowName property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler ShowNameChanged
{
add { this.Events.AddHandler(_eventShowNameChanged, value); }
remove { this.Events.RemoveHandler(_eventShowNameChanged, value); }
}
/// <summary>
/// Occurs when the TextAlign property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler TextAlignChanged
{
add { this.Events.AddHandler(_eventTextAlignChanged, value); }
remove { this.Events.RemoveHandler(_eventTextAlignChanged, value); }
}
#endregion
#region Properties
[Category("Appearance")]
[DefaultValue(typeof(Color), "White")]
public Color Color
{
get { return _color; }
set
{
if (_color != value)
{
_color = value;
this.OnColorChanged(EventArgs.Empty);
}
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Font Font
{
get { return base.Font; }
set { base.Font = value; }
}
[Category("Appearance")]
[DefaultValue(false)]
public bool ShowName
{
get { return _showName; }
set
{
if (_showName != value)
{
_showName = value;
this.OnShowNameChanged(EventArgs.Empty);
}
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
[Category("Appearance")]
[DefaultValue(typeof(ContentAlignment), "BottomRight")]
public ContentAlignment TextAlign
{
get { return _textAlign; }
set
{
if (_textAlign != value)
{
_textAlign = value;
this.OnTextAlignChanged(EventArgs.Empty);
}
}
}
#endregion
#region Methods
/// <summary>
/// Raises the <see cref="ColorChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnColorChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventColorChanged];
handler?.Invoke(this, e);
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
this.Invalidate();
}
protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.Space && e.Modifiers == Keys.None)
{
e.Handled = true;
this.PerformClick();
}
base.OnKeyUp(e);
}
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g;
Rectangle bounds;
base.OnPaint(e);
bounds = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
g = e.Graphics;
this.DrawColor(g, bounds);
this.DrawName(g, bounds);
this.DrawFocus(g, bounds);
g.DrawRectangle(SystemPens.WindowFrame, bounds);
}
/// <summary>
/// Raises the <see cref="ShowNameChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnShowNameChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventShowNameChanged];
handler?.Invoke(this, e);
}
/// <summary>
/// Raises the <see cref="TextAlignChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
protected virtual void OnTextAlignChanged(EventArgs e)
{
EventHandler handler;
this.Invalidate();
handler = (EventHandler)this.Events[_eventTextAlignChanged];
handler?.Invoke(this, e);
}
private void DrawColor(Graphics g, Rectangle bounds)
{
if (_color.A != 255)
{
using (Brush brush = new HatchBrush(HatchStyle.DiagonalCross, Color.Silver, Color.White))
{
g.FillRectangle(brush, bounds);
}
}
using (Brush brush = new SolidBrush(_color))
{
g.FillRectangle(brush, bounds);
}
}
private void DrawFocus(Graphics g, Rectangle bounds)
{
if (this.ShowFocusCues && this.Focused)
{
NativeMethods.RECT rect;
rect = new NativeMethods.RECT(3, 3, bounds.Width - 2, bounds.Height - 2);
// The Win32 API DrawFocusRect draws using an inverted brush and so works on black,
// whereas ControlPaint.DrawFocusRect decidedly does not
NativeMethods.DrawFocusRect(g.GetHdc(), ref rect);
g.ReleaseHdc();
}
}
private void DrawName(Graphics g, Rectangle bounds)
{
if (_showName)
{
string name;
TextFormatFlags flags;
bounds = Rectangle.Inflate(bounds, -3, -3);
name = _color.R + ", " + _color.G + ", " + _color.B;
flags = TextFormatFlags.NoPadding | this.GetAlignmentFlags();
TextRenderer.DrawText(g, name, this.Font, bounds, this.GetFixedContrast(_color), _color, flags);
}
}
private TextFormatFlags GetAlignmentFlags()
{
TextFormatFlags result;
result = 0;
// ReSharper disable once ConvertIfStatementToSwitchStatement
if (_textAlign == ContentAlignment.BottomLeft || _textAlign == ContentAlignment.MiddleLeft || _textAlign == ContentAlignment.TopLeft)
{
result |= TextFormatFlags.Left;
}
else if (_textAlign == ContentAlignment.BottomRight || _textAlign == ContentAlignment.MiddleRight || _textAlign == ContentAlignment.TopRight)
{
result |= TextFormatFlags.Right;
}
else
{
result |= TextFormatFlags.HorizontalCenter;
}
// ReSharper disable once ConvertIfStatementToSwitchStatement
if (_textAlign == ContentAlignment.TopLeft || _textAlign == ContentAlignment.TopCenter || _textAlign == ContentAlignment.TopRight)
{
result |= TextFormatFlags.Top;
}
else if (_textAlign == ContentAlignment.BottomLeft || _textAlign == ContentAlignment.BottomCenter || _textAlign == ContentAlignment.BottomRight)
{
result |= TextFormatFlags.Bottom;
}
else
{
result |= TextFormatFlags.VerticalCenter;
}
return result;
}
private Color GetFixedContrast(Color color)
{
int threshold;
int grayscale;
Color result;
threshold = 105;
grayscale = Convert.ToInt32(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);
result = 255 - grayscale < threshold ? Color.Black : Color.White;
return result;
}
#endregion
#region IButtonControl Interface
public void NotifyDefault(bool value)
{
this.Invalidate();
}
public void PerformClick()
{
this.OnClick(EventArgs.Empty);
}
DialogResult IButtonControl.DialogResult
{
get { return _dialogResult; }
set { _dialogResult = value; }
}
#endregion
}
}
Donate
This software may be used free of charge, but as with all free software there are costs involved to develop and maintain.
If this site or its services have saved you time, please consider a donation to help with running costs and timely updates.
Donate