mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add predefined tags to the multi mod selector.
This commit is contained in:
parent
24cbc6c5e1
commit
8304579d29
4 changed files with 132 additions and 13 deletions
|
|
@ -30,7 +30,7 @@ public class ModPanelDescriptionTab(
|
|||
ImGui.Dummy(ImGuiHelpers.ScaledVector2(2));
|
||||
|
||||
ImGui.Dummy(ImGuiHelpers.ScaledVector2(2));
|
||||
var (predefinedTagsEnabled, predefinedTagButtonOffset) = predefinedTagsConfig.Count > 0
|
||||
var (predefinedTagsEnabled, predefinedTagButtonOffset) = predefinedTagsConfig.Enabled
|
||||
? (true, ImGui.GetFrameHeight() + ImGui.GetStyle().WindowPadding.X + (ImGui.GetScrollMaxY() > 0 ? ImGui.GetStyle().ScrollbarSize : 0))
|
||||
: (false, 0);
|
||||
var tagIdx = _localTags.Draw("Local Tags: ",
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class ModPanelEditTab(
|
|||
FeatureChecker.DrawFeatureFlagInput(modManager.DataEditor, _mod, UiHelpers.InputTextWidth.X);
|
||||
|
||||
UiHelpers.DefaultLineSpace();
|
||||
var sharedTagsEnabled = predefinedTagManager.Count > 0;
|
||||
var sharedTagsEnabled = predefinedTagManager.Enabled;
|
||||
var sharedTagButtonOffset = sharedTagsEnabled ? ImGui.GetFrameHeight() + ImGui.GetStyle().FramePadding.X : 0;
|
||||
var tagIdx = _modTags.Draw("Mod Tags: ", "Edit tags by clicking them, or add new tags. Empty tags are removed.", _mod.ModTags,
|
||||
out var editedTag, rightEndOffset: sharedTagButtonOffset);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Dalamud.Bindings.ImGui;
|
|||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility;
|
||||
using OtterGui.Extensions;
|
||||
using OtterGui.Filesystem;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
|
|
@ -10,7 +11,7 @@ using Penumbra.Mods.Manager;
|
|||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
public class MultiModPanel(ModFileSystemSelector selector, ModDataEditor editor) : IUiService
|
||||
public class MultiModPanel(ModFileSystemSelector selector, ModDataEditor editor, PredefinedTagManager tagManager) : IUiService
|
||||
{
|
||||
public void Draw()
|
||||
{
|
||||
|
|
@ -97,7 +98,12 @@ public class MultiModPanel(ModFileSystemSelector selector, ModDataEditor editor)
|
|||
var width = ImGuiHelpers.ScaledVector2(150, 0);
|
||||
ImUtf8.TextFrameAligned("Multi Tagger:"u8);
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 2 * (width.X + ImGui.GetStyle().ItemSpacing.X));
|
||||
|
||||
var predefinedTagsEnabled = tagManager.Enabled;
|
||||
var inputWidth = predefinedTagsEnabled
|
||||
? ImGui.GetContentRegionAvail().X - 2 * width.X - 3 * ImGui.GetStyle().ItemInnerSpacing.X - ImGui.GetFrameHeight()
|
||||
: ImGui.GetContentRegionAvail().X - 2 * (width.X + ImGui.GetStyle().ItemInnerSpacing.X);
|
||||
ImGui.SetNextItemWidth(inputWidth);
|
||||
ImUtf8.InputText("##tag"u8, ref _tag, "Local Tag Name..."u8);
|
||||
|
||||
UpdateTagCache();
|
||||
|
|
@ -109,7 +115,7 @@ public class MultiModPanel(ModFileSystemSelector selector, ModDataEditor editor)
|
|||
? "No tag specified."
|
||||
: $"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();
|
||||
ImUtf8.SameLineInner();
|
||||
if (ImUtf8.ButtonEx(label, tooltip, width, _addMods.Count == 0))
|
||||
foreach (var mod in _addMods)
|
||||
editor.ChangeLocalTag(mod, mod.LocalTags.Count, _tag);
|
||||
|
|
@ -122,10 +128,18 @@ public class MultiModPanel(ModFileSystemSelector selector, ModDataEditor editor)
|
|||
? "No tag specified."
|
||||
: $"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();
|
||||
ImUtf8.SameLineInner();
|
||||
if (ImUtf8.ButtonEx(label, tooltip, width, _removeMods.Count == 0))
|
||||
foreach (var (mod, index) in _removeMods)
|
||||
editor.ChangeLocalTag(mod, index, string.Empty);
|
||||
|
||||
if (predefinedTagsEnabled)
|
||||
{
|
||||
ImUtf8.SameLineInner();
|
||||
tagManager.DrawToggleButton();
|
||||
tagManager.DrawListMulti(selector.SelectedPaths.OfType<ModFileSystem.Leaf>().Select(l => l.Value));
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ using OtterGui.Classes;
|
|||
using OtterGui.Extensions;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Classes;
|
||||
|
|
@ -52,6 +54,9 @@ public sealed class PredefinedTagManager : ISavable, IReadOnlyList<string>, ISer
|
|||
jObj.WriteTo(jWriter);
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
=> Count > 0;
|
||||
|
||||
public void Save()
|
||||
=> _saveService.DelaySave(this, TimeSpan.FromSeconds(5));
|
||||
|
||||
|
|
@ -98,9 +103,9 @@ public sealed class PredefinedTagManager : ISavable, IReadOnlyList<string>, ISer
|
|||
}
|
||||
|
||||
public void DrawAddFromSharedTagsAndUpdateTags(IReadOnlyCollection<string> localTags, IReadOnlyCollection<string> modTags, bool editLocal,
|
||||
Mods.Mod mod)
|
||||
Mod mod)
|
||||
{
|
||||
DrawToggleButton();
|
||||
DrawToggleButtonTopRight();
|
||||
if (!DrawList(localTags, modTags, editLocal, out var changedTag, out var index))
|
||||
return;
|
||||
|
||||
|
|
@ -110,17 +115,22 @@ public sealed class PredefinedTagManager : ISavable, IReadOnlyList<string>, ISer
|
|||
_modManager.DataEditor.ChangeModTag(mod, index, changedTag);
|
||||
}
|
||||
|
||||
private void DrawToggleButton()
|
||||
public void DrawToggleButton()
|
||||
{
|
||||
ImGui.SameLine(ImGui.GetContentRegionMax().X
|
||||
- ImGui.GetFrameHeight()
|
||||
- (ImGui.GetScrollMaxY() > 0 ? ImGui.GetStyle().ItemInnerSpacing.X : 0));
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.ButtonActive), _isListOpen);
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Tags.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
|
||||
"Add Predefined Tags...", false, true))
|
||||
_isListOpen = !_isListOpen;
|
||||
}
|
||||
|
||||
private void DrawToggleButtonTopRight()
|
||||
{
|
||||
ImGui.SameLine(ImGui.GetContentRegionMax().X
|
||||
- ImGui.GetFrameHeight()
|
||||
- (ImGui.GetScrollMaxY() > 0 ? ImGui.GetStyle().ItemInnerSpacing.X : 0));
|
||||
DrawToggleButton();
|
||||
}
|
||||
|
||||
private bool DrawList(IReadOnlyCollection<string> localTags, IReadOnlyCollection<string> modTags, bool editLocal, out string changedTag,
|
||||
out int changedIndex)
|
||||
{
|
||||
|
|
@ -130,7 +140,7 @@ public sealed class PredefinedTagManager : ISavable, IReadOnlyList<string>, ISer
|
|||
if (!_isListOpen)
|
||||
return false;
|
||||
|
||||
ImGui.TextUnformatted("Predefined Tags");
|
||||
ImUtf8.Text("Predefined Tags"u8);
|
||||
ImGui.Separator();
|
||||
|
||||
var ret = false;
|
||||
|
|
@ -155,6 +165,101 @@ public sealed class PredefinedTagManager : ISavable, IReadOnlyList<string>, ISer
|
|||
return ret;
|
||||
}
|
||||
|
||||
private readonly List<Mod> _selectedMods = [];
|
||||
private readonly List<(int Index, int DataIndex)> _countedMods = [];
|
||||
|
||||
private void PrepareLists(IEnumerable<Mod> selection)
|
||||
{
|
||||
_selectedMods.Clear();
|
||||
_selectedMods.AddRange(selection);
|
||||
_countedMods.EnsureCapacity(_selectedMods.Count);
|
||||
while (_countedMods.Count < _selectedMods.Count)
|
||||
_countedMods.Add((-1, -1));
|
||||
}
|
||||
|
||||
public void DrawListMulti(IEnumerable<Mod> selection)
|
||||
{
|
||||
if (!_isListOpen)
|
||||
return;
|
||||
|
||||
ImUtf8.Text("Predefined Tags"u8);
|
||||
PrepareLists(selection);
|
||||
|
||||
_enabledColor = ColorId.PredefinedTagAdd.Value();
|
||||
_disabledColor = ColorId.PredefinedTagRemove.Value();
|
||||
using var color = new ImRaii.Color();
|
||||
foreach (var (tag, idx) in _predefinedTags.Keys.WithIndex())
|
||||
{
|
||||
var alreadyContained = 0;
|
||||
var inModData = 0;
|
||||
var missing = 0;
|
||||
|
||||
foreach (var (modIndex, mod) in _selectedMods.Index())
|
||||
{
|
||||
var tagIdx = mod.LocalTags.IndexOf(tag);
|
||||
if (tagIdx >= 0)
|
||||
{
|
||||
++alreadyContained;
|
||||
_countedMods[modIndex] = (tagIdx, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
var dataIdx = mod.ModTags.IndexOf(tag);
|
||||
if (dataIdx >= 0)
|
||||
{
|
||||
++inModData;
|
||||
_countedMods[modIndex] = (-1, dataIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
++missing;
|
||||
_countedMods[modIndex] = (-1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using var id = ImRaii.PushId(idx);
|
||||
var buttonWidth = CalcTextButtonWidth(tag);
|
||||
// Prevent adding a new tag past the right edge of the popup
|
||||
if (buttonWidth + ImGui.GetStyle().ItemSpacing.X >= ImGui.GetContentRegionAvail().X)
|
||||
ImGui.NewLine();
|
||||
|
||||
var (usedColor, disabled, tt) = (missing, alreadyContained) switch
|
||||
{
|
||||
(> 0, _) => (_enabledColor, false,
|
||||
$"Add this tag to {missing} mods.{(inModData > 0 ? $" {inModData} mods contain it in their mod tags and are untouched." : string.Empty)}"),
|
||||
(_, > 0) => (_disabledColor, false,
|
||||
$"Remove this tag from {alreadyContained} mods.{(inModData > 0 ? $" {inModData} mods contain it in their mod tags and are untouched." : string.Empty)}"),
|
||||
_ => (_disabledColor, true, "This tag is already present in the mod tags of all selected mods."),
|
||||
};
|
||||
color.Push(ImGuiCol.Button, usedColor);
|
||||
if (ImUtf8.ButtonEx(tag, tt, new Vector2(buttonWidth, 0), disabled))
|
||||
{
|
||||
if (missing > 0)
|
||||
foreach (var (mod, (localIdx, _)) in _selectedMods.Zip(_countedMods))
|
||||
{
|
||||
if (localIdx >= 0)
|
||||
continue;
|
||||
|
||||
_modManager.DataEditor.ChangeLocalTag(mod, mod.LocalTags.Count, tag);
|
||||
}
|
||||
else
|
||||
foreach (var (mod, (localIdx, _)) in _selectedMods.Zip(_countedMods))
|
||||
{
|
||||
if (localIdx < 0)
|
||||
continue;
|
||||
|
||||
_modManager.DataEditor.ChangeLocalTag(mod, localIdx, string.Empty);
|
||||
}
|
||||
}
|
||||
ImGui.SameLine();
|
||||
|
||||
color.Pop();
|
||||
}
|
||||
|
||||
ImGui.NewLine();
|
||||
}
|
||||
|
||||
private bool DrawColoredButton(string buttonLabel, int index, int tagIdx, bool inOther)
|
||||
{
|
||||
using var id = ImRaii.PushId(index);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue