Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorCss/Css/CssPrimitiveValue.cs @ 13949

Last change on this file since 13949 was 12762, checked in by aballeit, 9 years ago

#2283 GUI updates, Tree-chart, MCTS Version 2 (prune leaves)

File size: 18.4 KB
RevLine 
[12762]1// <developer>niklas@protocol7.com</developer>
2// <completed>100</completed>
3
4using System;
5using System.Xml;
6using System.Globalization;
7using System.Text.RegularExpressions;
8
9namespace SharpVectors.Dom.Css
10{
11    /// <summary>
12    /// The CSSPrimitiveValue interface represents a single CSS value.
13    /// </summary>
14    /// <remarks>
15    /// <para>
16    /// This interface may be used to determine the value of a specific style
17    /// property currently set in a block or to set a specific style property
18    /// explicitly within the block. An instance of this interface might be
19    /// obtained from the getPropertyCSSValue method of the CSSStyleDeclaration
20    /// interface. A CSSPrimitiveValue object only occurs in a context of a CSS property.
21    /// </para>
22    /// <para>
23    /// Conversions are allowed between absolute values (from millimeters to centimeters,
24    /// from degrees to radians, and so on) but not between relative values. (For example,
25    /// a pixel value cannot be converted to a centimeter value.) Percentage values can't
26    /// be converted since they are relative to the parent value (or another property value).
27    /// There is one exception for color percentage values: since a color percentage value
28    /// is relative to the range 0-255, a color percentage value can be converted to a number;
29    /// (see also the RGBColor interface).
30    /// </para>
31    /// </remarks>
32    public class CssPrimitiveValue : CssValue, ICssPrimitiveValue
33    {
34        #region Private Fields
35
36        private CssPrimitiveType _primitiveType;
37
38        protected double floatValue;
39        private string stringValue;
40        private   CssRect rectValue;
41        protected CssColor colorValue;
42
43        #endregion
44
45        #region Constructors and Destructor
46
47        /// <summary>
48        /// Constructor called by CssValue.GetCssValue()
49        /// </summary>
50        /// <param name="match">A Regex that matches a CssPrimitiveValue</param>
51        /// <param name="readOnly">Specifiec if this instance is read-only</param>
52        private CssPrimitiveValue(Match match, bool readOnly)
53            : this(match.Value, readOnly)
54        {
55            if (match.Groups["func"].Success)
56            {
57                switch (match.Groups["funcname"].Value)
58                {
59                    case "rect":
60                        _primitiveType = CssPrimitiveType.Rect;
61                        rectValue = new CssRect(match.Groups["funcvalue"].Value, ReadOnly);
62                        break;
63                    case "attr":
64                        _primitiveType = CssPrimitiveType.Attr;
65                        stringValue = match.Groups["funcvalue"].Value;
66                        break;
67                    case "url":
68                        stringValue = match.Groups["funcvalue"].Value;
69                        _primitiveType = CssPrimitiveType.Uri;
70                        break;
71                    case "counter":
72                        throw new NotImplementedException("Counters are not implemented");
73                    //_primitiveType = CssPrimitiveType.CSS_COUNTER;
74                }
75            }
76            else if (match.Groups["freqTimeNumber"].Success)
77            {
78                floatValue = Single.Parse(match.Groups["numberValue2"].Value, CssNumber.Format);
79
80                switch (match.Groups["unit2"].Value)
81                {
82                    case "Hz":
83                        _primitiveType = CssPrimitiveType.Hz;
84                        break;
85                    case "kHz":
86                        _primitiveType = CssPrimitiveType.KHz;
87                        break;
88                    case "in":
89                        _primitiveType = CssPrimitiveType.In;
90                        break;
91                    case "s":
92                        _primitiveType = CssPrimitiveType.S;
93                        break;
94                    case "ms":
95                        _primitiveType = CssPrimitiveType.Ms;
96                        break;
97                    case "%":
98                        _primitiveType = CssPrimitiveType.Percentage;
99                        break;
100                    default:
101                        _primitiveType = CssPrimitiveType.Number;
102                        break;
103                }
104            }
105            else if (match.Groups["string"].Success)
106            {
107                stringValue = match.Groups["stringvalue"].Value;
108                _primitiveType = CssPrimitiveType.String;
109            }
110            else if (match.Groups["colorIdent"].Success)
111            {
112                string val = match.Value;
113                stringValue = match.Value;
114                _primitiveType = CssPrimitiveType.Ident;
115            }
116            else
117            {
118                _primitiveType = CssPrimitiveType.Unknown;
119            }
120        }
121
122        protected CssPrimitiveValue(string cssText, bool readOnly)
123            : base(CssValueType.PrimitiveValue, cssText, readOnly)
124        {
125            _primitiveType = CssPrimitiveType.Unknown;
126            floatValue     = Double.NaN;
127        }
128
129        /// <summary>
130        /// Only for internal use
131        /// </summary>
132        protected CssPrimitiveValue()
133            : base()
134        {
135            _primitiveType = CssPrimitiveType.Unknown;
136            _cssValueType  = CssValueType.PrimitiveValue;
137            floatValue     = Double.NaN;
138        }
139
140        #endregion
141
142        #region Public Properties
143
144        public string PrimitiveTypeAsString
145        {
146            get
147            {
148                switch (PrimitiveType)
149                {
150                    case CssPrimitiveType.Percentage:
151                        return "%";
152                    case CssPrimitiveType.Ems:
153                        return "em";
154                    case CssPrimitiveType.Exs:
155                        return "ex";
156                    case CssPrimitiveType.Px:
157                        return "px";
158                    case CssPrimitiveType.Cm:
159                        return "cm";
160                    case CssPrimitiveType.Mm:
161                        return "mm";
162                    case CssPrimitiveType.In:
163                        return "in";
164                    case CssPrimitiveType.Pt:
165                        return "pt";
166                    case CssPrimitiveType.Pc:
167                        return "pc";
168                    case CssPrimitiveType.Deg:
169                        return "deg";
170                    case CssPrimitiveType.Rad:
171                        return "rad";
172                    case CssPrimitiveType.Grad:
173                        return "grad";
174                    case CssPrimitiveType.Ms:
175                        return "ms";
176                    case CssPrimitiveType.S:
177                        return "s";
178                    case CssPrimitiveType.Hz:
179                        return "hz";
180                    case CssPrimitiveType.KHz:
181                        return "khz";
182                    default:
183                        return String.Empty;
184                }
185            }
186        }
187
188        public override string CssText
189        {
190            get
191            {
192                if (PrimitiveType == CssPrimitiveType.String)
193                {
194                    return "\"" + GetStringValue() + "\"";
195                }
196                else
197                {
198                    return base.CssText;
199                }
200            }
201            set
202            {
203                if (ReadOnly)
204                {
205                    throw new DomException(DomExceptionType.InvalidModificationErr,
206                        "CssPrimitiveValue is read-only");
207                }
208                else
209                {
210                    OnSetCssText(value);
211                }
212            }
213        }
214
215        #endregion
216
217        #region Public Methods
218
219        public static CssPrimitiveValue Create(Match match, bool readOnly)
220        {
221            if (match.Groups["length"].Success)
222            {
223                return new CssPrimitiveLengthValue(match.Groups["lengthNumber"].Value, match.Groups["lengthUnit"].Value, readOnly);
224            }
225            else if (match.Groups["angle"].Success)
226            {
227                return new CssPrimitiveAngleValue(match.Groups["angleNumber"].Value, match.Groups["angleUnit"].Value, readOnly);
228            }
229            else if (match.Groups["funcname"].Success && match.Groups["funcname"].Value == "rgb")
230            {
231                return new CssPrimitiveRgbValue(match.Groups["func"].Value, readOnly);
232            }
233            else if (match.Groups["colorIdent"].Success && CssPrimitiveRgbValue.IsColorName(match.Groups["colorIdent"].Value))
234            {
235                return new CssPrimitiveRgbValue(match.Groups["colorIdent"].Value, readOnly);
236            }
237            else
238            {
239                return new CssPrimitiveValue(match, readOnly);
240            }
241        }
242
243        public override CssValue GetAbsoluteValue(string propertyName, XmlElement elm)
244        {
245            if (propertyName == "font-size")
246            {
247                return new CssAbsPrimitiveLengthValue(this, propertyName, elm);
248            }
249            else
250            {
251                return new CssAbsPrimitiveValue(this, propertyName, elm);
252            }
253        }
254
255        #endregion
256
257        #region Protected Methods
258
259        protected virtual void OnSetCssText(string cssText)
260        {
261        }
262
263        #endregion
264
265        #region ICssPrimitiveValue Members
266
267        /// <summary>
268        /// A method to set the float value with a specified unit. If the property attached with this value can not accept the specified unit or the float value, the value will be unchanged and a DOMException will be raised.
269        /// </summary>
270        /// <param name="unitType">A unit code as defined above. The unit code can only be a float unit type (i.e. CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS, CSS_PX, CSS_CM, CSS_MM, CSS_IN, CSS_PT, CSS_PC, CSS_DEG, CSS_RAD, CSS_GRAD, CSS_MS, CSS_S, CSS_HZ, CSS_KHZ, CSS_DIMENSION).</param>
271        /// <param name="floatValue">The new float value.</param>
272        /// <exception cref="DomException">INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a float value.</exception>
273        /// <exception cref="DomException">NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly.</exception>
274        public virtual void SetFloatValue(CssPrimitiveType unitType, double floatValue)
275        {
276            if (this.ReadOnly)
277            {
278                throw new DomException(DomExceptionType.NoModificationAllowedErr);
279            }
280            else
281            {
282                _primitiveType = unitType;
283                SetFloatValue(floatValue);
284            }
285        }
286
287        protected void SetFloatValue(string floatValue)
288        {
289            SetFloatValue(Double.Parse(floatValue, CssNumber.Format));
290        }
291
292        protected void SetFloatValue(double floatValue)
293        {
294            this.floatValue = floatValue;
295        }
296
297        /// <summary>
298        /// This method is used to get a float value in a specified unit. If this CSS value doesn't contain a float value or can't be converted into the specified unit, a DOMException is raised
299        /// </summary>
300        /// <param name="unitType">A unit code to get the float value. The unit code can only be a float unit type (i.e. CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS, CSS_PX, CSS_CM, CSS_MM, CSS_IN, CSS_PT, CSS_PC, CSS_DEG, CSS_RAD, CSS_GRAD, CSS_MS, CSS_S, CSS_HZ, CSS_KHZ, CSS_DIMENSION).</param>
301        /// <returns>The float value in the specified unit.</returns>
302        /// <exception cref="DomException">INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a float value.</exception>
303        public virtual double GetFloatValue(CssPrimitiveType unitType)
304        {
305            if (Double.IsNaN(floatValue))
306            {
307                throw new DomException(DomExceptionType.InvalidAccessErr);
308            }
309            else
310            {
311                double ret = Double.NaN;
312                switch (PrimitiveType)
313                {
314                    case CssPrimitiveType.Percentage:
315                        if (unitType == CssPrimitiveType.Percentage) ret = floatValue;
316                        break;
317                    case CssPrimitiveType.Ms:
318                        if (unitType == CssPrimitiveType.Ms) ret = floatValue;
319                        else if (unitType == CssPrimitiveType.S) ret = floatValue / 1000;
320                        break;
321                    case CssPrimitiveType.S:
322                        if (unitType == CssPrimitiveType.Ms) ret = floatValue * 1000;
323                        else if (unitType == CssPrimitiveType.S) ret = floatValue;
324                        break;
325                    case CssPrimitiveType.Hz:
326                        if (unitType == CssPrimitiveType.Hz) ret = floatValue;
327                        else if (unitType == CssPrimitiveType.KHz) ret = floatValue / 1000;
328                        break;
329                    case CssPrimitiveType.KHz:
330                        if (unitType == CssPrimitiveType.Hz) ret = floatValue * 1000;
331                        else if (unitType == CssPrimitiveType.KHz) ret = floatValue;
332                        break;
333                    case CssPrimitiveType.Dimension:
334                        if (unitType == CssPrimitiveType.Dimension) ret = floatValue;
335                        break;
336                }
337                if (Double.IsNaN(ret))
338                {
339                    throw new DomException(DomExceptionType.InvalidAccessErr);
340                }
341                else
342                {
343                    return ret;
344                }
345            }
346        }
347
348        /// <summary>
349        /// A method to set the string value with the specified unit. If the property attached to this value can't accept the specified unit or the string value, the value will be unchanged and a DOMException will be raised.
350        /// </summary>
351        /// <param name="stringType">A string code as defined above. The string code can only be a string unit type (i.e. CSS_STRING, CSS_URI, CSS_IDENT, and CSS_ATTR).</param>
352        /// <param name="stringValue">The new string value</param>
353        /// <exception cref="DomException">INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a string value.</exception>
354        /// <exception cref="DomException">NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly.</exception>
355        public virtual void SetStringValue(CssPrimitiveType stringType, string stringValue)
356        {
357            throw new NotImplementedException("SetStringValue");
358        }
359
360        /// <summary>
361        /// This method is used to get the string value. If the CSS value doesn't contain a string value, a DOMException is raised.
362        /// Note: Some properties (like 'font-family' or 'voice-family') convert a whitespace separated list of idents to a string.
363        /// </summary>
364        /// <returns>The string value in the current unit. The current primitiveType can only be a string unit type (i.e. CSS_STRING, CSS_URI, CSS_IDENT and CSS_ATTR).</returns>
365        /// <exception cref="DomException">INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a string value.</exception>
366        public virtual string GetStringValue()
367        {
368            string ret = null;
369            switch (PrimitiveType)
370            {
371                case CssPrimitiveType.String:
372                case CssPrimitiveType.Uri:
373                case CssPrimitiveType.Ident:
374                case CssPrimitiveType.Attr:
375                    ret = stringValue;
376                    break;
377            }
378
379            if (ret != null)
380                return ret;
381            else
382                throw new DomException(DomExceptionType.InvalidAccessErr);
383        }
384
385        /// <summary>
386        /// This method is used to get the Counter value. If this CSS value doesn't contain a counter value, a DOMException is raised. Modification to the corresponding style property can be achieved using the Counter interface
387        /// </summary>
388        /// <returns>The Counter value.</returns>
389        /// <exception cref="DomException">INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a Counter value (e.g. this is not CSS_COUNTER).</exception>
390        public virtual ICssCounter GetCounterValue()
391        {
392            throw new NotImplementedException("GetCounterValue");
393        }
394
395        /// <summary>
396        /// This method is used to get the Rect value. If this CSS value doesn't contain a rect value, a DOMException is raised. Modification to the corresponding style property can be achieved using the Rect interface.
397        /// </summary>
398        /// <returns>The Rect value.</returns>
399        /// <exception cref="DomException">INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a rect value.</exception>
400        public virtual ICssRect GetRectValue()
401        {
402            if (PrimitiveType == CssPrimitiveType.Rect)
403                return rectValue;
404            else
405                throw new DomException(DomExceptionType.InvalidAccessErr);
406        }
407
408        /// <summary>
409        /// This method is used to get the RGB color. If this CSS value doesn't contain a RGB color value, a DOMException is raised. Modification to the corresponding style property can be achieved using the RGBColor interface.
410        /// </summary>
411        /// <returns>the RGB color value.</returns>
412        /// <exception cref="DomException">INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a rgb value.</exception>
413        public virtual ICssColor GetRgbColorValue()
414        {
415            if (PrimitiveType == CssPrimitiveType.RgbColor)
416                return colorValue;
417            else
418                throw new DomException(DomExceptionType.InvalidAccessErr);
419        }
420
421        protected void SetPrimitiveType(CssPrimitiveType type)
422        {
423            _primitiveType = type;
424        }
425
426        /// <summary>
427        /// The type of the value as defined by the constants specified above.
428        /// </summary>
429        public virtual CssPrimitiveType PrimitiveType
430        {
431            get
432            {
433                return _primitiveType;
434            }
435            protected set
436            {
437                _primitiveType = value;
438            }
439        }
440
441        #endregion
442    }
443}
Note: See TracBrowser for help on using the repository browser.