PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/PhantomMvvmToolkit/Silverlight/Converter/ToSolidColorBrush.cs

#
C# | 266 lines | 217 code | 34 blank | 15 comment | 54 complexity | 0cc8bcb4f0e78b35d86dbd7b59d80a19 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Ink;
  10. using System.Windows.Input;
  11. using System.Windows.Media;
  12. using System.Windows.Media.Animation;
  13. using System.Windows.Shapes;
  14. namespace PhantomMvvmToolkit.Converter
  15. {
  16. /// <summary>
  17. /// This will convert a boolean value, numeric value, or a string value into a SolidColorBrush.
  18. /// </summary>
  19. /// <remarks>
  20. /// 1. String Hex Value (#AABBCC) or (#AABBCCDD)
  21. /// 2. String RBG value (RGB111,222,333) or (RGBA111,222,333,444)
  22. /// 3. Color struct
  23. /// 4. Int, Float, Double that range from 0 to 1 (it will convert it to a gray scale)
  24. /// 5. Boolean (to black and white)
  25. ///
  26. /// For strings it will look in the parameters for one of the follow values "HEX3", "HEX4", "RGB", or "RGBA". That will define what format it will build the
  27. /// outbound string to, default will be HEX4
  28. /// </remarks>
  29. /// <exception cref="InvalidOperationException"></exception>
  30. public class ToSolidColorBrush : IValueConverter
  31. {
  32. private static List<string> ValidStringFormats = new List<string> { "HEX3", "HEX4", "RGB", "RGBA" };
  33. public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  34. {
  35. SolidColorBrush result;
  36. if (value is Color)
  37. {
  38. var casted = (Color)value;
  39. return BuildSolidColorBrush(casted.A, casted.R, casted.B, casted.G);
  40. }
  41. if (value is bool)
  42. {
  43. if ((bool)value)
  44. result = BuildSolidColorBrush(255, 255, 255, 255);
  45. else
  46. result = BuildSolidColorBrush(255, 0, 0, 0);
  47. }
  48. else if (value is int)
  49. {
  50. var casted = (int) value;
  51. result = casted <= 0 ? BuildSolidColorBrush(255, 0, 0, 0) : BuildSolidColorBrush(255, 255, 255, 255);
  52. }
  53. else if (value is float)
  54. {
  55. var casted = (float)value;
  56. var intCode = (int)(casted*255);
  57. var bitCode = byte.Parse(Math.Max(0, Math.Min(255, intCode)).ToString());
  58. result = BuildSolidColorBrush(255, bitCode, bitCode, bitCode);
  59. }
  60. else if (value is double)
  61. {
  62. var casted = (double)value;
  63. var intCode = (int)(casted * 255);
  64. var bitCode = byte.Parse(Math.Max(0, Math.Min(255, intCode)).ToString());
  65. result = BuildSolidColorBrush(255, bitCode, bitCode, bitCode);
  66. }
  67. else if (value is string)
  68. {
  69. var casted = (string)value;
  70. casted = casted.ToUpper();
  71. if (string.IsNullOrEmpty((string)value))
  72. {
  73. return BuildSolidColorBrush(255, 0, 0, 0);
  74. }
  75. else if (casted.StartsWith("#") && casted.Length == 7 || casted.Length == 9)
  76. {
  77. byte[] hexValues;
  78. try
  79. {
  80. hexValues = Enumerable.Range(0, casted.Length - 1)
  81. .Where(x => x % 2 == 0)
  82. .Select(x => System.Convert.ToByte(casted.Substring(x + 1, 2), 16))
  83. .ToArray();
  84. }
  85. catch (Exception)
  86. {
  87. throw new InvalidOperationException(string.Format("Failed to convert string value {0} from hex to byte array.", casted));
  88. }
  89. byte a = 255;
  90. byte r;
  91. byte g;
  92. byte b;
  93. if (hexValues.Length == 3)
  94. {
  95. r = hexValues[0];
  96. g = hexValues[1];
  97. b = hexValues[2];
  98. }
  99. else
  100. {
  101. a = hexValues[0];
  102. r = hexValues[1];
  103. g = hexValues[2];
  104. b = hexValues[3];
  105. }
  106. return BuildSolidColorBrush(a, r, b, g);
  107. }
  108. else if (casted.StartsWith("RGB"))
  109. {
  110. var rbg = casted.Substring(3).Split(',');
  111. byte r;
  112. byte g;
  113. byte b;
  114. try
  115. {
  116. r = byte.Parse(rbg[0]);
  117. g = byte.Parse(rbg[1]);
  118. b = byte.Parse(rbg[2]);
  119. }
  120. catch (Exception)
  121. {
  122. throw new InvalidOperationException(string.Format("Failed to convert string value {0} from RBG to byte array.", casted));
  123. }
  124. return BuildSolidColorBrush(255, r, b, g);
  125. }
  126. else if (casted.StartsWith("RGBA"))
  127. {
  128. var rbg = casted.Substring(4).Split(',');
  129. byte a;
  130. byte r;
  131. byte g;
  132. byte b;
  133. try
  134. {
  135. r = byte.Parse(rbg[0]);
  136. g = byte.Parse(rbg[1]);
  137. b = byte.Parse(rbg[2]);
  138. a = byte.Parse(rbg[3]);
  139. }
  140. catch (Exception)
  141. {
  142. throw new InvalidOperationException(string.Format("Failed to convert string value {0} from RBGA to byte array.", casted));
  143. }
  144. return BuildSolidColorBrush(a, r, b, g);
  145. }
  146. else
  147. {
  148. throw new InvalidOperationException(string.Format("Type is string but it did not convert to a valid hex, rgb, or rgba value. It's value was {0}", value));
  149. }
  150. }
  151. else if (value == null)
  152. {
  153. result = BuildSolidColorBrush(255, 0, 0, 0);
  154. }
  155. else
  156. {
  157. throw new InvalidOperationException(string.Format("Type {0} is not a valid conversion type.", value.GetType().Name));
  158. }
  159. return result;
  160. }
  161. static ToSolidColorBrush()
  162. {
  163. BuiltBrushes = new Dictionary<string, SolidColorBrush>();
  164. }
  165. private static Dictionary<string, SolidColorBrush> BuiltBrushes { get; set; }
  166. private static SolidColorBrush BuildSolidColorBrush(byte a, byte r, byte b, byte g)
  167. {
  168. var key = string.Format("{0}{1}{2}{3}", a, b, g, r);
  169. if (!BuiltBrushes.ContainsKey(key))
  170. {
  171. BuiltBrushes.Add(key, new SolidColorBrush(new Color() { A = a, B = b, G = g, R = r }));
  172. }
  173. return BuiltBrushes[key];
  174. }
  175. public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  176. {
  177. var current = ((SolidColorBrush)value).Color;
  178. if (targetType == typeof(Color))
  179. {
  180. return current;
  181. }
  182. if (targetType == typeof(bool) || targetType == typeof(bool?))
  183. {
  184. return current != Colors.Black;
  185. }
  186. if (targetType == typeof(int) || targetType == typeof(int?))
  187. {
  188. return current == Colors.Black ? 0 : 1;
  189. }
  190. if (targetType == typeof(float) || targetType == typeof(double) ||
  191. targetType == typeof(float?) || targetType == typeof(double?))
  192. {
  193. // takes the avg of the rgb (thus converting it to grey scale if it is not already)
  194. return (new List<int>
  195. {
  196. System.Convert.ToInt32(current.R),
  197. System.Convert.ToInt32(current.G),
  198. System.Convert.ToInt32(current.B)
  199. }).Average() / 255;
  200. }
  201. if (targetType == typeof(string))
  202. {
  203. var format = "HEX4";
  204. if (parameter != null && ValidStringFormats.Contains(parameter.ToString()))
  205. {
  206. format = parameter.ToString();
  207. }
  208. switch (format)
  209. {
  210. case "HEX3":
  211. return string.Format("#{0}{1}{2}",
  212. System.Convert.ToString(current.R, 16),
  213. System.Convert.ToString(current.G, 16),
  214. System.Convert.ToString(current.B, 16)).ToUpper();
  215. case "HEX4":
  216. return string.Format("#{0}{1}{2}{3}",
  217. System.Convert.ToString(current.A, 16),
  218. System.Convert.ToString(current.R, 16),
  219. System.Convert.ToString(current.G, 16),
  220. System.Convert.ToString(current.B, 16)).ToUpper();
  221. case "RGB":
  222. return string.Format("RGB{0},{1},{2}",
  223. current.R, current.G, current.B);
  224. case "RGBA":
  225. return string.Format("RGBA{0},{1},{2},{3}",
  226. current.R, current.G, current.B, current.A);
  227. }
  228. }
  229. throw new InvalidOperationException(string.Format("Type {0} is not a valid conversion type.", targetType.Name));
  230. }
  231. }
  232. }