using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; namespace Svg { /// /// A collection of Scalable Vector Attributes that can be inherited from the owner elements ancestors. /// public sealed class SvgAttributeCollection : Dictionary { private SvgElement _owner; /// /// Initialises a new instance of a with the given as the owner. /// /// The owner of the collection. public SvgAttributeCollection(SvgElement owner) { this._owner = owner; } /// /// Gets the attribute with the specified name. /// /// The type of the attribute value. /// A containing the name of the attribute. /// The attribute value if available; otherwise the default value of . public TAttributeType GetAttribute(string attributeName) { if (this.ContainsKey(attributeName) && base[attributeName] != null) { return (TAttributeType)base[attributeName]; } return this.GetAttribute(attributeName, default(TAttributeType)); } /// /// Gets the attribute with the specified name. /// /// The type of the attribute value. /// A containing the name of the attribute. /// The value to return if a value hasn't already been specified. /// The attribute value if available; otherwise the default value of . public T GetAttribute(string attributeName, T defaultValue) { if (this.ContainsKey(attributeName) && base[attributeName] != null) { return (T)base[attributeName]; } return defaultValue; } /// /// Gets the attribute with the specified name and inherits from ancestors if there is no attribute set. /// /// The type of the attribute value. /// A containing the name of the attribute. /// The attribute value if available; otherwise the ancestors value for the same attribute; otherwise the default value of . public TAttributeType GetInheritedAttribute(string attributeName) { if (this.ContainsKey(attributeName) /*&& base[attributeName] != null*/) { return (TAttributeType)base[attributeName]; } if (this._owner.Parent != null) { if (this._owner.Parent.Attributes[attributeName] != null) { return (TAttributeType)this._owner.Parent.Attributes[attributeName]; } } return default(TAttributeType); } /// /// Gets the attribute with the specified name. /// /// A containing the attribute name. /// The attribute value associated with the specified name; If there is no attribute the parent's value will be inherited. public new object this[string attributeName] { get { return this.GetInheritedAttribute(attributeName); } set { if(base.ContainsKey(attributeName)) { var oldVal = base[attributeName]; if(TryUnboxAndCheck(oldVal, value)) { base[attributeName] = value; OnAttributeChanged(attributeName, value); } } else { base[attributeName] = value; OnAttributeChanged(attributeName, value); } } } private bool TryUnboxAndCheck(object a, object b) { System.Diagnostics.Debug.WriteLine("object type: " + a.GetType().ToString()); if(IsValueType(a)) { System.Diagnostics.Debug.WriteLine("is value type"); if(a is SvgUnit) return UnboxAndCheck(a, b); else if(a is bool) return UnboxAndCheck(a, b); else if(a is int) return UnboxAndCheck(a, b); else if(a is float) return UnboxAndCheck(a, b); else return true; } else { return a != b; } } private bool UnboxAndCheck(object a, object b) { return !((T)a).Equals((T)b); } private bool IsValueType(object obj) { return obj != null && obj.GetType().IsValueType; } /// /// Fired when an Atrribute has changed /// public event EventHandler AttributeChanged; private void OnAttributeChanged(string attribute, object value) { var handler = AttributeChanged; if(handler != null) { handler(this._owner, new AttributeEventArgs { Attribute = attribute, Value = value }); } } } /// /// A collection of Custom Attributes /// public sealed class SvgCustomAttributeCollection : Dictionary { private SvgElement _owner; /// /// Initialises a new instance of a with the given as the owner. /// /// The owner of the collection. public SvgCustomAttributeCollection(SvgElement owner) { this._owner = owner; } /// /// Gets the attribute with the specified name. /// /// A containing the attribute name. /// The attribute value associated with the specified name; If there is no attribute the parent's value will be inherited. public new string this[string attributeName] { get { return base[attributeName]; } set { if(base.ContainsKey(attributeName)) { var oldVal = base[attributeName]; base[attributeName] = value; if(oldVal != value) OnAttributeChanged(attributeName, value); } else { base[attributeName] = value; OnAttributeChanged(attributeName, value); } } } /// /// Fired when an Atrribute has changed /// public event EventHandler AttributeChanged; private void OnAttributeChanged(string attribute, object value) { var handler = AttributeChanged; if(handler != null) { handler(this._owner, new AttributeEventArgs { Attribute = attribute, Value = value }); } } } }