Esempio n. 1
0
        // TODO. Display status string? (right now only on/off texture, but True/False, Yes/No, Enabled/Disabled options)
        public BooleanElement(PropertyFieldWrapper memberInfo, object modConfig, IList <bool> array = null, int index = -1) : base(memberInfo, modConfig, (IList)array)
        {
            this._toggleTexture = TextureManager.Load("Images/UI/Settings_Toggle");

            if (array != null)
            {
                _IsOnFunction = () => array[index];
                this.OnClick += (ev, v) =>
                {
                    array[index] = !array[index];
                    Interface.modConfig.SetPendingChanges();
                };
            }
            else
            {
                this._IsOnFunction = () => (bool)memberInfo.GetValue(modConfig);
                if (memberInfo.CanWrite)
                {
                    this.OnClick += (ev, v) =>
                    {
                        memberInfo.SetValue(modConfig, !(bool)memberInfo.GetValue(modConfig));
                        Interface.modConfig.SetPendingChanges();
                    }
                }
                ;
            }
        }
Esempio n. 2
0
        public static Tuple <UIElement, UIElement> WrapIt(UIElement parent, ref int top, PropertyFieldWrapper memberInfo, object item, int order, object list = null, Type arrayType = null, int index = -1)
        {
            int  elementHeight = 0;
            Type type          = memberInfo.Type;

            if (arrayType != null)
            {
                type = arrayType;
            }
            UIElement e;

            // TODO: Other common structs? -- Rectangle, Point
            CustomModConfigItemAttribute customUI = ConfigManager.GetCustomAttribute <CustomModConfigItemAttribute>(memberInfo, null, null);

            if (customUI != null)
            {
                Type customUIType = customUI.t;
                if (typeof(ConfigElement).IsAssignableFrom(customUIType))
                {
                    ConstructorInfo ctor = customUIType.GetConstructor(new Type[0]);
                    if (ctor != null)
                    {
                        object instance = ctor.Invoke(new object[0]);
                        e = instance as UIElement;
                    }
                    else
                    {
                        e = new UIText($"{customUIType.Name} specified via CustomModConfigItem for {memberInfo.Name} does not have an empty constructor.");
                    }
                }
                else
                {
                    e = new UIText($"{customUIType.Name} specified via CustomModConfigItem for {memberInfo.Name} does not inherit from ConfigElement.");
                }
            }
            else if (item.GetType() == typeof(HeaderAttribute))
            {
                e = new HeaderElement((string)memberInfo.GetValue(item));
            }
            else if (type == typeof(ItemDefinition))
            {
                e = new ItemDefinitionElement();
            }
            else if (type == typeof(ProjectileDefinition))
            {
                e = new ProjectileDefinitionElement();
            }
            else if (type == typeof(NPCDefinition))
            {
                e = new NPCDefinitionElement();
            }
            else if (type == typeof(PrefixDefinition))
            {
                e = new PrefixDefinitionElement();
            }
            else if (type == typeof(Color))
            {
                e = new ColorElement();
            }
            else if (type == typeof(Vector2))
            {
                e = new Vector2Element();
            }
            else if (type == typeof(bool))             // isassignedfrom?
            {
                e = new BooleanElement();
            }
            else if (type == typeof(float))
            {
                e = new FloatElement();
            }
            else if (type == typeof(byte))
            {
                e = new ByteElement();
            }
            else if (type == typeof(uint))
            {
                e = new UIntElement();
            }
            else if (type == typeof(int))
            {
                SliderAttribute sliderAttribute = ConfigManager.GetCustomAttribute <SliderAttribute>(memberInfo, item, list);
                if (sliderAttribute != null)
                {
                    e = new IntRangeElement();
                }
                else
                {
                    e = new IntInputElement();
                }
            }
            else if (type == typeof(string))
            {
                OptionStringsAttribute ost = ConfigManager.GetCustomAttribute <OptionStringsAttribute>(memberInfo, item, list);
                if (ost != null)
                {
                    e = new StringOptionElement();
                }
                else
                {
                    e = new StringInputElement();
                }
            }
            else if (type.IsEnum)
            {
                if (list != null)
                {
                    e = new UIText($"{memberInfo.Name} not handled yet ({type.Name}).");
                }
                else
                {
                    e = new EnumElement();
                }
            }
            else if (type.IsArray)
            {
                e = new ArrayElement();
            }
            else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>))
            {
                e = new ListElement();
            }
            else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet <>))
            {
                e = new SetElement();
            }
            else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary <,>))
            {
                e = new DictionaryElement();
            }
            else if (type.IsClass)
            {
                e = new ObjectElement(/*, ignoreSeparatePage: ignoreSeparatePage*/);
            }
            else if (type.IsValueType && !type.IsPrimitive)
            {
                e = new UIText($"{memberInfo.Name} not handled yet ({type.Name}) Structs need special UI.");
                //e.Top.Pixels += 6;
                e.Height.Pixels += 6;
                e.Left.Pixels   += 4;

                object subitem = memberInfo.GetValue(item);
            }
            else
            {
                e              = new UIText($"{memberInfo.Name} not handled yet ({type.Name})");
                e.Top.Pixels  += 6;
                e.Left.Pixels += 4;
            }
            if (e != null)
            {
                if (e is ConfigElement configElement)
                {
                    configElement.Bind(memberInfo, item, (IList)list, index);
                    configElement.OnBind();
                }
                e.Recalculate();
                elementHeight = (int)e.GetOuterDimensions().Height;

                var container = GetContainer(e, index == -1 ? order : index);
                container.Height.Pixels = elementHeight;
                UIList uiList = parent as UIList;
                if (uiList != null)
                {
                    uiList.Add(container);
                    float p = uiList.GetTotalHeight();
                }
                else
                {
                    // Only Vector2 and Color use this I think, but modders can use the non-UIList approach for custom UI and layout.
                    container.Top.Pixels   = top;
                    container.Width.Pixels = -20;
                    container.Left.Pixels  = 20;
                    top += elementHeight + 4;
                    parent.Append(container);
                    parent.Height.Set(top, 0);
                }
                var tuple = new Tuple <UIElement, UIElement>(container, e);
                if (parent == Interface.modConfig.mainConfigList)
                {
                    Interface.modConfig.mainConfigItems.Add(tuple);
                }

                return(tuple);
            }
            return(null);
        }
