private void Signal_ExportProject(string dir) { var validationErrors = DoValidation(); if (validationErrors.Count > 0) { string str = "The following errors were found when validating your project:\n\n"; foreach (var error in validationErrors) { str += error + "\n"; } var popup = GetNode <AcceptDialog>("ProjectValidationErrorsDialog"); popup.DialogText = str; popup.PopupCenteredClamped(); return; } GD.Print("Exporting..."); string path = System.IO.Path.Combine(dir, ModProject.Name); if (System.IO.Directory.Exists(path)) { System.IO.Directory.Delete(path, true); } System.IO.Directory.CreateDirectory(path); foreach (var mod in ModProject.Mods) { GD.Print("Exporting for " + mod.ContentPackFor); var controller = ContentPackController.GetControllerForMod(mod.ContentPackFor); controller.OnExport(this, mod, path); } }
private void Signal_NewModMenuActivated(int index) { var controller = ContentPackController.GetControllerForMod(ContentPackController.GetRegisteredControllerTypes()[index]); var mod = ProjectTree.CreateItem(ProjectRoot); mod.SetText(0, $"[{controller.ModAbbreviation}] {ModProject.Name}"); mod.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this mod"); mod.SetMeta(Meta.CorrespondingController, controller.ModUniqueId); ModProject.Mods.Add(controller.OnModCreated(this, mod)); }
private void Signal_ProjectNameEdited(string str) { ModProject.Name = str; ProjectRoot.SetText(0, $"{str} {ModProject.Version}"); for (var child = ProjectRoot.GetChildren(); child != null; child = child.GetNext()) { if (child.GetText(0).BeginsWith("[")) { var controller = ContentPackController.GetControllerForMod((string)child.GetMeta(Meta.CorrespondingController)); child.SetText(0, $"[{controller.ModAbbreviation}] {str}"); } } }
private void ClearMainEditingArea() { for (int i = 0; i < MainEditingArea.GetChildCount(); ++i) { var child = MainEditingArea.GetChild(i); if (child.HasMeta(Meta.CorrespondingController)) { var controller = ContentPackController.GetControllerForMod((string)child.GetMeta(Meta.CorrespondingController)); var data = ModProject.Mods.Find(md => md.ContentPackFor == controller.ModUniqueId); controller.OnEditingAreaChanged(this, data, child); } child.QueueFree(); } }
private void Signal_TreeButtonPressed(TreeItem item, int column, int id) { if (id == REMOVE_BUTTON_INDEX) { pendingRemoval = item; var confirm = GetNode <ConfirmationDialog>("PendingRemovalDialog"); confirm.PopupCenteredClamped(); } else if (id == ADD_BUTTON_INDEX) { if (item == depsRoot) { Dependency dep; ModProject.Dependencies.Add(dep = new Dependency() { UniqueID = "mod.id" }); var depItem = ProjectTree.CreateItem(depsRoot); depItem.SetText(0, dep.UniqueID); depItem.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this dependency"); deps.Add(depItem, dep); } else if (item == updateKeysRoot) { UpdateKey updateKey; ModProject.UpdateKeys.Add(updateKey = new UpdateKey() { Platform = "Nexus" }); var updateKeyItem = ProjectTree.CreateItem(updateKeysRoot); updateKeyItem.SetText(0, "Nexus:"); updateKeyItem.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this update key"); updateKeys.Add(updateKeyItem, updateKey); } else if (item == resourcesRoot) { var import = GetNode <FileDialog>("ResourceImportDialog"); import.PopupCenteredClamped(); } else if (item.GetMeta(Meta.CorrespondingController) != null) { var controller = ContentPackController.GetControllerForMod((string)item.GetParent().GetMeta(Meta.CorrespondingController)); var data = ModProject.Mods.Find(md => md.ContentPackFor == controller.ModUniqueId); controller.OnAdded(this, data, item); } } }
private List <string> DoValidation() { GD.Print("Validating..."); var ret = new List <string>(); if (string.IsNullOrEmpty(ModProject.UniqueId) || !idRegex.IsMatch(ModProject.UniqueId)) { ret.Add("Invalid project unique ID"); } if (string.IsNullOrEmpty(ModProject.Version) || !semVerRegex.IsMatch(ModProject.Version)) { ret.Add("Invalid project version"); } foreach (var dep in ModProject.Dependencies) { if (string.IsNullOrEmpty(dep.UniqueID) || !idRegex.IsMatch(dep.UniqueID)) { ret.Add("Invalid dependency unique ID: " + dep.UniqueID); } if (!string.IsNullOrEmpty(dep.MinimumVersion) && !semVerRegex.IsMatch(dep.MinimumVersion)) { ret.Add($"Invalid dependency version for dependency {dep.UniqueID}: {dep.MinimumVersion}"); } } foreach (var key in ModProject.UpdateKeys) { if (key.Platform != "GitHub" && !int.TryParse(key.Id, out int _)) { ret.Add($"Update key for {key.Platform} must be an integer."); } } foreach (var mod in ModProject.Mods) { GD.Print("Validating for " + mod.ContentPackFor); var controller = ContentPackController.GetControllerForMod(mod.ContentPackFor); var errors = new List <string>(); controller.OnValidate(this, mod, errors); ret.AddRange(errors); } return(ret); }
private void Signal_TreeItemEdited() { var edited = ProjectTree.GetSelected(); if (edited.GetParent() == resourcesRoot) { var oldFilename = resourcesNames[edited]; string newFilename = edited.GetText(0); justRenamedInUi = newFilename; System.IO.File.Move(System.IO.Path.Combine(ModProjectDir, oldFilename), System.IO.Path.Combine(ModProjectDir, newFilename)); resourcesNames[edited] = newFilename; foreach (var mod in ModProject.Mods) { var controller = ContentPackController.GetControllerForMod(mod.ContentPackFor); controller.OnResourceRenamed(this, mod, oldFilename, newFilename); } } }
private void SaveProject() { string path = System.IO.Path.Combine(ModProjectDir, "project.stardeweditor"); GD.Print("Saving to " + path); JsonSerializerSettings settings = new JsonSerializerSettings() { Formatting = Formatting.Indented, TypeNameHandling = TypeNameHandling.Objects, }; System.IO.File.WriteAllText(path, JsonConvert.SerializeObject(ModProject, settings)); foreach (var mod in ModProject.Mods) { var controller = ContentPackController.GetControllerForMod(mod.ContentPackFor); controller.OnSave(this, mod); } }
private void Signal_PendingRemovalConfirm() { if (pendingRemoval.GetParent() == depsRoot) { ModProject.Dependencies.Remove(deps[pendingRemoval]); deps.Remove(pendingRemoval); } else if (pendingRemoval.GetParent() == updateKeysRoot) { ModProject.UpdateKeys.Remove(updateKeys[pendingRemoval]); updateKeys.Remove(pendingRemoval); } else if (pendingRemoval.GetParent() == resourcesRoot) { string filename = resourcesNames[pendingRemoval]; System.IO.File.Delete(System.IO.Path.Combine(ModProjectDir, filename)); foreach (var mod in ModProject.Mods) { var controller = ContentPackController.GetControllerForMod(mod.ContentPackFor); controller.OnResourceDeleted(this, mod, filename); } } else if (pendingRemoval.GetMeta(Meta.CorrespondingController) != null) { var controller = ContentPackController.GetControllerForMod((string)pendingRemoval.GetMeta(Meta.CorrespondingController)); var data = ModProject.Mods.Find(md => md.ContentPackFor == controller.ModUniqueId); if (pendingRemoval.GetParent() == ProjectRoot) { ModProject.Mods.Remove(data); } else { controller.OnRemoved(this, data, pendingRemoval); } } pendingRemoval.GetParent().RemoveChild(pendingRemoval); }
private void Signal_TreeCellActivated() { var sel = ProjectTree.GetSelected(); Node newArea = null; if (sel == ProjectRoot) { var editor = ProjectEditor.Instance(); var lineEdit = editor.GetNode <LineEdit>("Name/LineEdit"); lineEdit.Text = ModProject.Name; lineEdit.Connect("text_changed", this, nameof(Signal_ProjectNameEdited)); lineEdit = editor.GetNode <LineEdit>("Description/LineEdit"); lineEdit.Text = ModProject.Description; lineEdit.Connect("text_changed", this, nameof(Signal_ProjectDescriptionEdited)); lineEdit = editor.GetNode <LineEdit>("UniqueId/LineEdit"); lineEdit.Text = ModProject.UniqueId; lineEdit.Connect("text_changed", this, nameof(Signal_ProjectUniqueIdEdited)); lineEdit = editor.GetNode <LineEdit>("Version/LineEdit"); lineEdit.Text = ModProject.Version; lineEdit.Connect("text_changed", this, nameof(Signal_ProjectVersionEdited)); lineEdit = editor.GetNode <LineEdit>("Author/LineEdit"); lineEdit.Text = ModProject.Author; lineEdit.Connect("text_changed", this, nameof(Signal_ProjectAuthorEdited)); newArea = editor; } else if (sel.GetParent() == depsRoot) { activeDep = sel; var dep = deps[sel]; var editor = DependencyEditor.Instance(); var lineEdit = editor.GetNode <LineEdit>("Id/LineEdit"); lineEdit.Text = dep.UniqueID; lineEdit.Connect("text_changed", this, nameof(Signal_DependencyIdEdited)); var checkBox = editor.GetNode <CheckBox>("Required/CheckBox"); checkBox.Pressed = dep.IsRequired; checkBox.Connect("toggled", this, nameof(Signal_DependencyRequiredToggled)); lineEdit = editor.GetNode <LineEdit>("MinimumVersion/LineEdit"); lineEdit.Text = dep.MinimumVersion; lineEdit.Connect("text_changed", this, nameof(Signal_DependencyMinimumVersionEdited)); newArea = editor; } else if (sel.GetParent() == updateKeysRoot) { activeUpdateKey = sel; var updateKey = updateKeys[sel]; var editor = UpdateKeyEditor.Instance(); var optionButton = editor.GetNode <OptionButton>("Platform/OptionButton"); int selInd = 0; for (int i = 0; i < optionButton.GetItemCount(); ++i) { if (optionButton.GetItemText(i) == updateKey.Platform) { selInd = i; break; } } optionButton.Selected = selInd; optionButton.Connect("item_selected", this, nameof(Signal_UpdateKeyPlatformEdited)); var lineEdit = editor.GetNode <LineEdit>("Id/LineEdit"); lineEdit.Text = updateKey.Id; lineEdit.Connect("text_changed", this, nameof(Signal_UpdateKeyIdEdited)); newArea = editor; } else if (sel.HasMeta(Meta.CorrespondingController)) { var controller = ContentPackController.GetControllerForMod((string)sel.GetMeta(Meta.CorrespondingController)); var data = ModProject.Mods.Find(md => md.ContentPackFor == controller.ModUniqueId); newArea = controller.CreateMainEditingArea(this, data, sel); } if (newArea != null) { ClearMainEditingArea(); MainEditingArea.AddChild(newArea); } }
public override void _Ready() { EditIcon = GD.Load <Texture>("res://res/icons/edit.png"); AddIcon = GD.Load <Texture>("res://res/icons/add.png"); RemoveIcon = GD.Load <Texture>("res://res/icons/remove.png"); ProjectEditor = GD.Load <PackedScene>("res://ProjectEditor.tscn"); DependencyEditor = GD.Load <PackedScene>("res://DependencyEditor.tscn"); UpdateKeyEditor = GD.Load <PackedScene>("res://UpdateKeyEditor.tscn"); fileMenu = GetNode <MenuButton>("MenuSeparator/MenuPanel/Menu/File"); var filePopup = fileMenu.GetPopup(); filePopup.Connect("index_pressed", this, nameof(Signal_FileMenuActivated)); filePopup.AddItem("New project..."); newModMenu = new PopupMenu() { Name = "NewMod" }; newModMenu.Connect("index_pressed", this, nameof(Signal_NewModMenuActivated)); foreach (var controllerId in ContentPackController.GetRegisteredControllerTypes()) { var controller = ContentPackController.GetControllerForMod(controllerId); newModMenu.AddItem(controller.ModName); } filePopup.AddChild(newModMenu); filePopup.AddSubmenuItem("New content pack...", "NewMod"); filePopup.SetItemDisabled(1, true); filePopup.AddSeparator(); filePopup.AddItem("Save"); var keyHelper = new InputEventKey() { Scancode = (uint)KeyList.S, Control = true, }; filePopup.SetItemAccelerator(3, keyHelper.GetScancodeWithModifiers()); filePopup.SetItemDisabled(3, true); filePopup.AddItem("Open"); keyHelper.Scancode = (uint)KeyList.O; filePopup.SetItemAccelerator(4, keyHelper.GetScancodeWithModifiers()); filePopup.AddSeparator(); filePopup.AddItem("Export"); keyHelper.Scancode = (uint)KeyList.E; filePopup.SetItemAccelerator(6, keyHelper.GetScancodeWithModifiers()); filePopup.SetItemDisabled(6, true); filePopup.AddItem("Import"); keyHelper.Scancode = (uint)KeyList.I; filePopup.SetItemAccelerator(7, keyHelper.GetScancodeWithModifiers()); filePopup.SetItemDisabled(7, true); ProjectTree = GetNode <Tree>("MenuSeparator/Splitter/Left/ProjectTree"); ProjectTree.Connect("button_pressed", this, nameof(Signal_TreeButtonPressed)); ProjectTree.Connect("item_activated", this, nameof(Signal_TreeCellActivated)); ProjectTree.Connect("item_edited", this, nameof(Signal_TreeItemEdited)); MainEditingArea = GetNode <Container>("MenuSeparator/Splitter/Main/PanelContainer"); var confirm = GetNode <ConfirmationDialog>("ConfirmNewProjectDialog"); confirm.Connect("confirmed", this, nameof(Signal_CreateNewProject_Pre)); var confirm2 = GetNode <ConfirmationDialog>("ConfirmOpenProjectDialog"); confirm2.Connect("confirmed", this, nameof(Signal_OpenProject_Pre)); var removal = GetNode <ConfirmationDialog>("PendingRemovalDialog"); removal.Connect("confirmed", this, nameof(Signal_PendingRemovalConfirm)); var createDir = GetNode <FileDialog>("NewProjectDirectoryDialog"); createDir.Connect("dir_selected", this, nameof(Signal_CreateNewProject_SelectedDirectory)); var open = GetNode <FileDialog>("OpenProjectDialog"); open.Connect("file_selected", this, nameof(Signal_OpenProject)); var import = GetNode <FileDialog>("ResourceImportDialog"); import.Connect("files_selected", this, nameof(Signal_ResourceImport_Multiple)); var export = GetNode <FileDialog>("ExportProjectDialog"); export.Connect("dir_selected", this, nameof(Signal_ExportProject)); var importPack = GetNode <FileDialog>("ImportPackDialog"); importPack.Connect("file_selected", this, nameof(Signal_ImportPack)); }
private void Signal_ImportPack(string file) { var manifest = JsonConvert.DeserializeObject <ExportManifest>(System.IO.File.ReadAllText(file)); ContentPackController matchingController = null; foreach (var controller in ContentPackController.GetRegisteredControllerTypes()) { if (controller == manifest.ContentPackFor.UniqueID) { matchingController = ContentPackController.GetControllerForMod(manifest.ContentPackFor.UniqueID); } } if (matchingController == null) { GetNode <AcceptDialog>("UnsupportedPackTypeDialog").PopupCenteredClamped(); return; } foreach (var updateKey in manifest.UpdateKeys) { int colon = updateKey.IndexOf(':'); string keyPlatform = updateKey.Substring(0, colon); string keyId = updateKey.Substring(colon + 1); if (ModProject.UpdateKeys.Find(uk => uk.Platform == keyPlatform) == null) { var uk = new UpdateKey() { Platform = keyPlatform, Id = keyId }; ModProject.UpdateKeys.Add(uk); var updateKeyItem = ProjectTree.CreateItem(updateKeysRoot); updateKeyItem.SetText(0, updateKey); updateKeyItem.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this update key"); updateKeys.Add(updateKeyItem, uk); } } foreach (var dep in manifest.Dependencies) { if (ModProject.Dependencies.Find(d => d.UniqueID == dep.UniqueID) == null) { ModProject.Dependencies.Add(dep); var depItem = ProjectTree.CreateItem(depsRoot); depItem.SetText(0, dep.UniqueID); depItem.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this dependency"); deps.Add(depItem, dep); } } var existingMod = ModProject.Mods.Find(md => md.ContentPackFor == matchingController.ModUniqueId); if (existingMod == null) { var mod = ProjectTree.CreateItem(ProjectRoot); mod.SetText(0, $"[{matchingController.ModAbbreviation}] {ModProject.Name}"); mod.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this mod"); mod.SetMeta(Meta.CorrespondingController, matchingController.ModUniqueId); ModProject.Mods.Add(existingMod = matchingController.OnModCreated(this, mod)); } matchingController.OnImport(this, existingMod, System.IO.Path.GetDirectoryName(file)); }
private void Signal_OpenProject(string path) { string json = System.IO.File.ReadAllText(path); var verCheck = JsonConvert.DeserializeObject <VersionCheck>(json); if (verCheck.FormatVersion != Project.LATEST_VERSION) { GD.Print($"Bad version {verCheck.FormatVersion}, expected {Project.LATEST_VERSION}."); return; } GD.Print("Opening " + path); JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Objects, }; ModProjectDir = System.IO.Path.GetDirectoryName(path); ModProject = JsonConvert.DeserializeObject <Project>(json, settings); CreateNewProject(loading: true); ProjectRoot.SetText(0, $"{ModProject.Name} {ModProject.Version}"); foreach (var dep in ModProject.Dependencies) { GD.Print($"Dependency: {dep.UniqueID}"); var depItem = ProjectTree.CreateItem(depsRoot); depItem.SetText(0, $"{dep.UniqueID} {dep.MinimumVersion}"); depItem.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this dependency"); deps.Add(depItem, dep); } foreach (var updateKey in ModProject.UpdateKeys) { GD.Print($"Update key: {updateKey.Platform}"); var updateKeyItem = ProjectTree.CreateItem(updateKeysRoot); updateKeyItem.SetText(0, $"{updateKey.Platform}:{updateKey.Id}"); updateKeyItem.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this update key"); updateKeys.Add(updateKeyItem, updateKey); } foreach (var mod in ModProject.Mods) { GD.Print($"Mod: {mod.ContentPackFor}"); var controller = ContentPackController.GetControllerForMod(mod.ContentPackFor); var modItem = ProjectTree.CreateItem(ProjectRoot); modItem.SetText(0, $"[{controller.ModAbbreviation}] {ModProject.Name}"); modItem.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Remove this mod"); modItem.SetMeta(Meta.CorrespondingController, controller.ModUniqueId); controller.OnLoad(this, mod, modItem); } foreach (var filename_ in System.IO.Directory.GetFiles(ModProjectDir)) { var filename = System.IO.Path.GetFileName(filename_); var ext = System.IO.Path.GetExtension(filename); if (ext == ".png" || ext == ".tbin" || ext == ".tmx" || ext == ".json" || ext == ".xnb") { var resItem = ProjectTree.CreateItem(resourcesRoot); resItem.SetText(0, filename); resItem.SetEditable(0, true); resItem.AddButton(0, RemoveIcon, REMOVE_BUTTON_INDEX, tooltip: "Delete this resource"); resourcesNames.Add(resItem, filename); } } InitFileSystemWatcher(); }