2003-10-11 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Style.cs
1 //
2 // System.Web.UI.WebControls.Style.cs
3 //
4 // Authors:
5 //   Gaurav Vaish (gvaish@iitk.ac.in)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //
8 // (C) Gaurav Vaish (2002)
9 // (C) 2003 Andreas Nahr
10 //
11
12 using System;
13 using System.Text;
14 using System.Collections;
15 using System.Drawing;
16 using System.Globalization;
17 using System.ComponentModel;
18 using System.Web;
19 using System.Web.UI;
20
21 namespace System.Web.UI.WebControls
22 {
23         [ToolboxItem(false)]
24         [TypeConverter(typeof(ExpandableObjectConverter))]
25         public class Style : Component , IStateManager
26         {
27                 internal static int MARKED      = (0x01 << 0);
28                 internal static int BACKCOLOR   = (0x01 << 1);
29                 internal static int BORDERCOLOR = (0x01 << 2);
30                 internal static int BORDERSTYLE = (0x01 << 3);
31                 internal static int BORDERWIDTH = (0x01 << 4);
32                 internal static int CSSCLASS    = (0x01 << 5);
33                 internal static int FORECOLOR   = (0x01 << 6);
34                 internal static int HEIGHT      = (0x01 << 7);
35                 internal static int WIDTH       = (0x01 << 8);
36                 internal static int FONT_BOLD   = (0x01 << 9);
37                 internal static int FONT_ITALIC = (0x01 << 10);
38                 internal static int FONT_NAMES  = (0x01 << 11);
39                 internal static int FONT_SIZE   = (0x01 << 12);
40                 internal static int FONT_STRIKE = (0x01 << 13);
41                 internal static int FONT_OLINE  = (0x01 << 14);
42                 internal static int FONT_ULINE  = (0x01 << 15);
43
44                 internal static string selectionBitString = "_SBS";
45
46                 StateBag viewState;
47                 int  selectionBits;
48                 bool selfStateBag;
49                 bool marked;
50
51                 private FontInfo font;
52
53                 public Style ()
54                 {
55                         Initialize(null);
56                         selfStateBag = true;
57                 }
58
59                 public Style (StateBag bag)
60                 {
61                         Initialize (bag);
62                         selfStateBag = false;
63                 }
64
65                 private void Initialize (StateBag bag)
66                 {
67                         viewState     = bag;
68                         selectionBits = 0x00;
69                 }
70
71                 protected internal StateBag ViewState {
72                         get {
73                                 if (viewState == null) {
74                                         viewState = new StateBag (false);
75                                         if (IsTrackingViewState)
76                                                 viewState.TrackViewState ();
77                                 }
78                                 return viewState;
79                         }
80                 }
81
82                 internal bool IsSet (int bit)
83                 {
84                         return ((selectionBits & bit) != 0x00);
85                 }
86
87                 internal virtual void Set (int bit)
88                 {
89                         selectionBits |= bit;
90                         if (IsTrackingViewState)
91                                 selectionBits |= MARKED;
92                 }
93
94                 [NotifyParentProperty (true)]
95                 [DefaultValue (null), Bindable (true), WebCategory ("Appearance")]
96                 [TypeConverter (typeof (WebColorConverter))]
97                 [WebSysDescription ("The background color for the WebControl.")]
98                 public Color BackColor {
99                         get {
100                                 if(IsSet(BACKCOLOR))
101                                         return (Color)ViewState["BackColor"];
102                                 return Color.Empty;
103                         }
104                         set {
105                                 ViewState["BackColor"] = value;
106                                 Set(BACKCOLOR);
107                         }
108                 }
109
110                 [NotifyParentProperty (true)]
111                 [DefaultValue (null), Bindable (true), WebCategory ("Appearance")]
112                 [TypeConverter (typeof (WebColorConverter))]
113                 [WebSysDescription ("The border color for the WebControl.")]
114                 public Color BorderColor {
115                         get {
116                                 if (IsSet (BORDERCOLOR))
117                                         return (Color) ViewState ["BorderColor"];
118                                 return Color.Empty;
119                         }
120                         set {
121                                 ViewState ["BorderColor"] = value;
122                                 Set (BORDERCOLOR);
123                         }
124                 }
125
126                 [NotifyParentProperty (true)]
127                 [DefaultValue (typeof(BorderStyle), "NotSet"), Bindable (true), WebCategory ("Appearance")]
128                 [WebSysDescription ("The style/type of the border used for the WebControl.")]
129                 public BorderStyle BorderStyle {
130                         get {
131                                 if (IsSet (BORDERSTYLE))
132                                         return (BorderStyle) ViewState ["BorderStyle"];
133                                 return BorderStyle.NotSet;
134                         }
135                         set {
136                                 ViewState ["BorderStyle"] = value;
137                                 Set (BORDERSTYLE);
138                         }
139                 }
140
141                 [NotifyParentProperty (true)]
142                 [DefaultValue (null), Bindable (true), WebCategory ("Appearance")]
143                 [WebSysDescription ("The width of the border used for the WebControl.")]
144                 public Unit BorderWidth {
145                         get {
146                                 if (IsSet (BORDERWIDTH))
147                                         return (Unit) ViewState ["BorderWidth"];
148                                 return Unit.Empty;
149                         }
150                         set {
151                                 ViewState ["BorderWidth"] = value;
152                                 Set (BORDERWIDTH);
153                         }
154                 }
155
156                 [NotifyParentProperty (true)]
157                 [DefaultValue (""), WebCategory ("Appearance")]
158                 [WebSysDescription ("The cascading stylesheet class that is associated with this WebControl.")]
159                 public string CssClass {
160                         get {
161                                 if (IsSet (CSSCLASS))
162                                         return (string) ViewState["CssClass"];
163                                 return string.Empty;
164                         }
165                         set {
166                                 ViewState ["CssClass"] = value;
167                                 Set (CSSCLASS);
168                         }
169                 }
170
171                 [NotifyParentProperty (true)]
172                 [DefaultValue (null), Bindable (true), WebCategory ("Appearance")]
173                 [TypeConverter (typeof (WebColorConverter))]
174                 [WebSysDescription ("The color that is used to paint the primary display of the WebControl.")]
175                 public Color ForeColor {
176                         get {
177                                 if (IsSet (FORECOLOR))
178                                         return (Color) ViewState ["ForeColor"];
179                                 return Color.Empty;
180                         }
181                         set {
182                                 ViewState ["ForeColor"] = value;
183                                 Set (FORECOLOR);
184                         }
185                 }
186
187                 [NotifyParentProperty (true)]
188                 [DefaultValue (null), Bindable (true), WebCategory ("Layout")]
189                 [WebSysDescription ("The height of this WebControl.")]
190                 public Unit Height {
191                         get {
192                                 if (IsSet (HEIGHT))
193                                         return (Unit) ViewState ["Height"];
194                                 return Unit.Empty;
195                         }
196                         set {
197                                 ViewState ["Height"] = value;
198                                 Set (HEIGHT);
199                         }
200                 }
201
202                 [NotifyParentProperty (true)]
203                 [DefaultValue (null), Bindable (true), WebCategory ("Layout")]
204                 [WebSysDescription ("The width of this WebControl.")]
205                 public Unit Width {
206                         get {
207                                 if (IsSet(WIDTH))
208                                         return (Unit) ViewState ["Width"];
209                                 return Unit.Empty;
210                         }
211                         set {
212                                 ViewState ["Width"] = value;
213                                 Set (WIDTH);
214                         }
215                 }
216
217                 [NotifyParentProperty (true)]
218                 [WebCategory ("Appearance")]
219                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
220                 [WebSysDescription ("The font of this WebControl.")]
221                 public FontInfo Font {
222                         get {
223                                 if (font==null)
224                                         font = new FontInfo (this);
225                                 return font;
226                         }
227                 }
228
229                 protected internal virtual bool IsEmpty
230                 {
231                         get { return (selectionBits == 0); }
232                 }
233
234                 private void AddColor (HtmlTextWriter writer, HtmlTextWriterStyle style, Color color)
235                 {
236                         if (!color.IsEmpty)
237                                 writer.AddStyleAttribute (style, ColorTranslator.ToHtml (color));
238                 }
239
240                 private static string StringArrayToString (string [] array, char separator)
241                 {
242                         if (array.Length == 0)
243                                 return String.Empty;
244                         StringBuilder sb = new StringBuilder ();
245                         for (int i = 0; i < array.Length; i++) {
246                                 if (i == 0) {
247                                         sb.Append (array [0]);
248                                 } else {
249                                         sb.Append (separator);
250                                         sb.Append (array [i]);
251                                 }
252                         }
253                         return sb.ToString ();
254                 }
255
256                 public void AddAttributesToRender (HtmlTextWriter writer)
257                 {
258                         AddAttributesToRender (writer, null);
259                 }
260
261                 public virtual void AddAttributesToRender (HtmlTextWriter writer, WebControl owner)
262                 {
263                         if (IsSet (BACKCOLOR))
264                                 AddColor (writer, HtmlTextWriterStyle.BackgroundColor, BackColor);
265
266                         if (IsSet(BORDERCOLOR))
267                                 AddColor (writer, HtmlTextWriterStyle.BorderColor, BorderColor);
268
269                         if (IsSet (FORECOLOR))
270                                 AddColor (writer, HtmlTextWriterStyle.Color, ForeColor);
271
272                         if (IsSet (CSSCLASS)) {
273                                 string cssClass = (string) ViewState ["CssClass"];
274                                 if (cssClass.Length > 0)
275                                         writer.AddAttribute (HtmlTextWriterAttribute.Class, cssClass);
276                         }
277
278                         if (!BorderWidth.IsEmpty) {
279                                 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth,
280                                                 BorderWidth.ToString (CultureInfo.InvariantCulture));
281
282                                 if (BorderStyle != BorderStyle.NotSet) {
283                                         writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle,
284                                                         Enum.Format (typeof (BorderStyle), BorderStyle, "G"));
285                                 } else {
286                                         if (BorderWidth.Value != 0.0)
287                                                 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle,
288                                                                           "solid");
289                                 }
290                         } else {
291                                 if (BorderStyle != BorderStyle.NotSet)
292                                         writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle,
293                                                         Enum.Format (typeof (BorderStyle), BorderStyle, "G"));
294                         }
295
296                         if (Font.Names.Length > 0)
297                                 writer.AddStyleAttribute (HtmlTextWriterStyle.FontFamily,
298                                                         StringArrayToString (Font.Names, ','));
299
300                         if (!Font.Size.IsEmpty)
301                                 writer.AddStyleAttribute (HtmlTextWriterStyle.FontSize,
302                                                         Font.Size.ToString (CultureInfo.InvariantCulture));
303
304                         if (Font.Bold)
305                                 writer.AddStyleAttribute (HtmlTextWriterStyle.FontWeight, "bold");
306
307                         if (Font.Italic)
308                                 writer.AddStyleAttribute (HtmlTextWriterStyle.FontStyle, "italic");
309
310                         string textDecoration = String.Empty;
311                         if (Font.Strikeout)
312                                 textDecoration += " line-through";
313
314                         if (Font.Underline)
315                                 textDecoration += " underline";
316
317                         if (Font.Overline)
318                                 textDecoration += " overline";
319
320                         if (textDecoration.Length > 0)
321                                 writer.AddStyleAttribute( HtmlTextWriterStyle.TextDecoration, textDecoration);
322
323                         Unit u = Unit.Empty;
324                         if (IsSet (HEIGHT)) {
325                                 u = (Unit) ViewState ["Height"];
326                                 if (!u.IsEmpty)
327                                         writer.AddStyleAttribute (HtmlTextWriterStyle.Height,
328                                                                 u.ToString (CultureInfo.InvariantCulture));
329                         }
330
331                         if (IsSet (WIDTH)) {
332                                 u = (Unit) ViewState ["Width"];
333                                 if (!u.IsEmpty)
334                                         writer.AddStyleAttribute (HtmlTextWriterStyle.Width,
335                                                                 u.ToString (CultureInfo.InvariantCulture));
336                         }
337                 }
338
339                 public virtual void CopyFrom (Style source)
340                 {
341                         if (source == null || source.IsEmpty)
342                                 return;
343
344                         Font.CopyFrom (source.Font);
345                         if (source.IsSet (HEIGHT))
346                                 Height = source.Height;
347
348                         if (source.IsSet (WIDTH))
349                                 Width = source.Width;
350
351                         if (source.IsSet (BORDERCOLOR))
352                                 BorderColor = source.BorderColor;
353
354                         if (source.IsSet (BORDERWIDTH))
355                                 BorderWidth = source.BorderWidth;
356
357                         if (source.IsSet (BORDERSTYLE))
358                                 BorderStyle = source.BorderStyle;
359
360                         if (source.IsSet (BACKCOLOR))
361                                 BackColor = source.BackColor;
362
363                         if (source.IsSet (CSSCLASS))
364                                 CssClass = source.CssClass;
365
366                         if (source.IsSet (FORECOLOR))
367                                 ForeColor = source.ForeColor;
368
369                 }
370
371                 public virtual void MergeWith (Style with)
372                 {
373                         if (with == null || with.IsEmpty)
374                                 return;
375
376                         if (IsEmpty) {
377                                 CopyFrom (with);
378                                 return;
379                         }
380
381                         Font.MergeWith (with.Font);
382                         if (!IsSet (HEIGHT) && with.Height != Unit.Empty)
383                                 Height = with.Height;
384
385                         if (!IsSet(WIDTH) && with.Width != Unit.Empty)
386                                 Width = with.Width;
387
388                         if (!IsSet (BORDERCOLOR) && with.BorderColor != Color.Empty)
389                                 BorderColor = with.BorderColor;
390
391                         if (!IsSet (BORDERWIDTH) && with.BorderWidth != Unit.Empty)
392                                 BorderWidth = with.BorderWidth;
393
394                         if (!IsSet (BORDERSTYLE) && with.BorderStyle != BorderStyle.NotSet)
395                                 BorderStyle = with.BorderStyle;
396
397                         if (!IsSet (BACKCOLOR) && with.BackColor != Color.Empty)
398                                 BackColor = with.BackColor;
399
400                         if (!IsSet (CSSCLASS) && with.CssClass != String.Empty)
401                                 CssClass = with.CssClass;
402
403                         if (!IsSet (FORECOLOR) && with.ForeColor != Color.Empty)
404                                 ForeColor = with.ForeColor;
405                 }
406
407                 public virtual void Reset ()
408                 {
409                         if (IsSet (BACKCOLOR))
410                                 ViewState.Remove ("BackColor");
411
412                         if (IsSet (BORDERCOLOR))
413                                 ViewState.Remove ("BorderColor");
414
415                         if (IsSet (BORDERSTYLE))
416                                 ViewState.Remove ("BorderStyle");
417
418                         if (IsSet (BORDERWIDTH))
419                                 ViewState.Remove ("BorderWidth");
420
421                         if (IsSet (CSSCLASS))
422                                 ViewState.Remove ("CssClass");
423
424                         if (IsSet (FORECOLOR))
425                                 ViewState.Remove ("ForeColor");
426
427                         if (IsSet (HEIGHT))
428                                 ViewState.Remove ("Height");
429
430                         if (IsSet (WIDTH))
431                                 ViewState.Remove( "Width");
432
433                         if (font != null)
434                                 font.Reset ();
435
436                         selectionBits = 0x00;
437                 }
438
439                 protected bool IsTrackingViewState {
440                         get { return marked; }
441                 }
442
443                 protected internal virtual void TrackViewState ()
444                 {
445                         if (selfStateBag)
446                                 ViewState.TrackViewState ();
447
448                         marked = true;
449                 }
450
451                 protected internal virtual object SaveViewState ()
452                 {
453                         if (viewState != null) {
454                                 if (marked)
455                                         ViewState [selectionBitString] = selectionBits;
456
457                                 if (selfStateBag)
458                                         return ViewState.SaveViewState ();
459                         }
460
461                         return null;
462                 }
463
464                 protected internal void LoadViewState (object state)
465                 {
466                         if (state != null && selfStateBag)
467                                 ViewState.LoadViewState (state);
468
469                         if (viewState != null) {
470                                 object o = ViewState [selectionBitString];
471                                 if (o != null)
472                                         selectionBits = (int) o;
473                         }
474                 }
475
476                 void IStateManager.LoadViewState(object state)
477                 {
478                         LoadViewState(state);
479                 }
480
481                 object IStateManager.SaveViewState ()
482                 {
483                         return SaveViewState ();
484                 }
485
486                 void IStateManager.TrackViewState ()
487                 {
488                         TrackViewState ();
489                 }
490
491                 bool IStateManager.IsTrackingViewState {
492                         get { return IsTrackingViewState; }
493                 }
494
495                 public override string ToString ()
496                 {
497                         return String.Empty;
498                 }
499         }
500 }
501