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; }