[WIP] Some more work on Properties Dock plugin...

This commit is contained in:
MaxED 2012-10-11 14:59:12 +00:00
parent 12a7256c29
commit dd0ecf1b96
14 changed files with 325 additions and 1099 deletions

Binary file not shown.

View file

@ -15,6 +15,7 @@ using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Windows; using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Types;
#endregion #endregion
@ -50,6 +51,13 @@ namespace CodeImp.DoomBuilder.Plugins
//mxd. It's nice to have these avaliable to plugins... //mxd. It's nice to have these avaliable to plugins...
protected static Size DisplaySize { get { return (General.MainWindow == null || General.MainWindow.Display == null) ? new Size() : General.MainWindow.Display.Size; } } protected static Size DisplaySize { get { return (General.MainWindow == null || General.MainWindow.Display == null) ? new Size() : General.MainWindow.Display.Size; } }
//mxd
public static TypeHandlerAttribute[] GetCustomUseAttributes() {
//TypeHandlerAttribute[] attrs = General.Types.GetCustomUseAttributes();
return General.Types.GetCustomUseAttributes();
}
#endregion #endregion
#region ================== Properties #region ================== Properties

View file

@ -30,7 +30,7 @@ using System.Diagnostics;
namespace CodeImp.DoomBuilder.Types namespace CodeImp.DoomBuilder.Types
{ {
internal class TypeHandlerAttribute : Attribute public class TypeHandlerAttribute : Attribute
{ {
#region ================== Constants #region ================== Constants

View file

@ -39,7 +39,13 @@ namespace CodeImp.DoomBuilder.PropertiesDock
// This is called after a map has been successfully opened // This is called after a map has been successfully opened
public override void OnMapOpenEnd() { public override void OnMapOpenEnd() {
MapElementsData.Init(); MapElementsData.Init();
if (General.Map.UDMF) {
MapElementsData.InitTypes(GetCustomUseAttributes());
}
if(propertiesDocker == null) { if(propertiesDocker == null) {
propertiesDocker = new PropertiesDocker(); propertiesDocker = new PropertiesDocker();
docker = new Docker("propertiesdockerpanel", "Properties", propertiesDocker); docker = new Docker("propertiesdockerpanel", "Properties", propertiesDocker);
@ -50,7 +56,6 @@ namespace CodeImp.DoomBuilder.PropertiesDock
// This is called after a map has been closed // This is called after a map has been closed
public override void OnMapCloseBegin() { public override void OnMapCloseBegin() {
// If we have a Tag Explorer panel, remove it
if(propertiesDocker != null) { if(propertiesDocker != null) {
General.Interface.RemoveDocker(docker); General.Interface.RemoveDocker(docker);
docker = null; docker = null;
@ -122,7 +127,7 @@ namespace CodeImp.DoomBuilder.PropertiesDock
} }
public override void OnActionEnd(CodeImp.DoomBuilder.Actions.Action action) { public override void OnActionEnd(CodeImp.DoomBuilder.Actions.Action action) {
Console.WriteLine("OnActionEnd: " + action.Name); //Console.WriteLine("OnActionEnd: " + action.Name);
if (propertiesDocker != null && Array.IndexOf(actions, action.Name) != -1) if (propertiesDocker != null && Array.IndexOf(actions, action.Name) != -1)
propertiesDocker.Update(); propertiesDocker.Update();

View file

@ -33,9 +33,9 @@
this.tabPage3 = new System.Windows.Forms.TabPage(); this.tabPage3 = new System.Windows.Forms.TabPage();
this.propertyGrid3 = new System.Windows.Forms.PropertyGrid(); this.propertyGrid3 = new System.Windows.Forms.PropertyGrid();
this.gbCustomFields = new System.Windows.Forms.GroupBox(); this.gbCustomFields = new System.Windows.Forms.GroupBox();
this.cbFieldType = new System.Windows.Forms.ComboBox();
this.bAddField = new System.Windows.Forms.Button();
this.tbFieldName = new System.Windows.Forms.TextBox(); this.tbFieldName = new System.Windows.Forms.TextBox();
this.bAddField = new System.Windows.Forms.Button();
this.cbFieldType = new System.Windows.Forms.ComboBox();
this.tabControl.SuspendLayout(); this.tabControl.SuspendLayout();
this.tabPage1.SuspendLayout(); this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout(); this.tabPage2.SuspendLayout();
@ -87,7 +87,7 @@
this.tabPage2.Location = new System.Drawing.Point(4, 23); this.tabPage2.Location = new System.Drawing.Point(4, 23);
this.tabPage2.Name = "tabPage2"; this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3); this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(258, 308); this.tabPage2.Size = new System.Drawing.Size(258, 314);
this.tabPage2.TabIndex = 1; this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "tabPage2"; this.tabPage2.Text = "tabPage2";
this.tabPage2.UseVisualStyleBackColor = true; this.tabPage2.UseVisualStyleBackColor = true;
@ -109,7 +109,7 @@
this.tabPage3.Controls.Add(this.propertyGrid3); this.tabPage3.Controls.Add(this.propertyGrid3);
this.tabPage3.Location = new System.Drawing.Point(4, 23); this.tabPage3.Location = new System.Drawing.Point(4, 23);
this.tabPage3.Name = "tabPage3"; this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(258, 308); this.tabPage3.Size = new System.Drawing.Size(258, 314);
this.tabPage3.TabIndex = 2; this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "tabPage3"; this.tabPage3.Text = "tabPage3";
this.tabPage3.UseVisualStyleBackColor = true; this.tabPage3.UseVisualStyleBackColor = true;
@ -141,16 +141,14 @@
this.gbCustomFields.TabStop = false; this.gbCustomFields.TabStop = false;
this.gbCustomFields.Text = "Add custom field:"; this.gbCustomFields.Text = "Add custom field:";
// //
// cbFieldType // tbFieldName
// //
this.cbFieldType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) this.tbFieldName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right))); | System.Windows.Forms.AnchorStyles.Right)));
this.cbFieldType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.tbFieldName.Location = new System.Drawing.Point(10, 20);
this.cbFieldType.FormattingEnabled = true; this.tbFieldName.Name = "tbFieldName";
this.cbFieldType.Location = new System.Drawing.Point(148, 19); this.tbFieldName.Size = new System.Drawing.Size(134, 20);
this.cbFieldType.Name = "cbFieldType"; this.tbFieldName.TabIndex = 3;
this.cbFieldType.Size = new System.Drawing.Size(80, 22);
this.cbFieldType.TabIndex = 0;
// //
// bAddField // bAddField
// //
@ -163,14 +161,15 @@
this.bAddField.UseVisualStyleBackColor = true; this.bAddField.UseVisualStyleBackColor = true;
this.bAddField.Click += new System.EventHandler(this.bAddField_Click); this.bAddField.Click += new System.EventHandler(this.bAddField_Click);
// //
// tbFieldName // cbFieldType
// //
this.tbFieldName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) this.cbFieldType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
| System.Windows.Forms.AnchorStyles.Right))); this.cbFieldType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.tbFieldName.Location = new System.Drawing.Point(10, 20); this.cbFieldType.FormattingEnabled = true;
this.tbFieldName.Name = "tbFieldName"; this.cbFieldType.Location = new System.Drawing.Point(148, 19);
this.tbFieldName.Size = new System.Drawing.Size(134, 20); this.cbFieldType.Name = "cbFieldType";
this.tbFieldName.TabIndex = 3; this.cbFieldType.Size = new System.Drawing.Size(80, 22);
this.cbFieldType.TabIndex = 0;
// //
// PropertiesDocker // PropertiesDocker
// //