Esempio n. 3
0
 public ColorObject(PropertyFieldWrapper memberInfo, object item)
 {
     this.item       = item;
     this.memberInfo = memberInfo;
     current         = (Color)memberInfo.GetValue(item);
 }
Esempio n. 4
0
        bool AllowNull => array == null;         // nulls don't make sense for a collection, but a standalone might be useful. NonNull attribute might be nice.

        // Label:
        //  Members
        //  Members
        public ObjectElement(PropertyFieldWrapper memberInfo, object item, IList array = null, int index = -1, bool ignoreSeparatePage = false) : base(memberInfo, item, array)
        {
            this.index = index;
            this.ignoreSeparatePage = ignoreSeparatePage;
            _GetValue = () => memberInfo.GetValue(this.item);
            _SetValue = (object value) => {
                if (!memberInfo.CanWrite)
                {
                    return;
                }
                memberInfo.SetValue(this.item, value);
            };

            if (array != null)
            {
                _GetValue = () => array[index];
                _SetValue = (object value) => { array[index] = value; Interface.modConfig.SetPendingChanges(); };
                // TODO: only do this if ToString is overriden.

                var  listType    = memberInfo.Type.GetGenericArguments()[0];
                bool hasToString = listType.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);

                if (hasToString)
                {
                    _TextDisplayFunction        = () => index + 1 + ": " + (array[index]?.ToString() ?? "null");
                    AbridgedTextDisplayFunction = () => (array[index]?.ToString() ?? "null");
                }
                else
                {
                    _TextDisplayFunction = () => index + 1 + ": ";
                }
            }
            else
            {
                bool hasToString = memberInfo.Type.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);
                if (hasToString)
                {
                    _TextDisplayFunction        = () => (labelAttribute == null ? memberInfo.Name : labelAttribute.Label) + (_GetValue() == null ? "" : ": " + _GetValue().ToString());
                    AbridgedTextDisplayFunction = () => _GetValue()?.ToString() ?? "";
                }
            }

            if (_GetValue() == null && !AllowNull)
            {
                object data = Activator.CreateInstance(memberInfo.Type);
                JsonConvert.PopulateObject("{}", data, ConfigManager.serializerSettings);
                //JsonDefaultValueAttribute jsonDefaultValueAttribute = (JsonDefaultValueAttribute)Attribute.GetCustomAttribute(memberInfo.MemberInfo, typeof(JsonDefaultValueAttribute));
                //if (jsonDefaultValueAttribute != null)
                //{
                //	JsonConvert.PopulateObject(jsonDefaultValueAttribute.json, subitem, ConfigManager.serializerSettings);
                //}
                _SetValue(data);
            }

            separatePage = ConfigManager.GetCustomAttribute <SeparatePageAttribute>(memberInfo, item, array) != null;
            //separatePage = separatePage && !ignoreSeparatePage;
            //separatePage = (SeparatePageAttribute)Attribute.GetCustomAttribute(memberInfo.MemberInfo, typeof(SeparatePageAttribute)) != null;
            if (separatePage && !ignoreSeparatePage)
            {
                // TODO: UITextPanel doesn't update...
                separatePageButton = new UITextPanel <FuncStringWrapper>(new FuncStringWrapper()
                {
                    func = _TextDisplayFunction
                });
                separatePageButton.HAlign = 0.5f;
                //e.Recalculate();
                //elementHeight = (int)e.GetOuterDimensions().Height;
                separatePageButton.OnClick += (a, c) => {
                    UIModConfig.SwitchToSubConfig(this.separatePagePanel);

                    /*	Interface.modConfig.uIElement.RemoveChild(Interface.modConfig.configPanelStack.Peek());
                     *      Interface.modConfig.uIElement.Append(separateListPanel);
                     *      Interface.modConfig.configPanelStack.Push(separateListPanel);*/
                    //separateListPanel.SetScrollbar(Interface.modConfig.uIScrollbar);

                    //UIPanel panel = new UIPanel();
                    //panel.Width.Set(200, 0);
                    //panel.Height.Set(200, 0);
                    //panel.Left.Set(200, 0);
                    //panel.Top.Set(200, 0);
                    //Interface.modConfig.Append(panel);

                    //Interface.modConfig.subMenu.Enqueue(subitem);
                    //Interface.modConfig.DoMenuModeState();
                };
                //e = new UIText($"{memberInfo.Name} click for more ({type.Name}).");
                //e.OnClick += (a, b) => { };
            }

            //data = _GetValue();// memberInfo.GetValue(this.item);
            //drawLabel = false;

            dataList = new NestedUIList();
            dataList.Width.Set(-14, 1f);
            dataList.Left.Set(14, 0f);
            dataList.Height.Set(-30, 1f);
            dataList.Top.Set(30, 0);
            dataList.ListPadding = 5f;
            Append(dataList);

            //string name = memberInfo.Name;
            //if (labelAttribute != null)
            //{
            //	name = labelAttribute.Label;
            //}
            if (array == null)
            {
                // drawLabel = false; TODO uncomment
            }

            initializeButton              = new UIModConfigHoverImage(playTexture, "Initialize");
            initializeButton.Top.Pixels  += 4;
            initializeButton.Left.Pixels -= 3;
            initializeButton.HAlign       = 1f;
            initializeButton.OnClick     += (a, b) => {
                Main.PlaySound(21);
                object data = Activator.CreateInstance(memberInfo.Type);
                // Crashes JSONItem
                JsonConvert.PopulateObject("{}", data, ConfigManager.serializerSettings);                 // Seems to fail on all data structures?

                //JsonDefaultValueAttribute jsonDefaultValueAttribute = (JsonDefaultValueAttribute)Attribute.GetCustomAttribute(memberInfo.MemberInfo, typeof(JsonDefaultValueAttribute));
                //if (jsonDefaultValueAttribute != null)
                //{
                //	JsonConvert.PopulateObject(jsonDefaultValueAttribute.json, subitem, ConfigManager.serializerSettings);
                //}

                _SetValue(data);

                //SeparatePageAttribute here?

                pendingChanges = true;
                //RemoveChild(initializeButton);
                //Append(deleteButton);
                //Append(expandButton);

                SetupList();
                Interface.modConfig.RecalculateChildren();
                Interface.modConfig.SetPendingChanges();
            };

            expandButton = new UIModConfigHoverImage(expandedTexture, "Expand");
            expandButton.Top.Set(4, 0f);             // 10, -25: 4, -52
            expandButton.Left.Set(-52, 1f);
            expandButton.OnClick += (a, b) => {
                expanded       = !expanded;
                pendingChanges = true;
            };

            deleteButton = new UIModConfigHoverImage(deleteTexture, "Clear");
            deleteButton.Top.Set(4, 0f);
            deleteButton.Left.Set(-25, 1f);
            deleteButton.OnClick += (a, b) => {
                _SetValue(null);
                pendingChanges = true;

                SetupList();
                //Interface.modConfig.RecalculateChildren();
                Interface.modConfig.SetPendingChanges();
            };

            if (_GetValue() != null)
            {
                //Append(expandButton);
                //Append(deleteButton);
                SetupList();
            }
            else
            {
                Append(initializeButton);
                //sortedContainer.Append(initializeButton);
            }

            pendingChanges = true;
            Recalculate();
        }
