/// <summary> /// Set up any enumerations whose values are stored as strings /// </summary> /// <param name="attribute"></param> /// <param name="enumType"></param> public static void SetupStringBasedEnumeration(AttributeInfo attribute, Type enumType) { var strings = Enum.GetNames(enumType); AttributeRule rule = new StringEnumRule(strings); attribute.AddRule(rule); attribute.DefaultValue = strings[0]; }
public void TestValidation() { AttributeType type = new AttributeType("test", typeof(string)); AttributeInfo test = new AttributeInfo("test", type); CollectionAssert.IsEmpty(test.Rules); var rule = new SimpleAttributeRule(); test.AddRule(rule); Utilities.TestSequenceEqual(test.Rules, rule); Assert.True(test.Validate("bar")); Assert.True(rule.Validated); Assert.False(test.Validate(1)); // wrong type }
void AddProperty(DomNodeType domNodeType, SF.Tong.Schema.Property prop, PropertyDescriptorCollection newDescs) { if (prop.Type == SF.Tong.Schema.PropertyType.Enum) { SF.Tong.Schema.EnumTypeInfo enumInfo; if (!m_EnumDefines.TryGetValue(prop.TypeName, out enumInfo)) { Outputs.WriteLine(OutputMessageType.Error, "Invalid enum type {1} for property {0}", prop.Name, prop.TypeName); return; } AttributeInfo newAttr = null; if (prop.IsArray) { newAttr = new AttributeInfo(prop.Name, enumInfo.ArrayValueType); } else { newAttr = new AttributeInfo(prop.Name, enumInfo.SingleValueType); } if (prop.Default == null) { newAttr.DefaultValue = enumInfo.Value[0]; } else { newAttr.DefaultValue = prop.Default; } newAttr.AddRule(enumInfo.EnumRule); var newDesc = new AttributePropertyDescriptor(newAttr.Name, newAttr, "Node", newAttr.Name, false, new EnumUITypeEditor(enumInfo.Value), new EnumTypeConverter(enumInfo.Value)); newDescs.Add(newDesc); domNodeType.Define(newAttr); return; } var propTypeInfo = m_PropertyInfos[(int)prop.Type]; if (propTypeInfo.AttributeInfo != null) { AttributeInfo newAttr = null; if (prop.IsArray) { newAttr = propTypeInfo.ListAttributeInfo.Clone(prop.Name); } else { newAttr = propTypeInfo.AttributeInfo.Clone(prop.Name); } if (!string.IsNullOrEmpty(prop.Default)) { newAttr.DefaultValue = newAttr.Type.Convert(prop.Default); } newAttr.AddRule(new GameDataAttributeRule(prop)); var newDesc = new AttributePropertyDescriptor(newAttr.Name, newAttr, "Node", newAttr.Name, false, propTypeInfo.Editor, propTypeInfo.Converter); newDescs.Add(newDesc); domNodeType.Define(newAttr); } else if (propTypeInfo.ChildInfo != null) { var newChild = propTypeInfo.ChildInfo.Clone(prop.Name, prop.IsArray); newChild.AddRule(new GameDataChildRule(prop)); object editor = m_ChildCollectionEditor; var newDesc = new ChildPropertyDescriptor(newChild.Name, newChild, "Node", newChild.Name, false, editor, propTypeInfo.Converter); newDescs.Add(newDesc); domNodeType.Define(newChild); } }
void InitializeProperties() { m_PropertyInfos.Clear(); foreach (var enumValueObj in Enum.GetValues(typeof(SF.Tong.Schema.PropertyType))) { var enumValue = (SF.Tong.Schema.PropertyType)enumValueObj; AttributeInfo newAttr = null, newListAttr = null; DomNodeType childNodeType = null; object editor = null; TypeConverter converter = null; switch (enumValue) { //case SF.Tong.Schema.PropertyType.Event: // newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.BooleanType); // newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.BooleanArrayType); // break; case SF.Tong.Schema.PropertyType.Boolean: newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.BooleanType); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.BooleanArrayType); break; case SF.Tong.Schema.PropertyType.@Int: newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.IntType); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.IntArrayType); break; //case SF.Tong.Schema.PropertyType.@float: // newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.FloatType); // newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.FloatArrayType); // break; //case SF.Tong.Schema.PropertyType.@double: // newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.DoubleType); // newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.DoubleArrayType); // break; case SF.Tong.Schema.PropertyType.@Decimal: newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.DecimalType); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.DecimalArrayType); break; case SF.Tong.Schema.PropertyType.@String: newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.StringType); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.StringArrayType); break; case SF.Tong.Schema.PropertyType.FixedString: newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.StringType); newAttr.AddRule(new StringHashRule()); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.StringArrayType); newListAttr.AddRule(new StringHashRule()); break; case SF.Tong.Schema.PropertyType.Vector3: newAttr = new AttributeInfo(enumValue.ToString(), new AttributeType(enumValue.ToString(), typeof(float[]), 3)); editor = new Sce.Atf.Controls.PropertyEditing.NumericTupleEditor(typeof(float), new string[] { "x", "y", "z" }); break; case SF.Tong.Schema.PropertyType.Socket: childNodeType = CreateDOMType(typeof(SF.Tong.Schema.EditorSocket)); socketType.Type = childNodeType; // cache for global use break; case SF.Tong.Schema.PropertyType.Signal: newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.NameStringType); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.NameStringType); break; case SF.Tong.Schema.PropertyType.File: case SF.Tong.Schema.PropertyType.Asset: // TODO: add new types for them case SF.Tong.Schema.PropertyType.Enum: // We don't actually use Enum here. just assign string for now newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.StringType); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.StringArrayType); break; case SF.Tong.Schema.PropertyType.@Object: newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.DomNodeRefType); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.DomNodeRefArrayType); break; case SF.Tong.Schema.PropertyType.@ObjectType: newAttr = new AttributeInfo(enumValue.ToString(), AttributeType.StringType); newListAttr = new AttributeInfo(enumValue.ToString() + "[]", AttributeType.StringArrayType); editor = m_ObjectTypeEditor; converter = m_ObjectTypeConverter; break; default: throw new InvalidDataException("There is a not-handled property type"); } if (newAttr != null) { var propInfo = new PropertyInformation() { AttributeInfo = newAttr, ListAttributeInfo = newListAttr, ChildInfo = null, Editor = editor, Converter = converter, }; m_PropertyInfos.Add(propInfo); } else if (childNodeType != null) { ChildInfo newChild = new ChildInfo(enumValue.ToString(), childNodeType); var propInfo = new PropertyInformation() { AttributeInfo = null, ListAttributeInfo = null, ChildInfo = newChild, Editor = null, Converter = null, }; m_PropertyInfos.Add(propInfo); } else { Outputs.WriteLine(OutputMessageType.Warning, "Invalid property {0}", enumValue.ToString()); } } }
DomNodeType CreateDOMType(Type clrType) { var nodeType = new DomNodeType(clrType.Name); var propertyDescs = new PropertyDescriptorCollection(null); var properties = clrType.GetProperties(); foreach (var prop in properties) { var propType = prop.PropertyType; AttributeInfo newAttr = null; PropertyDescriptor propDesc = null; if (propType.IsClass && propType != typeof(string)) { ChildInfo newChild = null; object editor = null; var childCLRType = propType.IsArray ? propType.GetElementType() : propType; newChild = new ChildInfo(prop.Name, CreateDOMType(childCLRType), propType.IsArray); nodeType.Define(newChild); if (propType.IsArray && clrType != typeof(SF.Tong.Schema.EditorSocket)) { editor = m_ChildCollectionEditor; } propDesc = new ChildPropertyDescriptor(prop.Name, newChild, "Node", prop.Name, false, editor); } else if (propType.IsEnum) { if (propType.IsArray) { newAttr = new AttributeInfo(prop.Name, AttributeType.StringArrayType); newAttr.AddRule(new StringEnumRule(Enum.GetNames(propType))); } else { newAttr = new AttributeInfo(prop.Name, AttributeType.StringType); newAttr.AddRule(new StringEnumRule(Enum.GetNames(propType))); } } else { if (propType.IsArray) { switch (propType.Name) { case "String": // Consider them as string crc always? newAttr = new AttributeInfo(prop.Name, new AttributeType(AttributeTypes.SingleArray.ToString(), typeof(string[]))); newAttr.AddRule(new StringHashRule()); break; case "int": newAttr = new AttributeInfo(prop.Name, new AttributeType(AttributeTypes.Int32Array.ToString(), typeof(int[]))); break; case "boolean": newAttr = new AttributeInfo(prop.Name, new AttributeType(AttributeTypes.BooleanArray.ToString(), typeof(bool[]))); break; case "Single": newAttr = new AttributeInfo(prop.Name, new AttributeType(AttributeTypes.SingleArray.ToString(), typeof(float[]))); break; default: throw new NotSupportedException("Not supported data type for DOM type gen:" + prop.PropertyType.Name); } } else { switch (propType.Name) { case "String": // Consider them as string crc always? newAttr = new AttributeInfo(prop.Name, AttributeType.StringType); newAttr.AddRule(new StringHashRule()); break; case "int": newAttr = new AttributeInfo(prop.Name, AttributeType.IntType); break; case "boolean": newAttr = new AttributeInfo(prop.Name, AttributeType.BooleanType); break; case "Single": newAttr = new AttributeInfo(prop.Name, AttributeType.FloatType); break; default: throw new NotSupportedException("Not supported data type for DOM type gen:" + prop.PropertyType.Name); } } } if (newAttr != null) { propDesc = new AttributePropertyDescriptor(prop.Name, newAttr, "Node", prop.Name, false); nodeType.Define(newAttr); } if (propDesc != null) { propertyDescs.Add(propDesc); } } nodeType.SetTag(propertyDescs); return(nodeType); }
/// <summary> /// Finishes initializing component by adding palette information and defining module types</summary> public virtual void Initialize() { // add palette info to annotation type, and register with palette var annotationItem = new NodeTypePaletteItem( Schema.annotationType.Type, "Comment".Localize(), "Create a moveable resizable comment on the circuit canvas".Localize(), Resources.AnnotationImage); m_paletteService.AddItem( annotationItem, "Misc".Localize("abbreviation for miscellaneous"), this); // define editable properties on annotation Schema.annotationType.Type.SetTag( new PropertyDescriptorCollection( new PropertyDescriptor[] { new AttributePropertyDescriptor( "Text".Localize(), Schema.annotationType.textAttribute, null, "Comment Text".Localize(), false), new AttributePropertyDescriptor( "Background Color".Localize(), // name Schema.annotationType.backcolorAttribute, //AttributeInfo null, // category "Comment's background color".Localize(), //description false, //isReadOnly new Sce.Atf.Controls.PropertyEditing.ColorEditor(), // editor new Sce.Atf.Controls.PropertyEditing.IntColorConverter() // typeConverter ), new AttributePropertyDescriptor( "Foreground Color".Localize(), // name Schema.annotationType.foreColorAttribute, //AttributeInfo null, // category "Comment's foreground color".Localize(), //description false, //isReadOnly new Sce.Atf.Controls.PropertyEditing.ColorEditor(), // editor new Sce.Atf.Controls.PropertyEditing.IntColorConverter() // typeConverter ), })); // define module types DefineModuleType( new XmlQualifiedName("buttonType", Schema.NS), "Button".Localize(), "On/Off Button".Localize(), Resources.ButtonImage, EmptyArray <ElementType.Pin> .Instance, new ElementType.Pin[] { new ElementType.Pin("Out".Localize(), BooleanPinTypeName, 0) }, m_schemaLoader); var lightType = DefineModuleType( new XmlQualifiedName("lightType", Schema.NS), "Light".Localize(), "Light source".Localize(), Resources.LightImage, new ElementType.Pin[] { new ElementType.Pin("In".Localize(), BooleanPinTypeName, 0) }, EmptyArray <ElementType.Pin> .Instance, m_schemaLoader); // define and add new attribute to light type. var featuresAttribute = new AttributeInfo("features".Localize(), AttributeType.IntType); featuresAttribute.DefaultValue = 3; lightType.Define(featuresAttribute); // create property descriptor for the above attribute. FlagsUITypeEditor featuresEditor = new FlagsUITypeEditor(new[] { "ENERGY STAR", "High CRI" }, new[] { 1, 2 }); FlagsTypeConverter featuresConverter = new FlagsTypeConverter(new[] { "Energy Star", "High CRI" }, new[] { 1, 2 }); lightType.SetTag( new PropertyDescriptorCollection( new PropertyDescriptor[] { new AttributePropertyDescriptor( "Features".Localize(), featuresAttribute, null, //category "Features".Localize(), //description false, featuresEditor, featuresConverter) //is not read-only })); DomNodeType speakerNodeType = DefineModuleType( new XmlQualifiedName("speakerType", Schema.NS), "Speaker".Localize("an electronic speaker, for playing sounds"), "Speaker".Localize("an electronic speaker, for playing sounds"), Resources.SpeakerImage, new ElementType.Pin[] { new ElementType.Pin("In".Localize(), FloatPinTypeName, 0), }, EmptyArray <ElementType.Pin> .Instance, m_schemaLoader); var speakerManufacturerInfo = new AttributeInfo("Manufacturer".Localize(), AttributeType.StringType); // add bass level attribute to demo/test BoundedFloatEditor() float bassMin = -1; float bassMax = 1; var bassLevel = new AttributeInfo("bassLevel".Localize("bass level"), AttributeType.FloatType); bassLevel.AddRule(new NumericMinRule(bassMin, true)); bassLevel.AddRule(new NumericMaxRule(bassMax, true)); bassLevel.DefaultValue = 0.1f; //bassLevel.def speakerNodeType.Define(bassLevel); speakerNodeType.Define(speakerManufacturerInfo); speakerNodeType.SetTag( new PropertyDescriptorCollection( new PropertyDescriptor[] { new AttributePropertyDescriptor( "Manufacturer".Localize(), speakerManufacturerInfo, null, //category "Manufacturer".Localize(), //description false), new AttributePropertyDescriptor( "Bass Level".Localize(), bassLevel, null, //category "Bass Level".Localize(), //description false, new BoundedFloatEditor(bassMin, bassMax)) })); DefineModuleType( new XmlQualifiedName("soundType", Schema.NS), "Sound".Localize(), "Sound Player".Localize(), Resources.SoundImage, new ElementType.Pin[] { new ElementType.Pin("On".Localize(), "boolean", 0), new ElementType.Pin("Reset".Localize(), "boolean", 1), new ElementType.Pin("Pause".Localize(), "boolean", 2), }, new ElementType.Pin[] { new ElementType.Pin("Out".Localize(), "float", 0), }, m_schemaLoader); DefineModuleType( new XmlQualifiedName("andType", Schema.NS), "And".Localize(), "Logical AND".Localize(), Resources.AndImage, new ElementType.Pin[] { new ElementType.Pin("In1".Localize("input pin #1"), "boolean", 0), new ElementType.Pin("In2".Localize("input pin #2"), "boolean", 1), }, new ElementType.Pin[] { new ElementType.Pin("Out".Localize(), "boolean", 0), }, m_schemaLoader); DefineModuleType( new XmlQualifiedName("orType", Schema.NS), "Or".Localize(), "Logical OR".Localize(), Resources.OrImage, new ElementType.Pin[] { new ElementType.Pin("In1".Localize("input pin #1"), "boolean", 0), new ElementType.Pin("In2".Localize("input pin #2"), "boolean", 1), }, new ElementType.Pin[] { new ElementType.Pin("Out".Localize(), "boolean", 0), }, m_schemaLoader); DefineModuleType( new XmlQualifiedName("16To1MultiplexerType", Schema.NS), "16-to-1 Multiplexer".Localize(), "16-to-1 Multiplexer".Localize(), Resources.AndImage, new ElementType.Pin[] { new ElementType.Pin("In1".Localize("input pin #1"), "boolean", 0), new ElementType.Pin("In2".Localize("input pin #2"), "boolean", 1), new ElementType.Pin("In3".Localize(), "boolean", 2), new ElementType.Pin("In4".Localize(), "boolean", 3), new ElementType.Pin("In5".Localize(), "boolean", 4), new ElementType.Pin("In6".Localize(), "boolean", 5), new ElementType.Pin("In7".Localize(), "boolean", 6), new ElementType.Pin("In8".Localize(), "boolean", 7), new ElementType.Pin("In9".Localize(), "boolean", 8), new ElementType.Pin("In10".Localize(), "boolean", 9), new ElementType.Pin("In11".Localize(), "boolean", 10), new ElementType.Pin("In12".Localize(), "boolean", 11), new ElementType.Pin("In13".Localize(), "boolean", 12), new ElementType.Pin("In14".Localize(), "boolean", 13), new ElementType.Pin("In15".Localize(), "boolean", 14), new ElementType.Pin("In16".Localize(), "boolean", 15), new ElementType.Pin("Select1".Localize("The name of a pin on a circuit element"), "boolean", 16), new ElementType.Pin("Select2".Localize("The name of a pin on a circuit element"), "boolean", 17), new ElementType.Pin("Select3".Localize("The name of a pin on a circuit element"), "boolean", 18), new ElementType.Pin("Select4".Localize("The name of a pin on a circuit element"), "boolean", 19), }, new ElementType.Pin[] { new ElementType.Pin("Out".Localize(), "boolean", 0), }, m_schemaLoader); DefineModuleType( new XmlQualifiedName("1To16DemultiplexerType", Schema.NS), "1-to-16 Demultiplexer".Localize(), "1-to-16 Demultiplexer".Localize(), Resources.OrImage, new ElementType.Pin[] { new ElementType.Pin("Data".Localize(), "boolean", 0), new ElementType.Pin("Select1".Localize("The name of a pin on a circuit element"), "boolean", 1), new ElementType.Pin("Select2".Localize("The name of a pin on a circuit element"), "boolean", 2), new ElementType.Pin("Select3".Localize("The name of a pin on a circuit element"), "boolean", 3), new ElementType.Pin("Select4".Localize("The name of a pin on a circuit element"), "boolean", 4), }, new ElementType.Pin[] { new ElementType.Pin("Out1".Localize(), "boolean", 0), new ElementType.Pin("Out2".Localize(), "boolean", 1), new ElementType.Pin("Out3".Localize(), "boolean", 2), new ElementType.Pin("Out4".Localize(), "boolean", 3), new ElementType.Pin("Out5".Localize(), "boolean", 4), new ElementType.Pin("Out6".Localize(), "boolean", 5), new ElementType.Pin("Out7".Localize(), "boolean", 6), new ElementType.Pin("Out8".Localize(), "boolean", 7), new ElementType.Pin("Out9".Localize(), "boolean", 8), new ElementType.Pin("Out10".Localize(), "boolean", 9), new ElementType.Pin("Out11".Localize(), "boolean", 10), new ElementType.Pin("Out12".Localize(), "boolean", 11), new ElementType.Pin("Out13".Localize(), "boolean", 12), new ElementType.Pin("Out14".Localize(), "boolean", 13), new ElementType.Pin("Out15".Localize(), "boolean", 14), new ElementType.Pin("Out16".Localize(), "boolean", 15), }, m_schemaLoader); }