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