View file

@ -74,8 +74,10 @@ namespace CodeImp.DoomBuilder.PropertiesDock
propertyGrid1.SelectedObjects = infos; propertyGrid1.SelectedObjects = infos;
viewThings(things.Count, things.Count == 1 ? things[0].Index : -1, true); viewThings(things.Count, things.Count == 1 ? things[0].Index : -1, true);
if (gbCustomFields.Visible) gbCustomFields.Enabled = true;
} else { } else {
viewThings(-1, -1, false); viewThings(-1, -1, false);
gbCustomFields.Enabled = false;
} }
} }
@ -93,8 +95,10 @@ namespace CodeImp.DoomBuilder.PropertiesDock
propertyGrid1.SelectedObjects = infos; propertyGrid1.SelectedObjects = infos;
viewVertices(verts.Count, verts.Count == 1 ? verts[0].Index : -1, true); viewVertices(verts.Count, verts.Count == 1 ? verts[0].Index : -1, true);
if (gbCustomFields.Visible) gbCustomFields.Enabled = true;
} else { } else {
viewVertices(-1, -1, false); viewVertices(-1, -1, false);
gbCustomFields.Enabled = false;
} }
} }

View file

@ -0,0 +1,135 @@
using System;
using System.Collections;
using System.ComponentModel;
namespace CodeImp.DoomBuilder.PropertiesDock {
public class CustomPropertiesCollection : CollectionBase, ICustomTypeDescriptor {
/// <summary>
/// Add CustomProperty to Collectionbase List
/// </summary>
/// <param name="Value"></param>
public void Add(CustomProperty Value) {
base.List.Add(Value);
}
/// <summary>
/// Remove item from List
/// </summary>
/// <param name="Name"></param>
public void Remove(string Name) {
foreach (CustomProperty prop in base.List) {
if (prop.Name == Name) {
base.List.Remove(prop);
return;
}
}
}
/// <summary>
/// Indexer
/// </summary>
public CustomProperty this[int index] {
get {
return (CustomProperty)base.List[index];
}
set {
base.List[index] = (CustomProperty)value;
}
}
#region "TypeDescriptor Implementation"
/// <summary>
/// Get Class Name
/// </summary>
/// <returns>String</returns>
public String GetClassName() {
return TypeDescriptor.GetClassName(this, true);
}
/// <summary>
/// GetAttributes
/// </summary>
/// <returns>AttributeCollection</returns>
public AttributeCollection GetAttributes() {
return TypeDescriptor.GetAttributes(this, true);
}
/// <summary>
/// GetComponentName
/// </summary>
/// <returns>String</returns>
public String GetComponentName() {
return TypeDescriptor.GetComponentName(this, true);
}
/// <summary>
/// GetConverter
/// </summary>
/// <returns>TypeConverter</returns>
public TypeConverter GetConverter() {
return TypeDescriptor.GetConverter(this, true);
}
/// <summary>
/// GetDefaultEvent
/// </summary>
/// <returns>EventDescriptor</returns>
public EventDescriptor GetDefaultEvent() {
return TypeDescriptor.GetDefaultEvent(this, true);
}
/// <summary>
/// GetDefaultProperty
/// </summary>
/// <returns>PropertyDescriptor</returns>
public PropertyDescriptor GetDefaultProperty() {
return TypeDescriptor.GetDefaultProperty(this, true);
}
/// <summary>
/// GetEditor
/// </summary>
/// <param name="editorBaseType">editorBaseType</param>
/// <returns>object</returns>
public object GetEditor(Type editorBaseType) {
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
public EventDescriptorCollection GetEvents(Attribute[] attributes) {
return TypeDescriptor.GetEvents(this, attributes, true);
}
public EventDescriptorCollection GetEvents() {
return TypeDescriptor.GetEvents(this, true);
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes) {
PropertyDescriptor[] newProps = new PropertyDescriptor[this.Count];
for (int i = 0; i < this.Count; i++) {
CustomProperty prop = (CustomProperty)this[i];
newProps[i] = new CustomPropertyDescriptor(ref prop, attributes);
}
return new PropertyDescriptorCollection(newProps);
}
public PropertyDescriptorCollection GetProperties() {
PropertyDescriptorCollection c = TypeDescriptor.GetProperties(this, true);
return TypeDescriptor.GetProperties(this, true);
/*PropertyDescriptor[] newProps = new PropertyDescriptor[this.Count];
for (int i = 0; i < this.Count; i++) {
CustomProperty prop = (CustomProperty)this[i];
newProps[i] = new CustomPropertyDescriptor(ref prop);
}
return new PropertyDescriptorCollection(newProps);*/
}
public object GetPropertyOwner(PropertyDescriptor pd) {
return this;
}
#endregion
}
}

View file

@ -0,0 +1,41 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
namespace CodeImp.DoomBuilder.PropertiesDock {
public class CustomProperty {
public bool ReadOnly { get { return bReadOnly; } }
public string Name { get { return sName; } }
public string Category { get { return category; } }
public bool Visible { get { return bVisible; } }
public object Value { get { return objValue; } set { objValue = value; } }
private string sName = string.Empty;
private string category = string.Empty;
private bool bReadOnly = false;
private bool bVisible = true;
private object objValue = null;
//private Attribute[] attributes;
public CustomProperty(string sName, object value, bool bReadOnly, bool bVisible) {
this.sName = sName;
this.objValue = value;
this.bReadOnly = bReadOnly;
this.bVisible = bVisible;
//this.attributes = new Attribute[0];
}
//mxd
public CustomProperty(string sName, object value, string category, bool bReadOnly, bool bVisible) : this(sName, value, bReadOnly, bVisible) {
//attributes = attrs;
this.category = category;
}
/*public Attribute[] Attributes {
get {
return attributes;
}
}*/
}
}

View file

@ -0,0 +1,84 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
namespace CodeImp.DoomBuilder.PropertiesDock {
public class CustomPropertyDescriptor : PropertyDescriptor {
CustomProperty m_Property;
public CustomPropertyDescriptor(ref CustomProperty myProperty, Attribute[] attrs)
: base(myProperty.Name, attrs) {
m_Property = myProperty;
}
/*public CustomPropertyDescriptor(ref CustomProperty myProperty, Attribute[] attrs)
: base(myProperty.Name, combineAttributes(attrs, myProperty.Attributes)) {
m_Property = myProperty;
}*/
/*private static Attribute[] combineAttributes(Attribute[] attrs, Attribute[] attribute) {
List<Attribute> l = new List<Attribute>();
l.AddRange(attrs);
l.AddRange(attribute);
return l.ToArray();
}*/
#region PropertyDescriptor specific
public override bool CanResetValue(object component) {
return false;
}
public override Type ComponentType {
get {
return null;
}
}
public override object GetValue(object component) {
return m_Property.Value;
}
public override string Description {
get {
return m_Property.Name;
}
}
public override string Category {
get {
return m_Property.Category;
}
}
public override string DisplayName {
get {
return m_Property.Name;
}
}
public override bool IsReadOnly {
get {
return m_Property.ReadOnly;
}
}
public override void ResetValue(object component) {
//Have to implement
}
public override bool ShouldSerializeValue(object component) {
return false;
}
public override void SetValue(object component, object value) {
m_Property.Value = value;
}
public override Type PropertyType {
get { return m_Property.Value.GetType(); }
}
#endregion
}
}

View file

@ -3,14 +3,15 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Types;
namespace CodeImp.DoomBuilder.PropertiesDock { namespace CodeImp.DoomBuilder.PropertiesDock {
public static class MapElementsData { internal static class MapElementsData {
public static Dictionary<int, string> ThingTypeDescriptions { get { return thingTypeDescriptions;}} internal static Dictionary<int, string> ThingTypeDescriptions { get { return thingTypeDescriptions; } }
private static Dictionary<int, string> thingTypeDescriptions; private static Dictionary<int, string> thingTypeDescriptions;
public static void Init() { internal static void Init() {
//thing types //thing types
thingTypeDescriptions = new Dictionary<int, string>(); thingTypeDescriptions = new Dictionary<int, string>();
@ -20,5 +21,9 @@ namespace CodeImp.DoomBuilder.PropertiesDock {
} }
} }
} }
internal static void InitTypes(TypeHandlerAttribute[] types) {
}
} }
} }

