1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Peter Dennis Bartok (pbartok@novell.com)
27 using System.ComponentModel;
29 using System.Security.Permissions;
31 namespace System.Web.UI.WebControls {
34 [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
35 [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
38 // Not until we actually have StyleConverter
39 // [TypeConverter(typeof(System.Web.UI.WebControls.StyleConverter))]
41 [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
44 public class Style : System.ComponentModel.Component, System.Web.UI.IStateManager
46 internal const string BitStateKey = "_!SB";
51 BackColor = 0x00000008,
52 BorderColor = 0x00000010,
53 BorderStyle = 0x00000040,
54 BorderWidth = 0x00000020,
55 CssClass = 0x00000002,
57 ForeColor = 0x00000004,
65 FontOverline = 0x4000,
67 FontStrikeout = 0x8000,
68 FontUnderline = 0x2000
73 private int stylesTraked;
74 internal StateBag viewstate;
75 private FontInfo fontinfo;
76 private bool tracking;
77 bool _isSharedViewState;
79 private string registered_class;
83 #region Public Constructors
86 viewstate = new StateBag ();
89 public Style(System.Web.UI.StateBag bag)
92 if (viewstate == null)
93 viewstate = new StateBag ();
94 _isSharedViewState = true;
96 #endregion // Public Constructors
98 #region Public Instance Properties
102 [DefaultValue(typeof (Color), "")]
103 [NotifyParentProperty(true)]
104 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
105 [WebSysDescription ("")]
106 [WebCategory ("Appearance")]
107 public Color BackColor
111 if (!CheckBit ((int) Styles.BackColor))
116 return (Color)viewstate["BackColor"];
121 viewstate["BackColor"] = value;
122 SetBit ((int) Styles.BackColor);
129 [DefaultValue(typeof (Color), "")]
130 [NotifyParentProperty(true)]
131 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
132 [WebSysDescription ("")]
133 [WebCategory ("Appearance")]
134 public Color BorderColor
138 if (!CheckBit ((int) Styles.BorderColor))
143 return (Color)viewstate["BorderColor"];
148 viewstate["BorderColor"] = value;
149 SetBit ((int) Styles.BorderColor);
156 [DefaultValue(BorderStyle.NotSet)]
157 [NotifyParentProperty(true)]
158 [WebSysDescription ("")]
159 [WebCategory ("Appearance")]
160 public BorderStyle BorderStyle
164 if (!CheckBit ((int) Styles.BorderStyle))
166 return BorderStyle.NotSet;
169 return (BorderStyle)viewstate["BorderStyle"];
174 viewstate["BorderStyle"] = value;
175 SetBit ((int) Styles.BorderStyle);
182 [DefaultValue(typeof (Unit), "")]
183 [NotifyParentProperty(true)]
184 [WebSysDescription ("")]
185 [WebCategory ("Appearance")]
186 public Unit BorderWidth
190 if (!CheckBit ((int) Styles.BorderWidth))
195 return (Unit)viewstate["BorderWidth"];
202 throw new ArgumentOutOfRangeException("Value", value.Value, "BorderWidth must not be negative");
205 viewstate["BorderWidth"] = value;
206 SetBit ((int) Styles.BorderWidth);
211 [NotifyParentProperty(true)]
212 [WebSysDescription ("")]
213 [WebCategory ("Appearance")]
214 public string CssClass
218 if (!CheckBit ((int) Styles.CssClass))
223 return (string)viewstate["CssClass"];
228 viewstate["CssClass"] = value;
229 SetBit ((int) Styles.CssClass);
233 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
234 [NotifyParentProperty(true)]
235 [WebSysDescription ("")]
236 [WebCategory ("Appearance")]
241 if (fontinfo == null)
243 fontinfo = new FontInfo(this);
252 [DefaultValue(typeof (Color), "")]
253 [NotifyParentProperty(true)]
254 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
255 [WebSysDescription ("")]
256 [WebCategory ("Appearance")]
257 public Color ForeColor
261 if (!CheckBit ((int) Styles.ForeColor))
266 return (Color)viewstate["ForeColor"];
271 viewstate["ForeColor"] = value;
272 SetBit ((int) Styles.ForeColor);
279 [DefaultValue(typeof (Unit), "")]
280 [NotifyParentProperty(true)]
281 [WebSysDescription ("")]
282 [WebCategory ("Appearance")]
287 if (!CheckBit ((int) Styles.Height))
292 return (Unit)viewstate["Height"];
299 throw new ArgumentOutOfRangeException("Value", value.Value, "Height must not be negative");
302 viewstate["Height"] = value;
303 SetBit ((int) Styles.Height);
310 [DefaultValue(typeof (Unit), "")]
311 [NotifyParentProperty(true)]
312 [WebSysDescription ("")]
313 [WebCategory ("Appearance")]
318 if (!CheckBit ((int) Styles.Width))
323 return (Unit)viewstate["Width"];
330 throw new ArgumentOutOfRangeException("Value", value.Value, "Width must not be negative");
333 viewstate["Width"] = value;
334 SetBit ((int) Styles.Width);
337 #endregion // Public Instance Properties
339 #region Protected Instance Properties
342 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
343 public virtual bool IsEmpty
345 protected internal virtual bool IsEmpty
351 return (styles == 0 && RegisteredCssClass.Length == 0);
353 return (styles == 0);
358 protected bool IsTrackingViewState
367 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
368 protected internal StateBag ViewState
375 #endregion // Protected Instance Properties
377 #region Internal Instance Properties
378 internal bool AlwaysRenderTextDecoration
382 if (viewstate["AlwaysRenderTextDecoration"] == null)
384 return (bool)viewstate["AlwaysRenderTextDecoration"];
389 viewstate["AlwaysRenderTextDecoration"] = value;
392 #endregion // Internal Instance Properties
394 #region Public Instance Methods
395 public void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
397 AddAttributesToRender(writer, null);
400 public virtual void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer, WebControl owner)
403 if (RegisteredCssClass.Length > 0) {
404 if (CssClass.Length > 0)
405 writer.AddAttribute (HtmlTextWriterAttribute.Class, CssClass + " " + RegisteredCssClass);
407 writer.AddAttribute (HtmlTextWriterAttribute.Class, RegisteredCssClass);
412 if (CssClass.Length > 0)
413 writer.AddAttribute (HtmlTextWriterAttribute.Class, CssClass);
414 WriteStyleAttributes (writer);
418 void WriteStyleAttributes (HtmlTextWriter writer)
421 CssStyleCollection col = new CssStyleCollection (new StateBag ());
422 FillStyleAttributes (col, null);
423 foreach (string key in col.Keys) {
424 writer.AddStyleAttribute (key, col [key]);
432 if (CheckBit ((int) Styles.BackColor)) {
433 color = (Color)viewstate["BackColor"];
435 writer.AddStyleAttribute (HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(color));
438 if (CheckBit ((int) Styles.BorderColor)) {
439 color = (Color)viewstate["BorderColor"];
441 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderColor, ColorTranslator.ToHtml(color));
444 bool have_width = false;
445 if (CheckBit ((int) Styles.BorderWidth)) {
446 u = (Unit)viewstate["BorderWidth"];
450 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, u.ToString());
454 if (CheckBit ((int) Styles.BorderStyle)) {
455 bs = (BorderStyle)viewstate["BorderStyle"];
456 if (bs != BorderStyle.NotSet)
457 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle, bs.ToString());
459 if (CheckBit ((int) Styles.BorderWidth))
460 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle, "solid");
462 } else if (have_width) {
463 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle, "solid");
466 if (CheckBit ((int) Styles.ForeColor)) {
467 color = (Color)viewstate["ForeColor"];
469 writer.AddStyleAttribute (HtmlTextWriterStyle.Color, ColorTranslator.ToHtml(color));
472 if (CheckBit ((int) Styles.Height)) {
473 u = (Unit)viewstate["Height"];
475 writer.AddStyleAttribute (HtmlTextWriterStyle.Height, u.ToString());
478 if (CheckBit ((int) Styles.Width)) {
479 u = (Unit)viewstate["Width"];
481 writer.AddStyleAttribute (HtmlTextWriterStyle.Width, u.ToString());
484 if (CheckBit ((int) Style.Styles.FontAll)) {
485 // Fonts are a bit weird
486 if (fontinfo.Name != string.Empty) {
487 s = fontinfo.Names[0];
488 for (int i = 1; i < fontinfo.Names.Length; i++)
489 s += "," + fontinfo.Names[i];
490 writer.AddStyleAttribute (HtmlTextWriterStyle.FontFamily, s);
494 writer.AddStyleAttribute (HtmlTextWriterStyle.FontWeight, "bold");
497 writer.AddStyleAttribute (HtmlTextWriterStyle.FontStyle, "italic");
499 if (!fontinfo.Size.IsEmpty)
500 writer.AddStyleAttribute (HtmlTextWriterStyle.FontSize, fontinfo.Size.ToString());
502 // These styles are munged into a attribute decoration
505 if (fontinfo.Overline)
508 if (fontinfo.Strikeout)
509 s += "line-through ";
511 if (fontinfo.Underline)
514 s = (s != "") ? s : AlwaysRenderTextDecoration ? "none" : "";
516 writer.AddStyleAttribute (HtmlTextWriterStyle.TextDecoration, s);
522 void FillStyleAttributes (CssStyleCollection attributes)
528 if (CheckBit ((int) Styles.BackColor))
530 color = (Color)viewstate["BackColor"];
532 attributes.Add (HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(color));
535 if (CheckBit ((int) Styles.BorderColor))
537 color = (Color)viewstate["BorderColor"];
539 attributes.Add (HtmlTextWriterStyle.BorderColor, ColorTranslator.ToHtml(color));
542 bool have_width = false;
543 if (CheckBit ((int) Styles.BorderWidth)) {
544 u = (Unit) viewstate ["BorderWidth"];
548 attributes.Add (HtmlTextWriterStyle.BorderWidth, u.ToString ());
552 if (CheckBit ((int) Styles.BorderStyle)) {
553 bs = (BorderStyle) viewstate ["BorderStyle"];
554 if (bs != BorderStyle.NotSet)
555 attributes.Add (HtmlTextWriterStyle.BorderStyle, bs.ToString ());
557 attributes.Add (HtmlTextWriterStyle.BorderStyle, "solid");
559 else if (have_width) {
560 attributes.Add (HtmlTextWriterStyle.BorderStyle, "solid");
563 if (CheckBit ((int) Styles.ForeColor))
565 color = (Color)viewstate["ForeColor"];
567 attributes.Add (HtmlTextWriterStyle.Color, ColorTranslator.ToHtml(color));
570 if (CheckBit ((int) Styles.Height))
572 u = (Unit)viewstate["Height"];
574 attributes.Add (HtmlTextWriterStyle.Height, u.ToString());
577 if (CheckBit ((int) Styles.Width))
579 u = (Unit)viewstate["Width"];
581 attributes.Add (HtmlTextWriterStyle.Width, u.ToString());
584 Font.FillStyleAttributes (attributes, AlwaysRenderTextDecoration);
588 public virtual void CopyFrom(Style s)
590 if ((s == null) || s.IsEmpty)
595 if (s.fontinfo != null)
597 Font.CopyFrom(s.fontinfo);
600 if ((s.CheckBit ((int) Styles.BackColor)) && (s.BackColor != Color.Empty))
602 this.BackColor = s.BackColor;
604 if ((s.CheckBit ((int) Styles.BorderColor)) && (s.BorderColor != Color.Empty))
606 this.BorderColor = s.BorderColor;
608 if ((s.CheckBit ((int) Styles.BorderStyle)) && (s.BorderStyle != BorderStyle.NotSet))
610 this.BorderStyle = s.BorderStyle;
612 if ((s.CheckBit ((int) Styles.BorderWidth)) && (!s.BorderWidth.IsEmpty))
614 this.BorderWidth = s.BorderWidth;
616 if ((s.CheckBit ((int) Styles.CssClass)) && (s.CssClass != string.Empty))
618 this.CssClass = s.CssClass;
620 if ((s.CheckBit ((int) Styles.ForeColor)) && (s.ForeColor != Color.Empty))
622 this.ForeColor = s.ForeColor;
624 if ((s.CheckBit ((int) Styles.Height)) && (!s.Height.IsEmpty))
626 this.Height = s.Height;
628 if ((s.CheckBit ((int) Styles.Width)) && (!s.Width.IsEmpty))
630 this.Width = s.Width;
634 public virtual void MergeWith(Style s)
636 if ((s == null) || (s.IsEmpty))
641 if (s.fontinfo != null)
643 Font.MergeWith(s.fontinfo);
646 if ((!CheckBit ((int) Styles.BackColor)) && (s.CheckBit ((int) Styles.BackColor)) && (s.BackColor != Color.Empty))
648 this.BackColor = s.BackColor;
650 if ((!CheckBit ((int) Styles.BorderColor)) && (s.CheckBit ((int) Styles.BorderColor)) && (s.BorderColor != Color.Empty))
652 this.BorderColor = s.BorderColor;
654 if ((!CheckBit ((int) Styles.BorderStyle)) && (s.CheckBit ((int) Styles.BorderStyle)) && (s.BorderStyle != BorderStyle.NotSet))
656 this.BorderStyle = s.BorderStyle;
658 if ((!CheckBit ((int) Styles.BorderWidth)) && (s.CheckBit ((int) Styles.BorderWidth)) && (!s.BorderWidth.IsEmpty))
660 this.BorderWidth = s.BorderWidth;
662 if ((!CheckBit ((int) Styles.CssClass)) && (s.CheckBit ((int) Styles.CssClass)) && (s.CssClass != string.Empty))
664 this.CssClass = s.CssClass;
666 if ((!CheckBit ((int) Styles.ForeColor)) && (s.CheckBit ((int) Styles.ForeColor)) && (s.ForeColor != Color.Empty))
668 this.ForeColor = s.ForeColor;
670 if ((!CheckBit ((int) Styles.Height)) && (s.CheckBit ((int) Styles.Height)) && (!s.Height.IsEmpty))
672 this.Height = s.Height;
674 if ((!CheckBit ((int) Styles.Width)) && (s.CheckBit ((int) Styles.Width)) && (!s.Width.IsEmpty))
676 this.Width = s.Width;
681 internal void Print ()
683 Console.WriteLine ("BackColor: {0}", BackColor);
684 Console.WriteLine ("BorderColor: {0}", BorderColor);
685 Console.WriteLine ("BorderStyle: {0}", BorderStyle);
686 Console.WriteLine ("BorderWidth: {0}", BorderWidth);
687 Console.WriteLine ("CssClass: {0}", CssClass);
688 Console.WriteLine ("ForeColor: {0}", ForeColor);
689 Console.WriteLine ("Height: {0}", Height);
690 Console.WriteLine ("Width: {0}", Width);
694 public virtual void Reset()
696 viewstate.Remove("BackColor");
697 viewstate.Remove("BorderColor");
698 viewstate.Remove("BorderStyle");
699 viewstate.Remove("BorderWidth");
700 viewstate.Remove("CssClass");
701 viewstate.Remove("ForeColor");
702 viewstate.Remove("Height");
703 viewstate.Remove("Width");
704 if (fontinfo != null)
709 viewstate.Remove (BitStateKey);
713 public override string ToString()
718 #endregion // Public Instance Methods
720 #region Protected Instance Methods
721 protected internal void LoadViewState(object state)
723 viewstate.LoadViewState(state);
728 protected internal virtual object SaveViewState ()
732 if (_isSharedViewState)
735 return viewstate.SaveViewState ();
739 internal void SaveBitState ()
741 if (stylesTraked != 0)
742 viewstate [BitStateKey] = stylesTraked;
745 internal void LoadBitState () {
746 if (viewstate [BitStateKey] == null)
749 int bit = (int) viewstate [BitStateKey];
754 protected internal virtual void SetBit( int bit )
761 internal void RemoveBit (int bit) {
764 stylesTraked &= ~bit;
765 if (stylesTraked == 0)
766 viewstate.Remove (BitStateKey);
770 internal bool CheckBit (int bit) {
771 return (styles & bit) != 0;
774 protected internal virtual void TrackViewState ()
777 viewstate.TrackViewState();
779 #endregion // Protected Instance Methods
781 #region IStateManager Properties & Methods
782 void IStateManager.LoadViewState(object state)
784 LoadViewState(state);
787 object IStateManager.SaveViewState()
789 return SaveViewState();
792 void IStateManager.TrackViewState()
797 bool IStateManager.IsTrackingViewState
801 return this.IsTrackingViewState;
804 #endregion // IStateManager Properties & Methods
807 protected virtual void FillStyleAttributes (CssStyleCollection attributes, IUrlResolutionService urlResolver)
809 FillStyleAttributes (attributes);
812 internal void SetRegisteredCssClass (string name)
814 registered_class = name;
817 public CssStyleCollection GetStyleAttributes (IUrlResolutionService resolver)
819 CssStyleCollection col = new CssStyleCollection (new StateBag ());
820 FillStyleAttributes (col, resolver);
824 [EditorBrowsable(EditorBrowsableState.Advanced)]
825 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
827 public string RegisteredCssClass {
829 if (registered_class == null)
830 registered_class = String.Empty;
831 return registered_class;
835 internal void CopyTextStylesFrom (Style source) {
836 // Used primary for TreeView and Menu
837 if (source.CheckBit ((int) Styles.ForeColor)) {
838 ForeColor = source.ForeColor;
840 if (source.CheckBit((int) Styles.FontAll)) {
841 Font.CopyFrom (source.Font);
845 internal void RemoveTextStyles () {
846 ForeColor = Color.Empty;
850 internal void AddCssClass (string cssClass) {
851 if (String.IsNullOrEmpty (cssClass))
854 if (CssClass.Length > 0)
856 CssClass += cssClass;
859 public void SetDirty ()
861 if (viewstate != null)
862 viewstate.SetDirty (true);
863 stylesTraked = styles;