* UIStyle: 多彩颜色增加随机颜色Demo
This commit is contained in:
parent
d88d7e433f
commit
16091b91b0
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
47
SunnyUI.Demo/FColorful.Designer.cs
generated
47
SunnyUI.Demo/FColorful.Designer.cs
generated
@ -39,6 +39,9 @@ namespace Sunny.UI.Demo
|
|||||||
this.uiPanel8 = new Sunny.UI.UIPanel();
|
this.uiPanel8 = new Sunny.UI.UIPanel();
|
||||||
this.uiPanel9 = new Sunny.UI.UIPanel();
|
this.uiPanel9 = new Sunny.UI.UIPanel();
|
||||||
this.uiPanel10 = new Sunny.UI.UIPanel();
|
this.uiPanel10 = new Sunny.UI.UIPanel();
|
||||||
|
this.uiLabel1 = new Sunny.UI.UILabel();
|
||||||
|
this.uiPanel11 = new Sunny.UI.UIPanel();
|
||||||
|
this.uiLabel2 = new Sunny.UI.UILabel();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// uiPanel1
|
// uiPanel1
|
||||||
@ -221,12 +224,53 @@ namespace Sunny.UI.Demo
|
|||||||
this.uiPanel10.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
|
this.uiPanel10.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
|
||||||
this.uiPanel10.Click += new System.EventHandler(this.uiPanel1_Click);
|
this.uiPanel10.Click += new System.EventHandler(this.uiPanel1_Click);
|
||||||
//
|
//
|
||||||
|
// uiLabel1
|
||||||
|
//
|
||||||
|
this.uiLabel1.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||||
|
this.uiLabel1.Location = new System.Drawing.Point(23, 297);
|
||||||
|
this.uiLabel1.Name = "uiLabel1";
|
||||||
|
this.uiLabel1.Size = new System.Drawing.Size(698, 23);
|
||||||
|
this.uiLabel1.TabIndex = 10;
|
||||||
|
this.uiLabel1.Text = "多彩主题,以颜色深色,文字白色为主,主题配色自动计算,不能保证所有颜色显示效果";
|
||||||
|
this.uiLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// uiPanel11
|
||||||
|
//
|
||||||
|
this.uiPanel11.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(130)))), ((int)(((byte)(58)))), ((int)(((byte)(183)))));
|
||||||
|
this.uiPanel11.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||||
|
this.uiPanel11.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.uiPanel11.Location = new System.Drawing.Point(23, 340);
|
||||||
|
this.uiPanel11.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||||
|
this.uiPanel11.MinimumSize = new System.Drawing.Size(1, 1);
|
||||||
|
this.uiPanel11.Name = "uiPanel11";
|
||||||
|
this.uiPanel11.RectColor = System.Drawing.Color.FromArgb(((int)(((byte)(130)))), ((int)(((byte)(58)))), ((int)(((byte)(183)))));
|
||||||
|
this.uiPanel11.Size = new System.Drawing.Size(120, 100);
|
||||||
|
this.uiPanel11.Style = Sunny.UI.UIStyle.Custom;
|
||||||
|
this.uiPanel11.StyleCustomMode = true;
|
||||||
|
this.uiPanel11.TabIndex = 11;
|
||||||
|
this.uiPanel11.Text = "随机颜色";
|
||||||
|
this.uiPanel11.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
|
||||||
|
this.uiPanel11.Click += new System.EventHandler(this.uiPanel11_Click);
|
||||||
|
//
|
||||||
|
// uiLabel2
|
||||||
|
//
|
||||||
|
this.uiLabel2.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||||
|
this.uiLabel2.Location = new System.Drawing.Point(23, 457);
|
||||||
|
this.uiLabel2.Name = "uiLabel2";
|
||||||
|
this.uiLabel2.Size = new System.Drawing.Size(172, 23);
|
||||||
|
this.uiLabel2.TabIndex = 12;
|
||||||
|
this.uiLabel2.Text = "RGB: 255, 255, 255 ";
|
||||||
|
this.uiLabel2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
// FColorful
|
// FColorful
|
||||||
//
|
//
|
||||||
this.AllowShowTitle = true;
|
this.AllowShowTitle = true;
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.ClientSize = new System.Drawing.Size(776, 543);
|
this.ClientSize = new System.Drawing.Size(776, 543);
|
||||||
|
this.Controls.Add(this.uiLabel2);
|
||||||
|
this.Controls.Add(this.uiPanel11);
|
||||||
|
this.Controls.Add(this.uiLabel1);
|
||||||
this.Controls.Add(this.uiPanel10);
|
this.Controls.Add(this.uiPanel10);
|
||||||
this.Controls.Add(this.uiPanel6);
|
this.Controls.Add(this.uiPanel6);
|
||||||
this.Controls.Add(this.uiPanel7);
|
this.Controls.Add(this.uiPanel7);
|
||||||
@ -258,5 +302,8 @@ namespace Sunny.UI.Demo
|
|||||||
private UIPanel uiPanel8;
|
private UIPanel uiPanel8;
|
||||||
private UIPanel uiPanel9;
|
private UIPanel uiPanel9;
|
||||||
private UIPanel uiPanel10;
|
private UIPanel uiPanel10;
|
||||||
|
private UILabel uiLabel1;
|
||||||
|
private UIPanel uiPanel11;
|
||||||
|
private UILabel uiLabel2;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using System.Drawing;
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
namespace Sunny.UI.Demo
|
namespace Sunny.UI.Demo
|
||||||
{
|
{
|
||||||
@ -7,6 +8,8 @@ namespace Sunny.UI.Demo
|
|||||||
public FColorful()
|
public FColorful()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
uiPanel11.FillColor = uiPanel11.RectColor = RandomColor.GetColor(ColorScheme.Random, Luminosity.Bright);
|
||||||
|
uiLabel2.Text = "RGB: " + uiPanel11.FillColor.R + ", " + uiPanel11.FillColor.G + ", " + uiPanel11.FillColor.B;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uiPanel1_Click(object sender, System.EventArgs e)
|
private void uiPanel1_Click(object sender, System.EventArgs e)
|
||||||
@ -14,5 +17,34 @@ namespace Sunny.UI.Demo
|
|||||||
var panel = (UIPanel)sender;
|
var panel = (UIPanel)sender;
|
||||||
UIStyles.InitColorful(panel.FillColor, Color.White);
|
UIStyles.InitColorful(panel.FillColor, Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void uiPanel11_Click(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
uiPanel11.FillColor = uiPanel11.RectColor = RandomColor.GetColor(ColorScheme.Random, Luminosity.Bright);
|
||||||
|
uiLabel2.Text = "RGB: " + uiPanel11.FillColor.R + ", " + uiPanel11.FillColor.G + ", " + uiPanel11.FillColor.B;
|
||||||
|
UIStyles.InitColorful(uiPanel11.FillColor, Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static System.Drawing.Color GetRandomColor()
|
||||||
|
{
|
||||||
|
Random random = new Random(DateTime.Now.Millisecond);
|
||||||
|
int int_Red = random.Next(255);
|
||||||
|
int int_Green = random.Next(255);
|
||||||
|
int int_Blue = random.Next(255);
|
||||||
|
int_Blue = (int_Red + int_Green > 380) ? int_Red + int_Green - 380 : int_Blue;
|
||||||
|
int_Blue = (int_Blue > 255) ? 255 : int_Blue;
|
||||||
|
|
||||||
|
return GetDarkerColor(System.Drawing.Color.FromArgb(int_Red, int_Green, int_Blue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color GetDarkerColor(Color color)
|
||||||
|
{
|
||||||
|
const int max = 255;
|
||||||
|
int increase = new Random(Guid.NewGuid().GetHashCode()).Next(30, 220); //还可以根据需要调整此处的值
|
||||||
|
int r = Math.Abs(Math.Min(color.R - increase, max));
|
||||||
|
int g = Math.Abs(Math.Min(color.G - increase, max));
|
||||||
|
int b = Math.Abs(Math.Min(color.B - increase, max));
|
||||||
|
return Color.FromArgb(r, g, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
547
SunnyUI/Style/UIRandomColor.cs
Normal file
547
SunnyUI/Style/UIRandomColor.cs
Normal file
@ -0,0 +1,547 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
https://github.com/nathanpjones/randomColorSharped
|
||||||
|
Port of David Merfield's javascript random color generator. Ported by Nathan Jones.
|
||||||
|
License: MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sunny.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Generates random numbers.
|
||||||
|
/// </summary>
|
||||||
|
public static class RandomColor
|
||||||
|
{
|
||||||
|
private class DefinedColor
|
||||||
|
{
|
||||||
|
public Range HueRange
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public Point[] LowerBounds
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public Range SaturationRange
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public Range BrightnessRange
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<ColorScheme, DefinedColor> ColorDictionary = new Dictionary<ColorScheme, DefinedColor>();
|
||||||
|
private static readonly object LockObj = new object();
|
||||||
|
private static Random _rng = new Random();
|
||||||
|
|
||||||
|
static RandomColor()
|
||||||
|
{
|
||||||
|
// Populate the color dictionary
|
||||||
|
LoadColorBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a new random color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scheme">Which color schemed to use when generating the color.</param>
|
||||||
|
/// <param name="luminosity">The desired luminosity of the color.</param>
|
||||||
|
public static Color GetColor(ColorScheme scheme, Luminosity luminosity)
|
||||||
|
{
|
||||||
|
int H, S, B;
|
||||||
|
|
||||||
|
// First we pick a hue (H)
|
||||||
|
H = PickHue(scheme);
|
||||||
|
|
||||||
|
// Then use H to determine saturation (S)
|
||||||
|
S = PickSaturation(H, luminosity, scheme);
|
||||||
|
|
||||||
|
// Then use S and H to determine brightness (B).
|
||||||
|
B = PickBrightness(H, S, luminosity);
|
||||||
|
|
||||||
|
// Then we return the HSB color in the desired format
|
||||||
|
return HsvToColor(H, S, B);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates multiple random colors.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scheme">Which color schemed to use when generating the color.</param>
|
||||||
|
/// <param name="luminosity">The desired luminosity of the color.</param>
|
||||||
|
/// <param name="count">How many colors to generate</param>
|
||||||
|
public static Color[] GetColors(ColorScheme scheme, Luminosity luminosity, int count)
|
||||||
|
{
|
||||||
|
var ret = new Color[count];
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
ret[i] = GetColor(scheme, luminosity);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate one color for each of the provided generator options.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">List of options to use when creating colors.</param>
|
||||||
|
public static Color[] GetColors(params Options[] options)
|
||||||
|
{
|
||||||
|
if (options == null) throw new ArgumentNullException(nameof(options));
|
||||||
|
|
||||||
|
return options.Select(o => GetColor(o.ColorScheme, o.Luminosity)).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reseeds the random number generated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seed">The number used to reseed the random number generator.</param>
|
||||||
|
public static void Seed(int seed)
|
||||||
|
{
|
||||||
|
lock (LockObj)
|
||||||
|
{
|
||||||
|
_rng = new Random(seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Reseeds the random number generated.
|
||||||
|
/// </summary>
|
||||||
|
public static void Seed()
|
||||||
|
{
|
||||||
|
lock (LockObj)
|
||||||
|
{
|
||||||
|
_rng = new Random();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int PickHue(ColorScheme scheme)
|
||||||
|
{
|
||||||
|
var hueRange = GetHueRange(scheme);
|
||||||
|
var hue = RandomWithin(hueRange);
|
||||||
|
|
||||||
|
// Instead of storing red as two separate ranges,
|
||||||
|
// we group them, using negative numbers
|
||||||
|
if (hue < 0) hue = 360 + hue;
|
||||||
|
|
||||||
|
return hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int PickSaturation(int hue, Luminosity luminosity, ColorScheme scheme)
|
||||||
|
{
|
||||||
|
if (scheme == ColorScheme.Monochrome)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luminosity == Luminosity.Random)
|
||||||
|
{
|
||||||
|
return RandomWithin(0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
var saturationRange = GetColorInfo(hue).SaturationRange;
|
||||||
|
|
||||||
|
var sMin = saturationRange.Lower;
|
||||||
|
var sMax = saturationRange.Upper;
|
||||||
|
|
||||||
|
switch (luminosity)
|
||||||
|
{
|
||||||
|
case Luminosity.Bright:
|
||||||
|
sMin = 55;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Luminosity.Dark:
|
||||||
|
sMin = sMax - 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Luminosity.Light:
|
||||||
|
sMax = 55;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RandomWithin(sMin, sMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int PickBrightness(int H, int S, Luminosity luminosity)
|
||||||
|
{
|
||||||
|
var bMin = GetMinimumBrightness(H, S);
|
||||||
|
var bMax = 100;
|
||||||
|
|
||||||
|
switch (luminosity)
|
||||||
|
{
|
||||||
|
case Luminosity.Dark:
|
||||||
|
bMax = bMin + 20;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Luminosity.Light:
|
||||||
|
bMin = (bMax + bMin) / 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Luminosity.Random:
|
||||||
|
bMin = 0;
|
||||||
|
bMax = 100;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RandomWithin(bMin, bMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetMinimumBrightness(int H, int S)
|
||||||
|
{
|
||||||
|
var lowerBounds = GetColorInfo(H).LowerBounds;
|
||||||
|
|
||||||
|
for (var i = 0; i < lowerBounds.Length - 1; i++)
|
||||||
|
{
|
||||||
|
var s1 = lowerBounds[i].X;
|
||||||
|
var v1 = lowerBounds[i].Y;
|
||||||
|
|
||||||
|
var s2 = lowerBounds[i + 1].X;
|
||||||
|
var v2 = lowerBounds[i + 1].Y;
|
||||||
|
|
||||||
|
if (S >= s1 && S <= s2)
|
||||||
|
{
|
||||||
|
var m = (v2 - v1) / (s2 - s1);
|
||||||
|
var b = v1 - m * s1;
|
||||||
|
|
||||||
|
return (int)(m * S + b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Range GetHueRange(ColorScheme colorInput)
|
||||||
|
{
|
||||||
|
DefinedColor color;
|
||||||
|
if (ColorDictionary.TryGetValue(colorInput, out color))
|
||||||
|
{
|
||||||
|
if (color.HueRange != null)
|
||||||
|
{
|
||||||
|
return color.HueRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Range(0, 360);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DefinedColor GetColorInfo(int hue)
|
||||||
|
{
|
||||||
|
// Maps red colors to make picking hue easier
|
||||||
|
if (hue >= 334 && hue <= 360)
|
||||||
|
{
|
||||||
|
hue -= 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret = ColorDictionary.FirstOrDefault(c => c.Value.HueRange != null &&
|
||||||
|
hue >= c.Value.HueRange[0] &&
|
||||||
|
hue <= c.Value.HueRange[1]);
|
||||||
|
|
||||||
|
Debug.Assert(ret.Value != null);
|
||||||
|
|
||||||
|
return ret.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int RandomWithin(Range range)
|
||||||
|
{
|
||||||
|
return RandomWithin(range.Lower, range.Upper);
|
||||||
|
}
|
||||||
|
private static int RandomWithin(int lower, int upper)
|
||||||
|
{
|
||||||
|
lock (LockObj)
|
||||||
|
{
|
||||||
|
return _rng.Next(lower, upper + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DefineColor(ColorScheme scheme, int[] hueRange, int[,] lowerBounds)
|
||||||
|
{
|
||||||
|
int[][] jagged = new int[lowerBounds.GetLength(0)][];
|
||||||
|
for (int i = 0; i < lowerBounds.GetLength(0); i++)
|
||||||
|
{
|
||||||
|
jagged[i] = new int[lowerBounds.GetLength(1)];
|
||||||
|
for (int j = 0; j < lowerBounds.GetLength(1); j++)
|
||||||
|
{
|
||||||
|
jagged[i][j] = lowerBounds[i, j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sMin = jagged[0][0];
|
||||||
|
var sMax = jagged[jagged.Length - 1][0];
|
||||||
|
var bMin = jagged[jagged.Length - 1][1];
|
||||||
|
var bMax = jagged[0][1];
|
||||||
|
|
||||||
|
ColorDictionary[scheme] = new DefinedColor()
|
||||||
|
{
|
||||||
|
HueRange = Range.ToRange(hueRange),
|
||||||
|
LowerBounds = jagged.Select(j => new Point(j[0], j[1])).ToArray(),
|
||||||
|
SaturationRange = new Range(sMin, sMax),
|
||||||
|
BrightnessRange = new Range(bMin, bMax)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LoadColorBounds()
|
||||||
|
{
|
||||||
|
DefineColor(
|
||||||
|
ColorScheme.Monochrome,
|
||||||
|
null,
|
||||||
|
new[,] { { 0, 0 }, { 100, 0 } }
|
||||||
|
);
|
||||||
|
|
||||||
|
DefineColor(
|
||||||
|
ColorScheme.Red,
|
||||||
|
new[] { -26, 18 },
|
||||||
|
new[,] { { 20, 100 }, { 30, 92 }, { 40, 89 }, { 50, 85 }, { 60, 78 }, { 70, 70 }, { 80, 60 }, { 90, 55 }, { 100, 50 } }
|
||||||
|
);
|
||||||
|
|
||||||
|
DefineColor(
|
||||||
|
ColorScheme.Orange,
|
||||||
|
new[] { 19, 46 },
|
||||||
|
new[,] { { 20, 100 }, { 30, 93 }, { 40, 88 }, { 50, 86 }, { 60, 85 }, { 70, 70 }, { 100, 70 } }
|
||||||
|
);
|
||||||
|
|
||||||
|
DefineColor(
|
||||||
|
ColorScheme.Yellow,
|
||||||
|
new[] { 47, 62 },
|
||||||
|
new[,] { { 25, 100 }, { 40, 94 }, { 50, 89 }, { 60, 86 }, { 70, 84 }, { 80, 82 }, { 90, 80 }, { 100, 75 } }
|
||||||
|
);
|
||||||
|
|
||||||
|
DefineColor(
|
||||||
|
ColorScheme.Green,
|
||||||
|
new[] { 63, 178 },
|
||||||
|
new[,] { { 30, 100 }, { 40, 90 }, { 50, 85 }, { 60, 81 }, { 70, 74 }, { 80, 64 }, { 90, 50 }, { 100, 40 } }
|
||||||
|
);
|
||||||
|
|
||||||
|
DefineColor(
|
||||||
|
ColorScheme.Blue,
|
||||||
|
new[] { 179, 257 },
|
||||||
|
new[,] { { 20, 100 }, { 30, 86 }, { 40, 80 }, { 50, 74 }, { 60, 60 }, { 70, 52 }, { 80, 44 }, { 90, 39 }, { 100, 35 } }
|
||||||
|
);
|
||||||
|
|
||||||
|
DefineColor(
|
||||||
|
ColorScheme.Purple,
|
||||||
|
new[] { 258, 282 },
|
||||||
|
new[,] { { 20, 100 }, { 30, 87 }, { 40, 79 }, { 50, 70 }, { 60, 65 }, { 70, 59 }, { 80, 52 }, { 90, 45 }, { 100, 42 } }
|
||||||
|
);
|
||||||
|
|
||||||
|
DefineColor(
|
||||||
|
ColorScheme.Pink,
|
||||||
|
new[] { 283, 334 },
|
||||||
|
new[,] { { 20, 100 }, { 30, 90 }, { 40, 86 }, { 60, 84 }, { 80, 80 }, { 90, 75 }, { 100, 73 } }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts hue, saturation, and lightness to a color.
|
||||||
|
/// </summary>
|
||||||
|
public static Color HsvToColor(int hue, int saturation, double value)
|
||||||
|
{
|
||||||
|
// this doesn't work for the values of 0 and 360
|
||||||
|
// here's the hacky fix
|
||||||
|
var h = Convert.ToDouble(hue);
|
||||||
|
if (h == 0)
|
||||||
|
{
|
||||||
|
h = 1;
|
||||||
|
}
|
||||||
|
if (h == 360)
|
||||||
|
{
|
||||||
|
h = 359;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebase the h,s,v values
|
||||||
|
h = h / 360.0;
|
||||||
|
var s = saturation / 100.0;
|
||||||
|
var v = value / 100.0;
|
||||||
|
|
||||||
|
var hInt = (int)Math.Floor(h * 6.0);
|
||||||
|
var f = h * 6 - hInt;
|
||||||
|
var p = v * (1 - s);
|
||||||
|
var q = v * (1 - f * s);
|
||||||
|
var t = v * (1 - (1 - f) * s);
|
||||||
|
var r = 256.0;
|
||||||
|
var g = 256.0;
|
||||||
|
var b = 256.0;
|
||||||
|
|
||||||
|
switch (hInt)
|
||||||
|
{
|
||||||
|
case 0: r = v; g = t; b = p; break;
|
||||||
|
case 1: r = q; g = v; b = p; break;
|
||||||
|
case 2: r = p; g = v; b = t; break;
|
||||||
|
case 3: r = p; g = q; b = v; break;
|
||||||
|
case 4: r = t; g = p; b = v; break;
|
||||||
|
case 5: r = v; g = p; b = q; break;
|
||||||
|
}
|
||||||
|
var c = Color.FromArgb(255,
|
||||||
|
(byte)Math.Floor(r * 255.0),
|
||||||
|
(byte)Math.Floor(g * 255.0),
|
||||||
|
(byte)Math.Floor(b * 255.0));
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Predefined color schemes.
|
||||||
|
/// </summary>
|
||||||
|
public enum ColorScheme
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Select randomly from among the other color schemes.
|
||||||
|
/// </summary>
|
||||||
|
Random,
|
||||||
|
/// <summary>
|
||||||
|
/// Generates only grayscale colors.
|
||||||
|
/// </summary>
|
||||||
|
Monochrome,
|
||||||
|
/// <summary>
|
||||||
|
/// Generates only red colors.
|
||||||
|
/// </summary>
|
||||||
|
Red,
|
||||||
|
/// <summary>
|
||||||
|
/// Generates only orange colors.
|
||||||
|
/// </summary>
|
||||||
|
Orange,
|
||||||
|
/// <summary>
|
||||||
|
/// Generates only yellow colors.
|
||||||
|
/// </summary>
|
||||||
|
Yellow,
|
||||||
|
/// <summary>
|
||||||
|
/// Generates only green colors.
|
||||||
|
/// </summary>
|
||||||
|
Green,
|
||||||
|
/// <summary>
|
||||||
|
/// Generates only blue colors.
|
||||||
|
/// </summary>
|
||||||
|
Blue,
|
||||||
|
/// <summary>
|
||||||
|
/// Generates only purple colors.
|
||||||
|
/// </summary>
|
||||||
|
Purple,
|
||||||
|
/// <summary>
|
||||||
|
/// Generates only pink colors.
|
||||||
|
/// </summary>
|
||||||
|
Pink
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Predefined luminosity ranges.
|
||||||
|
/// </summary>
|
||||||
|
public enum Luminosity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Select randomly from among the other luminosities.
|
||||||
|
/// </summary>
|
||||||
|
Random,
|
||||||
|
/// <summary>
|
||||||
|
/// Generate dark colors.
|
||||||
|
/// </summary>
|
||||||
|
Dark,
|
||||||
|
/// <summary>
|
||||||
|
/// Generate light, pastel colors.
|
||||||
|
/// </summary>
|
||||||
|
Light,
|
||||||
|
/// <summary>
|
||||||
|
/// Generate vibrant colors.
|
||||||
|
/// </summary>
|
||||||
|
Bright,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a range using an upper and lower value.
|
||||||
|
/// </summary>
|
||||||
|
[DebuggerDisplay(@"\{{Lower},{Upper}\}")]
|
||||||
|
internal class Range
|
||||||
|
{
|
||||||
|
public int Lower
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
public int Upper
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Range()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public Range(int lower, int upper)
|
||||||
|
{
|
||||||
|
Lower = lower;
|
||||||
|
Upper = upper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the lower range for an index of 0 and the upper for an index of 1.
|
||||||
|
/// </summary>
|
||||||
|
public int this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return Lower;
|
||||||
|
case 1: return Upper;
|
||||||
|
default: throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: Lower = value; break;
|
||||||
|
case 1: Upper = value; break;
|
||||||
|
default: throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Range ToRange(int[] range)
|
||||||
|
{
|
||||||
|
if (range == null) return null;
|
||||||
|
Debug.Assert(range.Length == 2);
|
||||||
|
return new Range(range[0], range[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Options for generating a random color.
|
||||||
|
/// </summary>
|
||||||
|
public class Options
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color scheme to use when generating the color.
|
||||||
|
/// </summary>
|
||||||
|
public ColorScheme ColorScheme
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the luminosity range to use when generating the color.
|
||||||
|
/// </summary>
|
||||||
|
public Luminosity Luminosity
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance using default values.
|
||||||
|
/// </summary>
|
||||||
|
public Options()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance with the given color scheme and luminosity range.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scheme">The color scheme to use when generating the color.</param>
|
||||||
|
/// <param name="luminosity">The luminosity range to use when generating the color.</param>
|
||||||
|
public Options(ColorScheme scheme, Luminosity luminosity)
|
||||||
|
{
|
||||||
|
ColorScheme = scheme;
|
||||||
|
Luminosity = luminosity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user