Allow drag & drop of multiple mods or folders with Control.

This commit is contained in:
Ottermandias 2023-09-13 17:06:29 +02:00
parent 4fdb89ce62
commit d21cba4669
3 changed files with 61 additions and 9 deletions

@ -1 +1 @@
Subproject commit 86ec4d72c9c9ed57aa7be4a7d0c81069c5b94ad7 Subproject commit 9c7a3147f6e64e93074bc318a52b0723efc6ffff

View file

@ -42,7 +42,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
public ModFileSystemSelector(KeyState keyState, CommunicatorService communicator, ModFileSystem fileSystem, ModManager modManager, public ModFileSystemSelector(KeyState keyState, CommunicatorService communicator, ModFileSystem fileSystem, ModManager modManager,
CollectionManager collectionManager, Configuration config, TutorialService tutorial, FileDialogService fileDialog, ChatService chat, CollectionManager collectionManager, Configuration config, TutorialService tutorial, FileDialogService fileDialog, ChatService chat,
ModImportManager modImportManager, IDragDropManager dragDrop) ModImportManager modImportManager, IDragDropManager dragDrop)
: base(fileSystem, keyState, HandleException) : base(fileSystem, keyState, HandleException, allowMultipleSelection: true)
{ {
_communicator = communicator; _communicator = communicator;
_modManager = modManager; _modManager = modManager;
@ -179,7 +179,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
var offset = remainingSpace - requiredSize; var offset = remainingSpace - requiredSize;
if (ImGui.GetScrollMaxY() == 0) if (ImGui.GetScrollMaxY() == 0)
offset -= ImGui.GetStyle().ItemInnerSpacing.X; offset -= ImGui.GetStyle().ItemInnerSpacing.X;
if (offset > ImGui.GetStyle().ItemSpacing.X) if (offset > ImGui.GetStyle().ItemSpacing.X)
ImGui.GetWindowDrawList().AddText(new Vector2(itemPos + offset, line), ColorId.SelectorPriority.Value(), priorityString); ImGui.GetWindowDrawList().AddText(new Vector2(itemPos + offset, line), ColorId.SelectorPriority.Value(), priorityString);
} }
@ -341,7 +341,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
private void DrawHelpPopup() private void DrawHelpPopup()
{ {
ImGuiUtil.HelpPopup("ExtendedHelp", new Vector2(1000 * UiHelpers.Scale, 34.5f * ImGui.GetTextLineHeightWithSpacing()), () => ImGuiUtil.HelpPopup("ExtendedHelp", new Vector2(1000 * UiHelpers.Scale, 36.5f * ImGui.GetTextLineHeightWithSpacing()), () =>
{ {
ImGui.Dummy(Vector2.UnitY * ImGui.GetTextLineHeight()); ImGui.Dummy(Vector2.UnitY * ImGui.GetTextLineHeight());
ImGui.TextUnformatted("Mod Management"); ImGui.TextUnformatted("Mod Management");
@ -380,6 +380,10 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
indent.Pop(1); indent.Pop(1);
ImGui.BulletText( ImGui.BulletText(
"You can drag and drop mods and subfolders into existing folders. Dropping them onto mods is the same as dropping them onto the parent of the mod."); "You can drag and drop mods and subfolders into existing folders. Dropping them onto mods is the same as dropping them onto the parent of the mod.");
indent.Push();
ImGui.BulletText("You can select multiple mods and folders by holding Control while clicking them, and then drag all of them at once." );
ImGui.BulletText("Selected mods inside an also selected folder will be ignored when dragging and move inside their folder instead of directly into the target.");
indent.Pop(1);
ImGui.BulletText("Right-clicking a folder opens a context menu."); ImGui.BulletText("Right-clicking a folder opens a context menu.");
ImGui.BulletText("Right-clicking empty space allows you to expand or collapse all folders at once."); ImGui.BulletText("Right-clicking empty space allows you to expand or collapse all folders at once.");
ImGui.BulletText("Use the Filter Mods... input at the top to filter the list for mods whose name or path contain the text."); ImGui.BulletText("Use the Filter Mods... input at the top to filter the list for mods whose name or path contain the text.");
@ -471,7 +475,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
var leaf = (ModFileSystem.Leaf?)FileSystem.Root.GetAllDescendants(ISortMode<Mod>.Lexicographical) var leaf = (ModFileSystem.Leaf?)FileSystem.Root.GetAllDescendants(ISortMode<Mod>.Lexicographical)
.FirstOrDefault(l => l is ModFileSystem.Leaf m && m.Value.ModPath.FullName == _lastSelectedDirectory); .FirstOrDefault(l => l is ModFileSystem.Leaf m && m.Value.ModPath.FullName == _lastSelectedDirectory);
Select(leaf); Select(leaf, AllowMultipleSelection);
_lastSelectedDirectory = string.Empty; _lastSelectedDirectory = string.Empty;
} }

View file

@ -1,5 +1,11 @@
using System; using System;
using System.Linq;
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Plugin; using Dalamud.Plugin;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.UI.AdvancedWindow; using Penumbra.UI.AdvancedWindow;
@ -7,10 +13,10 @@ namespace Penumbra.UI.ModsTab;
public class ModPanel : IDisposable public class ModPanel : IDisposable
{ {
private readonly ModFileSystemSelector _selector; private readonly ModFileSystemSelector _selector;
private readonly ModEditWindow _editWindow; private readonly ModEditWindow _editWindow;
private readonly ModPanelHeader _header; private readonly ModPanelHeader _header;
private readonly ModPanelTabBar _tabs; private readonly ModPanelTabBar _tabs;
public ModPanel(DalamudPluginInterface pi, ModFileSystemSelector selector, ModEditWindow editWindow, ModPanelTabBar tabs) public ModPanel(DalamudPluginInterface pi, ModFileSystemSelector selector, ModEditWindow editWindow, ModPanelTabBar tabs)
{ {
@ -24,7 +30,10 @@ public class ModPanel : IDisposable
public void Draw() public void Draw()
{ {
if (!_valid) if (!_valid)
{
DrawMultiSelection();
return; return;
}
_header.Draw(); _header.Draw();
_tabs.Draw(_mod); _tabs.Draw(_mod);
@ -36,6 +45,45 @@ public class ModPanel : IDisposable
_header.Dispose(); _header.Dispose();
} }
private void DrawMultiSelection()
{
if (_selector.SelectedPaths.Count == 0)
return;
var sizeType = ImGui.GetFrameHeight();
var availableSizePercent = (ImGui.GetContentRegionAvail().X - sizeType - 4 * ImGui.GetStyle().CellPadding.X) / 100;
var sizeMods = availableSizePercent * 35;
var sizeFolders = availableSizePercent * 65;
ImGui.NewLine();
ImGui.TextUnformatted("Currently Selected Objects");
ImGui.Separator();
using var table = ImRaii.Table("mods", 3, ImGuiTableFlags.RowBg);
ImGui.TableSetupColumn("type", ImGuiTableColumnFlags.WidthFixed, sizeType);
ImGui.TableSetupColumn("mod", ImGuiTableColumnFlags.WidthFixed, sizeMods);
ImGui.TableSetupColumn("path", ImGuiTableColumnFlags.WidthFixed, sizeFolders);
var i = 0;
foreach (var (fullName, path) in _selector.SelectedPaths.Select(p => (p.FullName(), p))
.OrderBy(p => p.Item1, StringComparer.OrdinalIgnoreCase))
{
using var id = ImRaii.PushId(i++);
ImGui.TableNextColumn();
var icon = (path is ModFileSystem.Leaf ? FontAwesomeIcon.FileCircleMinus : FontAwesomeIcon.FolderMinus).ToIconString();
if (ImGuiUtil.DrawDisabledButton(icon, new Vector2(sizeType), "Remove from selection.", false, true))
_selector.RemovePathFromMultiselection(path);
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(path is ModFileSystem.Leaf l ? l.Value.Name : string.Empty);
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(fullName);
}
}
private bool _valid; private bool _valid;
private Mod _mod = null!; private Mod _mod = null!;