View file

@ -1,979 +0,0 @@
/********************************************************************
*
* PropertyBag.cs
* --------------
* Copyright (C) 2002 Tony Allowatt
* Last Update: 12/14/2002
*
* THE SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS", WITHOUT WARRANTY
* OF ANY KIND, EXPRESS OR IMPLIED. IN NO EVENT SHALL THE AUTHOR BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF THIS
* SOFTWARE.
*
* Public types defined in this file:
* ----------------------------------
* namespace Flobbster.Windows.Forms
* class PropertySpec
* class PropertySpecEventArgs
* delegate PropertySpecEventHandler
* class PropertyBag
* class PropertyBag.PropertySpecCollection
* class PropertyTable
*
********************************************************************/
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Design;
namespace CodeImp.DoomBuilder.PropertiesDock {
/// <summary>
/// Represents a single property in a PropertySpec.
/// </summary>
public class PropertySpec {
private Attribute[] attributes;
private string category;
private object defaultValue;
private string description;
private string editor;
private string name;
private string type;
private string typeConverter;
private object currentValue; //mxd
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">The fully qualified name of the type of the property.</param>
public PropertySpec(string name, string type) : this(name, type, null, null, null) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">A Type that represents the type of the property.</param>
public PropertySpec(string name, Type type) :
this(name, type.AssemblyQualifiedName, null, null, null) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">The fully qualified name of the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
public PropertySpec(string name, string type, string category) : this(name, type, category, null, null) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">A Type that represents the type of the property.</param>
/// <param name="category"></param>
public PropertySpec(string name, Type type, string category) :
this(name, type.AssemblyQualifiedName, category, null, null) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">The fully qualified name of the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
public PropertySpec(string name, string type, string category, string description) :
this(name, type, category, description, null) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">A Type that represents the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
public PropertySpec(string name, Type type, string category, string description) :
this(name, type.AssemblyQualifiedName, category, description, null) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">The fully qualified name of the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
public PropertySpec(string name, string type, string category, string description, object defaultValue) {
this.name = name;
this.type = type;
this.category = category;
this.description = description;
this.defaultValue = defaultValue;
this.attributes = null;
this.currentValue = defaultValue; //mxd
}
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">A Type that represents the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
public PropertySpec(string name, Type type, string category, string description, object defaultValue) :
this(name, type.AssemblyQualifiedName, category, description, defaultValue) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">The fully qualified name of the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
/// <param name="editor">The fully qualified name of the type of the editor for this
/// property. This type must derive from UITypeEditor.</param>
/// <param name="typeConverter">The fully qualified name of the type of the type
/// converter for this property. This type must derive from TypeConverter.</param>
public PropertySpec(string name, string type, string category, string description, object defaultValue,
string editor, string typeConverter)
: this(name, type, category, description, defaultValue) {
this.editor = editor;
this.typeConverter = typeConverter;
}
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">A Type that represents the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
/// <param name="editor">The fully qualified name of the type of the editor for this
/// property. This type must derive from UITypeEditor.</param>
/// <param name="typeConverter">The fully qualified name of the type of the type
/// converter for this property. This type must derive from TypeConverter.</param>
public PropertySpec(string name, Type type, string category, string description, object defaultValue,
string editor, string typeConverter) :
this(name, type.AssemblyQualifiedName, category, description, defaultValue, editor, typeConverter) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">The fully qualified name of the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
/// <param name="editor">The Type that represents the type of the editor for this
/// property. This type must derive from UITypeEditor.</param>
/// <param name="typeConverter">The fully qualified name of the type of the type
/// converter for this property. This type must derive from TypeConverter.</param>
public PropertySpec(string name, string type, string category, string description, object defaultValue,
Type editor, string typeConverter) :
this(name, type, category, description, defaultValue, editor.AssemblyQualifiedName,
typeConverter) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">A Type that represents the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
/// <param name="editor">The Type that represents the type of the editor for this
/// property. This type must derive from UITypeEditor.</param>
/// <param name="typeConverter">The fully qualified name of the type of the type
/// converter for this property. This type must derive from TypeConverter.</param>
public PropertySpec(string name, Type type, string category, string description, object defaultValue,
Type editor, string typeConverter) :
this(name, type.AssemblyQualifiedName, category, description, defaultValue,
editor.AssemblyQualifiedName, typeConverter) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">The fully qualified name of the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
/// <param name="editor">The fully qualified name of the type of the editor for this
/// property. This type must derive from UITypeEditor.</param>
/// <param name="typeConverter">The Type that represents the type of the type
/// converter for this property. This type must derive from TypeConverter.</param>
public PropertySpec(string name, string type, string category, string description, object defaultValue,
string editor, Type typeConverter) :
this(name, type, category, description, defaultValue, editor, typeConverter.AssemblyQualifiedName) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">A Type that represents the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
/// <param name="editor">The fully qualified name of the type of the editor for this
/// property. This type must derive from UITypeEditor.</param>
/// <param name="typeConverter">The Type that represents the type of the type
/// converter for this property. This type must derive from TypeConverter.</param>
public PropertySpec(string name, Type type, string category, string description, object defaultValue,
string editor, Type typeConverter) :
this(name, type.AssemblyQualifiedName, category, description, defaultValue, editor,
typeConverter.AssemblyQualifiedName) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">The fully qualified name of the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
/// <param name="editor">The Type that represents the type of the editor for this
/// property. This type must derive from UITypeEditor.</param>
/// <param name="typeConverter">The Type that represents the type of the type
/// converter for this property. This type must derive from TypeConverter.</param>
public PropertySpec(string name, string type, string category, string description, object defaultValue,
Type editor, Type typeConverter) :
this(name, type, category, description, defaultValue, editor.AssemblyQualifiedName,
typeConverter.AssemblyQualifiedName) { }
/// <summary>
/// Initializes a new instance of the PropertySpec class.
/// </summary>
/// <param name="name">The name of the property displayed in the property grid.</param>
/// <param name="type">A Type that represents the type of the property.</param>
/// <param name="category">The category under which the property is displayed in the
/// property grid.</param>
/// <param name="description">A string that is displayed in the help area of the
/// property grid.</param>
/// <param name="defaultValue">The default value of the property, or null if there is
/// no default value.</param>
/// <param name="editor">The Type that represents the type of the editor for this
/// property. This type must derive from UITypeEditor.</param>
/// <param name="typeConverter">The Type that represents the type of the type
/// converter for this property. This type must derive from TypeConverter.</param>
public PropertySpec(string name, Type type, string category, string description, object defaultValue,
Type editor, Type typeConverter) :
this(name, type.AssemblyQualifiedName, category, description, defaultValue,
editor.AssemblyQualifiedName, typeConverter.AssemblyQualifiedName) { }
/// <summary>
/// Gets or sets a collection of additional Attributes for this property. This can
/// be used to specify attributes beyond those supported intrinsically by the
/// PropertySpec class, such as ReadOnly and Browsable.
/// </summary>
public Attribute[] Attributes {
get { return attributes; }
set { attributes = value; }
}
/// <summary>
/// Gets or sets the category name of this property.
/// </summary>
public string Category {
get { return category; }
set { category = value; }
}
/// <summary>
/// Gets or sets the fully qualified name of the type converter
/// type for this property.
/// </summary>
public string ConverterTypeName {
get { return typeConverter; }
set { typeConverter = value; }
}
/// <summary>
/// Gets or sets the default value of this property.
/// </summary>
public object DefaultValue {
get { return defaultValue; }
set { defaultValue = value; }
}
//mxd
/// <summary>
/// Gets or sets the value of this property.
/// </summary>
public object Value {
get { return currentValue; }
set { currentValue = value; }
}
/// <summary>
/// Gets or sets the help text description of this property.
/// </summary>
public string Description {
get { return description; }
set { description = value; }
}
/// <summary>
/// Gets or sets the fully qualified name of the editor type for
/// this property.
/// </summary>
public string EditorTypeName {
get { return editor; }
set { editor = value; }
}
/// <summary>
/// Gets or sets the name of this property.
/// </summary>
public string Name {
get { return name; }
set { name = value; }
}
/// <summary>
/// Gets or sets the fully qualfied name of the type of this
/// property.
/// </summary>
public string TypeName {
get { return type; }
set { type = value; }
}
}
/// <summary>
/// Provides data for the GetValue and SetValue events of the PropertyBag class.
/// </summary>
public class PropertySpecEventArgs : EventArgs {
private PropertySpec property;
private object val;
/// <summary>
/// Initializes a new instance of the PropertySpecEventArgs class.
/// </summary>
/// <param name="property">The PropertySpec that represents the property whose
/// value is being requested or set.</param>
/// <param name="val">The current value of the property.</param>
public PropertySpecEventArgs(PropertySpec property, object val) {
this.property = property;
this.val = val;
}
/// <summary>
/// Gets the PropertySpec that represents the property whose value is being
/// requested or set.
/// </summary>
public PropertySpec Property {
get { return property; }
}
/// <summary>
/// Gets or sets the current value of the property.
/// </summary>
public object Value {
get { return val; }
set { val = value; }
}
}
/// <summary>
/// Represents the method that will handle the GetValue and SetValue events of the
/// PropertyBag class.
/// </summary>
public delegate void PropertySpecEventHandler(object sender, PropertySpecEventArgs e);
/// <summary>
/// Represents a collection of custom properties that can be selected into a
/// PropertyGrid to provide functionality beyond that of the simple reflection
/// normally used to query an object's properties.
/// </summary>
public class PropertyBag : ICustomTypeDescriptor {
#region PropertySpecCollection class definition
/// <summary>
/// Encapsulates a collection of PropertySpec objects.
/// </summary>
[Serializable]
public class PropertySpecCollection : IList {
private ArrayList innerArray;
/// <summary>
/// Initializes a new instance of the PropertySpecCollection class.
/// </summary>
public PropertySpecCollection() {
innerArray = new ArrayList();
}
/// <summary>
/// Gets the number of elements in the PropertySpecCollection.
/// </summary>
/// <value>
/// The number of elements contained in the PropertySpecCollection.
/// </value>
public int Count {
get { return innerArray.Count; }
}
/// <summary>
/// Gets a value indicating whether the PropertySpecCollection has a fixed size.
/// </summary>
/// <value>
/// true if the PropertySpecCollection has a fixed size; otherwise, false.
/// </value>
public bool IsFixedSize {
get { return false; }
}
/// <summary>
/// Gets a value indicating whether the PropertySpecCollection is read-only.
/// </summary>
public bool IsReadOnly {
get { return false; }
}
/// <summary>
/// Gets a value indicating whether access to the collection is synchronized (thread-safe).
/// </summary>
/// <value>
/// true if access to the PropertySpecCollection is synchronized (thread-safe); otherwise, false.
/// </value>
public bool IsSynchronized {
get { return false; }
}
/// <summary>
/// Gets an object that can be used to synchronize access to the collection.
/// </summary>
/// <value>
/// An object that can be used to synchronize access to the collection.
/// </value>
object ICollection.SyncRoot {
get { return null; }
}
/// <summary>
/// Gets or sets the element at the specified index.
/// In C#, this property is the indexer for the PropertySpecCollection class.
/// </summary>
/// <param name="index">The zero-based index of the element to get or set.</param>
/// <value>
/// The element at the specified index.
/// </value>
public PropertySpec this[int index] {
get { return (PropertySpec)innerArray[index]; }
set { innerArray[index] = value; }
}
/// <summary>
/// Adds a PropertySpec to the end of the PropertySpecCollection.
/// </summary>
/// <param name="value">The PropertySpec to be added to the end of the PropertySpecCollection.</param>
/// <returns>The PropertySpecCollection index at which the value has been added.</returns>
public int Add(PropertySpec value) {
int index = innerArray.Add(value);
return index;
}
/// <summary>
/// Adds the elements of an array of PropertySpec objects to the end of the PropertySpecCollection.
/// </summary>
/// <param name="array">The PropertySpec array whose elements should be added to the end of the
/// PropertySpecCollection.</param>
public void AddRange(PropertySpec[] array) {
innerArray.AddRange(array);
}
/// <summary>
/// Removes all elements from the PropertySpecCollection.
/// </summary>
public void Clear() {
innerArray.Clear();
}
/// <summary>
/// Determines whether a PropertySpec is in the PropertySpecCollection.
/// </summary>
/// <param name="item">The PropertySpec to locate in the PropertySpecCollection. The element to locate
/// can be a null reference (Nothing in Visual Basic).</param>
/// <returns>true if item is found in the PropertySpecCollection; otherwise, false.</returns>
public bool Contains(PropertySpec item) {
return innerArray.Contains(item);
}
/// <summary>
/// Determines whether a PropertySpec with the specified name is in the PropertySpecCollection.
/// </summary>
/// <param name="name">The name of the PropertySpec to locate in the PropertySpecCollection.</param>
/// <returns>true if item is found in the PropertySpecCollection; otherwise, false.</returns>
public bool Contains(string name) {
foreach (PropertySpec spec in innerArray)
if (spec.Name == name)
return true;
return false;
}
/// <summary>
/// Copies the entire PropertySpecCollection to a compatible one-dimensional Array, starting at the
/// beginning of the target array.
/// </summary>
/// <param name="array">The one-dimensional Array that is the destination of the elements copied
/// from PropertySpecCollection. The Array must have zero-based indexing.</param>
public void CopyTo(PropertySpec[] array) {
innerArray.CopyTo(array);
}
/// <summary>
/// Copies the PropertySpecCollection or a portion of it to a one-dimensional array.
/// </summary>
/// <param name="array">The one-dimensional Array that is the destination of the elements copied
/// from the collection.</param>
/// <param name="index">The zero-based index in array at which copying begins.</param>
public void CopyTo(PropertySpec[] array, int index) {
innerArray.CopyTo(array, index);
}
/// <summary>
/// Returns an enumerator that can iterate through the PropertySpecCollection.
/// </summary>
/// <returns>An IEnumerator for the entire PropertySpecCollection.</returns>
public IEnumerator GetEnumerator() {
return innerArray.GetEnumerator();
}
/// <summary>
/// Searches for the specified PropertySpec and returns the zero-based index of the first
/// occurrence within the entire PropertySpecCollection.
/// </summary>
/// <param name="value">The PropertySpec to locate in the PropertySpecCollection.</param>
/// <returns>The zero-based index of the first occurrence of value within the entire PropertySpecCollection,
/// if found; otherwise, -1.</returns>
public int IndexOf(PropertySpec value) {
return innerArray.IndexOf(value);
}
/// <summary>
/// Searches for the PropertySpec with the specified name and returns the zero-based index of
/// the first occurrence within the entire PropertySpecCollection.
/// </summary>
/// <param name="name">The name of the PropertySpec to locate in the PropertySpecCollection.</param>
/// <returns>The zero-based index of the first occurrence of value within the entire PropertySpecCollection,
/// if found; otherwise, -1.</returns>
public int IndexOf(string name) {
int i = 0;
foreach (PropertySpec spec in innerArray) {
if (spec.Name == name)
return i;
i++;
}
return -1;
}
/// <summary>
/// Inserts a PropertySpec object into the PropertySpecCollection at the specified index.
/// </summary>
/// <param name="index">The zero-based index at which value should be inserted.</param>
/// <param name="value">The PropertySpec to insert.</param>
public void Insert(int index, PropertySpec value) {
innerArray.Insert(index, value);
}
/// <summary>
/// Removes the first occurrence of a specific object from the PropertySpecCollection.
/// </summary>
/// <param name="obj">The PropertySpec to remove from the PropertySpecCollection.</param>
public void Remove(PropertySpec obj) {
innerArray.Remove(obj);
}
/// <summary>
/// Removes the property with the specified name from the PropertySpecCollection.
/// </summary>
/// <param name="name">The name of the PropertySpec to remove from the PropertySpecCollection.</param>
public void Remove(string name) {
int index = IndexOf(name);
RemoveAt(index);
}
/// <summary>
/// Removes the object at the specified index of the PropertySpecCollection.
/// </summary>
/// <param name="index">The zero-based index of the element to remove.</param>
public void RemoveAt(int index) {
innerArray.RemoveAt(index);
}
/// <summary>
/// Copies the elements of the PropertySpecCollection to a new PropertySpec array.
/// </summary>
/// <returns>A PropertySpec array containing copies of the elements of the PropertySpecCollection.</returns>
public PropertySpec[] ToArray() {
return (PropertySpec[])innerArray.ToArray(typeof(PropertySpec));
}
#region Explicit interface implementations for ICollection and IList
/// <summary>
/// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
/// </summary>
void ICollection.CopyTo(Array array, int index) {
CopyTo((PropertySpec[])array, index);
}
/// <summary>
/// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
/// </summary>
int IList.Add(object value) {
return Add((PropertySpec)value);
}
/// <summary>
/// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
/// </summary>
bool IList.Contains(object obj) {
return Contains((PropertySpec)obj);
}
/// <summary>
/// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
/// </summary>
object IList.this[int index] {
get {
return ((PropertySpecCollection)this)[index];
}
set {
((PropertySpecCollection)this)[index] = (PropertySpec)value;
}
}
/// <summary>
/// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
/// </summary>
int IList.IndexOf(object obj) {
return IndexOf((PropertySpec)obj);
}
/// <summary>
/// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
/// </summary>
void IList.Insert(int index, object value) {
Insert(index, (PropertySpec)value);
}
/// <summary>
/// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
/// </summary>
void IList.Remove(object value) {
Remove((PropertySpec)value);
}
#endregion
}
#endregion
#region PropertySpecDescriptor class definition
private class PropertySpecDescriptor : PropertyDescriptor {
private PropertyBag bag;
private PropertySpec item;
public PropertySpecDescriptor(PropertySpec item, PropertyBag bag, string name, Attribute[] attrs) :
base(name, attrs) {
this.bag = bag;
this.item = item;
}
public override Type ComponentType {
get { return item.GetType(); }
}
public override bool IsReadOnly {
get { return (Attributes.Matches(ReadOnlyAttribute.Yes)); }
}
public override Type PropertyType {
get { return Type.GetType(item.TypeName); }
}
public override bool CanResetValue(object component) {
if (item.DefaultValue == null)
return false;
else
return !this.GetValue(component).Equals(item.DefaultValue);
}
public override object GetValue(object component) {
// Have the property bag raise an event to get the current value
// of the property.
PropertySpecEventArgs e = new PropertySpecEventArgs(item, null);
bag.OnGetValue(e);
return e.Value;
}
public override void ResetValue(object component) {
SetValue(component, item.DefaultValue);
}
public override void SetValue(object component, object value) {
// Have the property bag raise an event to set the current value
// of the property.
PropertySpecEventArgs e = new PropertySpecEventArgs(item, value);
bag.OnSetValue(e);
}
public override bool ShouldSerializeValue(object component) {
object val = this.GetValue(component);
if (item.DefaultValue == null && val == null)
return false;
else if (item.DefaultValue != null && val == null)//mxd
return true;
else
return !val.Equals(item.DefaultValue);
}
}
#endregion
private string defaultProperty;
protected PropertySpecCollection properties; //mxd
/// <summary>
/// Initializes a new instance of the PropertyBag class.
/// </summary>
public PropertyBag() {
defaultProperty = null;
properties = new PropertySpecCollection();
}
/// <summary>
/// Gets or sets the name of the default property in the collection.
/// </summary>
public string DefaultProperty {
get { return defaultProperty; }
set { defaultProperty = value; }
}
/// <summary>
/// Gets the collection of properties contained within this PropertyBag.
/// </summary>
public PropertySpecCollection Properties {
get { return properties; }
}
/// <summary>
/// Occurs when a PropertyGrid requests the value of a property.
/// </summary>
public event PropertySpecEventHandler GetValue;
/// <summary>
/// Occurs when the user changes the value of a property in a PropertyGrid.
/// </summary>
public event PropertySpecEventHandler SetValue;
/// <summary>
/// Raises the GetValue event.
/// </summary>
/// <param name="e">A PropertySpecEventArgs that contains the event data.</param>
protected virtual void OnGetValue(PropertySpecEventArgs e) {
if (GetValue != null)
GetValue(this, e);
}
/// <summary>
/// Raises the SetValue event.
/// </summary>
/// <param name="e">A PropertySpecEventArgs that contains the event data.</param>
protected virtual void OnSetValue(PropertySpecEventArgs e) {
//mxd
e.Property.Value = e.Value;
if (SetValue != null)
SetValue(this, e);
}
#region ICustomTypeDescriptor explicit interface definitions
// Most of the functions required by the ICustomTypeDescriptor are
// merely pssed on to the default TypeDescriptor for this type,
// which will do something appropriate. The exceptions are noted
// below.
AttributeCollection ICustomTypeDescriptor.GetAttributes() {
return TypeDescriptor.GetAttributes(this, true);
}
string ICustomTypeDescriptor.GetClassName() {
return TypeDescriptor.GetClassName(this, true);
}
string ICustomTypeDescriptor.GetComponentName() {
return TypeDescriptor.GetComponentName(this, true);
}
TypeConverter ICustomTypeDescriptor.GetConverter() {
return TypeDescriptor.GetConverter(this, true);
}
EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() {
return TypeDescriptor.GetDefaultEvent(this, true);
}
PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() {
// This function searches the property list for the property
// with the same name as the DefaultProperty specified, and
// returns a property descriptor for it. If no property is
// found that matches DefaultProperty, a null reference is
// returned instead.
PropertySpec propertySpec = null;
if (defaultProperty != null) {
int index = properties.IndexOf(defaultProperty);
propertySpec = properties[index];
}
if (propertySpec != null)
return new PropertySpecDescriptor(propertySpec, this, propertySpec.Name, null);
else
return null;
}
object ICustomTypeDescriptor.GetEditor(Type editorBaseType) {
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents() {
return TypeDescriptor.GetEvents(this, true);
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) {
return TypeDescriptor.GetEvents(this, attributes, true);
}
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() {
return ((ICustomTypeDescriptor)this).GetProperties(new Attribute[0]);
}
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) {
// Rather than passing this function on to the default TypeDescriptor,
// which would return the actual properties of PropertyBag, I construct
// a list here that contains property descriptors for the elements of the
// Properties list in the bag.
ArrayList props = new ArrayList();
foreach (PropertySpec property in properties) {
ArrayList attrs = new ArrayList();
// If a category, description, editor, or type converter are specified
// in the PropertySpec, create attributes to define that relationship.
if (property.Category != null)
attrs.Add(new CategoryAttribute(property.Category));
if (property.Description != null)
attrs.Add(new DescriptionAttribute(property.Description));
if (property.EditorTypeName != null)
attrs.Add(new EditorAttribute(property.EditorTypeName, typeof(UITypeEditor)));
if (property.ConverterTypeName != null)
attrs.Add(new TypeConverterAttribute(property.ConverterTypeName));
// Additionally, append the custom attributes associated with the
// PropertySpec, if any.
if (property.Attributes != null)
attrs.AddRange(property.Attributes);
Attribute[] attrArray = (Attribute[])attrs.ToArray(typeof(Attribute));
// Create a new property descriptor for the property item, and add
// it to the list.
PropertySpecDescriptor pd = new PropertySpecDescriptor(property,
this, property.Name, attrArray);
props.Add(pd);
}
// Convert the list of PropertyDescriptors to a collection that the
// ICustomTypeDescriptor can use, and return it.
PropertyDescriptor[] propArray = (PropertyDescriptor[])props.ToArray(
typeof(PropertyDescriptor));
return new PropertyDescriptorCollection(propArray);
}
object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) {
return this;
}
#endregion
}
/// <summary>
/// An extension of PropertyBag that manages a table of property values, in
/// addition to firing events when property values are requested or set.
/// </summary>
public class PropertyTable : PropertyBag {
private Hashtable propValues;
/// <summary>
/// Initializes a new instance of the PropertyTable class.
/// </summary>
public PropertyTable() {
propValues = new Hashtable();
}
/// <summary>
/// Gets or sets the value of the property with the specified name.
/// <p>In C#, this property is the indexer of the PropertyTable class.</p>
/// </summary>
public object this[string key] {
get { return propValues[key]; }
set { propValues[key] = value; }
}
/// <summary>
/// This member overrides PropertyBag.OnGetValue.
/// </summary>
protected override void OnGetValue(PropertySpecEventArgs e) {
e.Value = propValues[e.Property.Name];
base.OnGetValue(e);
}
/// <summary>
/// This member overrides PropertyBag.OnSetValue.
/// </summary>
protected override void OnSetValue(PropertySpecEventArgs e) {
propValues[e.Property.Name] = e.Value;
base.OnSetValue(e);
}
}
}

