public WProperty(string category, string name, bool editable, string tip = "", SourceScene source = SourceScene.Room) { Category = category; DisplayName = name; IsEditable = editable; ToolTip = tip; SourceScene = source; }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var node = (SerializableDOMNode)value; var wproperties = node.GetType().GetProperties().Where(prop => { CustomAttributeData[] custom_attributes = prop.CustomAttributes.ToArray(); CustomAttributeData wproperty_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "WProperty"); if (wproperty_attribute == null) { return(false); } CustomAttributeData jsonignore_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "JsonIgnoreAttribute"); if (jsonignore_attribute != null) { return(false); } return(true); }); Dictionary <string, object> objPropsDict = new Dictionary <string, object>(); foreach (var prop in wproperties) { object propValue = prop.GetValue(node, null); if (prop.PropertyType == typeof(MessageReference)) { propValue = (propValue as MessageReference).MessageID; } else if (prop.PropertyType == typeof(Path_v2)) { WDOMNode cur_object = node; while (cur_object.Parent != null) { cur_object = cur_object.Parent; } List <Path_v2> pathsList = cur_object.GetChildrenOfType <Path_v2>(); propValue = pathsList.IndexOf(propValue as Path_v2); } else if (prop.PropertyType == typeof(ExitData)) { WScene scene; CustomAttributeData[] custom_attributes = prop.CustomAttributes.ToArray(); CustomAttributeData wproperty_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "WProperty"); SourceScene source_scene = (SourceScene)wproperty_attribute.ConstructorArguments[4].Value; if (source_scene == SourceScene.Stage) { scene = m_world.Map.SceneList.First(x => x.GetType() == typeof(WStage)) as WScene; } else { WDOMNode cur_object = node; while (cur_object.Parent != null) { cur_object = cur_object.Parent; } scene = cur_object as WScene; } List <ExitData> exitsList = scene.GetChildrenOfType <ExitData>(); propValue = exitsList.IndexOf(propValue as ExitData); } else if (prop.PropertyType == typeof(MapEvent)) { WStage stage = m_world.Map.SceneList.First(x => x.GetType() == typeof(WStage)) as WStage; List <MapEvent> eventsList = stage.GetChildrenOfType <MapEvent>(); propValue = eventsList.IndexOf(propValue as MapEvent); } objPropsDict[prop.Name] = propValue; } serializer.Serialize(writer, objPropsDict); }
public void ReflectObject(object obj) { OrderedDictionary new_details = new OrderedDictionary(); if (obj == null) { Categories = new_details; return; } HideCategoriesAttribute hidden_categories = (HideCategoriesAttribute)obj.GetType().GetCustomAttribute(typeof(HideCategoriesAttribute)); PropertyInfo[] obj_properties = obj.GetType().GetProperties(); foreach (PropertyInfo p in obj_properties) { // We want to ignore all properties that are not marked with the WProperty attribute. CustomAttributeData[] custom_attributes = p.CustomAttributes.ToArray(); CustomAttributeData wproperty_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "WProperty"); if (wproperty_attribute == null) { continue; } // Grab our custom attribute data for use string category_name = (string)wproperty_attribute.ConstructorArguments[0].Value; string property_name = (string)wproperty_attribute.ConstructorArguments[1].Value; bool is_editable = (bool)wproperty_attribute.ConstructorArguments[2].Value; string tool_tip = (string)wproperty_attribute.ConstructorArguments[3].Value; SourceScene source_scene = (SourceScene)wproperty_attribute.ConstructorArguments[4].Value; // Get the base type for possible use later Type base_type = p.PropertyType; while (base_type.BaseType != typeof(object)) { base_type = base_type.BaseType; } // Only add the category to the view if it's not blacklisted by the HideCategories attribute. if (!new_details.Contains(category_name) && (hidden_categories == null || !hidden_categories.CategoryHidden(category_name))) { new_details.Add(category_name, new WDetailsCategoryRowViewModel(category_name)); } WDetailsCategoryRowViewModel current_category = null; if (new_details.Contains(category_name)) { current_category = (WDetailsCategoryRowViewModel)new_details[category_name]; } else { continue; } /* This is where we generate the control for the details view. */ List <WDetailSingleRowViewModel> property_rows = new List <WDetailSingleRowViewModel>(); // We first check if the type of the property has a customization registered. // If it is, we just grab the customization and generate a control with it. if (m_TypeCustomizations.ContainsKey(p.PropertyType.Name)) { property_rows = m_TypeCustomizations[p.PropertyType.Name].CustomizeHeader(p, property_name, is_editable, obj); } // If there is no customization registered, and the type is an enum, we // use EnumTypeCustomization to generate a control. else if (p.PropertyType.IsEnum) { EnumTypeCustomization enu = new EnumTypeCustomization(); property_rows = enu.CustomizeHeader(p, property_name, is_editable, obj); } // Check if the type is an AndvancedBindingList. else if (p.PropertyType.Name == typeof(AdvancedBindingList <object>).Name) { Type underlying_type = p.PropertyType.GetGenericArguments().Single(); Type type_from_generic = typeof(AdvancedBindingListTypeCustomization <>).MakeGenericType(underlying_type); IPropertyTypeCustomization adv_cus = Activator.CreateInstance(type_from_generic) as IPropertyTypeCustomization; property_rows = adv_cus.CustomizeHeader(p, property_name, is_editable, obj); WAdvancedBindingListControl base_ctrl = property_rows[0].PropertyControl as WAdvancedBindingListControl; base_ctrl.entry_combo.SelectedIndex = 0; property_rows.AddRange(base_ctrl.GenerateBoundFields()); base_ctrl.OnEntryComboSelectionChanged(); } // Failing the prior checks, we see if the base type of the property is WDOMNode, // in which case we just use the WDOMNode customization to generate a control. else if (base_type.Name == typeof(WDOMNode).Name) { property_rows = m_TypeCustomizations[typeof(WDOMNode).Name].CustomizeHeader(p, property_name, is_editable, obj); WActorReferenceControl c = (WActorReferenceControl)property_rows[0].PropertyControl; c.Source = source_scene; c.FillComboBox(); } // If the property type is completely unknown or unsupported, we create an empty row with // just the property's name. else { property_rows.Add(new WDetailSingleRowViewModel(property_name)); } // Saw online that adding multiple things to a binding list can be slow, // so I'll do what that guy suggested. Disable raising changed events, then re-enable when we're done. current_category.PropertyRows.RaiseListChangedEvents = false; foreach (var row in property_rows) { current_category.PropertyRows.Add(row); if (tool_tip != "") { row.PropertyToolTip = tool_tip; } } current_category.PropertyRows.RaiseListChangedEvents = true; current_category.PropertyRows.ResetBindings(); } // We want to force certain categories to the top of the list, so reorder it at the end. foreach (var cat_name in new string[] { "Actor", "Transform", "Entity" }) { if (new_details.Contains(cat_name)) { var row = new_details[cat_name]; new_details.Remove(cat_name); new_details.Insert(0, cat_name, row); } } Categories = new_details; }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var nodeJson = JObject.Load(reader); var actorName = (string)nodeJson["Name"]; SerializableDOMNode newNode; if (m_parent is WDOMLayeredGroupNode) { if (actorName == null) { return(null); } WDOMLayeredGroupNode layerNode = m_parent as WDOMLayeredGroupNode; string unlayedFourCC = layerNode.FourCC.ToString(); MapLayer layer = ChunkHeader.FourCCToLayer(ref unlayedFourCC); FourCC fourcc = FourCCConversion.GetEnumFromString(unlayedFourCC); Type newObjType = WResourceManager.GetTypeByName(actorName); if (newObjType == typeof(Actor)) { return(null); } newNode = (SerializableDOMNode)Activator.CreateInstance(newObjType, fourcc, m_world); newNode.Layer = layer; } else if (m_parent is WDOMGroupNode) { WDOMGroupNode groupNode = m_parent as WDOMGroupNode; FourCC fourcc = groupNode.FourCC; if (fourcc == FourCC.ACTR || fourcc == FourCC.SCOB || fourcc == FourCC.TRES) { return(null); } if (fourcc == FourCC.TGDR || fourcc == FourCC.TGSC || fourcc == FourCC.TGOB) { if (actorName == null) { return(null); } Type newObjType = WResourceManager.GetTypeByName(actorName); if (newObjType == typeof(Actor)) { return(null); } newNode = (SerializableDOMNode)Activator.CreateInstance(newObjType, fourcc, m_world); } else { Type newObjType = FourCCConversion.GetTypeFromEnum(groupNode.FourCC); newNode = (SerializableDOMNode)Activator.CreateInstance(newObjType, fourcc, m_world); } } else { return(null); } newNode.SetParent(m_parent); try { var wproperties = newNode.GetType().GetProperties().Where(prop => { CustomAttributeData[] custom_attributes = prop.CustomAttributes.ToArray(); CustomAttributeData wproperty_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "WProperty"); if (wproperty_attribute == null) { return(false); } CustomAttributeData jsonignore_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "JsonIgnoreAttribute"); if (jsonignore_attribute != null) { return(false); } return(true); }); foreach (var prop in wproperties) { JToken jsonValue = nodeJson[prop.Name]; if (jsonValue == null) { continue; } if (prop.PropertyType == typeof(WTransform)) { if (!(jsonValue is JObject)) { continue; } JObject jsonValueObject = (JObject)jsonValue; WTransform transform = prop.GetValue(newNode, null) as WTransform; if (transform != null) { if (jsonValueObject.ContainsKey("Position")) { var position = transform.Position; position.X = ((float?)jsonValueObject["Position"]["X"]).GetValueOrDefault(); position.Y = ((float?)jsonValueObject["Position"]["Y"]).GetValueOrDefault(); position.Z = ((float?)jsonValueObject["Position"]["Z"]).GetValueOrDefault(); transform.Position = position; } if (jsonValueObject.ContainsKey("Rotation")) { var rotation = transform.Rotation; rotation.X = ((float?)jsonValueObject["Rotation"]["X"]).GetValueOrDefault(); rotation.Y = ((float?)jsonValueObject["Rotation"]["Y"]).GetValueOrDefault(); rotation.Z = ((float?)jsonValueObject["Rotation"]["Z"]).GetValueOrDefault(); rotation.W = ((float?)jsonValueObject["Rotation"]["W"]).GetValueOrDefault(); transform.Rotation = rotation; } if (jsonValueObject.ContainsKey("LocalScale")) { var localScale = transform.LocalScale; localScale.X = ((float?)jsonValueObject["LocalScale"]["X"]).GetValueOrDefault(1.0f); localScale.Y = ((float?)jsonValueObject["LocalScale"]["Y"]).GetValueOrDefault(1.0f); localScale.Z = ((float?)jsonValueObject["LocalScale"]["Z"]).GetValueOrDefault(1.0f); transform.LocalScale = localScale; } } } else if (prop.PropertyType == typeof(MessageReference)) { ushort messageID = (ushort)jsonValue; MessageReference msgRef = new MessageReference(messageID); prop.SetValue(newNode, msgRef); } else if (prop.PropertyType == typeof(Path_v2)) { int pathIndex = (int)jsonValue; WDOMNode cur_object = m_parent; while (cur_object.Parent != null) { cur_object = cur_object.Parent; } List <Path_v2> pathsList = cur_object.GetChildrenOfType <Path_v2>(); if (pathIndex < 0) { prop.SetValue(newNode, null); } else if (pathIndex < pathsList.Count) { Path_v2 path = pathsList[pathIndex]; prop.SetValue(newNode, path); } } else if (prop.PropertyType == typeof(ExitData)) { int exitIndex = (int)jsonValue; WScene scene; CustomAttributeData[] custom_attributes = prop.CustomAttributes.ToArray(); CustomAttributeData wproperty_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "WProperty"); SourceScene source_scene = (SourceScene)wproperty_attribute.ConstructorArguments[4].Value; if (source_scene == SourceScene.Stage) { scene = m_world.Map.SceneList.First(x => x.GetType() == typeof(WStage)) as WScene; } else { WDOMNode cur_object = m_parent; while (cur_object.Parent != null) { cur_object = cur_object.Parent; } scene = cur_object as WScene; } List <ExitData> exitsList = scene.GetChildrenOfType <ExitData>(); if (exitIndex < 0) { prop.SetValue(newNode, null); } else if (exitIndex < exitsList.Count) { ExitData exit = exitsList[exitIndex]; prop.SetValue(newNode, exit); } } else if (prop.PropertyType == typeof(MapEvent)) { int eventIndex = (int)jsonValue; WStage stage = m_world.Map.SceneList.First(x => x.GetType() == typeof(WStage)) as WStage; List <MapEvent> eventsList = stage.GetChildrenOfType <MapEvent>(); if (eventIndex < 0) { prop.SetValue(newNode, null); } else if (eventIndex < eventsList.Count) { MapEvent evnt = eventsList[eventIndex]; prop.SetValue(newNode, evnt); } } else { var value = Convert.ChangeType(jsonValue, prop.PropertyType); if (value != null) { prop.SetValue(newNode, value); } } } newNode.PostLoad(); return(newNode); } catch (Exception e) { // Creating the entity failed, so remove it from the scene. newNode.SetParent(null); throw; } }
public static List <WDetailSingleRowViewModel> GeneratePropertyRows(Type type) { List <WDetailSingleRowViewModel> property_rows = new List <WDetailSingleRowViewModel>(); HideCategoriesAttribute hidden_categories = (HideCategoriesAttribute)type.GetCustomAttribute(typeof(HideCategoriesAttribute)); PropertyInfo[] obj_properties = type.GetProperties(); List <string> tooltips = new List <string>(); foreach (PropertyInfo p in obj_properties) { // We want to ignore all properties that are not marked with the WProperty attribute. CustomAttributeData[] custom_attributes = p.CustomAttributes.ToArray(); CustomAttributeData wproperty_attribute = custom_attributes.FirstOrDefault(x => x.AttributeType.Name == "WProperty"); if (wproperty_attribute == null) { continue; } // Grab our custom attribute data for use string category_name = (string)wproperty_attribute.ConstructorArguments[0].Value; string property_name = (string)wproperty_attribute.ConstructorArguments[1].Value; bool is_editable = (bool)wproperty_attribute.ConstructorArguments[2].Value; string tool_tip = (string)wproperty_attribute.ConstructorArguments[3].Value; SourceScene source_scene = (SourceScene)wproperty_attribute.ConstructorArguments[4].Value; tooltips.Add(tool_tip); // Get the base type for possible use later Type base_type = p.PropertyType; while (base_type.BaseType != typeof(object)) { base_type = base_type.BaseType; } /* This is where we generate the control for the details view. */ // We first check if the type of the property has a customization registered. // If it is, we just grab the customization and generate a control with it. if (m_TypeCustomizations.ContainsKey(p.PropertyType.Name)) { property_rows.AddRange(m_TypeCustomizations[p.PropertyType.Name].CustomizeHeader(p, property_name, is_editable, null)); } // If there is no customization registered, and the type is an enum, we // use EnumTypeCustomization to generate a control. else if (p.PropertyType.IsEnum) { EnumTypeCustomization enu = new EnumTypeCustomization(); property_rows.AddRange(enu.CustomizeHeader(p, property_name, is_editable, null)); } // Check if the type is an AndvancedBindingList. else if (p.PropertyType.Name == typeof(AdvancedBindingList <object>).Name) { Type underlying_type = p.PropertyType.GetGenericArguments().Single(); Type type_from_generic = typeof(AdvancedBindingListTypeCustomization <>).MakeGenericType(underlying_type); IPropertyTypeCustomization adv_cus = Activator.CreateInstance(type_from_generic) as IPropertyTypeCustomization; property_rows = adv_cus.CustomizeHeader(p, property_name, is_editable, null); WAdvancedBindingListControl base_ctrl = property_rows[0].PropertyControl as WAdvancedBindingListControl; property_rows.AddRange(base_ctrl.GenerateBoundFields()); } // Failing the prior checks, we see if the base type of the property is WDOMNode, // in which case we just use the WDOMNode customization to generate a control. else if (base_type.Name == typeof(WDOMNode).Name) { property_rows.AddRange(m_TypeCustomizations[typeof(WDOMNode).Name].CustomizeHeader(p, property_name, is_editable, null)); WActorReferenceControl c = (WActorReferenceControl)property_rows[0].PropertyControl; c.Source = source_scene; c.FillComboBox(); } // If the property type is completely unknown or unsupported, we create an empty row with // just the property's name. else { property_rows.Add(new WDetailSingleRowViewModel(property_name)); } } for (int i = 0; i < property_rows.Count; i++) { property_rows[i].PropertyToolTip = tooltips[i]; } return(property_rows); }