From 53b36f2597696ffce4de6048d190ce6b7eb60c0f Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Fri, 18 Aug 2023 17:16:38 +0200 Subject: [PATCH] Add drag & drop to texture import. --- Penumbra/Api/PenumbraApi.cs | 1 - .../AdvancedWindow/ModEditWindow.Textures.cs | 70 +++++++++++++------ Penumbra/UI/AdvancedWindow/ModEditWindow.cs | 35 +++++----- 3 files changed, 69 insertions(+), 37 deletions(-) diff --git a/Penumbra/Api/PenumbraApi.cs b/Penumbra/Api/PenumbraApi.cs index 140a928b..01078450 100644 --- a/Penumbra/Api/PenumbraApi.cs +++ b/Penumbra/Api/PenumbraApi.cs @@ -8,7 +8,6 @@ using Penumbra.Meta.Manipulations; using Penumbra.Mods; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Textures.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Textures.cs index 32cd400f..fcbb054d 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Textures.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Textures.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Numerics; @@ -37,30 +39,36 @@ private static readonly (string, string)[] SaveAsStrings = private void DrawInputChild(string label, Texture tex, Vector2 size, Vector2 imageSize) { - using var child = ImRaii.Child(label, size, true); - if (!child) - return; + using (var child = ImRaii.Child(label, size, true)) + { + if (!child) + return; - using var id = ImRaii.PushId(label); - ImGuiUtil.DrawTextButton(label, new Vector2(-1, 0), ImGui.GetColorU32(ImGuiCol.FrameBg)); - ImGui.NewLine(); + using var id = ImRaii.PushId(label); + ImGuiUtil.DrawTextButton(label, new Vector2(-1, 0), ImGui.GetColorU32(ImGuiCol.FrameBg)); + ImGui.NewLine(); - TextureDrawer.PathInputBox(_textures, tex, ref tex.TmpPath, "##input", "Import Image...", - "Can import game paths as well as your own files.", _mod!.ModPath.FullName, _fileDialog, _config.DefaultModImportPath); - if (_textureSelectCombo.Draw("##combo", - "Select the textures included in this mod on your drive or the ones they replace from the game files.", tex.Path, - _mod.ModPath.FullName.Length + 1, out var newPath) && newPath != tex.Path) - tex.Load(_textures, newPath); + TextureDrawer.PathInputBox(_textures, tex, ref tex.TmpPath, "##input", "Import Image...", + "Can import game paths as well as your own files.", _mod!.ModPath.FullName, _fileDialog, _config.DefaultModImportPath); + if (_textureSelectCombo.Draw("##combo", + "Select the textures included in this mod on your drive or the ones they replace from the game files.", tex.Path, + _mod.ModPath.FullName.Length + 1, out var newPath) + && newPath != tex.Path) + tex.Load(_textures, newPath); - if (tex == _left) - _center.DrawMatrixInputLeft(size.X); - else - _center.DrawMatrixInputRight(size.X); + if (tex == _left) + _center.DrawMatrixInputLeft(size.X); + else + _center.DrawMatrixInputRight(size.X); - ImGui.NewLine(); - using var child2 = ImRaii.Child("image"); - if (child2) - TextureDrawer.Draw(tex, imageSize); + ImGui.NewLine(); + using var child2 = ImRaii.Child("image"); + if (child2) + TextureDrawer.Draw(tex, imageSize); + } + + if (_dragDropManager.CreateImGuiTarget("TextureDragDrop", out var files, out _) && GetFirstTexture(files, out var file)) + tex.Load(_textures, file); } private void SaveAsCombo() @@ -229,6 +237,15 @@ private void DrawTextureTab() try { + _dragDropManager.CreateImGuiSource("TextureDragDrop", + m => m.Extensions.Any(e => ValidTextureExtensions.Contains(e.ToLowerInvariant())), m => + { + if (!GetFirstTexture(m.Files, out var file)) + return false; + + ImGui.TextUnformatted($"Dragging texture for editing: {Path.GetFileName(file)}"); + return true; + }); var childWidth = GetChildWidth(); var imageSize = new Vector2(childWidth.X - ImGui.GetStyle().FramePadding.X * 2); DrawInputChild("Input Texture", _left, childWidth, imageSize); @@ -259,4 +276,17 @@ private void DrawOverlayCollapseButton() ImGuiUtil.HoverTooltip(tooltip); } + + private static bool GetFirstTexture(IEnumerable files, [NotNullWhen(true)] out string? file) + { + file = files.FirstOrDefault(f => ValidTextureExtensions.Contains(Path.GetExtension(f).ToLowerInvariant())); + return file != null; + } + + private static readonly string[] ValidTextureExtensions = + { + ".png", + ".dds", + ".tex", + }; } diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.cs index 8b870937..59cf8b80 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.cs @@ -5,6 +5,7 @@ using System.Text; using Dalamud.Interface; using Dalamud.Interface.Components; +using Dalamud.Interface.DragDrop; using Dalamud.Interface.Windowing; using Dalamud.Plugin.Services; using ImGuiNET; @@ -40,6 +41,7 @@ public partial class ModEditWindow : Window, IDisposable private readonly StainService _stainService; private readonly ModMergeTab _modMergeTab; private readonly CommunicatorService _communicator; + private readonly IDragDropManager _dragDropManager; private Mod? _mod; private Vector2 _iconSize = Vector2.Zero; @@ -283,7 +285,7 @@ private void DrawDuplicatesTab() } else { - if (ImGuiUtil.DrawDisabledButton("Cancel Scanning for Duplicates", Vector2.Zero, "Cancel the current scanning operation...", false)) + if (ImGuiUtil.DrawDisabledButton("Cancel Scanning for Duplicates", Vector2.Zero, "Cancel the current scanning operation...", false)) _editor.Duplicates.Clear(); } @@ -303,14 +305,14 @@ private void DrawDuplicatesTab() new Vector2(300 * UiHelpers.Scale, ImGui.GetFrameHeight()), $"{_editor.ModNormalizer.Step} / {_editor.ModNormalizer.TotalSteps}"); } - else if(ImGuiUtil.DrawDisabledButton("Re-Duplicate and Normalize Mod", Vector2.Zero, tt, !_allowReduplicate && !modifier)) + else if (ImGuiUtil.DrawDisabledButton("Re-Duplicate and Normalize Mod", Vector2.Zero, tt, !_allowReduplicate && !modifier)) { _editor.ModNormalizer.Normalize(_mod!); _editor.ModNormalizer.Worker.ContinueWith(_ => _editor.LoadMod(_mod!, _editor.GroupIdx, _editor.OptionIdx)); } if (!_editor.Duplicates.Worker.IsCompleted) - return; + return; if (_editor.Duplicates.Duplicates.Count == 0) { @@ -521,21 +523,22 @@ private FullPath FindBestMatch(Utf8GamePath path) public ModEditWindow(PerformanceTracker performance, FileDialogService fileDialog, ItemSwapTab itemSwapTab, IDataManager gameData, Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, MetaFileManager metaFileManager, StainService stainService, ActiveCollections activeCollections, DalamudServices dalamud, ModMergeTab modMergeTab, - CommunicatorService communicator, TextureManager textures) + CommunicatorService communicator, TextureManager textures, IDragDropManager dragDropManager) : base(WindowBaseLabel) { - _performance = performance; - _itemSwapTab = itemSwapTab; - _config = config; - _editor = editor; - _metaFileManager = metaFileManager; - _stainService = stainService; - _activeCollections = activeCollections; - _dalamud = dalamud; - _modMergeTab = modMergeTab; - _communicator = communicator; - _textures = textures; - _fileDialog = fileDialog; + _performance = performance; + _itemSwapTab = itemSwapTab; + _config = config; + _editor = editor; + _metaFileManager = metaFileManager; + _stainService = stainService; + _activeCollections = activeCollections; + _dalamud = dalamud; + _modMergeTab = modMergeTab; + _communicator = communicator; + _dragDropManager = dragDropManager; + _textures = textures; + _fileDialog = fileDialog; _materialTab = new FileEditor(this, gameData, config, _fileDialog, "Materials", ".mtrl", () => _editor.Files.Mtrl, DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty, bytes => new MtrlTab(this, new MtrlFile(bytes)));