Class ModsGUI { static title := "" selectedMod := "" __New() { if ModsGUI.title != "" && WinExist(ModsGUI.title) WinActivate(ModsGUI.title) else this.Constructor() } Constructor() { local languageCode := Language.Get() local title := App.Title("+status+version") " — " Locale.Read("dictionary.mods") ModsGUI.title := title local w := 900 local h := 600 local xPos := (A_ScreenWidth - w) / 2 local yPos := (A_ScreenHeight - h) / 2 local BtnW := 128 local BtnH := 32 local BtnY := h - 40 local lvW := 400 local lvH := (h - BtnH) - 21 local lvX := 10 local lvY := 10 local lvCols := [lvW * 0.60, lvW * 0.14, lvW * 0.25, 0, 0] local infoGroupX := lvX + lvW + 10 local infoGroupY := 10 local infoGroupW := w - 10 - infoGroupX local infoGroupH := (h - BtnH) - 21 local reloadBtnX := w - BtnW - 10 local createModBtnX := lvX local optionsBtnX := infoGroupX local editDataBtnX := optionsBtnX + BtnW + 5 local previewImageW := 96 local previewImageH := 96 local previewImageX := infoGroupX + 10 local previewImageY := infoGroupY + 35 local versionX := previewImageX + previewImageW + 10 local versionY := previewImageY + 10 local versionW := infoGroupX + infoGroupW - versionX - 10 local versionH := 20 local authorX := versionX local authorY := versionY + versionH + 8 local authorW := versionW local authorH := versionH local modPageX := versionX local modPageY := authorY + authorH + 8 local modPageW := versionW local modPageH := versionH * 2.7 local descriptionX := previewImageX local descriptionY := previewImageY + previewImageH + 25 local descriptionW := infoGroupX + infoGroupW - descriptionX - 10 local descriptionH := infoGroupY + infoGroupH - descriptionY - 10 local panel := Gui() panel.title := ModsGUI.title local listTitles := [] for each in ["dictionary.title", "dictionary.version", "init", "dictionary.folder"] listTitles.Push(Locale.Read(each)) listTitles.Push("") local modListLV := panel.AddListview(Format("vModsList w{} h{} x{} y{} Checked +NoSort -Multi", lvW, lvH, lvX, lvY), listTitles) modListLV.OnEvent("ItemCheck", (LV, Item, Checked) => this.ToggleMod(&LV, &Item, &Checked)) modListLV.OnEvent("ItemFocus", (LV, Item) => this.SetInfo(&LV, &Item, &panel)) local createModBtn := panel.AddButton(Format("vCreateModBtn w{} h{} x{} y{}", BtnW, BtnH, createModBtnX, BtnY), Locale.Read("gui.mods.creation.short")) createModBtn.OnEvent("Click", (*) => ModsGUI.ModCreation(&panel)) local optionsBtn := panel.AddButton(Format("vOptionsBtn w{} h{} x{} y{}", BtnW, BtnH, optionsBtnX, BtnY), Locale.Read("gui.options")) optionsBtn.OnEvent("Click", (*) => ModTools.OptionsEditor(this.selectedMod, &panel)) optionsBtn.Enabled := False local editDataBtn := panel.AddButton(Format("vEditDataBtn w{} h{} x{} y{}", BtnW, BtnH, editDataBtnX, BtnY), Locale.Read("dictionary.edit")) editDataBtn.OnEvent("Click", (*) => ModsGUI.ModCreation(&panel, this.selectedMod)) optionsBtn.Enabled := False local reloadBtn := panel.AddButton(Format("vReloadBtn w{} h{} x{} y{}", BtnW, BtnH, reloadBtnX, BtnY), Locale.Read("dictionary.reload")) reloadBtn.OnEvent("Click", (*) => Reload()) for i, each in lvCols modListLV.ModifyCol(i, lvCols[i]) local modsRead := ModsInjector.Read() local modsList := [] local imgList := IL_Create() IL_Add(imgList, App.ICONS_DLL, App.indexIcos.Get("mods_flat")) local idx := 1 for each in ["pre_init", "post_init"] { for key, value in modsRead[each].OwnProps() { local path := App.PATHS.MODS "\" key local modData := ModsInjector.ReadModManifest(key) local previewImg := this.GetPreview(&path, , True, "-16") if previewImg is String { idx++ IL_Add(imgList, previewImg) } modsList.Push([ ( (modData["status"] = 1 ? "Check " : "") ("Icon" (previewImg is String ? idx : 1)) ), modData.Has(languageCode) && modData[languageCode].Has("title") && modData[languageCode]["title"] != "" ? modData[languageCode]["title"] : modData["title"], modData["version"], modData["type"] = "pre_init" ? Locale.Read("init.before_start") : Locale.Read("init.after_start"), modData["folder"], modData["type"],]) } } modListLV.SetImageList(imgList) for item in modsList modListLV.Add(item*) local infoGroup := panel.AddGroupBox(Format("vInfoGroup w{} h{} x{} y{}", infoGroupW, infoGroupH, infoGroupX, infoGroupY)) infoGroup.SetFont("s14 c333333") local previewImage := panel.AddPicture(Format("vPreviewImage w{} h{} x{} y{}", previewImageW, previewImageH, previewImageX, previewImageY), this.GetPreview()) local versionLabel := panel.AddText(Format("vVersionLabel w{} h{} x{} y{}", versionW, versionH, versionX, versionY), "") versionLabel.SetFont("s12 c333333") local authorLabel := panel.AddLink(Format("vAuthorLabel w{} h{} x{} y{}", authorW, authorH, authorX, authorY), "") authorLabel.SetFont("s12 c333333") local modPage := panel.AddLink(Format("vModPage w{} h{} x{} y{} +Wrap", modPageW, modPageH, modPageX, modPageY), "") modPage.SetFont("s10 c333333") local descritpion := panel.AddText(Format("vDescription w{} h{} x{} y{} +Wrap", descriptionW, descriptionH, descriptionX, descriptionY), "") descritpion.SetFont("s11 c333333") panel.Show(Format("w{} h{} x{} y{}", w, h, xPos, yPos)) if modListLV.GetCount() > 0 { modListLV.Modify(1, "+Focus +Select") local item := modListLV.GetNext(0) this.SetInfo(&modListLV, &item, &panel) } return panel } ToggleMod(&LV, &Item, &Checked) { if !item return local modFolder := LV.GetText(Item, 4) local modType := LV.GetText(Item, 5) if !FileExist(ModsInjector.registryINI) FileAppend("[pre_init]`n`n[post_init]`n", ModsInjector.registryINI, "UTF-16") IniWrite(Checked, ModsInjector.registryINI, modType, modFolder) return } SetInfo(&LV, &Item, &panel) { if !item return local languageCode := Language.Get() local modFolder := LV.GetText(Item, 4) local modType := LV.GetText(Item, 5) local modPath := App.PATHS.MODS "\" modFolder local optionsMap := ModsInjector.ReadModManifest(modFolder) local className := "Mod__" ModTools.FolderToClassName(modFolder) local title := optionsMap.Has(languageCode) && optionsMap[languageCode].Has("title") && optionsMap[languageCode]["title"] != "" ? optionsMap[languageCode]["title"] : optionsMap["title"] if title = "" title := modFolder local homepage := optionsMap.Has(languageCode) && optionsMap[languageCode].Has("homepage") && optionsMap[languageCode]["homepage"] != "" ? optionsMap[languageCode]["homepage"] : optionsMap["homepage"] homepage := homepage != "" ? Format('{}', homepage, homepage) : homepage local author := optionsMap.Has(languageCode) && optionsMap[languageCode].Has("author") && optionsMap[languageCode]["author"] != "" ? optionsMap[languageCode]["author"] : optionsMap["author"] if RegExMatch(author, "^(.*)@(https.*)$", &match) author := Format('{}', match[2], match[1]) local description := optionsMap.Has(languageCode) && optionsMap[languageCode].Has("description") && optionsMap[languageCode]["description"] != "" ? optionsMap[languageCode]["description"] : optionsMap["description"] if description is Array description := description.ToString("") panel["PreviewImage"].Value := this.GetPreview(&modPath) panel["InfoGroup"].Text := title panel["VersionLabel"].Text := Locale.ReadInject("gui.mods.version", [optionsMap["version"]]) panel["AuthorLabel"].Text := Locale.ReadInject("gui.mods.author", [author]) panel["ModPage"].Text := Locale.ReadInject("gui.mods.homepage", [homepage]) panel["Description"].Text := Locale.HandleString(description) panel["OptionsBtn"].Enabled := IsSet(%className%) && %className%.HasOwnProp("tools") && %className%.tools.HasOwnProp("config_editor") && %className%.tools.config_editor is Gui panel["EditDataBtn"].Enabled := IsSet(%className%) && %className%.HasOwnProp("tools") && %className%.tools.HasOwnProp("config_editor") && %className%.tools.isEditable return this.selectedMod := modFolder } GetPreview(&modPath?, sizes := 96, returnArray := False, postfix := "") { if IsSet(modPath) { for suffix in (postfix ? [postfix, ""] : [""]) Loop Files modPath "\preview" suffix ".*", "F" if A_LoopFileExt ~= "(ico|png|jpg)" return A_LoopFileFullPath } return returnArray ? [App.ICONS_DLL, App.indexIcos.Get("mods")] : "HBITMAP:*" LoadPicture(App.ICONS_DLL, "Icon" App.indexIcos.Get("mods") " " Format("w{} h{}", sizes, sizes)) } Class ModCreation { title := "" defW := 500 defH := 700 w := this.defW h := this.defH fieldStep := 30 fieldH := 24 data := Map( "title", "My Mod", "folder", "My_Mod", "version", "1.0.0", "author", "Mod's author", "description", "My Mod's description", "type", "pre_init", "homepage", "" ) changeFolderNameTriggered := False supportedLocales := Language.GetSupported() locales := this.supportedLocales.DraftMap(default := Map( "title", "", "version", "", "author", "", "description", "", "homepage", "" )) currentLocale := False CalcSizes() { local fieldsCount := 7 local minRequiredHeight := (fieldsCount - 1) * this.fieldStep + this.fieldH * 7 + 120 if (this.h < minRequiredHeight) { this.h := minRequiredHeight } this.grpBoxW := this.w - 20 this.grpBoxH := this.h - 20 this.grpBoxX := (this.w - this.grpBoxW) / 2 this.grpBoxY := (this.h - this.grpBoxH) / 2 this.btnW := 100 this.btnH := 32 this.btnY := this.grpBoxY + this.grpBoxH - this.btnH - 10 this.fieldW := this.grpBoxW - 20 this.fieldX := this.grpBoxX + (this.grpBoxW - this.fieldW) / 2 this.fieldTitleW := this.fieldW this.fieldTitleH := 14 this.fieldTitleX := this.fieldX this.fieldTitleY := this.grpBoxY + 20 this.fieldY := (this.fieldTitleY + this.fieldTitleH) + 6 } btnX(multi := 1) => (this.grpBoxX + 10 + (this.btnW * (multi - 1))) incrementField(stepsCount := 1, extraHeight := 1, verticalExpand := False) { local x := this.fieldX local y := this.fieldY + (stepsCount - 1) * (this.fieldH + this.fieldStep) local w := this.fieldW local h := (this.fieldH * (extraHeight)) + (verticalExpand ? (this.h - this.defH) : 0) local field := [x, y, w, h] local x := this.fieldTitleX local y := this.fieldTitleY + (stepsCount - 1) * (this.fieldH + this.fieldStep) local w := this.fieldTitleW local h := this.fieldTitleH local fieldTitle := [x, y, w, h] return [field, fieldTitle] } Resize(modWindow, MinMax, W, H) { this.w := W this.h := H this.CalcSizes() modWindow["ModGrpBox"].Move(this.grpBoxX, this.grpBoxY, this.grpBoxW, this.grpBoxH) modWindow["TitleTitle"].Move(this.incrementField(1)[2]*) modWindow["TitleField"].Move(this.incrementField(1)[1]*) modWindow["FolderTitle"].Move(this.incrementField(2)[2]*) modWindow["FolderField"].Move(this.incrementField(2)[1]*) modWindow["VersionTitle"].Move(this.incrementField(3)[2]*) modWindow["VersionField"].Move(this.incrementField(3)[1]*) modWindow["AuthorTitle"].Move(this.incrementField(4)[2]*) modWindow["AuthorField"].Move(this.incrementField(4)[1]*) modWindow["TypeTitle"].Move(this.incrementField(5)[2]*) modWindow["TypeField"].Move(this.incrementField(5)[1]*) modWindow["HomepageTitle"].Move(this.incrementField(6)[2]*) modWindow["HomepageField"].Move(this.incrementField(6)[1]*) modWindow["DescriptionTitle"].Move(this.incrementField(7)[2]*) modWindow["DescriptionField"].Move(this.incrementField(7, 6 * 12, True)[1]*) modWindow["CreateBtn"].Move(this.btnX(1), this.btnY, this.btnW, this.btnH) modWindow["CancelBtn"].Move(this.btnX(2), this.btnY, this.btnW, this.btnH) return } __New(&parentGUI?, selectedMod?) { this.CalcSizes() local modClassName := IsSet(selectedMod) ? "Mod__" ModTools.FolderToClassName(selectedMod) : "MOD_CLASS_DOES_NOT_EXIST" this.selectedMod := IsSet(selectedMod) ? selectedMod : unset this.modClassName := modClassName this.selectedModIsValid := IsSet(selectedMod) && IsSet(modClassName) && %modClassName%.HasOwnProp("tools") this.selectedModManifest := this.selectedModIsValid ? JSON.LoadFile(%modClassName%.tools.paths.manifest, "UTF-8") : False if this.selectedModManifest { for key, value in this.selectedModManifest { if this.data.Has(key) { this.data.Set(key, value) } else if this.locales.Has(key) { for localeKey, localeValue in value this.locales[key].Set(localeKey, localeValue) } } this.data.Set("folder", this.selectedMod) } if IsSet(parentGUI) { parentGUI.GetPos(&parentX, &parentY, &parentW, &parentH) this.xPos := parentX + ((parentW - this.w) / 2) this.yPos := parentY + ((parentH - this.h) / 2) } else { this.xPos := (A_ScreenWidth - this.w) / 2 this.yPos := (A_ScreenHeight - this.h) / 2 } this.Show() return } Constructor() { this.title := App.Title("+status+version") " — " Locale.Read("gui.mods." (this.selectedModIsValid ? "edit" : "creation")) local modWindow := Gui() modWindow.Title := this.title local grpBox := modWindow.AddGroupBox(Format("vModGrpBox x{} y{} w{} h{}", this.grpBoxX, this.grpBoxY, this.grpBoxW, this.grpBoxH), Locale.Read("gui.mods." (this.selectedModIsValid ? "edit" : "creation"))) local titleTitle := modWindow.AddText(Format("vTitleTitle x{} y{} w{} h{}", this.incrementField(1)[2]*), "* " Locale.Read("dictionary.title")) local titleField := modWindow.AddEdit(Format("vTitleField x{} y{} w{} h{} -Multi", this.incrementField(1)[1]*), this.data.Get("title")) local folderTitle := modWindow.AddText(Format("vFolderTitle x{} y{} w{} h{}", this.incrementField(2)[2]*), "* " Locale.Read("dictionary.folder")) local folderField := modWindow.AddEdit(Format("vFolderField x{} y{} w{} h{} -Multi", this.incrementField(2)[1]*), this.data.Get("folder")) local versionTitle := modWindow.AddText(Format("vVersionTitle x{} y{} w{} h{}", this.incrementField(3)[2]*), "* " Locale.Read("dictionary.version")) local versionField := modWindow.AddEdit(Format("vVersionField x{} y{} w{} h{} -Multi", this.incrementField(3)[1]*), this.data.Get("version")) local authorTitle := modWindow.AddText(Format("vAuthorTitle x{} y{} w{} h{} ", this.incrementField(4)[2]*), Locale.Read("dictionary.author")) local authorField := modWindow.AddEdit(Format("vAuthorField x{} y{} w{} h{} -Multi", this.incrementField(4)[1]*), this.data.Get("author")) local typeFieldOptions := Map( "pre_init", Locale.Read("gui.mods.pre_init"), "post_init", Locale.Read("gui.mods.post_init") ) local typeTitle := modWindow.AddText(Format("vTypeTitle x{} y{} w{} h{}", this.incrementField(5)[2]*), Locale.Read("dictionary.initialization")) local typeField := modWindow.AddDropDownList(Format("vTypeField x{} y{} w{} h{}", this.incrementField(5)[1]*) Format(" R{}", typeFieldOptions.Count), typeFieldOptions.Values()) PostMessage(0x0153, -1, 15, typeField) typeField.Choose(typeFieldOptions.Get(this.data.Get("type"))) local homepageTitle := modWindow.AddText(Format("vHomepageTitle x{} y{} w{} h{}", this.incrementField(6)[2]*), Locale.Read("dictionary.homepage")) local homepageField := modWindow.AddEdit(Format("vHomepageField x{} y{} w{} h{} -Multi", this.incrementField(6)[1]*), this.data.Get("homepage")) local descriptionTitle := modWindow.AddText(Format("vDescriptionTitle x{} y{} w{} h{}", this.incrementField(7)[2]*), Locale.Read("dictionary.description")) local descriptionField := modWindow.AddEdit(Format("vDescriptionField x{} y{} w{} h{} Multi WantTab", this.incrementField(7, 10)[1]*), JSONExt.EscapeString(this.data.Get("description"), True)) titleField.OnEvent("Change", (*) => SetTitleField(titleField.Value)) versionField.OnEvent("Change", (*) => this.data.Set("version", versionField.Value)) authorField.OnEvent("Change", (*) => this.data.Set("author", authorField.Value)) typeField.OnEvent("Change", (*) => SetTypeField(typeField.Text)) homepageField.OnEvent("Change", (*) => this.data.Set("homepage", homepageField.Value)) descriptionField.OnEvent("Change", (*) => this.data.Set("description", descriptionField.Value)) local createButton := modWindow.AddButton(Format("vCreateBtn x{} y{} w{} h{}", this.btnX(1), this.btnY, this.btnW, this.btnH), Locale.Read("dictionary." (this.selectedModIsValid ? "save" : "create"))) local cancelButton := modWindow.AddButton(Format("vCancelBtn x{} y{} w{} h{}", this.btnX(2), this.btnY, this.btnW, this.btnH), Locale.Read("dictionary.cancel")) createButton.OnEvent("Click", (*) => this.Mod%this.selectedModIsValid ? "EditManifest" : "Create"%()) cancelButton.OnEvent("Click", (*) => WinExist(this.title) && WinClose(this.title)) if this.selectedModIsValid { folderField.Enabled := False } else { folderField.OnEvent("Change", (*) => SetFolderField(folderField.Value)) } return modWindow SetTitleField(value) { this.data.Set("title", titleField.Value) if !this.selectedModIsValid { local folder := ModTools.FolderToClassName(titleField.Value) if !this.changeFolderNameTriggered { folderField.Value := folder this.data.Set("folder", folder) } } return } SetFolderField(value) { this.changeFolderNameTriggered := True this.data.Set("folder", folderField.Value) return } SetTypeField(displayValue) { for key, displayText in typeFieldOptions { if (displayText = displayValue) { this.data.Set("type", key) break } } return } } Show() { if this.title != "" && WinExist(this.title) WinActivate(this.title) else { this.GUI := this.Constructor() this.GUI.Show(Format("x{} y{} w{} h{}", this.xPos, this.yPos, this.w, this.h)) } return } ModCreate() { if this.data.Get("title") = "" || this.data.Get("folder") = "" || this.data.Get("version") = "" { local fieldToBeFocused := this.data.Get("title") = "" ? "TitleField" : this.data.Get("folder") = "" ? "FolderField" : "VersionField" this.GUI[fieldToBeFocused].Focus() } else if ModTools.CreateMod(this.data, this.locales) { ModTools.SetEditable(this.data["folder"]) ModsInjector.Build(False) WinExist(this.title) && WinClose(this.title) if WinExist(ModsGUI.title) { WinClose(ModsGUI.title) SetTimer((*) => ModsGUI(), -100) } SetTimer((*) => ModTools.OpenModFolder(this.data), -150) } return } ModEditManifest() { } } }