Пример #1
0
 public CollectionEditor(Func <Object> value, Action <Object> setValue, CelestialBody body, String name, MemberInfo member, ParserTargetCollection collection, Func <Object> getReference) : base(value, setValue, body, name)
 {
     Member        = member;
     _getReference = getReference;
     Collection    = collection;
 }
Пример #2
0
            /**
             * Load collection for ParserTargetCollection
             *
             * @param member Member to load data for
             * @param o Instance of the object which owns member
             * @param node Configuration node from which to load data
             **/
            public static void LoadCollectionMemberFromConfigurationNode(MemberInfo member, object o, ConfigNode node, bool getChilds = true)
            {
                // Get the target attribute
                ParserTargetCollection target = (member.GetCustomAttributes(typeof(ParserTargetCollection), true) as ParserTargetCollection[]) [0];

                // Figure out if this field exists and if we care
                bool isNode  = node.HasNode(target.fieldName);
                bool isValue = node.HasValue(target.fieldName);

                // Obtain the type the member is (can only be field or property)
                Type   targetType  = null;
                object targetValue = null;

                if (member.MemberType == MemberTypes.Field)
                {
                    targetType = (member as FieldInfo).FieldType;
                    if (getChilds)
                    {
                        targetValue = (member as FieldInfo).GetValue(o);
                    }
                    else
                    {
                        targetValue = null;
                    }
                }
                else
                {
                    targetType = (member as PropertyInfo).PropertyType;
                    try
                    {
                        if ((member as PropertyInfo).CanRead && getChilds)
                        {
                            targetValue = (member as PropertyInfo).GetValue(o, null);
                        }
                        else
                        {
                            targetValue = null;
                        }
                    }
                    catch (Exception)
                    {
                        // ignored
                    }
                }

                // If there was no data found for this node
                if (!isNode && !isValue)
                {
                    if (!target.optional && !(target.allowMerge && targetValue != null))
                    {
                        // Error - non optional field is missing
                        throw new ParserTargetMissingException("Missing non-optional field: " + o.GetType() + "." + target.fieldName);
                    }

                    // Nothing to do, so return
                    return;
                }

                // If we are dealing with a generic collection
                if (targetType.IsGenericType)
                {
                    // If the target is a generic dictionary
                    if (typeof(IDictionary).IsAssignableFrom(targetType))
                    {
                        throw new Exception("Generic dictionaries are unsupported at this time");
                    }

                    // If the target is a generic collection
                    else if (typeof(IList).IsAssignableFrom(targetType))
                    {
                        // We need a node for this decoding
                        if (!isNode)
                        {
                            throw new Exception("Loading a generic list requires sources to be nodes");
                        }

                        // Get the target value as a collection
                        IList collection = targetValue as IList;

                        // Get the internal type of this collection
                        Type genericType = targetType.GetGenericArguments() [0];

                        // Create a new collection if merge is disallowed or if the collection is null
                        if (collection == null || !target.allowMerge)
                        {
                            collection  = Activator.CreateInstance(targetType) as IList;
                            targetValue = collection;
                        }

                        // Iterate over all of the nodes in this node
                        foreach (ConfigNode subnode in node.GetNode(target.fieldName).nodes)
                        {
                            // Check for the name significance
                            if (target.nameSignificance == NameSignificance.None)
                            {
                                // Just processes the contents of the node
                                collection.Add(CreateObjectFromConfigNode(genericType, subnode, target.getChild));
                            }

                            // Otherwise throw an exception because we don't support named ones yet
                            else if (target.nameSignificance == NameSignificance.Type)
                            {
                                // Generate the type from the name
                                Type elementType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).FirstOrDefault(t => t.Name == subnode.name);

                                // Add the object to the collection
                                collection.Add(CreateObjectFromConfigNode(elementType, subnode, target.getChild));
                            }
                        }
                    }
                }

                // If we are dealing with a non generic collection
                else
                {
                    // Check for invalid scenarios
                    if (target.nameSignificance == NameSignificance.None)
                    {
                        throw new Exception("Can not infer type from non generic target; can not infer type from zero name significance");
                    }
                }

                // If the member type is a field, set the value
                if (member.MemberType == MemberTypes.Field)
                {
                    (member as FieldInfo).SetValue(o, targetValue);
                }

                // If the member wasn't a field, it must be a property.  If the property is writable, set it.
                else if ((member as PropertyInfo).CanWrite)
                {
                    (member as PropertyInfo).SetValue(o, targetValue, null);
                }
            }
        /// <summary>
        /// Displays a parser target in the window
        /// </summary>
        private void DisplayParserTarget(ParserTarget target, MemberInfo member)
        {
            // Don't display hidden options
            if (Tools.HasAttribute <KittopiaHideOption>(member) &&
                !Tools.GetAttributes <KittopiaHideOption>(member)[0].Show)
            {
                return;
            }

            // Check if the object is a list or a single element
            if (!Tools.IsCollection(target))
            {
                GUIHorizontalLayout(() =>
                {
                    GUILabel(target.FieldName, modifier: Alignment(TextAlignmentOptions.Left));
                    GUIFlexibleSpace();
                    GUILabel(target.Optional ? "Optional" : "Required",
                             modifier: Alignment(TextAlignmentOptions.Right)
                             .And(TextColor(Color.gray)));
                });

                // Display a KittopiaDescription
                String description = Tools.GetDescription(member);
                if (!String.IsNullOrEmpty(description))
                {
                    GUISpace(2f);
                    GUILabel(description,
                             modifier: TextColor(Color.gray));
                }

                GUISpace(5f);

                // If the element is loaded from a config node, it needs a new window
                // Simply values can be edited with an inline textfield
                ConfigType configType =
                    Tools.GetConfigType(Tools.GetValue(member, Info.Value)?.GetType() ?? Tools.MemberType(member));

                if (configType == ConfigType.Node)
                {
                    GUIHorizontalLayout(() =>
                    {
                        // Edit Button
                        GUIToggleButton(
                            () => Children.ContainsKey(target.FieldName) && Children[target.FieldName].IsVisible,
                            "Edit", e => ToggleSubEditor(target, member, e), -1f, 25f,
                            Enabled <DialogGUIToggleButton>(() => Tools.GetValue(member, Info.Value) != null));

                        // Button to create or destroy the element
                        if (Tools.HasAttribute <KittopiaUntouchable>(member))
                        {
                            GUIButton(Tools.GetValue(member, Info.Value) != null ? "x" : "+", () => { }, 25f, 25f,
                                      false, () => { }, Enabled <DialogGUIButton>(() => false));
                        }
                        else
                        {
                            GUIButton(() => Tools.GetValue(member, Info.Value) != null ? "x" : "+", () =>
                            {
                                Object value = Tools.GetValue(member, Info.Value);
                                if (value != null)
                                {
                                    Tools.Destruct(value);
                                    Tools.SetValue(member, Info.Value, null);
                                    SetValue(null);
                                }
                                else
                                {
                                    Object v = Tools.Construct(Tools.MemberType(member), Info.Body);
                                    Tools.SetValue(member, Info.Value, v);
                                    SetValue(v);
                                }
                            }, 25f, 25f, false,
                                      () => { });
                        }
                    });
                }
                else
                {
                    GUIHorizontalLayout(() =>
                    {
                        GUITextInput("", false, Int32.MaxValue, s => Tools.ApplyInput(member, s, Info.Value),
                                     () => Tools.FormatParsable(Tools.GetValue(member, Info.Value)) ?? "",
                                     TMP_InputField.ContentType.Standard, 25f);
                        GUIToggleButton(
                            () => ValueEditors.ContainsKey(target.FieldName) &&
                            ValueEditors[target.FieldName].IsVisible, ">",
                            e => ToggleValueEditor(target, member, e), 25f, 25f,
                            Enabled <DialogGUIToggleButton>(() => HasValueEditor(member)));
                    });
                }
            }
            else
            {
                ParserTargetCollection collection = (ParserTargetCollection)target;

                // Is the collection parsing a subnode, or this one?
                if (collection.FieldName != "self")
                {
                    GUIHorizontalLayout(() =>
                    {
                        GUILabel(target.FieldName, modifier: Alignment(TextAlignmentOptions.Left));
                        GUIFlexibleSpace();
                        GUILabel(target.Optional ? "Optional" : "Required",
                                 modifier: Alignment(TextAlignmentOptions.Right)
                                 .And(TextColor(Color.gray)));
                    });

                    // Display a KittopiaDescription
                    String description = Tools.GetDescription(member);
                    if (!String.IsNullOrEmpty(description))
                    {
                        GUISpace(2f);
                        GUILabel(description,
                                 modifier: TextColor(Color.gray));
                    }

                    GUISpace(5f);

                    GUIHorizontalLayout(() =>
                    {
                        // Edit Button
                        GUIToggleButton(() => Children.ContainsKey(target.FieldName) && Children[target.FieldName].IsVisible, "Edit", e => ToggleCollectionEditor(target, member, e), -1f, 25f,
                                        Enabled <DialogGUIToggleButton>(() => Tools.GetValue(member, Info.Value) != null));

                        // Button to create or destroy the element
                        if (Tools.HasAttribute <KittopiaUntouchable>(member))
                        {
                            GUIButton(Tools.GetValue(member, Info.Value) != null ? "x" : "+", () => { }, 25f, 25f,
                                      false, () => { }, Enabled <DialogGUIButton>(() => false));
                        }
                        else
                        {
                            GUIButton(() => Tools.GetValue(member, Info.Value) != null ? "x" : "+", () =>
                            {
                                Object value = Tools.GetValue(member, Info.Value);
                                if (value != null)
                                {
                                    Tools.Destruct(value);
                                    Tools.SetValue(member, Info.Value, null);
                                    SetValue(null);
                                }
                                else
                                {
                                    Object v = Tools.Construct(Tools.MemberType(member), Info.Body);
                                    Tools.SetValue(member, Info.Value, v);
                                    SetValue(v);
                                }
                            }, 25f, 25f, false,
                                      () => { });
                        }
                    });
                }
                else
                {
                    new CollectionEditor(() => Tools.GetValue(member, Info.Value),
                                         v => Tools.SetValue(member, Info.Value, v), Info.Body,
                                         Info.Body.transform.name + " - " + target.FieldName, member, (ParserTargetCollection)target,
                                         () => Info.Value).DisplayCollection();
                }
            }

            if (target.FieldName != "self")
            {
                // Use a box as a seperator
                GUISpace(5f);
                GUIBox(-1f, 1f, () => { });
                GUISpace(5f);
            }
        }