Esempio n. 5
0
 public Vector2Object(PropertyFieldWrapper memberInfo, object item)
 {
     this.item       = item;
     this.memberInfo = memberInfo;
     current         = (Vector2)memberInfo.GetValue(item);
 }
Esempio n. 6
0
        public static Tuple <UIElement, UIElement> WrapIt(UIElement parent, ref int top, PropertyFieldWrapper memberInfo, object item, int order, object array = null, Type arrayType = null, int index = -1)
        {
            int  elementHeight = 0;
            Type type          = memberInfo.Type;

            if (arrayType != null)
            {
                type = arrayType;
            }
            UIElement e = null;

            // TODO: Other common structs? -- Rectangle, Point
            CustomModConfigItemAttribute customUI = ConfigManager.GetCustomAttribute <CustomModConfigItemAttribute>(memberInfo, null, null);

            if (customUI != null)
            {
                Type            customUIType = customUI.t;
                ConstructorInfo ctor         = customUIType.GetConstructor(new[] { typeof(PropertyFieldWrapper), typeof(object), typeof(int), typeof(IList), typeof(int) });
                if (ctor != null)
                {
                    object[] arguments = new object[] { memberInfo, item, 0, array, index };
                    object   instance  = ctor.Invoke(arguments);
                    e = instance as UIElement;
                    if (e != null)
                    {
                        //e.Recalculate();
                        //elementHeight = (int)e.GetOuterDimensions().Height;
                        //elementHeight = 400; //e.GetHeight();
                    }
                    else
                    {
                        e = new UIText($"CustomUI for {memberInfo.Name} does not inherit from UIElement.");
                    }
                }
                else
                {
                    e = new UIText($"CustomUI for {memberInfo.Name} does not have the correct constructor.");
                }
            }
            else if (item.GetType() == typeof(HeaderAttribute))
            {
                //e = new UIText($"{memberInfo.GetValue(item)}", .4f, true);
                //e.SetPadding(6);
                e = new HeaderElement((string)memberInfo.GetValue(item));
            }
            else if (type == typeof(ItemDefinition))
            {
                e = new ItemDefinitionElement(memberInfo, item, (IList <ItemDefinition>)array, index);
            }
            else if (type == typeof(Color))
            {
                e = new ColorElement(memberInfo, item, (IList <Color>)array, index);
                //elementHeight = (int)(e as UIModConfigColorItem).GetHeight();
            }
            else if (type == typeof(Vector2))
            {
                e = new Vector2Element(memberInfo, item, (IList <Vector2>)array, index);
            }
            else if (type == typeof(bool))             // isassignedfrom?
            {
                e = new BooleanElement(memberInfo, item, (IList <bool>)array, index);
            }
            else if (type == typeof(float))
            {
                e = new FloatElement(memberInfo, item, (IList <float>)array, index);
            }
            else if (type == typeof(byte))
            {
                e = new ByteElement(memberInfo, item, (IList <byte>)array, index);
            }
            else if (type == typeof(uint))
            {
                e = new UIntElement(memberInfo, item, (IList <uint>)array, index);
            }
            else if (type == typeof(int))
            {
                RangeAttribute rangeAttribute = ConfigManager.GetCustomAttribute <RangeAttribute>(memberInfo, item, array);
                if (rangeAttribute != null)
                {
                    e = new IntRangeElement(memberInfo, item, (IList <int>)array, index);
                }
                else
                {
                    e = new IntInputElement(memberInfo, item, (IList <int>)array, index);
                }
            }
            else if (type == typeof(string))
            {
                OptionStringsAttribute ost = ConfigManager.GetCustomAttribute <OptionStringsAttribute>(memberInfo, item, array);
                if (ost != null)
                {
                    e = new StringOptionElement(memberInfo, item, (IList <string>)array, index);
                }
                else
                {
                    e = new StringInputElement(memberInfo, item, (IList <string>)array, index);
                }
            }
            else if (type.IsEnum)
            {
                if (array != null)
                {
                    e = new UIText($"{memberInfo.Name} not handled yet ({type.Name}).");
                }
                else
                {
                    e = new EnumElement(memberInfo, item);
                }
            }
            else if (type.IsArray)
            {
                e = new ArrayElement(memberInfo, item);
                //elementHeight = 225;
            }
            else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>))
            {
                e = new ListElement(memberInfo, item);
                //elementHeight = 225;
            }
            else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet <>))
            {
                e = new SetElement(memberInfo, item);
            }
            else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary <,>))
            {
                e = new DictionaryElement(memberInfo, item);
                //elementHeight = 300;
            }
            else if (type.IsClass)
            {
                e = new ObjectElement(memberInfo, item, (IList)array, index /*, ignoreSeparatePage: ignoreSeparatePage*/);
            }
            else if (type.IsValueType && !type.IsPrimitive)
            {
                e = new UIText($"{memberInfo.Name} not handled yet ({type.Name}) Structs need special UI.");
                //e.Top.Pixels += 6;
                e.Height.Pixels += 6;
                e.Left.Pixels   += 4;

                object subitem = memberInfo.GetValue(item);
            }
            else
            {
                e              = new UIText($"{memberInfo.Name} not handled yet ({type.Name})");
                e.Top.Pixels  += 6;
                e.Left.Pixels += 4;
            }
            if (e != null)
            {
                e.Recalculate();
                elementHeight = (int)e.GetOuterDimensions().Height;

                var container = GetContainer(e, index == -1 ? order : index);
                container.Height.Pixels = elementHeight;
                UIList list = parent as UIList;
                if (list != null)
                {
                    list.Add(container);
                    float p = list.GetTotalHeight();
                }
                else
                {
                    // Only Vector2 and Color use this I think, but modders can use the non-UIList approach for custom UI and layout.
                    container.Top.Pixels   = top;
                    container.Width.Pixels = -20;
                    container.Left.Pixels  = 20;
                    top += elementHeight + 4;
                    parent.Append(container);
                    parent.Height.Set(top, 0);
                }

                return(new Tuple <UIElement, UIElement>(container, e));
            }
            return(null);
        }
