Exemplo n.º 1
0
        /// <summary>
        /// Creates a property source for the specified CLR object using reflection.
        /// </summary>
        /// <param name="instance">The instance.</param>
        /// <param name="name">The name for the property source.</param>
        /// <param name="typeName">The type name of the property source.</param>
        /// <returns>The property source.</returns>
        /// <remarks>
        /// <para>
        /// This method can be used for static types and dynamic types that implement
        /// <see cref="ICustomTypeDescriptor"/>. The property source lists instance properties.
        /// Properties where the <see cref="BrowsableAttribute"/> is set to <see langword="false"/>
        /// are ignored.
        /// </para>
        /// <para>
        /// To find the name of the property source the method uses (in this order):
        /// </para>
        /// <list type="number">
        /// <item>The <paramref name="name"/> parameter.</item>
        /// <item>The <see cref="INamedObject"/> interface.</item>
        /// <item>A string property called "Name".</item>
        /// </list>
        /// <para>
        /// To find the type name of the property source the method uses (in this order):
        /// </para>
        /// <list type="number">
        /// <item>The <paramref name="typeName"/> parameter.</item>
        /// <item>The CLR type name.</item>
        /// </list>
        /// <para>
        /// The <paramref name="instance"/> is stored in the <see cref="PropertySource.UserData"/>
        /// of the <see cref="PropertySource"/>.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="instance"/> is <see langword="null"/>.
        /// </exception>
        public static PropertySource CreatePropertySource(object instance, string name = null, string typeName = null)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }

            var propertySource = new PropertySource {
                UserData = instance
            };

            // Get property descriptors.
            var typeConverter = TypeDescriptor.GetConverter(instance);
            PropertyDescriptorCollection propertyDescriptors = null;

            if (typeConverter != null && typeConverter.GetPropertiesSupported())
            {
                // Try to get properties from type converter.
                propertyDescriptors = typeConverter.GetProperties(instance);
            }

            if (propertyDescriptors == null && instance is ICustomTypeDescriptor)
            {
                // Instance is a dynamic object.
                propertyDescriptors = ((ICustomTypeDescriptor)instance).GetProperties();
            }

            bool isBasicObject = false;

            if (propertyDescriptors == null)
            {
                // Instance is a regular CLR object.
                isBasicObject       = true;
                propertyDescriptors = TypeDescriptor.GetProperties(instance.GetType());
            }

            // Create a list of all properties.
            propertySource.Properties.AddRange(
                propertyDescriptors.OfType <PropertyDescriptor>()
                .Where(descriptor => descriptor.IsBrowsable)
                .Select(descriptor => new ReflectedProperty(instance, descriptor))
                .OrderBy(p => p, PropertyComparer.Instance));

            // Add public fields of regular CLR objects (very important for structs like Vector3F).
            if (isBasicObject)
            {
                foreach (var field in instance.GetType().GetFields())
                {
                    if (!field.IsLiteral && !field.IsStatic)
                    {
                        propertySource.Properties.Add(new ReflectedField(instance, field));
                    }
                }
            }

            // Add items of an IEnumerable.
            var enumerable = instance as IEnumerable;

            if (enumerable != null)
            {
                int index = 0;
                foreach (var item in enumerable)
                {
                    string itemName  = "Item[" + index + "]";
                    var    namedItem = item as INamedObject;
                    if (namedItem != null)
                    {
                        itemName = Invariant($"{itemName}: {namedItem.Name}");
                    }

                    propertySource.Properties.Add(new CustomProperty(itemName, item)
                    {
                        Category   = "Items",
                        IsReadOnly = true
                    });
                    index++;
                }
            }

            // ----- Set name:
            // 1. Try name parameter.
            propertySource.Name = name;

            // 2. Try INamedObject interface.
            if (propertySource.Name == null)
            {
                var namedObject = instance as INamedObject;
                if (namedObject != null)
                {
                    propertySource.Name = namedObject.Name;
                }
            }

            // 3. Try "Name" property.
            if (propertySource.Name == null)
            {
                var namePropertyDescriptor =
                    propertyDescriptors.OfType <PropertyDescriptor>()
                    .FirstOrDefault(d => d.Name == "Name" && d.PropertyType == typeof(string));

                if (namePropertyDescriptor != null)
                {
                    propertySource.Name = (string)namePropertyDescriptor.GetValue(instance);
                }
            }

            // Fallback: Empty string.
            if (propertySource.Name == null)
            {
                propertySource.Name = string.Empty;
            }

            // Set type name.
            propertySource.TypeName = typeName;
            if (propertySource.TypeName == null)
            {
                propertySource.TypeName = instance.GetType().Name;
            }

            return(propertySource);
        }
