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