Esempio n. 7
0
        public CollectionElement(PropertyFieldWrapper memberInfo, object item) : base(memberInfo, item, null)
        {
            data = memberInfo.GetValue(item);
            defaultListValueAttribute = ConfigManager.GetCustomAttribute <DefaultListValueAttribute>(memberInfo, null, null);

            MaxHeight.Set(300, 0f);
            dataListElement = new UIElement();
            dataListElement.Width.Set(-10f, 1f);
            dataListElement.Left.Set(10f, 0f);
            dataListElement.Height.Set(-30, 1f);
            dataListElement.Top.Set(30f, 0f);
            //panel.SetPadding(0);
            //panel.BackgroundColor = Microsoft.Xna.Framework.Color.Transparent;
            //panel.BorderColor =  Microsoft.Xna.Framework.Color.Transparent;
            if (data != null)
            {
                Append(dataListElement);
            }
            dataListElement.OverflowHidden = true;

            dataList = new NestedUIList();
            dataList.Width.Set(-20, 1f);
            dataList.Left.Set(0, 0f);
            dataList.Height.Set(0, 1f);
            dataList.ListPadding = 5f;
            dataListElement.Append(dataList);

            UIScrollbar scrollbar = new UIScrollbar();

            scrollbar.SetView(100f, 1000f);
            scrollbar.Height.Set(-16f, 1f);
            scrollbar.Top.Set(6f, 0f);
            scrollbar.Left.Pixels -= 3;
            scrollbar.HAlign       = 1f;
            dataList.SetScrollbar(scrollbar);
            dataListElement.Append(scrollbar);

            PrepareTypes();
            // allow null collections to simplify modder code for OnDeserialize and allow null and empty lists to have different meanings, etc.
            SetupList();

            if (CanAdd)
            {
                initializeButton              = new UIModConfigHoverImage(playTexture, "Initialize");
                initializeButton.Top.Pixels  += 4;
                initializeButton.Left.Pixels -= 3;
                initializeButton.HAlign       = 1f;
                initializeButton.OnClick     += (a, b) => {
                    Main.PlaySound(SoundID.Tink);
                    InitializeCollection();
                    SetupList();
                    Interface.modConfig.RecalculateChildren();                     // not needed?
                    Interface.modConfig.SetPendingChanges();
                    expanded       = true;
                    pendingChanges = true;
                };

                addButton = new UIModConfigHoverImage(plusTexture, "Add");
                addButton.Top.Set(4, 0f);
                addButton.Left.Set(-52, 1f);
                addButton.OnClick += (a, b) => {
                    Main.PlaySound(SoundID.Tink);
                    AddItem();
                    SetupList();
                    Interface.modConfig.RecalculateChildren();
                    Interface.modConfig.SetPendingChanges();
                    expanded       = true;
                    pendingChanges = true;
                };

                deleteButton = new UIModConfigHoverImage(deleteTexture, "Clear");
                deleteButton.Top.Set(4, 0f);
                deleteButton.Left.Set(-25, 1f);
                deleteButton.OnClick += (a, b) => {
                    Main.PlaySound(SoundID.Tink);
                    NullCollection();
                    SetupList();
                    Interface.modConfig.RecalculateChildren();
                    Interface.modConfig.SetPendingChanges();
                    pendingChanges = true;
                };
            }

            expandButton = new UIModConfigHoverImage(collapsedTexture, "Expand");
            expandButton.Top.Set(4, 0f);             // 10, -25: 4, -52
            expandButton.Left.Set(-79, 1f);
            expandButton.OnClick += (a, b) => {
                expanded       = !expanded;
                pendingChanges = true;
            };

            upDownButton = new UIModConfigHoverImageSplit(upDownTexture, "Scale Up", "Scale Down");
            upDownButton.Top.Set(4, 0f);
            upDownButton.Left.Set(-106, 1f);
            upDownButton.OnClick += (a, b) => {
                Rectangle r = b.GetDimensions().ToRectangle();
                if (a.MousePosition.Y < r.Y + r.Height / 2)
                {
                    scale = Math.Min(2f, scale + 0.5f);
                }
                else
                {
                    scale = Math.Max(1f, scale - 0.5f);
                }
                //dataListPanel.RecalculateChildren();
                ////dataList.RecalculateChildren();
                //float h = dataList.GetTotalHeight();
                //MinHeight.Set(Math.Min(Math.Max(h + 84, 100), 300) * scale, 0f);
                //Recalculate();
                //if (Parent != null && Parent is UISortableElement) {
                //	Parent.Height.Pixels = GetOuterDimensions().Height;
                //}
            };
            //Append(upButton);

            //var aasdf = Texture2D.FromStream(Main.instance.GraphicsDevice, Assembly.GetExecutingAssembly().GetManifestResourceStream("Terraria.ModLoader.Config.UI.ButtonDecrement.png"));
            //for (int i = 0; i < 100; i++) {
            //	var vb = Texture2D.FromStream(Main.instance.GraphicsDevice, Assembly.GetExecutingAssembly().GetManifestResourceStream("Terraria.ModLoader.Config.UI.ButtonDecrement.png"));
            //}

            pendingChanges = true;
            Recalculate();             // Needed?
        }