Exemplo n.º 2
0
        //--------------------------------------------------------------
        #region Properties & Events
        //--------------------------------------------------------------
        #endregion


        //--------------------------------------------------------------
        #region Creation & Cleanup
        //--------------------------------------------------------------
        #endregion


        //--------------------------------------------------------------
        #region Methods
        //--------------------------------------------------------------

        private void UpdateProperties()
        {
            if (_modelPropertySource == null)
                _modelPropertySource = new PropertySource();

            _currentPropertySource = _modelPropertySource;

            _modelPropertySource.Name = this.GetName();
            _modelPropertySource.TypeName = "3D Model";
            _modelPropertySource.Properties.Clear();

            if (State != ModelDocumentState.Loaded)
                return;

            // Try to load drmdl file.
            string drmdlFile = Path.ChangeExtension(Uri.LocalPath, "drmdl");
            if (UseDigitalRuneGraphics && File.Exists(drmdlFile))
            {
                _modelPropertySource.Properties.Add(new CustomProperty
                {
                    Category = "General",
                    Name = "Model description",
                    Value = drmdlFile,
                    //Description = ,
                    PropertyType = typeof(string),
                    DataTemplateKey = OpenLinkKey,
                    CanReset = false,
                    IsReadOnly = true,
                });
            }

            int numberOfVertices = 0;
            int numberOfPrimitives = 0;
            if (UseDigitalRuneGraphics)
            {
                foreach (var mesh in ModelNode.GetDescendants().OfType<MeshNode>().Select(mn => mn.Mesh))
                {
                    foreach (var submesh in mesh.Submeshes)
                    {
                        numberOfVertices += submesh.VertexCount;
                        numberOfPrimitives += submesh.PrimitiveCount;
                    }
                }
            }
            else
            {
                foreach (var meshPart in Model.Meshes.SelectMany(m => m.MeshParts))
                {
                    numberOfVertices += meshPart.NumVertices;
                    numberOfPrimitives += meshPart.PrimitiveCount;
                }
            }

            _modelPropertySource.Properties.Add(new CustomProperty
            {
                Category = "General",
                Name = "Triangles",
                Value = numberOfPrimitives,
                //Description = ,
                PropertyType = typeof(int),
                DataTemplateKey = TextBlockKey,
                CanReset = false,
                IsReadOnly = true,
            });

            _modelPropertySource.Properties.Add(new CustomProperty
            {
                Category = "General",
                Name = "Vertices",
                Value = numberOfVertices,
                //Description = ,
                PropertyType = typeof(int),
                DataTemplateKey = TextBlockKey,
                CanReset = false,
                IsReadOnly = true,
            });

            // Try to load drmat files.
            if (UseDigitalRuneGraphics)
            {
                string drmdlFolder = Path.GetDirectoryName(drmdlFile);
                var drmatFiles = new HashSet<string>();
                var textures = new HashSet<string>();
                var xDocument = XDocument.Load(drmdlFile);
                foreach (var submeshElement in xDocument.Descendants("Submesh"))
                {
                    var materialAttribute = submeshElement.Attributes("Material").FirstOrDefault();
                    if (materialAttribute == null)
                        continue;

                    string drmatFile = GetAbsolutePath(drmdlFolder, materialAttribute.Value);
                    if (!File.Exists(drmatFile))
                        continue;

                    drmatFiles.Add(drmatFile);
                    string drmatFolder = Path.GetDirectoryName(drmatFile);

                    // Collect all referenced texture filenames.
                    var drmatXDocument = XDocument.Load(drmatFile);
                    foreach (var textureElement in drmatXDocument.Descendants("Texture"))
                    {
                        var fileAttribute = textureElement.Attributes("File").FirstOrDefault();
                        if (fileAttribute == null)
                            continue;

                        string textureFile = GetAbsolutePath(drmatFolder, fileAttribute.Value);
                        textures.Add(textureFile);
                    }
                }

                int i = 0;
                foreach (var drmatFile in drmatFiles)
                {
                    _modelPropertySource.Properties.Add(new CustomProperty
                    {
                        Category = "Materials",
                        Name = Invariant($"Material {i}"),
                        Value = drmatFile,
                        //Description = ,
                        PropertyType = typeof(string),
                        DataTemplateKey = OpenLinkKey,
                        CanReset = false,
                        IsReadOnly = true,
                    });
                    i++;
                }

                i = 0;
                foreach (var texture in textures)
                {
                    _modelPropertySource.Properties.Add(new CustomProperty
                    {
                        Category = "Textures",
                        Name = Invariant($"Texture {i}"),
                        Value = texture,
                        //Description = ,
                        PropertyType = typeof(string),
                        DataTemplateKey = OpenLinkKey,
                        CanReset = false,
                        IsReadOnly = true,
                    });
                    i++;
                }

                _animationPropertyViewModels.Clear();
                if (HasAnimations)
                {
                    var mesh = ModelNode.GetDescendants().OfType<MeshNode>().First().Mesh;
                    foreach (var entry in mesh.Animations)
                    {
                        var animationPropertyViewModel = new AnimationPropertyViewModel(this)
                        {
                            Name = entry.Key,
                            Animation = entry.Value,
                        };
                        _animationPropertyViewModels.Add(animationPropertyViewModel);

                        _modelPropertySource.Properties.Add(new CustomProperty
                        {
                            Category = "Animations",
                            Name = "\"" + entry.Key + "\"",
                            Value = animationPropertyViewModel,
                            //Description = ,
                            PropertyType = typeof(AnimationPropertyViewModel),
                            CanReset = false,
                            IsReadOnly = true,
                        });
                    }
                }
            }

            if (_documentService.ActiveDocument == this)
            {
                // This document is active and can control tool windows.
                if (_propertiesService != null)
                    _propertiesService.PropertySource = _currentPropertySource;
            }
        }