View file

@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Globalization;
namespace CodeImp.DoomBuilder.PropertiesDock {
/*[TypeConverterAttribute(typeof(VertexPositionConverter)), DescriptionAttribute("Vertex position.")]
public class VertexPosition {
[DefaultValueAttribute(0f)]
public float X { get { return x; } set { x = value; } }
private float x;
[DefaultValueAttribute(0f)]
public float Y { get { return y; } set { y = value; } }
private float y;
public VertexPosition(float x, float y) {
this.x = x;
this.y = y;
}
}
public class VertexPositionConverter : ExpandableObjectConverter {
public override bool CanConvertTo(ITypeDescriptorContext context, System.Type destinationType) {
if (destinationType == typeof(VertexPosition))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, System.Type destinationType) {
if (destinationType == typeof(System.String) && value is VertexPosition) {
VertexPosition tp = (VertexPosition)value;
return "X:" + tp.X + ", Y: " + tp.Y;
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType) {
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
if (value is string) {
try {
string s = (string)value;
int colon = s.IndexOf(':');
int comma = s.IndexOf(',');
if (colon != -1 && comma != -1) {
string px = s.Substring(colon + 1, (comma - colon - 1));
colon = s.IndexOf(':', comma + 1);
if (colon != -1) {
string py = s.Substring(colon + 1, s.Length - (colon + 1));
VertexPosition tp = new VertexPosition(float.Parse(px), float.Parse(py));
return tp;
}
}
} catch {
throw new ArgumentException("Can not convert '" + (string)value + "' to type TestPosition");
}
}
return base.ConvertFrom(context, culture, value);
}
}*/
}

