// // (C) Copyright 2003-2010 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; using Autodesk.Revit.Utility; using Autodesk.Revit.DB; namespace Revit.SDK.Samples.Materials.CS { /// /// A description of a property consists of a name, its attributes and value /// here AssetPropertyPropertyDescriptor is used to wrap AssetProperty /// to display its name and value in PropertyGrid /// internal class AssetPropertyPropertyDescriptor : PropertyDescriptor { #region Fields /// /// A reference to an AssetProperty /// private AssetProperty m_assetProperty; /// /// The type of AssetProperty's property "Value" /// private Type m_valueType; /// /// The value of AssetProperty's property "Value" /// private Object m_value; #endregion #region Properties /// /// Property to get internal AssetProperty /// public AssetProperty AssetProperty { get { return m_assetProperty; } } #endregion #region override Properties /// /// Gets a value indicating whether this property is read-only /// public override bool IsReadOnly { get { return true; } } /// /// Gets the type of the component this property is bound to. /// public override Type ComponentType { get { return m_assetProperty.GetType(); } } /// /// Gets the type of the property. /// public override Type PropertyType { get { return m_valueType; } } #endregion /// /// Public class constructor /// /// the AssetProperty which a AssetPropertyPropertyDescriptor instance describes public AssetPropertyPropertyDescriptor(AssetProperty assetProperty) : base(assetProperty.Name, new Attribute[0]) { m_assetProperty = assetProperty; } #region override methods /// /// Compares this to another object to see if they are equivalent /// /// The object to compare to this AssetPropertyPropertyDescriptor. /// public override bool Equals(object obj) { AssetPropertyPropertyDescriptor other = obj as AssetPropertyPropertyDescriptor; return other != null && other.AssetProperty.Equals(m_assetProperty); } /// /// Returns the hash code for this object. /// Here override the method "Equals", so it is necessary to override GetHashCode too. /// /// public override int GetHashCode() { return m_assetProperty.GetHashCode(); } /// /// Resets the value for this property of the component to the default value. /// /// The component with the property value that is to be reset to the default value. public override void ResetValue(object component) { } /// /// Returns whether resetting an object changes its value. /// /// The component to test for reset capability. /// true if resetting the component changes its value; otherwise, false. public override bool CanResetValue(object component) { return false; } /// /// Determines a value indicating whether the value of this property needs to be persisted. /// /// The component with the property to be examined for persistence. /// true if the property should be persisted; otherwise, false. public override bool ShouldSerializeValue(object component) { return false; } /// /// Gets the current value of the property on a component. /// /// The component with the property for which to retrieve the value. /// The value of a property for a given component. public override object GetValue(object component) { //For each AssetProperty, it has different type and value //must deal with it separately try { if (m_assetProperty is AssetPropertyBoolean) { AssetPropertyBoolean property = m_assetProperty as AssetPropertyBoolean; m_valueType = typeof(Boolean); m_value = property.Value; } else if (m_assetProperty is AssetPropertyDistance) { AssetPropertyDistance property = m_assetProperty as AssetPropertyDistance; m_valueType = typeof(Double); m_value = property.Value; } else if (m_assetProperty is AssetPropertyDouble) { AssetPropertyDouble property = m_assetProperty as AssetPropertyDouble; m_valueType = typeof(Double); m_value = property.Value; } else if (m_assetProperty is AssetPropertyDoubleArray2d) { //Default, it is supported by PropertyGrid to display Double [] //Try to convert DoubleArray to Double [] AssetPropertyDoubleArray2d property = m_assetProperty as AssetPropertyDoubleArray2d; m_valueType = typeof(Double[]); m_value = GetSystemArray(property.Value); } else if (m_assetProperty is AssetPropertyDoubleArray3d) { AssetPropertyDoubleArray3d property = m_assetProperty as AssetPropertyDoubleArray3d; m_valueType = typeof(Double[]); m_value = GetSystemArray(property.Value); } else if (m_assetProperty is AssetPropertyDoubleArray4d) { AssetPropertyDoubleArray4d property = m_assetProperty as AssetPropertyDoubleArray4d; m_valueType = typeof(Double[]); m_value = GetSystemArray(property.Value); } else if (m_assetProperty is AssetPropertyDoubleMatrix44) { AssetPropertyDoubleMatrix44 property = m_assetProperty as AssetPropertyDoubleMatrix44; m_valueType = typeof(Double[]); m_value = GetSystemArray(property.Value); } else if (m_assetProperty is AssetPropertyEnum) { AssetPropertyEnum property = m_assetProperty as AssetPropertyEnum; m_valueType = typeof(int); m_value = property.Value; } else if (m_assetProperty is AssetPropertyFloat) { AssetPropertyFloat property = m_assetProperty as AssetPropertyFloat; m_valueType = typeof(float); m_value = property.Value; } else if (m_assetProperty is AssetPropertyInteger) { AssetPropertyInteger property = m_assetProperty as AssetPropertyInteger; m_valueType = typeof(int); m_value = property.Value; } else if (m_assetProperty is AssetPropertyReference) { AssetPropertyReference property = m_assetProperty as AssetPropertyReference; m_valueType = typeof(String); m_value = property.Type; } else if (m_assetProperty is AssetPropertyString) { AssetPropertyString property = m_assetProperty as AssetPropertyString; m_valueType = typeof(String); m_value = property.Value; } else if (m_assetProperty is AssetPropertyTime) { AssetPropertyTime property = m_assetProperty as AssetPropertyTime; m_valueType = typeof(DateTime); m_value = property.Value; } else { return null; } } catch { return null; } return m_value; } /// /// Sets the value of the component to a different value. /// For AssetProperty, it is not allowed to set its value, so here just return. /// /// The component with the property value that is to be set. /// The new value. public override void SetValue(object component, object value) { return; } #endregion /// /// Convert Autodesk.Revit.DB.DoubleArray to Double []. /// For Double [] is supported by PropertyGrid. /// /// the original Autodesk.Revit.DB.DoubleArray /// The converted Double [] private Double[] GetSystemArray(DoubleArray doubleArray) { double [] values = new double [doubleArray.Size]; int index = 0; foreach(Double value in doubleArray) { values[index++] = value; } return values; } } /// /// supplies dynamic custom type information for an Asset while it is displayed in PropertyGrid. /// public class RenderAppearanceDescriptor : ICustomTypeDescriptor { #region Fields /// /// Reference to Asset /// Asset m_asset; /// /// Asset's property descriptors /// PropertyDescriptorCollection m_propertyDescriptors; #endregion #region Constructors /// /// Initializes Asset object /// /// an Asset object public RenderAppearanceDescriptor(Asset asset) { m_asset = asset; GetAssetProperties(); } /// /// Initializes Asset object /// /// an Material where can get an Asset public RenderAppearanceDescriptor(Material material) { m_asset = material.RenderAppearance; GetAssetProperties(); } #endregion #region Methods #region ICustomTypeDescriptor Members /// /// Returns a collection of custom attributes for this instance of Asset. /// /// Asset's attributes public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(m_asset, false); } /// /// Returns the class name of this instance of Asset. /// /// Asset's class name public string GetClassName() { return TypeDescriptor.GetClassName(m_asset, false); } /// /// Returns the name of this instance of Asset. /// /// The name of Asset public string GetComponentName() { return TypeDescriptor.GetComponentName(m_asset, false); } /// /// Returns a type converter for this instance of Asset. /// /// The converter of the Asset public TypeConverter GetConverter() { return TypeDescriptor.GetConverter(m_asset, false); } /// /// Returns the default event for this instance of Asset. /// /// An EventDescriptor that represents the default event for this object, /// or null if this object does not have events. public EventDescriptor GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(m_asset, false); } /// /// Returns the default property for this instance of Asset. /// /// A PropertyDescriptor that represents the default property for this object, /// or null if this object does not have properties. public PropertyDescriptor GetDefaultProperty() { return TypeDescriptor.GetDefaultProperty(m_asset, false); } /// /// Returns an editor of the specified type for this instance of Asset. /// /// A Type that represents the editor for this object. /// An Object of the specified type that is the editor for this object, /// or null if the editor cannot be found. public object GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(m_asset, editorBaseType, false); } /// /// Returns the events for this instance of Asset using the specified attribute array as a filter. /// /// An array of type Attribute that is used as a filter. /// An EventDescriptorCollection that represents the filtered events for this Asset instance. public EventDescriptorCollection GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(m_asset, attributes, false); } /// /// Returns the events for this instance of Asset. /// /// An EventDescriptorCollection that represents the events for this Asset instance. public EventDescriptorCollection GetEvents() { return TypeDescriptor.GetEvents(m_asset, false); } /// /// Returns the properties for this instance of Asset using the attribute array as a filter. /// /// An array of type Attribute that is used as a filter. /// A PropertyDescriptorCollection that /// represents the filtered properties for this Asset instance. public PropertyDescriptorCollection GetProperties(Attribute[] attributes) { return m_propertyDescriptors; } /// /// Returns the properties for this instance of Asset. /// /// A PropertyDescriptorCollection that represents the properties /// for this Asset instance. public PropertyDescriptorCollection GetProperties() { return m_propertyDescriptors; } /// /// Returns an object that contains the property described by the specified property descriptor. /// /// A PropertyDescriptor that represents the property whose owner is to be found. /// Asset object public object GetPropertyOwner(PropertyDescriptor pd) { return m_asset; } #endregion /// /// Get Asset's property descriptors /// private void GetAssetProperties() { if (null == m_propertyDescriptors) { m_propertyDescriptors = new PropertyDescriptorCollection(new AssetPropertyPropertyDescriptor[0]); } else { return; } //For each AssetProperty in Asset, create an AssetPropertyPropertyDescriptor. //It means that each AssetProperty will be a property of Asset for (int index = 0; index < m_asset.Size; index++) { AssetProperty assetProperty = m_asset[index]; if(null != assetProperty) { AssetPropertyPropertyDescriptor assetPropertyPropertyDescriptor = new AssetPropertyPropertyDescriptor(assetProperty); m_propertyDescriptors.Add(assetPropertyPropertyDescriptor); } } } #endregion } }