Exemplo n.º 3
0
        private void UpdateProperties()
        {
            if (_propertySource == null)
                _propertySource = new PropertySource();

            _propertySource.Name = (IsUntitled) ? UntitledName : Path.GetFileName(Uri.LocalPath);
            _propertySource.TypeName = "Texture";

            var textBlockKey = new ComponentResourceKey(typeof(PropertyGrid), "TextBlock");

            _propertySource.Properties.Clear();
            _propertySource.Properties.Add(new CustomProperty
            {
                Category = "Misc",
                Name = "File name",
                Value = this.GetName(),
                Description = "The filename of the image.",
                PropertyType = typeof(string),
                //DataTemplateKey = textBlockKey,
                CanReset = false,
                IsReadOnly = true,
            });
            _propertySource.Properties.Add(new CustomProperty
            {
                Category = "Misc",
                Name = "Size",
                Value = Texture2D?.Width,
                Description = "Image width in pixels.",
                PropertyType = typeof(int),
                DataTemplateKey = textBlockKey,
                CanReset = false,
                IsReadOnly = true,
            });
            _propertySource.Properties.Add(new CustomProperty
            {
                Category = "Misc",
                Name = "Height",
                Value = Texture2D?.Height,
                Description = "Image height in pixels.",
                PropertyType = typeof(int),
                DataTemplateKey = textBlockKey,
                CanReset = false,
                IsReadOnly = true,
            });
            _propertySource.Properties.Add(new CustomProperty
            {
                Category = "Misc",
                Name = "Format",
                Value = Texture2D?.Format,
                Description = null,
                PropertyType = typeof(SurfaceFormat),
                DataTemplateKey = textBlockKey,
                CanReset = false,
                IsReadOnly = true,
            });
            _propertySource.Properties.Add(new CustomProperty
            {
                Category = "Misc",
                Name = "Mipmap levels",
                Value = Texture2D?.LevelCount,
                Description = null,
                PropertyType = typeof(int),
                DataTemplateKey = textBlockKey,
                CanReset = false,
                IsReadOnly = true,
            });
        }