// COPYRIGHT (C) Tom. ALL RIGHTS RESERVED. // THE AntdUI PROJECT IS AN WINFORM LIBRARY LICENSED UNDER THE Apache-2.0 License. // LICENSED UNDER THE Apache License, VERSION 2.0 (THE "License") // YOU MAY NOT USE THIS FILE EXCEPT IN COMPLIANCE WITH THE License. // YOU MAY OBTAIN A COPY OF THE LICENSE AT // // http://www.apache.org/licenses/LICENSE-2.0 // // UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE // DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND // LIMITATIONS UNDER THE License. // GITEE: https://gitee.com/antdui/AntdUI // GITHUB: https://github.com/AntdUI/AntdUI // CSDN: https://blog.csdn.net/v_132 // QQ: 17379620 using System; using System.Collections.Generic; using System.Drawing; namespace AntdUI { public static class Style { public static Theme.IColor Db = new Theme.Light(); /// /// 加载自定义主题 /// /// public static void LoadCustom(Theme.IColor style) { Db = style; EventHub.Dispatch(EventType.THEME); } public static void LoadCustom(Theme.IColor style) { Db.Primary = style.Primary.ToColor(); Db.PrimaryColor = style.PrimaryColor.ToColor(); Db.PrimaryHover = style.PrimaryHover.ToColor(); Db.PrimaryActive = style.PrimaryActive.ToColor(); Db.PrimaryBg = style.PrimaryBg.ToColor(); Db.Success = style.Success.ToColor(); Db.SuccessColor = style.SuccessColor.ToColor(); Db.SuccessBg = style.SuccessBg.ToColor(); Db.SuccessBorder = style.SuccessBorder.ToColor(); Db.SuccessHover = style.SuccessHover.ToColor(); Db.SuccessActive = style.SuccessActive.ToColor(); Db.Warning = style.Warning.ToColor(); Db.WarningColor = style.WarningColor.ToColor(); Db.WarningBg = style.WarningBg.ToColor(); Db.WarningBorder = style.WarningBorder.ToColor(); Db.WarningHover = style.WarningHover.ToColor(); Db.WarningActive = style.WarningActive.ToColor(); Db.Error = style.Error.ToColor(); Db.ErrorColor = style.ErrorColor.ToColor(); Db.ErrorBg = style.ErrorBg.ToColor(); Db.ErrorBorder = style.ErrorBorder.ToColor(); Db.ErrorHover = style.ErrorHover.ToColor(); Db.ErrorActive = style.ErrorActive.ToColor(); Db.Info = style.Info.ToColor(); Db.InfoColor = style.InfoColor.ToColor(); Db.InfoBg = style.InfoBg.ToColor(); Db.InfoBorder = style.InfoBorder.ToColor(); Db.InfoHover = style.InfoHover.ToColor(); Db.InfoActive = style.InfoActive.ToColor(); Db.DefaultBg = style.DefaultBg.ToColor(); Db.DefaultColor = style.DefaultColor.ToColor(); Db.DefaultBorder = style.DefaultBorder.ToColor(); Db.TagDefaultBg = style.TagDefaultBg.ToColor(); Db.TagDefaultColor = style.TagDefaultColor.ToColor(); Db.TextBase = style.TextBase.ToColor(); Db.Text = style.Text.ToColor(); Db.TextSecondary = style.TextSecondary.ToColor(); Db.TextTertiary = style.TextTertiary.ToColor(); Db.TextQuaternary = style.TextQuaternary.ToColor(); Db.BgBase = style.BgBase.ToColor(); Db.BgContainer = style.BgContainer.ToColor(); Db.BgElevated = style.BgElevated.ToColor(); Db.BgLayout = style.BgLayout.ToColor(); Db.Fill = style.Fill.ToColor(); Db.FillSecondary = style.FillSecondary.ToColor(); Db.FillTertiary = style.FillTertiary.ToColor(); Db.FillQuaternary = style.FillQuaternary.ToColor(); Db.BorderColor = style.BorderColor.ToColor(); Db.BorderSecondary = style.BorderSecondary.ToColor(); Db.BorderColorDisable = style.BorderColorDisable.ToColor(); Db.Split = style.Split.ToColor(); Db.HoverBg = style.HoverBg.ToColor(); Db.HoverColor = style.HoverColor.ToColor(); Db.SliderHandleColorDisabled = style.SliderHandleColorDisabled.ToColor(); EventHub.Dispatch(EventType.THEME); } /// /// 色彩模式(浅色、暗色) /// /// true Light;false Dark public static bool ColorMode(this Color color) { return ((color.R * 299 + color.G * 587 + color.B * 114) / 1000) > 128; } #region 生成色卡 static float warmDark = 0.5F; // 暖色调暗收音机 static float warmRotate = -26; // 暖色旋转度 static float coldDark = 0.55F; // 冷色调暗收音机 static float coldRotate = 10; // 冷色旋转度 public static Color shade(this Color shadeColor) { // 暖色和冷色会在不同的收音机中变暗,并以不同的程度旋转 // 暖色 if (shadeColor.R > shadeColor.B) { return shadeColor.darken(shadeColor.ToHSL().l * warmDark).spin(warmRotate).HSLToColor(); } // 冷色 return shadeColor.darken(shadeColor.ToHSL().l * coldDark).spin(coldRotate).HSLToColor(); } public static HSL darken(this Color color, float amount) { var hsl = color.ToHSL(); hsl.l -= amount / 100F; hsl.l = clamp01(hsl.l); return hsl; } static HSL spin(this HSL hsl, float amount) { var hue = (hsl.h + amount) % 360F; hsl.h = hue < 0F ? 360F + hue : hue; return hsl; } static float clamp01(float val) { return Math.Min(1F, Math.Max(0F, val)); } public static List GenerateColors(this Color primaryColor) { var hsv = primaryColor.ToHSV(); var colors = new List(lightColorCount + darkColorCount); // 主色前 for (var i = lightColorCount; i > 0; i--) { colors.Add(GenerateColor(hsv, i, true)); } // 主色 colors.Add(primaryColor); // 主色后 for (var i = 1; i <= darkColorCount; i++) { colors.Add(GenerateColor(hsv, i, false)); } return colors; } /// /// 生成色卡 /// /// 色调 /// 饱和度 /// 亮度 /// 序号 /// 是否浅色 public static Color GenerateColor(HSV hsv, int i, bool isLight) { // i 为index与6的相对距离 return HSVToColor(getHue(hsv, i, isLight), getSaturation(hsv, i, isLight), getValue(hsv, i, isLight)); } static int hueStep = 2; static int darkColorCount = 4, lightColorCount = 5; static float saturationStep = 0.16F, saturationStep2 = 0.05F; static float brightnessStep1 = 0.05F, brightnessStep2 = 0.15F; public static float getHue(HSV hsv, int i, bool isLight) { float hue; if (hsv.h >= 60 && hsv.h <= 240) hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i; else hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i; if (hue < 0) hue += 360F; else if (hue >= 360) hue -= 360F; return hue; } public static float getSaturation(HSV hsv, int i, bool isLight) { // grey color don't change saturation if (hsv.h == 0 && hsv.s == 0) return hsv.s; float saturation; if (isLight) saturation = hsv.s - saturationStep * i; else if (i == darkColorCount) saturation = hsv.s + saturationStep; else saturation = hsv.s + saturationStep2 * i; if (saturation > 1) saturation = 1; if (isLight && i == lightColorCount && saturation > 0.1) saturation = 0.1F; if (saturation < 0.06) saturation = 0.06F; return saturation;//保留两位小数 } public static float getValue(HSV hsv, int i, bool isLight) { float value; if (isLight) value = hsv.v + brightnessStep1 * i; else value = hsv.v - brightnessStep2 * i; if (value > 1) value = 1; return value; } #endregion #region 颜色转换 #region HSV /// /// 颜色转HSV /// public static HSV ToHSV(this Color color) { float min = Math.Min(Math.Min(color.R, color.G), color.B) / 255F, max = Math.Max(Math.Max(color.R, color.G), color.B) / 255F; return new HSV(color.GetHue(), max == 0F ? 0F : (max - min) / max, max); } /// /// HSV转颜色 /// public static Color HSVToColor(this HSV hsv, float alpha = 1) { return HSVToColor(hsv.h, hsv.s, hsv.v, alpha); } /// /// HSV转颜色 /// /// 色相 /// 饱和度 /// 明度 /// 透明度 public static Color HSVToColor(float hue, float saturation, float value, float alpha = 1) { int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6; float f = hue / 60F - (float)Math.Floor(hue / 60D); float v = value; float p = value * (1 - saturation); float q = value * (1 - f * saturation); float t = value * (1 - (1 - f) * saturation); if (hi == 0) return rgba(v, t, p, alpha); if (hi == 1) return rgba(q, v, p, alpha); if (hi == 2) return rgba(p, v, t, alpha); if (hi == 3) return rgba(p, q, v, alpha); if (hi == 4) return rgba(t, p, v, alpha); return rgba(v, p, q, alpha); } #endregion #region HSL /// /// 颜色转HSL /// public static HSL ToHSL(this Color color) { float min = Math.Min(Math.Min(color.R, color.G), color.B) / 255F, max = Math.Max(Math.Max(color.R, color.G), color.B) / 255F; float lightness = (max + min) / 2F; if (lightness == 0F || min == max) { return new HSL(color.GetHue(), 0F, lightness); } else if (lightness > 0F && lightness <= 0.5F) { return new HSL(color.GetHue(), (max - min) / (max + min), lightness); } return new HSL(color.GetHue(), (max - min) / (2F - (max + min)), lightness); } /// /// HSL转颜色 /// public static Color HSLToColor(this HSL hsl, float alpha = 1) { return HSLToColor(hsl.h, hsl.s, hsl.l, alpha); } /// /// HSL转颜色 /// /// 色相 /// 饱和度 /// 亮度 /// 透明度 public static Color HSLToColor(float hue, float saturation, float lightness, float alpha = 1) { float _saturation = saturation; float _lightness = lightness; float c = (1 - Math.Abs(2 * _lightness - 1)) * _saturation; float _hue = (hue % 360) / 60; float x = c * (1 - Math.Abs(_hue % 2 - 1)); float r = 0, g = 0, b = 0; if (_hue >= 0 && _hue < 1) { r = c; g = x; b = 0; } else if (_hue >= 1 && _hue <= 2) { r = x; g = c; b = 0; } else if (_hue >= 2 && _hue <= 3) { r = 0; g = c; b = x; } else if (_hue > 3 && _hue <= 4) { r = 0; g = x; b = c; } else if (_hue > 4 && _hue <= 5) { r = x; g = 9; b = c; } else if (_hue > 5 && _hue <= 6) { r = c; g = 0; b = x; } var m = _lightness - c / 2; return rgba(Math.Abs(r + m), Math.Abs(g + m), Math.Abs(b + m), alpha); } #endregion public static Color rgba(int r, int g, int b, float a = 1) { return Color.FromArgb((int)Math.Round(255F * a), r, g, b); } public static Color rgba(this Color color, float a = 1) { return rgba(color.R, color.G, color.B, a); } public static Color rgba(float r, float g, float b, float a = 1) { if (r < 0) r = 0F; else if (r > 1) r = 1F; if (g < 0) g = 0F; else if (g > 1) g = 1F; if (b < 0) b = 0F; else if (b > 1) b = 1F; return Color.FromArgb((int)Math.Round(255F * a), (int)Math.Round(255F * r), (int)Math.Round(255F * g), (int)Math.Round(255F * b)); } /// /// 颜色:16进制转成RGB /// /// 设置16进制颜色 [返回RGB] /// public static Color ToColor(this string hex) { try { if (hex != null && hex.Length > 5) { if (hex.StartsWith("#")) hex = hex.Substring(1); if (hex.Length == 6) return Color.FromArgb(hex.Substring(0, 2).HexToInt(), hex.Substring(2, 2).HexToInt(), hex.Substring(4, 2).HexToInt()); else if (hex.Length == 8) return Color.FromArgb(hex.Substring(6, 2).HexToInt(), hex.Substring(0, 2).HexToInt(), hex.Substring(2, 2).HexToInt(), hex.Substring(4, 2).HexToInt()); } } catch { } return Color.Black; } /// /// 颜色:RGB转成16进制 /// /// public static string ToHex(this Color color) { if (color.A == 255) return string.Format("{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B); return string.Format("{0:X2}{1:X2}{2:X2}{3:X2}", color.R, color.G, color.B, color.A); } static int HexToInt(this string str) { return int.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier); } #endregion } public class HSL { public HSL(float hue, float saturation, float lightness) { h = hue; s = saturation; l = lightness; } public HSL() { } /// /// 色相 取值范围为[0,360] /// public float h { get; set; } /// /// 饱和度 取值范围为[0,100],表示颜色的深浅程度 /// public float s { get; set; } /// /// 亮度 取值范围为[0,100],表示颜色的明暗程度 /// public float l { get; set; } } public class HSV { public HSV(float hue, float saturation, float value) { h = hue; s = saturation; v = value; } public HSV() { } /// /// 色相 /// public float h { get; set; } /// /// 饱和度 /// public float s { get; set; } /// /// 明度 /// public float v { get; set; } } }