2 // System.Drawing.ColorConverter
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 // Ravindra (rkumar@novell.com)
8 // Copyright (C) 2002 Ximian, Inc. http://www.ximian.com
9 // Copyright (C) 2004 Novell, Inc. http://www.novell.com
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Collections;
37 using System.ComponentModel;
38 using System.Globalization;
40 using System.ComponentModel.Design.Serialization;
41 using System.Reflection;
43 namespace System.Drawing
45 public class ColorConverter : TypeConverter
47 static StandardValuesCollection cached;
48 static object creatingCached = new object ();
50 public ColorConverter () { }
52 public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
54 if (sourceType == typeof (string))
57 return base.CanConvertFrom (context, sourceType);
60 public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
62 if (destinationType == typeof (InstanceDescriptor))
65 return base.CanConvertTo (context, destinationType);
68 public override object ConvertFrom (ITypeDescriptorContext context,
72 string s = value as string;
74 return base.ConvertFrom (context, culture, value);
82 object named = Color.NamedColors [s];
86 named = Color.SystemColors [s];
90 String numSeparator = culture.TextInfo.ListSeparator;
92 Int32Converter converter = new Int32Converter ();
96 if (s.IndexOf (numSeparator) == -1) {
97 if ((s.Length == 8 && (s.StartsWith ("0x") || s.StartsWith ("0X")))
98 || (s.Length == 7 && s.StartsWith ("#"))) {
99 result = Color.FromArgb (-16777216 | (int) converter.
100 ConvertFromString (context, culture, s));
102 else if ((s.Length == 5 && (s.StartsWith ("0x") || s.StartsWith ("0X")))
103 || (s.Length == 4 && s.StartsWith ("#"))) {
104 int i = (int) converter.ConvertFromString (context, culture, s);
105 i = ((i & 0xf00) << 12) | ((i & 0xf00) << 8) |
106 ((i & 0xf0) << 8) | ((i & 0xf0) << 4) |
107 ((i & 0xf) << 4) | (i & 0xf);
108 result = Color.FromArgb ( -16777216 | i );
112 if (result == null) {
113 String [] components = s.Split (numSeparator.ToCharArray ());
115 // MS seems to convert the indivual component to int before
116 // checking the number of components
117 int[] numComponents = new int[components.Length];
118 for (int i = 0; i < numComponents.Length; i++) {
119 numComponents[i] = (int) converter.ConvertFrom (context,
120 culture, components[i]);
123 switch (components.Length) {
125 result = Color.FromArgb (numComponents[0]);
128 result = Color.FromArgb (numComponents[0], numComponents[1],
132 result = Color.FromArgb (numComponents[0], numComponents[1],
133 numComponents[2], numComponents[3]);
136 throw new ArgumentException (s + " is not a valid color value.");
140 if (result != null) {
141 Color resultColor = (Color) result;
143 // Look for a named or system color with those values
144 foreach (Color c in Color.NamedColors.Values) {
145 if (c == resultColor)
149 foreach (Color c in Color.SystemColors.Values) {
150 if (c == resultColor)
158 public override object ConvertTo (ITypeDescriptorContext context,
161 Type destinationType)
163 if ((destinationType == typeof (string)) && (value is Color)) {
164 Color color = (Color) value;
166 if (color == Color.Empty) {
170 if (color.IsKnownColor) {
174 if (color.IsNamedColor)
177 String numSeparator = culture.TextInfo.ListSeparator;
179 StringBuilder sb = new StringBuilder ();
180 if (color.A != 255) {
182 sb.Append (numSeparator);
186 sb.Append (numSeparator);
190 sb.Append (numSeparator);
194 return sb.ToString ();
197 if (destinationType == typeof (InstanceDescriptor) && value is Color) {
198 Color c = (Color)value;
200 return new InstanceDescriptor (typeof (SystemColors).GetProperty (c.Name), null);
202 MethodInfo met = typeof(Color).GetMethod ("FromArgb", new Type[] { typeof(int), typeof(int), typeof(int), typeof(int) } );
203 return new InstanceDescriptor (met, new object[] {c.A, c.R, c.G, c.B });
207 return base.ConvertTo (context, culture, value, destinationType);
210 public override StandardValuesCollection GetStandardValues (ITypeDescriptorContext context)
215 lock (creatingCached)
220 ICollection named = (ICollection) Color.NamedColors.Values;
221 ICollection system = (ICollection) Color.SystemColors.Values;
222 Array colors = Array.CreateInstance (typeof (Color), named.Count + system.Count);
223 named.CopyTo (colors, 0);
224 system.CopyTo (colors, named.Count);
225 Array.Sort (colors, 0, colors.Length, new CompareColors ());
226 cached = new StandardValuesCollection (colors);
232 public override bool GetStandardValuesSupported (ITypeDescriptorContext context)
237 class CompareColors : IComparer
239 public int Compare (object x, object y)
241 return String.Compare (((Color) x).Name, ((Color) y).Name);