Exemple #1
0
        public SpecificModConfigMenu(IManifest modManifest, string page = "", string prevPage = null)
        {
            mod = modManifest;

            modConfig = Mod.instance.configs[mod];
            currPage  = page;

            Mod.instance.configs[mod].ActiveDisplayPage = modConfig.Options[currPage];

            table               = new Table();
            table.RowHeight     = 50;
            table.Size          = new Vector2(Math.Min(1200, Game1.viewport.Width - 200), Game1.viewport.Height - 128 - 116);
            table.LocalPosition = new Vector2((Game1.viewport.Width - table.Size.X) / 2, (Game1.viewport.Height - table.Size.Y) / 2);
            foreach (var opt in modConfig.Options[page].Options)
            {
                opt.SyncToMod();

                var label = new Label()
                {
                    String = opt.Name
                };
                label.UserData = opt.Description;
                if (opt.Description != null && opt.Description != "")
                {
                    optHovers.Add(label);
                }

                Element other = new Label()
                {
                    String = "TODO", LocalPosition = new Vector2(500, 0)
                };
                Element other2 = null;
                if (opt is ComplexModOption c)
                {
                    var custom = new ComplexModOptionWidget(c);
                    custom.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    other = custom;
                }
                else if (opt is SimpleModOption <bool> b)
                {
                    var checkbox = new Checkbox();
                    checkbox.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    checkbox.Checked       = b.Value;
                    checkbox.Callback      = (Element e) => b.Value = (e as Checkbox).Checked;
                    other = checkbox;
                }
                else if (opt is SimpleModOption <SButton> k)
                {
                    if (Constants.TargetPlatform == GamePlatform.Android)
                    {
                        continue; // TODO: Support virtual keyboard input.
                    }
                    var label2 = new Label()
                    {
                        String = k.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    label2.Callback      = (Element e) => doKeybindingFor(k, e as Label);
                    other = label2;
                }
                else if (opt is ClampedModOption <int> ci)
                {
                    var label2 = new Label()
                    {
                        String = ci.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 2 + table.Size.X / 3 + 50, 0);
                    other2 = label2;
                    var slider = new Slider <int>();
                    slider.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    slider.RequestWidth  = (int)table.Size.X / 3;
                    slider.Value         = ci.Value;
                    slider.Minimum       = ci.Minimum;
                    slider.Maximum       = ci.Maximum;
                    slider.Interval      = ci.Interval;
                    slider.Callback      = (Element e) =>
                    {
                        ci.Value      = (e as Slider <int>).Value;
                        label2.String = ci.Value.ToString();
                    };
                    other = slider;
                }
                else if (opt is ClampedModOption <float> cf)
                {
                    var label2 = new Label()
                    {
                        String = cf.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 2 + table.Size.X / 3 + 50, 0);
                    other2 = label2;
                    var slider = new Slider <float>();
                    slider.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    slider.RequestWidth  = (int)table.Size.X / 3;
                    slider.Value         = cf.Value;
                    slider.Minimum       = cf.Minimum;
                    slider.Maximum       = cf.Maximum;
                    slider.Interval      = cf.Interval;
                    slider.Callback      = (Element e) =>
                    {
                        cf.Value      = (e as Slider <float>).Value;
                        label2.String = cf.Value.ToString();
                    };
                    other = slider;
                }
                else if (opt is ChoiceModOption <string> cs)
                {
                    var dropdown = new Dropdown()
                    {
                        Choices = cs.Choices
                    };
                    dropdown.LocalPosition   = new Vector2(table.Size.X / 2, 0);
                    dropdown.RequestWidth    = (int)table.Size.X / 2;
                    dropdown.Value           = cs.Value;
                    dropdown.MaxValuesAtOnce = Math.Min(dropdown.Choices.Length, 5);
                    dropdown.Callback        = (Element e) => cs.Value = (e as Dropdown).Value;
                    other = dropdown;
                }
                // The following need to come after the Clamped/ChoiceModOption's since those subclass these
                else if (opt is SimpleModOption <int> i)
                {
                    if (Constants.TargetPlatform == GamePlatform.Android)
                    {
                        continue; // TODO: Support virtual keyboard input.
                    }
                    var intbox = new Intbox();
                    intbox.LocalPosition = new Vector2(table.Size.X / 2 - 8, 0);
                    intbox.Value         = i.Value;
                    intbox.Callback      = (Element e) => i.Value = (e as Intbox).Value;
                    other = intbox;
                }
                else if (opt is SimpleModOption <float> f)
                {
                    if (Constants.TargetPlatform == GamePlatform.Android)
                    {
                        continue; // TODO: Support virtual keyboard input.
                    }
                    var floatbox = new Floatbox();
                    floatbox.LocalPosition = new Vector2(table.Size.X / 2 - 8, 0);
                    floatbox.Value         = f.Value;
                    floatbox.Callback      = (Element e) => f.Value = (e as Floatbox).Value;
                    other = floatbox;
                }
                else if (opt is SimpleModOption <string> s)
                {
                    if (Constants.TargetPlatform == GamePlatform.Android)
                    {
                        continue; // TODO: Support virtual keyboard input.
                    }
                    var textbox = new Textbox();
                    textbox.LocalPosition = new Vector2(table.Size.X / 2 - 8, 0);
                    textbox.String        = s.Value;
                    textbox.Callback      = (Element e) => s.Value = (e as Textbox).String;
                    other = textbox;
                }
                else if (opt is LabelModOption l)
                {
                    label.LocalPosition = new Vector2(-8, 0);
                    label.Bold          = true;
                    if (l.Name == "")
                    {
                        label = null;
                    }
                    other = null;
                }
                else if (opt is PageLabelModOption pl)
                {
                    label.Bold     = true;
                    label.Callback = ( Element e ) =>
                    {
                        if (TitleMenu.subMenu == this)
                        {
                            TitleMenu.subMenu = new SpecificModConfigMenu(mod, pl.NewPage, currPage);
                        }
                        else if (Game1.activeClickableMenu == this)
                        {
                            Game1.activeClickableMenu = new SpecificModConfigMenu(mod, pl.NewPage, currPage);
                        }
                    };
                    other = null;
                }
                else if (opt is ParagraphModOption p)
                {
                    label.NonBoldScale  = 0.75f;
                    label.NonBoldShadow = false;
                    other = null;

                    string[] text = p.Name.Split(' ');
                    label.String = text[0] + " ";
                    for (int it = 1; it < text.Length; ++it)
                    {
                        string oldStr = label.String;
                        label.String += text[it];
                        if (label.Measure().X >= table.Size.X)
                        {
                            label.String = oldStr + "\n" + text[it];
                        }
                        if (it < text.Length - 1)
                        {
                            label.String += " ";
                        }
                    }

                    string[] lines = label.String.Split('\n');
                    for (int il = 0; il < lines.Length; il += 2)
                    {
                        table.AddRow(new Element[] { new Label()
                                                     {
                                                         UserData      = opt.Description,
                                                         NonBoldScale  = 0.75f,
                                                         NonBoldShadow = false,
                                                         String        = lines[il + 0] + "\n" + (il + 1 >= lines.Length ? "" : lines[il + 1])
                                                     } });
                        continue;
                    }
                    continue;
                }
                else if (opt is ImageModOption t)
                {
                    var tex     = Game1.content.Load <Texture2D>(t.TexturePath);
                    var imgSize = new Vector2(tex.Width, tex.Height);
                    if (t.TextureRect.HasValue)
                    {
                        imgSize = new Vector2(t.TextureRect.Value.Width, t.TextureRect.Value.Height);
                    }
                    imgSize *= t.Scale;


                    var localPos    = new Vector2(table.Size.X / 2 - imgSize.X / 2, 0);
                    var baseRectPos = new Vector2(t.TextureRect.HasValue ? t.TextureRect.Value.X : 0,
                                                  t.TextureRect.HasValue ? t.TextureRect.Value.Y : 0);

                    var texs = new List <Image>();
                    if (textures.ContainsKey(t.TexturePath))
                    {
                        texs = textures[t.TexturePath];
                    }
                    else
                    {
                        textures.Add(t.TexturePath, texs);
                    }

                    for (int ir = 0; ir < imgSize.Y / table.RowHeight; ++ir)
                    {
                        int section = Math.Min((int)(imgSize.Y / t.Scale), table.RowHeight);
                        int baseY   = ( int )(baseRectPos.Y + section * ir);
                        if (baseY + section > baseRectPos.Y + imgSize.Y / t.Scale)
                        {
                            section = ( int )(baseRectPos.Y + imgSize.Y / t.Scale) - baseY;
                        }
                        var img = new Image()
                        {
                            Texture     = tex,
                            TextureRect = new Rectangle((int)baseRectPos.X, baseY, (int)imgSize.X / t.Scale, section),
                            Scale       = t.Scale,
                        };
                        img.LocalPosition = localPos;
                        texs.Add(img);
                        table.AddRow(new Element[] { img });
                    }

                    continue;
                }

                if (label == null)
                {
                    table.AddRow(new Element[] { });
                }
                else if (other == null)
                {
                    table.AddRow(new Element[] { label });
                }
                else if (other2 == null)
                {
                    table.AddRow(new Element[] { label, other });
                }
                else
                {
                    table.AddRow(new Element[] { label, other, other2 });
                }
            }
            ui.AddChild(table);

            addDefaultLabels(modManifest);

            // We need to update widgets at least once so ComplexModOptionWidget's get initialized
            table.ForceUpdateEvenHidden();

            ActiveConfigMenu = this;

            Mod.instance.Helper.Content.AssetEditors.Add(this);
        }
        public SpecificModConfigMenu(IManifest modManifest)
        {
            mod = modManifest;

            modConfig = Mod.instance.configs[mod];

            table = new Table();
            table.LocalPosition = new Vector2(200 / 2, 82);
            table.Size          = new Vector2(Game1.viewport.Width - 200, Game1.viewport.Height - 64 - 100);
            table.RowHeight     = 50;
            foreach (var opt in modConfig.Options)
            {
                opt.SyncToMod();

                var label = new Label()
                {
                    String = opt.Name
                };
                label.UserData = opt.Description;
                if (opt.Description != null && opt.Description != "")
                {
                    optHovers.Add(label);
                }

                Element other = new Label()
                {
                    String = "TODO", LocalPosition = new Vector2(500, 0)
                };
                Element other2 = null;
                if (opt is ComplexModOption c)
                {
                    var custom = new ComplexModOptionWidget(c);
                    custom.LocalPosition = new Vector2(table.Size.X / 5 * 3, 0);
                    other = custom;
                }
                else if (opt is SimpleModOption <bool> b)
                {
                    var checkbox = new Checkbox();
                    checkbox.LocalPosition = new Vector2(table.Size.X / 3 * 2, 0);
                    checkbox.Checked       = b.Value;
                    checkbox.Callback      = (Element e) => b.Value = (e as Checkbox).Checked;
                    other = checkbox;
                }
                else if (opt is SimpleModOption <SButton> k)
                {
                    var label2 = new Label()
                    {
                        String = k.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 3 * 2, 0);
                    label2.Callback      = (Element e) => doKeybindingFor(k, e as Label);
                    other = label2;
                }
                else if (opt is ClampedModOption <int> ci)
                {
                    var label2 = new Label()
                    {
                        String = ci.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 2 + table.Size.X / 3 + 50, 0);
                    other2 = label2;
                    var slider = new Slider <int>();
                    slider.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    slider.Width         = (int)table.Size.X / 3;
                    slider.Value         = ci.Value;
                    slider.Minimum       = ci.Minimum;
                    slider.Maximum       = ci.Maximum;
                    slider.Callback      = (Element e) =>
                    {
                        ci.Value      = (e as Slider <int>).Value;
                        label2.String = ci.Value.ToString();
                    };
                    other = slider;
                }
                else if (opt is ClampedModOption <float> cf)
                {
                    var label2 = new Label()
                    {
                        String = cf.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 2 + table.Size.X / 3 + 50, 0);
                    other2 = label2;
                    var slider = new Slider <float>();
                    slider.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    slider.Width         = (int)table.Size.X / 3;
                    slider.Value         = cf.Value;
                    slider.Minimum       = cf.Minimum;
                    slider.Maximum       = cf.Maximum;
                    slider.Callback      = (Element e) =>
                    {
                        cf.Value      = (e as Slider <float>).Value;
                        label2.String = cf.Value.ToString();
                    };
                    other = slider;
                }
                else if (opt is ChoiceModOption <string> cs)
                {
                    var dropdown = new Dropdown()
                    {
                        Choices = cs.Choices
                    };
                    dropdown.LocalPosition = new Vector2(table.Size.X / 7 * 4, 0);
                    dropdown.Value         = cs.Value;
                    dropdown.Callback      = (Element e) => cs.Value = (e as Dropdown).Value;
                    other = dropdown;
                }
                // The following need to come after the Clamped/ChoiceModOption's since those subclass these
                else if (opt is SimpleModOption <int> i)
                {
                    var intbox = new Intbox();
                    intbox.LocalPosition = new Vector2(table.Size.X / 5 * 3, 0);
                    intbox.Value         = i.Value;
                    intbox.Callback      = (Element e) => i.Value = (e as Intbox).Value;
                    other = intbox;
                }
                else if (opt is SimpleModOption <float> f)
                {
                    var floatbox = new Floatbox();
                    floatbox.LocalPosition = new Vector2(table.Size.X / 5 * 3, 0);
                    floatbox.Value         = f.Value;
                    floatbox.Callback      = (Element e) => f.Value = (e as Floatbox).Value;
                    other = floatbox;
                }
                else if (opt is SimpleModOption <string> s)
                {
                    var textbox = new Textbox();
                    textbox.LocalPosition = new Vector2(table.Size.X / 5 * 3, 0);
                    textbox.String        = s.Value;
                    textbox.Callback      = (Element e) => s.Value = (e as Textbox).String;
                    other = textbox;
                }

                if (other2 == null)
                {
                    table.AddRow(new Element[] { label, other });
                }
                else
                {
                    table.AddRow(new Element[] { label, other, other2 });
                }
            }
            ui.AddChild(table);

            var titleLabel = new Label()
            {
                String = modManifest.Name
            };

            titleLabel.LocalPosition  = new Vector2((Game1.viewport.Width - titleLabel.Font.MeasureString(titleLabel.String).X) / 2, 12);
            titleLabel.HoverTextColor = titleLabel.IdleTextColor;
            ui.AddChild(titleLabel);

            var cancelLabel = new Label()
            {
                String = "Cancel"
            };

            cancelLabel.LocalPosition = new Vector2(Game1.viewport.Width / 2 - 300, Game1.viewport.Height - 50);
            cancelLabel.Callback      = (Element e) => TitleMenu.subMenu = new ModConfigMenu();
            ui.AddChild(cancelLabel);

            var defaultLabel = new Label()
            {
                String = "Default"
            };

            defaultLabel.LocalPosition = new Vector2(Game1.viewport.Width / 2 - 50, Game1.viewport.Height - 50);
            defaultLabel.Callback      = (Element e) => revertToDefault();
            ui.AddChild(defaultLabel);

            var saveLabel = new Label()
            {
                String = "Save"
            };

            saveLabel.LocalPosition = new Vector2(Game1.viewport.Width / 2 + 200, Game1.viewport.Height - 50);
            saveLabel.Callback      = (Element e) => save();
            ui.AddChild(saveLabel);

            // We need to update widgets at least once so ComplexModOptionWidget's get initialized
            table.ForceUpdateEvenHidden();
        }
        public SpecificModConfigMenu(IManifest modManifest)
        {
            mod = modManifest;

            modConfig = Mod.instance.configs[mod];

            table               = new Table();
            table.RowHeight     = 50;
            table.Size          = new Vector2(Math.Min(1200, Game1.viewport.Width - 200), Game1.viewport.Height - 128 - 116);
            table.LocalPosition = new Vector2((Game1.viewport.Width - table.Size.X) / 2, (Game1.viewport.Height - table.Size.Y) / 2);
            foreach (var opt in modConfig.Options)
            {
                opt.SyncToMod();

                var label = new Label()
                {
                    String = opt.Name
                };
                label.UserData = opt.Description;
                if (opt.Description != null && opt.Description != "")
                {
                    optHovers.Add(label);
                }

                Element other = new Label()
                {
                    String = "TODO", LocalPosition = new Vector2(500, 0)
                };
                Element other2 = null;
                if (opt is ComplexModOption c)
                {
                    var custom = new ComplexModOptionWidget(c);
                    custom.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    other = custom;
                }
                else if (opt is SimpleModOption <bool> b)
                {
                    var checkbox = new Checkbox();
                    checkbox.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    checkbox.Checked       = b.Value;
                    checkbox.Callback      = (Element e) => b.Value = (e as Checkbox).Checked;
                    other = checkbox;
                }
                else if (opt is SimpleModOption <SButton> k)
                {
                    if (Constants.TargetPlatform == GamePlatform.Android)
                    {
                        continue; // TODO: Support virtual keyboard input.
                    }
                    var label2 = new Label()
                    {
                        String = k.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    label2.Callback      = (Element e) => doKeybindingFor(k, e as Label);
                    other = label2;
                }
                else if (opt is ClampedModOption <int> ci)
                {
                    var label2 = new Label()
                    {
                        String = ci.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 2 + table.Size.X / 3 + 50, 0);
                    other2 = label2;
                    var slider = new Slider <int>();
                    slider.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    slider.RequestWidth  = (int)table.Size.X / 3;
                    slider.Value         = ci.Value;
                    slider.Minimum       = ci.Minimum;
                    slider.Maximum       = ci.Maximum;
                    slider.Interval      = ci.Interval;
                    slider.Callback      = (Element e) =>
                    {
                        ci.Value      = (e as Slider <int>).Value;
                        label2.String = ci.Value.ToString();
                    };
                    other = slider;
                }
                else if (opt is ClampedModOption <float> cf)
                {
                    var label2 = new Label()
                    {
                        String = cf.Value.ToString()
                    };
                    label2.LocalPosition = new Vector2(table.Size.X / 2 + table.Size.X / 3 + 50, 0);
                    other2 = label2;
                    var slider = new Slider <float>();
                    slider.LocalPosition = new Vector2(table.Size.X / 2, 0);
                    slider.RequestWidth  = (int)table.Size.X / 3;
                    slider.Value         = cf.Value;
                    slider.Minimum       = cf.Minimum;
                    slider.Maximum       = cf.Maximum;
                    slider.Interval      = cf.Interval;
                    slider.Callback      = (Element e) =>
                    {
                        cf.Value      = (e as Slider <float>).Value;
                        label2.String = cf.Value.ToString();
                    };
                    other = slider;
                }
                else if (opt is ChoiceModOption <string> cs)
                {
                    var dropdown = new Dropdown()
                    {
                        Choices = cs.Choices
                    };
                    dropdown.LocalPosition   = new Vector2(table.Size.X / 2, 0);
                    dropdown.RequestWidth    = (int)table.Size.X / 2;
                    dropdown.Value           = cs.Value;
                    dropdown.MaxValuesAtOnce = Math.Min(dropdown.Choices.Length, 5);
                    dropdown.Callback        = (Element e) => cs.Value = (e as Dropdown).Value;
                    other = dropdown;
                }
                // The following need to come after the Clamped/ChoiceModOption's since those subclass these
                else if (opt is SimpleModOption <int> i)
                {
                    if (Constants.TargetPlatform == GamePlatform.Android)
                    {
                        continue; // TODO: Support virtual keyboard input.
                    }
                    var intbox = new Intbox();
                    intbox.LocalPosition = new Vector2(table.Size.X / 2 - 8, 0);
                    intbox.Value         = i.Value;
                    intbox.Callback      = (Element e) => i.Value = (e as Intbox).Value;
                    other = intbox;
                }
                else if (opt is SimpleModOption <float> f)
                {
                    if (Constants.TargetPlatform == GamePlatform.Android)
                    {
                        continue; // TODO: Support virtual keyboard input.
                    }
                    var floatbox = new Floatbox();
                    floatbox.LocalPosition = new Vector2(table.Size.X / 2 - 8, 0);
                    floatbox.Value         = f.Value;
                    floatbox.Callback      = (Element e) => f.Value = (e as Floatbox).Value;
                    other = floatbox;
                }
                else if (opt is SimpleModOption <string> s)
                {
                    if (Constants.TargetPlatform == GamePlatform.Android)
                    {
                        continue; // TODO: Support virtual keyboard input.
                    }
                    var textbox = new Textbox();
                    textbox.LocalPosition = new Vector2(table.Size.X / 2 - 8, 0);
                    textbox.String        = s.Value;
                    textbox.Callback      = (Element e) => s.Value = (e as Textbox).String;
                    other = textbox;
                }
                else if (opt is LabelModOption l)
                {
                    label.LocalPosition = new Vector2(-8, 0);
                    label.Bold          = true;
                    if (l.Name == "")
                    {
                        label = null;
                    }
                    other = null;
                }

                if (label == null)
                {
                    table.AddRow(new Element[] { });
                }
                else if (other == null)
                {
                    table.AddRow(new Element[] { label });
                }
                else if (other2 == null)
                {
                    table.AddRow(new Element[] { label, other });
                }
                else
                {
                    table.AddRow(new Element[] { label, other, other2 });
                }
            }
            ui.AddChild(table);

            addDefaultLabels(modManifest);

            // We need to update widgets at least once so ComplexModOptionWidget's get initialized
            table.ForceUpdateEvenHidden();

            ActiveConfigMenu = this;
        }