2004-12-10 Lluis Sanchez Gual <lluis@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Unit.cs
1
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
10 // 
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 // 
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 /**\r
23  * Namespace: System.Web.UI.WebControls\r
24  * Struct:    Unit\r
25  *\r
26  * Author:  Gaurav Vaish\r
27  * Maintainer: gvaish@iitk.ac.in\r
28  * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>\r
29  * Implementation: yes\r
30  * Status:  100%\r
31  *\r
32  * (C) Gaurav Vaish (2001)\r
33  */\r
34 \r
35 using System;\r
36 using System.Globalization;\r
37 using System.ComponentModel;\r
38 using System.Web;\r
39 using System.Web.UI;\r
40 \r
41 namespace System.Web.UI.WebControls\r
42 {\r
43         [TypeConverter(typeof(UnitConverter))]\r
44         [Serializable]\r
45         public struct Unit\r
46         {\r
47                 public static readonly Unit Empty = new Unit();\r
48 \r
49                 private static int Min = -32768;\r
50                 private static int Max = +32767;\r
51 \r
52                 private UnitType type;\r
53                 private double   val;\r
54 \r
55                 public static Unit Parse(string s)\r
56                 {\r
57                         return new Unit(s);\r
58                 }\r
59 \r
60                 public static Unit Parse(string s, CultureInfo culture)\r
61                 {\r
62                         return new Unit(s, culture);\r
63                 }\r
64 \r
65                 public static Unit Percentage(double n)\r
66                 {\r
67                         return new Unit (n, UnitType.Percentage);\r
68                 }\r
69 \r
70                 public static Unit Pixel(int n)\r
71                 {\r
72                         return new Unit (n, UnitType.Pixel);\r
73                 }\r
74 \r
75                 public static Unit Point(int n)\r
76                 {\r
77                         return new Unit(n, UnitType.Point);\r
78                 }\r
79 \r
80                 public static bool operator ==(Unit left, Unit right)\r
81                 {\r
82                         return (left.type == right.type && left.val == right.val);\r
83                 }\r
84 \r
85                 public static bool operator !=(Unit left, Unit right)\r
86                 {\r
87                         return !(left == right);\r
88                 }\r
89 \r
90                 public static implicit operator Unit(int n)\r
91                 {\r
92                         return new Unit(n);\r
93                 }\r
94 \r
95                 public Unit(double value)\r
96                 {\r
97                         if(value < Min || value > Max)\r
98                         {\r
99                                 throw new ArgumentOutOfRangeException();\r
100                         }\r
101                         val = value;\r
102                         type = UnitType.Pixel;\r
103                 }\r
104 \r
105                 public Unit(int value)\r
106                 {\r
107                         if(value < Min || value > Max)\r
108                         {\r
109                                 throw new ArgumentOutOfRangeException();\r
110                         }\r
111                         val = value;\r
112                         type = UnitType.Pixel;\r
113                 }\r
114 \r
115                 public Unit(string value): this(value, CultureInfo.CurrentCulture)\r
116                 {\r
117                 }\r
118 \r
119                 public Unit(double value, UnitType type)\r
120                 {\r
121                         if(value < Min || value > Max)\r
122                         {\r
123                                 throw new ArgumentOutOfRangeException();\r
124                         }\r
125                         val = value;\r
126                         this.type = type;\r
127                 }\r
128 \r
129                 public Unit(string value, CultureInfo culture): this(value, culture, UnitType.Pixel)\r
130                 {\r
131                 }\r
132 \r
133                 internal Unit(string value, CultureInfo culture, UnitType defType)\r
134                 {\r
135                         string valueTrim;\r
136                         if (value == null || (valueTrim = value.Trim ()).Length == 0) {\r
137                                 val = 0;\r
138                                 type = (UnitType)0;\r
139                                 return;\r
140                         }\r
141 \r
142                         if (culture == null)\r
143                                 culture = CultureInfo.CurrentCulture;\r
144 \r
145                         string strVal = valueTrim.ToLower ();\r
146                         int length = strVal.Length;\r
147                         char c;\r
148                         int start = -1;\r
149                         for (int i = 0; i < length; i++) {\r
150                                 c = strVal [i];\r
151                                 if( (c >= '0' && c <= '9') || (c == '-' || c == '.' || c == ',') )\r
152                                         start = i;\r
153                         }\r
154                         \r
155                         if (start == -1)\r
156                                 throw new ArgumentException("No digits in 'value'");\r
157                         \r
158                         start++;\r
159                         if (start < length) {\r
160                                 type = GetTypeFromString (strVal.Substring (start).Trim ());\r
161                                 val  = 0;\r
162                         } else {\r
163                                 type = defType;\r
164                         }\r
165 \r
166                         try {\r
167                                 string numbers = strVal.Substring (0, start);\r
168                                 if (type == UnitType.Pixel)\r
169                                         val = (double) Int32.Parse (numbers, culture);\r
170                                 else\r
171                                         val = (double) Single.Parse (numbers, culture);\r
172                         } catch (Exception) {\r
173                                 throw new FormatException ("Error parsing " + value);\r
174                         }\r
175 \r
176                         if (val < Min || val > Max)\r
177                                 throw new ArgumentOutOfRangeException ();\r
178                 }\r
179 \r
180                 private static UnitType GetTypeFromString(string s)\r
181                 {\r
182                         if(s == null || s.Length == 0)\r
183                                 return UnitType.Pixel;\r
184                         switch(s)\r
185                         {\r
186                                 case "px":\r
187                                         return UnitType.Pixel;\r
188                                 case "pt":\r
189                                         return UnitType.Point;\r
190                                 case "pc":\r
191                                         return UnitType.Pica;\r
192                                 case "in":\r
193                                         return UnitType.Inch;\r
194                                 case "mm":\r
195                                         return UnitType.Mm;\r
196                                 case "cm":\r
197                                         return UnitType.Cm;\r
198                                 case "%":\r
199                                         return UnitType.Percentage;\r
200                                 case "em":\r
201                                         return UnitType.Em;\r
202                                 case "ex":\r
203                                         return UnitType.Ex;\r
204                                 default:\r
205                                         return UnitType.Pixel;\r
206                         }\r
207                 }\r
208 \r
209                 private string GetStringFromPixel(UnitType ut)\r
210                 {\r
211                         switch(ut)\r
212                         {\r
213                                 case UnitType.Pixel:\r
214                                         return "px";\r
215                                 case UnitType.Point:\r
216                                         return "pt";\r
217                                 case UnitType.Pica:\r
218                                         return "pc";\r
219                                 case UnitType.Inch:\r
220                                         return "in";\r
221                                 case UnitType.Mm:\r
222                                         return "mm";\r
223                                 case UnitType.Cm:\r
224                                         return "cm";\r
225                                 case UnitType.Percentage:\r
226                                         return "%";\r
227                                 case UnitType.Em:\r
228                                         return "em";\r
229                                 case UnitType.Ex:\r
230                                         return "ex";\r
231                                 default:\r
232                                         return String.Empty;\r
233                         }\r
234                 }\r
235 \r
236                 public bool IsEmpty\r
237                 {\r
238                         get\r
239                         {\r
240                                 return (type == 0);\r
241                         }\r
242                 }\r
243 \r
244                 public UnitType Type\r
245                 {\r
246                         get\r
247                         {\r
248                                 if(IsEmpty)\r
249                                         return UnitType.Pixel;\r
250                                 return type;\r
251                         }\r
252                 }\r
253 \r
254                 public double Value\r
255                 {\r
256                         get\r
257                         {\r
258                                 return val;\r
259                         }\r
260                 }\r
261 \r
262                 public override bool Equals(object obj)\r
263                 {\r
264                         if(obj != null && obj is Unit)\r
265                         {\r
266                                 Unit that = (Unit)obj;\r
267                                 return ( this.type == that.type && this.val == that.val );\r
268                         }\r
269                         return false;\r
270                 }\r
271 \r
272                 public override int GetHashCode()\r
273                 {\r
274                         return ( (type.GetHashCode() << 2) | (val.GetHashCode()) );\r
275                 }\r
276 \r
277                 public override string ToString()\r
278                 {\r
279                         if(IsEmpty)\r
280                                 return String.Empty;\r
281                         return ( val.ToString() + GetStringFromPixel(type) );\r
282                 }\r
283 \r
284                 public string ToString(CultureInfo culture)\r
285                 {\r
286                         if(IsEmpty)\r
287                                 return String.Empty;\r
288                         return ( val.ToString(culture.NumberFormat) + GetStringFromPixel(type) );\r
289                 }\r
290         }\r
291 }\r