Ejemplo n.º 1
0
 public WProperty(string category, string name, bool editable, string tip = "", SourceScene source = SourceScene.Room)
 {
     Category    = category;
     DisplayName = name;
     IsEditable  = editable;
     ToolTip     = tip;
     SourceScene = source;
 }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        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;
            }
        }
Ejemplo n.º 5
0
        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);
        }