diff --git a/Penumbra/UI/ModsTab/MultiModPanel.cs b/Penumbra/UI/ModsTab/MultiModPanel.cs index 4079748e..0e9b5d39 100644 --- a/Penumbra/UI/ModsTab/MultiModPanel.cs +++ b/Penumbra/UI/ModsTab/MultiModPanel.cs @@ -4,65 +4,88 @@ using OtterGui; using OtterGui.Raii; using OtterGui.Services; +using OtterGui.Text; using Penumbra.Mods; using Penumbra.Mods.Manager; namespace Penumbra.UI.ModsTab; -public class MultiModPanel(ModFileSystemSelector _selector, ModDataEditor _editor) : IUiService +public class MultiModPanel(ModFileSystemSelector selector, ModDataEditor editor) : IUiService { public void Draw() { - if (_selector.SelectedPaths.Count == 0) + if (selector.SelectedPaths.Count == 0) return; ImGui.NewLine(); - DrawModList(); + var treeNodePos = ImGui.GetCursorPos(); + var numLeaves = DrawModList(); + DrawCounts(treeNodePos, numLeaves); DrawMultiTagger(); } - private void DrawModList() + private void DrawCounts(Vector2 treeNodePos, int numLeaves) { - using var tree = ImRaii.TreeNode("Currently Selected Objects", ImGuiTreeNodeFlags.DefaultOpen | ImGuiTreeNodeFlags.NoTreePushOnOpen); + var startPos = ImGui.GetCursorPos(); + var numFolders = selector.SelectedPaths.Count - numLeaves; + var text = (numLeaves, numFolders) switch + { + (0, 0) => string.Empty, // should not happen + (> 0, 0) => $"{numLeaves} Mods", + (0, > 0) => $"{numFolders} Folders", + _ => $"{numLeaves} Mods, {numFolders} Folders", + }; + ImGui.SetCursorPos(treeNodePos); + ImUtf8.TextRightAligned(text); + ImGui.SetCursorPos(startPos); + } + + private int DrawModList() + { + using var tree = ImUtf8.TreeNode("Currently Selected Objects###Selected"u8, + ImGuiTreeNodeFlags.DefaultOpen | ImGuiTreeNodeFlags.NoTreePushOnOpen); ImGui.Separator(); + + if (!tree) - return; + return selector.SelectedPaths.Count(l => l is ModFileSystem.Leaf); - var sizeType = ImGui.GetFrameHeight(); - var availableSizePercent = (ImGui.GetContentRegionAvail().X - sizeType - 4 * ImGui.GetStyle().CellPadding.X) / 100; + var sizeType = new Vector2(ImGui.GetFrameHeight()); + var availableSizePercent = (ImGui.GetContentRegionAvail().X - sizeType.X - 4 * ImGui.GetStyle().CellPadding.X) / 100; var sizeMods = availableSizePercent * 35; var sizeFolders = availableSizePercent * 65; - using (var table = ImRaii.Table("mods", 3, ImGuiTableFlags.RowBg)) + var leaves = 0; + using (var table = ImUtf8.Table("mods"u8, 3, ImGuiTableFlags.RowBg)) { if (!table) - return; + return selector.SelectedPaths.Count(l => l is ModFileSystem.Leaf); - ImGui.TableSetupColumn("type", ImGuiTableColumnFlags.WidthFixed, sizeType); - ImGui.TableSetupColumn("mod", ImGuiTableColumnFlags.WidthFixed, sizeMods); - ImGui.TableSetupColumn("path", ImGuiTableColumnFlags.WidthFixed, sizeFolders); + ImUtf8.TableSetupColumn("type"u8, ImGuiTableColumnFlags.WidthFixed, sizeType.X); + ImUtf8.TableSetupColumn("mod"u8, ImGuiTableColumnFlags.WidthFixed, sizeMods); + ImUtf8.TableSetupColumn("path"u8, ImGuiTableColumnFlags.WidthFixed, sizeFolders); var i = 0; - foreach (var (fullName, path) in _selector.SelectedPaths.Select(p => (p.FullName(), p)) + foreach (var (fullName, path) in selector.SelectedPaths.Select(p => (p.FullName(), p)) .OrderBy(p => p.Item1, StringComparer.OrdinalIgnoreCase)) { using var id = ImRaii.PushId(i++); + var (icon, text) = path is ModFileSystem.Leaf l + ? (FontAwesomeIcon.FileCircleMinus, l.Value.Name.Text) + : (FontAwesomeIcon.FolderMinus, string.Empty); 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); + if (ImUtf8.IconButton(icon, "Remove from selection."u8, sizeType)) + 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); + ImUtf8.DrawFrameColumn(text); + ImUtf8.DrawFrameColumn(fullName); + if (path is ModFileSystem.Leaf) + ++leaves; } } ImGui.Separator(); + return leaves; } private string _tag = string.Empty; @@ -72,11 +95,10 @@ private void DrawModList() private void DrawMultiTagger() { var width = ImGuiHelpers.ScaledVector2(150, 0); - ImGui.AlignTextToFramePadding(); - ImGui.TextUnformatted("Multi Tagger:"); + ImUtf8.TextFrameAligned("Multi Tagger:"u8); ImGui.SameLine(); ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 2 * (width.X + ImGui.GetStyle().ItemSpacing.X)); - ImGui.InputTextWithHint("##tag", "Local Tag Name...", ref _tag, 128); + ImUtf8.InputText("##tag"u8, ref _tag, "Local Tag Name..."u8); UpdateTagCache(); var label = _addMods.Count > 0 @@ -88,9 +110,9 @@ private void DrawMultiTagger() : $"All mods selected already contain the tag \"{_tag}\", either locally or as mod data." : $"Add the tag \"{_tag}\" to {_addMods.Count} mods as a local tag:\n\n\t{string.Join("\n\t", _addMods.Select(m => m.Name.Text))}"; ImGui.SameLine(); - if (ImGuiUtil.DrawDisabledButton(label, width, tooltip, _addMods.Count == 0)) + if (ImUtf8.ButtonEx(label, tooltip, width, _addMods.Count == 0)) foreach (var mod in _addMods) - _editor.ChangeLocalTag(mod, mod.LocalTags.Count, _tag); + editor.ChangeLocalTag(mod, mod.LocalTags.Count, _tag); label = _removeMods.Count > 0 ? $"Remove from {_removeMods.Count} Mods" @@ -101,9 +123,9 @@ private void DrawMultiTagger() : $"No selected mod contains the tag \"{_tag}\" locally." : $"Remove the local tag \"{_tag}\" from {_removeMods.Count} mods:\n\n\t{string.Join("\n\t", _removeMods.Select(m => m.Item1.Name.Text))}"; ImGui.SameLine(); - if (ImGuiUtil.DrawDisabledButton(label, width, tooltip, _removeMods.Count == 0)) + if (ImUtf8.ButtonEx(label, tooltip, width, _removeMods.Count == 0)) foreach (var (mod, index) in _removeMods) - _editor.ChangeLocalTag(mod, index, string.Empty); + editor.ChangeLocalTag(mod, index, string.Empty); ImGui.Separator(); } @@ -114,7 +136,7 @@ private void UpdateTagCache() if (_tag.Length == 0) return; - foreach (var leaf in _selector.SelectedPaths.OfType()) + foreach (var leaf in selector.SelectedPaths.OfType()) { var index = leaf.Value.LocalTags.IndexOf(_tag); if (index >= 0)