diff --git a/PCK-Studio/Forms/Editor/ANIMEditor.cs b/PCK-Studio/Forms/Editor/ANIMEditor.cs index b6070f79..38f0f868 100644 --- a/PCK-Studio/Forms/Editor/ANIMEditor.cs +++ b/PCK-Studio/Forms/Editor/ANIMEditor.cs @@ -363,7 +363,7 @@ namespace PckStudio.Forms.Editor if (diag.ShowDialog(this) != DialogResult.OK) return; - SkinANIM templateANIM = SkinANIM.Empty.SetMask(Templates[diag.SelectedItem]); + SkinANIM templateANIM = Templates[diag.SelectedItem]; DialogResult prompt = MessageBox.Show(this, "Would you like to add this preset's effects to your current ANIM? Otherwise all of your effects will be cleared. Either choice can be undone by pressing \"Restore ANIM\".", "", MessageBoxButtons.YesNo); if (prompt == DialogResult.Yes) templateANIM |= ruleset.Value; diff --git a/PCK-Studio/Internal/Skin/SkinANIM.cs b/PCK-Studio/Internal/Skin/SkinANIM.cs index 69a21979..455f5a76 100644 --- a/PCK-Studio/Internal/Skin/SkinANIM.cs +++ b/PCK-Studio/Internal/Skin/SkinANIM.cs @@ -111,10 +111,5 @@ namespace PckStudio.Internal.Skin { return MemberwiseClone(); } - - internal SkinANIM SetMask(SkinAnimMask skinAnimMask) - { - return new SkinANIM(skinAnimMask); - } } } diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs index 39f7b3e1..7ca8410e 100644 --- a/PCK-Studio/MainForm.cs +++ b/PCK-Studio/MainForm.cs @@ -1291,37 +1291,30 @@ namespace PckStudio if ((node.TryGetTagData(out PckAsset asset) && currentPCK.Contains(asset.Filename, asset.Type)) || node.Parent is TreeNode) { - treeViewMain.DoDragDrop(node, DragDropEffects.Move); - } - } + // TODO: add (mouse) scrolling while dragging item(s) + treeViewMain.DoDragDrop(node, DragDropEffects.Scroll | DragDropEffects.Move); + } + } - private void treeViewMain_DragOver(object sender, DragEventArgs e) + private void treeViewMain_DragOver(object sender, DragEventArgs e) { Point dragLocation = new Point(e.X, e.Y); TreeNode node = treeViewMain.GetNodeAt(treeViewMain.PointToClient(dragLocation)); treeViewMain.SelectedNode = node.IsTagOfType() ? null : node; - } + } private void treeViewMain_DragEnter(object sender, DragEventArgs e) { e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : e.AllowedEffect; - } + BringToFront(); + FocusMe(); + treeViewMain.Focus(); + } private void treeViewMain_DragDrop(object sender, DragEventArgs e) { - if (e.Data.GetDataPresent(DataFormats.FileDrop) && e.Data.GetData(DataFormats.FileDrop) is string[] files) - { - ImportFiles(files); - return; - } - - string dataFormat = typeof(TreeNode).FullName; - - if (!e.Data.GetDataPresent(dataFormat)) - return; - - // Retrieve the client coordinates of the drop location. - Point dragLocation = new Point(e.X, e.Y); + // Retrieve the client coordinates of the drop location. + Point dragLocation = new Point(e.X, e.Y); Point targetPoint = treeViewMain.PointToClient(dragLocation); if (!treeViewMain.ClientRectangle.Contains(targetPoint)) @@ -1329,9 +1322,30 @@ namespace PckStudio // Retrieve the node at the drop location. TreeNode targetNode = treeViewMain.GetNodeAt(targetPoint); + + if (e.Data.GetDataPresent(DataFormats.FileDrop) && e.Data.GetData(DataFormats.FileDrop) is string[] filesDropped) + { + IEnumerable files = filesDropped.Where(File.Exists); + IEnumerable directoryFiles = filesDropped + .Where(f => (File.GetAttributes(f) & FileAttributes.Directory) != 0) + .SelectMany(dir => Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories)); + + string baseDirectory = Path.GetDirectoryName(filesDropped.First()); + + IEnumerable importPaths = files.Concat(directoryFiles); + + ImportFiles(baseDirectory, importPaths, string.IsNullOrWhiteSpace(targetNode?.FullPath) ? string.Empty : targetNode?.FullPath); + return; + } + + string dataFormat = typeof(TreeNode).FullName; + if (targetNode is null) return; + if (!e.Data.GetDataPresent(dataFormat)) + return; + bool isTargetPckFile = targetNode.IsTagOfType(); TreeNode draggedNode = e.Data.GetData(dataFormat) as TreeNode; if (draggedNode == null) @@ -1411,33 +1425,79 @@ namespace PckStudio return childNodes; } - - private void ImportFiles(string[] files) + private void ImportFiles(string baseDirectory, IEnumerable files, string prefix) { + int fileCount = files.Count(); int addedCount = 0; + int skippedFiles = 0; + int skipAttempts = 3; + int typeDuplication = 0; + PckAssetType lastSelectedAssetType = PckAssetType.SkinFile; + bool askForAssetType = true; foreach (var filepath in files) { - using AddFilePrompt addFile = new AddFilePrompt(Path.GetFileName(filepath)); - if (addFile.ShowDialog(this) != DialogResult.OK) - continue; + string assetPath = Path.Combine(prefix + filepath.Substring(baseDirectory.Length)).TrimStart('/', '\\'); + PckAssetType assetType = lastSelectedAssetType; - if (currentPCK.Contains(addFile.Filepath, addFile.Filetype)) + if (askForAssetType) + { + using AddFilePrompt addFile = new AddFilePrompt(assetPath); + if (addFile.ShowDialog(this) != DialogResult.OK) + { + skippedFiles++; + skipAttempts--; + if (skipAttempts > 0) + continue; + + int remainingFileCount = fileCount - addedCount - skippedFiles; + DialogResult abortFurtherImport = MessageBox.Show($"Do you wan't to abort further file imports?\n{remainingFileCount} file(s) left.", "Abort further import", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); + if (abortFurtherImport == DialogResult.Yes) + { + skippedFiles += remainingFileCount; + break; + } + skipAttempts = 3; + continue; + } + + assetType = addFile.Filetype; + assetPath = addFile.Filepath; + + if (lastSelectedAssetType == assetType) + typeDuplication++; + lastSelectedAssetType = addFile.Filetype; + if (typeDuplication > 1) + { + DialogResult useSameTypeForRest = MessageBox.Show($"Do you want to import all remaining files as {lastSelectedAssetType}?", "Import all as", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); + if (useSameTypeForRest == DialogResult.Yes) + { + askForAssetType = false; + } + } + } + + if (currentPCK.Contains(filepath, assetType)) { - MessageBox.Show(this, $"'{addFile.Filepath}' of type {addFile.Filetype} already exists.\nSkiping file.", "File already exists", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1); + if (askForAssetType) + MessageBox.Show(this, $"'{assetPath}' of type {assetType} already exists.\nSkiping file.", "File already exists", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1); + Debug.WriteLine($"'{assetPath}' of type {assetType} already exists.\nSkiping file."); continue; } - PckAsset importedAsset = currentPCK.CreateNewAsset(addFile.Filepath, addFile.Filetype, () => File.ReadAllBytes(filepath)); + PckAsset importedAsset = currentPCK.CreateNewAsset(assetPath, assetType, () => File.ReadAllBytes(filepath)); string propertyFile = filepath + ".txt"; if (File.Exists(propertyFile)) { importedAsset.DeserializeProperties(File.ReadAllLines(propertyFile)); } addedCount++; - - BuildMainTreeView(); - wasModified = true; } - Trace.TraceInformation("[{0}] Imported {1} file(s).", nameof(ImportFiles), addedCount); + Trace.TraceInformation("[{0}] Imported {1} file(s).", nameof(ImportFiles), addedCount); + Trace.TraceInformation("[{0}] Skipped {1} file(s).", nameof(ImportFiles), skippedFiles); + if (addedCount > 0) + { + wasModified = true; + BuildMainTreeView(); + } } #endregion @@ -1516,9 +1576,8 @@ namespace PckStudio if (namePrompt.ShowDialog(this) == DialogResult.OK) { currentPCK = InitializePack(new Random().Next(8000, int.MaxValue), 0, namePrompt.NewText, true); - isTemplateFile = true; - wasModified = true; - LoadEditorTab(); + MarkTemplateFile(); + LoadEditorTab(); } } @@ -1527,27 +1586,32 @@ namespace PckStudio CheckSaveState(); CreateTexturePackPrompt packPrompt = new CreateTexturePackPrompt(); if (packPrompt.ShowDialog(this) == DialogResult.OK) - { - currentPCK = InitializeTexturePack(new Random().Next(8000, int.MaxValue), 0, packPrompt.PackName, packPrompt.PackRes, packPrompt.CreateSkinsPck); - isTemplateFile = true; - wasModified = true; - LoadEditorTab(); - } - } + { + currentPCK = InitializeTexturePack(new Random().Next(8000, int.MaxValue), 0, packPrompt.PackName, packPrompt.PackRes, packPrompt.CreateSkinsPck); + MarkTemplateFile(); + LoadEditorTab(); + } + } - private void mashUpPackToolStripMenuItem_Click(object sender, EventArgs e) + private void mashUpPackToolStripMenuItem_Click(object sender, EventArgs e) { CheckSaveState(); CreateTexturePackPrompt packPrompt = new CreateTexturePackPrompt(); if (packPrompt.ShowDialog(this) == DialogResult.OK) { currentPCK = InitializeMashUpPack(new Random().Next(8000, int.MaxValue), 0, packPrompt.PackName, packPrompt.PackRes); - isTemplateFile = true; - wasModified = false; - LoadEditorTab(); + MarkTemplateFile(); + LoadEditorTab(); } } + private void MarkTemplateFile() + { + isTemplateFile = true; + wasModified = true; + saveLocation = string.Empty; + } + private void quickChangeToolStripMenuItem_Click(object sender, EventArgs e) { using AdvancedOptions advanced = new AdvancedOptions(currentPCK); @@ -1894,6 +1958,8 @@ namespace PckStudio { if (!string.IsNullOrEmpty(saveLocation)) Save(saveLocation); + if (string.IsNullOrWhiteSpace(saveLocation) || isTemplateFile) + SaveTemplate(); } private void saveAsPCK(object sender, EventArgs e)