public override void DoWindowContents(Rect rect) { const float LEFT = 25; const float BUTTON_LENGTH = 65; float lineLength = (int)rect.xMax - LEFT * 2; float buttonBuffer = (int)(((int)(lineLength * 0.5f) - BUTTON_LENGTH) * 0.5f); float y = 0; Text.Font = GameFont.Medium; Widgets.Label(new Rect(LEFT, y, lineLength, 64), "ModSync.UpdateOnModSyncNinja".Translate()); Text.Font = GameFont.Small; y += 52; // Label saying "Update Mod <mod name>" Widgets.Label(new Rect(LEFT, y, lineLength, 64), this.Mod.LocalInfo.ModName); y += 42; // Label saying "Previous version: <version> Widgets.Label(new Rect(LEFT, y, lineLength, 64), "ModSync.PreviousVersion".Translate().Replace("{previous_version}", this.Mod.LocalInfo.Version)); y += 40; // User input for new version Widgets.Label(new Rect(LEFT, y, 80, 32), "ModSync.NewVersion".Translate()); this.Mod.LocalInfo.Version = Widgets.TextField(new Rect(LEFT + 100, y, lineLength - 100, 32), this.Mod.LocalInfo.Version).Trim(); y += 42; // Quick copy version buttons Widgets.Label(new Rect(LEFT, y, 80, 32), "ModSync.QuickCopy".Translate()); string v = this.GetNextVersion(this.Mod.LocalInfo.Version); if (Widgets.ButtonText(new Rect(LEFT + 100, y, 80, 32), v)) { this.Mod.LocalInfo.Version = v; } if (!String.IsNullOrEmpty(this.AssemblyVersion)) { if (Widgets.ButtonText(new Rect(LEFT + 200, y, 80, 32), this.AssemblyVersion)) { this.Mod.LocalInfo.Version = this.AssemblyVersion; } } y += 42; // Is Save Breaking Widgets.Label(new Rect(LEFT, y, 120, 32), "ModSync.IsSaveBreaking".Translate()); Widgets.Checkbox(new Vector2(LEFT + 140, y + 4), ref this.Mod.LocalInfo.IsSaveBreaking); y += 40; // Host Selection Widgets.Label(new Rect(LEFT, y, 80, 32), "ModSync.Host".Translate()); if (Widgets.ButtonText(new Rect(LEFT + 100, y, 150, 32), this.selectedHost)) { List <FloatMenuOption> options = new List <FloatMenuOption>(); foreach (string host in this.Hosts) { options.Add(new FloatMenuOption(host, delegate { if (HostFactory.TryCreateHost(host, out this.Mod.Host)) { this.selectedHost = host; this.isHostValid = false; } })); } Find.WindowStack.Add(new FloatMenu(options)); } y += 40; bool canValidate = false; if (this.Mod.Host is IEditableHost editable) { y = editable.DrawHost(LEFT + 20, y, lineLength); canValidate = editable.IsFormFilled; if (Widgets.ButtonText(new Rect(LEFT + 20, y, 100, 32), "ModSync.Validate".Translate(), canValidate, false, canValidate)) { if (editable.Validate()) { RestUtil.GetAboutXml(this.Mod.Host.AboutXmlUri, delegate(bool found) { if (found) { this.isHostValid = true; Messages.Message("ModSync.FormIsValid".Translate(), MessageTypeDefOf.PositiveEvent); } else { Log.Warning(this.Mod.Host.AboutXmlUri); Log.Error("ModSync.UnableToAboutSyncFile".Translate()); } }); } } } y += 40; // Submit button bool canSubmit = !String.IsNullOrEmpty(this.Mod.LocalInfo.Version) && this.Mod.Host != null && canValidate && this.isHostValid; if (Widgets.ButtonText(new Rect(LEFT + buttonBuffer, y, 65, 32), "Confirm".Translate(), canSubmit, false, canSubmit)) // Using Confirm as it's translated already in the base game { XmlDocument xml = new XmlDocument(); xml.AppendChild(xml.CreateXmlDeclaration("1.0", "utf-8", null)); XmlElement root = xml.CreateElement("ModSyncNinjaData"); xml.AppendChild(root); XmlElement el = xml.CreateElement("ID"); el.InnerText = this.Mod.LocalInfo.Id; root.AppendChild(el); el = xml.CreateElement("ModName"); el.InnerText = this.Mod.LocalInfo.ModName; root.AppendChild(el); el = xml.CreateElement("Version"); el.InnerText = this.Mod.LocalInfo.Version; root.AppendChild(el); el = xml.CreateElement("SaveBreaking"); el.InnerText = this.Mod.LocalInfo.IsSaveBreaking.ToString(); root.AppendChild(el); this.WriteToXml(xml, root); XmlWriterSettings settings = new XmlWriterSettings { NewLineChars = "\n", Indent = true }; using (XmlWriter writer = XmlWriter.Create(this.Mod.Mod.RootDir + "/About/ModSync.xml", settings)) { xml.WriteTo(writer); } base.Close(); } // Cancel Button if (Widgets.ButtonText(new Rect((int)(rect.width * 0.5f) + buttonBuffer, y, 65, 32), "CancelButton".Translate())) // Using CancelButton as it's translated already in the base game { base.Close(); } }