View file

@ -6,48 +6,41 @@ using System.Text;
using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Map;
namespace CodeImp.DoomBuilder.PropertiesDock { namespace CodeImp.DoomBuilder.PropertiesDock {
public class VertexInfo : PropertyBag, IMapElementInfo {
/*[CategoryAttribute("Position"), DefaultValueAttribute(0f)]
public float X { get { return x; } set { x = value; } }*/
//private float x;
/*[CategoryAttribute("Position"), DefaultValueAttribute(0f)]
public float Y { get { return y; } set { y = value; } }*/
//private float y;
//public PropertyBag Properties { get { return properties; } }
//private PropertyBag properties;
public class VertexInfo : CustomPropertiesCollection, IMapElementInfo {
private Vertex vertex; private Vertex vertex;
public VertexInfo(Vertex v) : base() { public VertexInfo(Vertex v) : base() {
vertex = v; vertex = v;
//x = v.Position.x; Add(new CustomProperty("X:", v.Position.x, "Position:", false, true));
//y = v.Position.y; Add(new CustomProperty("Y:", v.Position.y, "Position:", false, true));
//properties = new PropertyBag();
properties.Add(new PropertySpec("X:", typeof(float), "Position:", null, v.Position.x)); //todo: add custom fields
properties.Add(new PropertySpec("Y:", typeof(float), "Position:", null, v.Position.y)); if (v.Fields != null && v.Fields.Count > 0) {
foreach (KeyValuePair<string, UniValue> group in v.Fields) {
Add(new CustomProperty(group.Key, group.Value.Value, "Custom properties:", false, true));
}
}
} }
public void ApplyChanges() { public void ApplyChanges() {
float min = (float)General.Map.FormatInterface.MinCoordinate; float min = (float)General.Map.FormatInterface.MinCoordinate;
float max = (float)General.Map.FormatInterface.MaxCoordinate; float max = (float)General.Map.FormatInterface.MaxCoordinate;
vertex.Move(new CodeImp.DoomBuilder.Geometry.Vector2D(General.Clamp((float)properties[0].Value, min, max), General.Clamp((float)properties[1].Value, min, max))); vertex.Move(new CodeImp.DoomBuilder.Geometry.Vector2D(General.Clamp((float)this[0].Value, min, max), General.Clamp((float)this[1].Value, min, max)));
//todo: add custom fields support //todo: add custom fields support
} }
public void AddCustomProperty(string name, Type type) { public void AddCustomProperty(string name, Type type) {
properties.Add(new PropertySpec(name + ":", type, "Custom properties:")); Add(new CustomProperty(name, Activator.CreateInstance(type), "Custom properties:", false, true));
} }
public void RemoveCustomProperty(string name){ public void RemoveCustomProperty(string name){
string n = name.ToUpperInvariant().Trim(); string n = name.ToUpperInvariant().Trim();
foreach (PropertySpec ps in properties) { foreach (CustomProperty ps in this) {
string cn = ps.Name.ToUpperInvariant(); string cn = ps.Name.ToUpperInvariant();
if (cn.IndexOf(n) == 0 && cn.Length == n.Length + 1) { if (cn.IndexOf(n) == 0 && cn.Length == n.Length + 1) {
properties.Remove(name); Remove(name);
return; return;
} }
} }

View file

@ -50,9 +50,10 @@
<Compile Include="Controls\PropertiesDocker.Designer.cs"> <Compile Include="Controls\PropertiesDocker.Designer.cs">
<DependentUpon>PropertiesDocker.cs</DependentUpon> <DependentUpon>PropertiesDocker.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Data\CustomPropertiesCollection.cs" />
<Compile Include="Data\CustomProperty.cs" />
<Compile Include="Data\CustomPropertyDescriptor.cs" />
<Compile Include="Data\MapElementsData.cs" /> <Compile Include="Data\MapElementsData.cs" />
<Compile Include="Data\PropertyBag.cs" />
<Compile Include="Data\VertexPosition.cs" />
<Compile Include="Info\IMapElementInfo.cs" /> <Compile Include="Info\IMapElementInfo.cs" />
<Compile Include="Info\ThingInfo.cs" /> <Compile Include="Info\ThingInfo.cs" />
<Compile Include="Info\VertexInfo.cs" /> <Compile Include="Info\VertexInfo.cs" />