2004-05-26 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Unit.cs
1 /**\r
2  * Namespace: System.Web.UI.WebControls\r
3  * Struct:    Unit\r
4  *\r
5  * Author:  Gaurav Vaish\r
6  * Maintainer: gvaish@iitk.ac.in\r
7  * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>\r
8  * Implementation: yes\r
9  * Status:  100%\r
10  *\r
11  * (C) Gaurav Vaish (2001)\r
12  */\r
13 \r
14 using System;\r
15 using System.Globalization;\r
16 using System.ComponentModel;\r
17 using System.Web;\r
18 using System.Web.UI;\r
19 \r
20 namespace System.Web.UI.WebControls\r
21 {\r
22         [TypeConverter(typeof(UnitConverter))]\r
23         public struct Unit\r
24         {\r
25                 public static readonly Unit Empty = new Unit();\r
26 \r
27                 private static int Min = -32768;\r
28                 private static int Max = +32767;\r
29 \r
30                 private UnitType type;\r
31                 private double   val;\r
32 \r
33                 public static Unit Parse(string s)\r
34                 {\r
35                         return new Unit(s);\r
36                 }\r
37 \r
38                 public static Unit Parse(string s, CultureInfo culture)\r
39                 {\r
40                         return new Unit(s, culture);\r
41                 }\r
42 \r
43                 public static Unit Percentage(double n)\r
44                 {\r
45                         return new Unit (n, UnitType.Percentage);\r
46                 }\r
47 \r
48                 public static Unit Pixel(int n)\r
49                 {\r
50                         return new Unit (n, UnitType.Pixel);\r
51                 }\r
52 \r
53                 public static Unit Point(int n)\r
54                 {\r
55                         return new Unit(n, UnitType.Point);\r
56                 }\r
57 \r
58                 public static bool operator ==(Unit left, Unit right)\r
59                 {\r
60                         return (left.type == right.type && left.val == right.val);\r
61                 }\r
62 \r
63                 public static bool operator !=(Unit left, Unit right)\r
64                 {\r
65                         return !(left == right);\r
66                 }\r
67 \r
68                 public static implicit operator Unit(int n)\r
69                 {\r
70                         return new Unit(n);\r
71                 }\r
72 \r
73                 public Unit(double value)\r
74                 {\r
75                         if(value < Min || value > Max)\r
76                         {\r
77                                 throw new ArgumentOutOfRangeException();\r
78                         }\r
79                         val = value;\r
80                         type = UnitType.Pixel;\r
81                 }\r
82 \r
83                 public Unit(int value)\r
84                 {\r
85                         if(value < Min || value > Max)\r
86                         {\r
87                                 throw new ArgumentOutOfRangeException();\r
88                         }\r
89                         val = value;\r
90                         type = UnitType.Pixel;\r
91                 }\r
92 \r
93                 public Unit(string value): this(value, CultureInfo.CurrentCulture)\r
94                 {\r
95                 }\r
96 \r
97                 public Unit(double value, UnitType type)\r
98                 {\r
99                         if(value < Min || value > Max)\r
100                         {\r
101                                 throw new ArgumentOutOfRangeException();\r
102                         }\r
103                         val = value;\r
104                         this.type = type;\r
105                 }\r
106 \r
107                 public Unit(string value, CultureInfo culture): this(value, culture, UnitType.Pixel)\r
108                 {\r
109                 }\r
110 \r
111                 internal Unit(string value, CultureInfo culture, UnitType defType)\r
112                 {\r
113                         string valueTrim;\r
114                         if (value == null || (valueTrim = value.Trim ()).Length == 0) {\r
115                                 val = 0;\r
116                                 type = UnitType.Pixel;\r
117                                 return;\r
118                         }\r
119 \r
120                         if (culture == null)\r
121                                 culture = CultureInfo.CurrentCulture;\r
122 \r
123                         string strVal = valueTrim.ToLower ();\r
124                         int length = strVal.Length;\r
125                         char c;\r
126                         int start = -1;\r
127                         for (int i = 0; i < length; i++) {\r
128                                 c = strVal [i];\r
129                                 if( (c >= '0' && c <= '9') || (c == '-' || c == '.' || c == ',') )\r
130                                         start = i;\r
131                         }\r
132                         \r
133                         if (start == -1)\r
134                                 throw new ArgumentException("No digits in 'value'");\r
135                         \r
136                         start++;\r
137                         if (start < length) {\r
138                                 type = GetTypeFromString (strVal.Substring (start).Trim ());\r
139                                 val  = 0;\r
140                         } else {\r
141                                 type = defType;\r
142                         }\r
143 \r
144                         try {\r
145                                 string numbers = strVal.Substring (0, start);\r
146                                 if (type == UnitType.Pixel)\r
147                                         val = (double) Int32.Parse (numbers, culture);\r
148                                 else\r
149                                         val = (double) Single.Parse (numbers, culture);\r
150                         } catch (Exception) {\r
151                                 throw new FormatException ("Error parsing " + value);\r
152                         }\r
153 \r
154                         if (val < Min || val > Max)\r
155                                 throw new ArgumentOutOfRangeException ();\r
156                 }\r
157 \r
158                 private static UnitType GetTypeFromString(string s)\r
159                 {\r
160                         if(s == null || s.Length == 0)\r
161                                 return UnitType.Pixel;\r
162                         s = s.ToLower().Trim();\r
163                         string[] uTypes = {\r
164                                 "px",\r
165                                 "pt",\r
166                                 "pc",\r
167                                 "in",\r
168                                 "mm",\r
169                                 "cm",\r
170                                 "%",\r
171                                 "em",\r
172                                 "ex"\r
173                         };\r
174                         int i = 0;\r
175                         foreach(string cType in uTypes)\r
176                         {\r
177                                 if(s == cType)\r
178                                         return (UnitType)Enum.ToObject(typeof(UnitType), (i + 1));\r
179                                 i++;\r
180                         }\r
181                         return UnitType.Pixel;\r
182                 }\r
183 \r
184                 private string GetStringFromPixel(UnitType ut)\r
185                 {\r
186                         string[] uTypes = {\r
187                                 "px",\r
188                                 "pt",\r
189                                 "pc",\r
190                                 "in",\r
191                                 "mm",\r
192                                 "cm",\r
193                                 "%",\r
194                                 "em",\r
195                                 "ex"\r
196                         };\r
197                         if( !Enum.IsDefined(typeof(UnitType), ut) )\r
198                                 return "px";\r
199                         return uTypes[(int)ut - 1];\r
200                 }\r
201 \r
202                 public bool IsEmpty\r
203                 {\r
204                         get\r
205                         {\r
206                                 return (type == 0);\r
207                         }\r
208                 }\r
209 \r
210                 public UnitType Type\r
211                 {\r
212                         get\r
213                         {\r
214                                 if(IsEmpty)\r
215                                         return UnitType.Pixel;\r
216                                 return type;\r
217                         }\r
218                 }\r
219 \r
220                 public double Value\r
221                 {\r
222                         get\r
223                         {\r
224                                 return val;\r
225                         }\r
226                 }\r
227 \r
228                 public override bool Equals(object obj)\r
229                 {\r
230                         if(obj != null && obj is Unit)\r
231                         {\r
232                                 Unit that = (Unit)obj;\r
233                                 return ( this.type == that.type && this.val == that.val );\r
234                         }\r
235                         return false;\r
236                 }\r
237 \r
238                 public override int GetHashCode()\r
239                 {\r
240                         return ( (type.GetHashCode() << 2) | (val.GetHashCode()) );\r
241                 }\r
242 \r
243                 public override string ToString()\r
244                 {\r
245                         if(IsEmpty)\r
246                                 return String.Empty;\r
247                         return ( val.ToString() + GetStringFromPixel(type) );\r
248                 }\r
249 \r
250                 public string ToString(CultureInfo culture)\r
251                 {\r
252                         if(IsEmpty)\r
253                                 return String.Empty;\r
254                         return ( val.ToString(culture.NumberFormat) + GetStringFromPixel(type) );\r
255                 }\r
256         }\r
257 }\r