This sucks so hard...

This commit is contained in:
Ottermandias 2024-04-24 23:04:04 +02:00
parent 07afbfb229
commit 6b1743b776
33 changed files with 852 additions and 695 deletions

View file

@ -305,7 +305,7 @@ public class FileEditor<T>(
UiHelpers.Text(gamePath.Path);
ImGui.TableNextColumn();
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
ImGui.TextUnformatted(option.FullName);
ImGui.TextUnformatted(option.GetFullName());
}
}

View file

@ -3,7 +3,6 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Classes;
using OtterGui.Raii;
using Penumbra.Mods;
using Penumbra.Mods.Editor;
using Penumbra.Mods.Subclasses;
using Penumbra.String.Classes;
@ -79,7 +78,7 @@ public partial class ModEditWindow
var file = f.RelPath.ToString();
return f.SubModUsage.Count == 0
? Enumerable.Repeat((file, "Unused", string.Empty, 0x40000080u), 1)
: f.SubModUsage.Select(s => (file, s.Item2.ToString(), s.Item1.FullName,
: f.SubModUsage.Select(s => (file, s.Item2.ToString(), s.Item1.GetFullName(),
_editor.Option! == s.Item1 && Mod!.HasOptions ? 0x40008000u : 0u));
});
@ -148,13 +147,13 @@ public partial class ModEditWindow
(string, int) GetMulti()
{
var groups = registry.SubModUsage.GroupBy(s => s.Item1).ToArray();
return (string.Join("\n", groups.Select(g => g.Key.Name)), groups.Length);
return (string.Join("\n", groups.Select(g => g.Key.GetName())), groups.Length);
}
var (text, groupCount) = color switch
{
ColorId.ConflictingMod => (string.Empty, 0),
ColorId.NewMod => (registry.SubModUsage[0].Item1.Name, 1),
ColorId.NewMod => (registry.SubModUsage[0].Item1.GetName(), 1),
ColorId.InheritedMod => GetMulti(),
_ => (string.Empty, 0),
};
@ -192,7 +191,7 @@ public partial class ModEditWindow
ImGuiUtil.RightAlign(rightText);
}
private void PrintGamePath(int i, int j, FileRegistry registry, SubMod subMod, Utf8GamePath gamePath)
private void PrintGamePath(int i, int j, FileRegistry registry, IModDataContainer subMod, Utf8GamePath gamePath)
{
using var id = ImRaii.PushId(j);
ImGui.TableNextColumn();
@ -228,7 +227,7 @@ public partial class ModEditWindow
}
}
private void PrintNewGamePath(int i, FileRegistry registry, SubMod subMod)
private void PrintNewGamePath(int i, FileRegistry registry, IModDataContainer subMod)
{
var tmp = _fileIdx == i && _pathIdx == -1 ? _gamePathEdit : string.Empty;
var pos = ImGui.GetCursorPosX() - ImGui.GetFrameHeight();
@ -301,9 +300,9 @@ public partial class ModEditWindow
tt = changes ? "Apply the current file setup to the currently selected option." : "No changes made.";
if (ImGuiUtil.DrawDisabledButton("Apply Changes", Vector2.Zero, tt, !changes))
{
var failedFiles = _editor.FileEditor.Apply(_editor.Mod!, (SubMod)_editor.Option!);
var failedFiles = _editor.FileEditor.Apply(_editor.Mod!, _editor.Option!);
if (failedFiles > 0)
Penumbra.Log.Information($"Failed to apply {failedFiles} file redirections to {_editor.Option!.FullName}.");
Penumbra.Log.Information($"Failed to apply {failedFiles} file redirections to {_editor.Option!.GetFullName()}.");
}

View file

@ -45,7 +45,7 @@ public partial class ModEditWindow
var tt = setsEqual ? "No changes staged." : "Apply the currently staged changes to the option.";
ImGui.NewLine();
if (ImGuiUtil.DrawDisabledButton("Apply Changes", Vector2.Zero, tt, setsEqual))
_editor.MetaEditor.Apply(_editor.Mod!, _editor.GroupIdx, _editor.OptionIdx);
_editor.MetaEditor.Apply(_editor.Mod!, _editor.GroupIdx, _editor.DataIdx);
ImGui.SameLine();
tt = setsEqual ? "No changes staged." : "Revert all currently staged changes.";

View file

@ -85,7 +85,7 @@ public partial class ModEditWindow
{
// TODO: Is it worth trying to order results based on option priorities for cases where more than one match is found?
// NOTE: We're using case-insensitive comparisons, as option group paths in mods are stored in lower case, but the mod editor uses paths directly from the file system, which may be mixed case.
return mod.AllSubMods
return mod.AllDataContainers
.SelectMany(m => m.Files.Concat(m.FileSwaps))
.Where(kv => kv.Value.FullName.Equals(path, StringComparison.OrdinalIgnoreCase))
.Select(kv => kv.Key)
@ -103,7 +103,7 @@ public partial class ModEditWindow
return [];
// Filter then prepend the current option to ensure it's chosen first.
return mod.AllSubMods
return mod.AllDataContainers
.Where(subMod => subMod != option)
.Prepend(option)
.SelectMany(subMod => subMod.Manipulations)

View file

@ -187,8 +187,8 @@ public partial class ModEditWindow
if (editor == null)
return new QuickImportAction(owner._editor, FallbackOptionName, gamePath);
var subMod = editor.Option;
var optionName = subMod!.FullName;
var subMod = editor.Option!;
var optionName = subMod is IModOption o ? o.FullName : FallbackOptionName;
if (gamePath.IsEmpty || file == null || editor.FileEditor.Changes)
return new QuickImportAction(editor, optionName, gamePath);
@ -199,7 +199,7 @@ public partial class ModEditWindow
if (mod == null)
return new QuickImportAction(editor, optionName, gamePath);
var (preferredPath, subDirs) = GetPreferredPath(mod, subMod, owner._config.ReplaceNonAsciiOnImport);
var (preferredPath, subDirs) = GetPreferredPath(mod, subMod as IModOption, owner._config.ReplaceNonAsciiOnImport);
var targetPath = new FullPath(Path.Combine(preferredPath.FullName, gamePath.ToString())).FullName;
if (File.Exists(targetPath))
return new QuickImportAction(editor, optionName, gamePath);
@ -222,16 +222,16 @@ public partial class ModEditWindow
{
fileRegistry,
}, _subDirs);
_editor.FileEditor.Apply(_editor.Mod!, (SubMod)_editor.Option!);
_editor.FileEditor.Apply(_editor.Mod!, _editor.Option!);
return fileRegistry;
}
private static (DirectoryInfo, int) GetPreferredPath(Mod mod, SubMod subMod, bool replaceNonAscii)
private static (DirectoryInfo, int) GetPreferredPath(Mod mod, IModOption? subMod, bool replaceNonAscii)
{
var path = mod.ModPath;
var subDirs = 0;
if (subMod == mod.Default)
if (subMod == null)
return (path, subDirs);
var name = subMod.Name;

View file

@ -77,10 +77,10 @@ public partial class ModEditWindow : Window, IDisposable
_forceTextureStartPath = true;
}
public void ChangeOption(SubMod? subMod)
public void ChangeOption(IModDataContainer? subMod)
{
var (groupIdx, optionIdx) = subMod?.GetIndices() ?? (-1, 0);
_editor.LoadOption(groupIdx, optionIdx);
var (groupIdx, dataIdx) = subMod?.GetDataIndices() ?? (-1, 0);
_editor.LoadOption(groupIdx, dataIdx);
}
public void UpdateModels()
@ -111,7 +111,7 @@ public partial class ModEditWindow : Window, IDisposable
});
var manipulations = 0;
var subMods = 0;
var swaps = Mod!.AllSubMods.Sum(m =>
var swaps = Mod!.AllDataContainers.Sum(m =>
{
++subMods;
manipulations += m.Manipulations.Count;
@ -330,7 +330,7 @@ public partial class ModEditWindow : Window, IDisposable
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), TaskScheduler.Default);
_editor.ModNormalizer.Worker.ContinueWith(_ => _editor.LoadMod(Mod!, _editor.GroupIdx, _editor.DataIdx), TaskScheduler.Default);
}
if (!_editor.Duplicates.Worker.IsCompleted)
@ -405,7 +405,7 @@ public partial class ModEditWindow : Window, IDisposable
var width = new Vector2(ImGui.GetContentRegionAvail().X / 3, 0);
var ret = false;
if (ImGuiUtil.DrawDisabledButton(defaultOption, width, "Switch to the default option for the mod.\nThis resets unsaved changes.",
_editor.Option!.IsDefault))
_editor.Option is DefaultSubMod))
{
_editor.LoadOption(-1, 0);
ret = true;
@ -414,7 +414,7 @@ public partial class ModEditWindow : Window, IDisposable
ImGui.SameLine();
if (ImGuiUtil.DrawDisabledButton("Refresh Data", width, "Refresh data for the current option.\nThis resets unsaved changes.", false))
{
_editor.LoadMod(_editor.Mod!, _editor.GroupIdx, _editor.OptionIdx);
_editor.LoadMod(_editor.Mod!, _editor.GroupIdx, _editor.DataIdx);
ret = true;
}
@ -422,17 +422,17 @@ public partial class ModEditWindow : Window, IDisposable
ImGui.SetNextItemWidth(width.X);
style.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale);
using var color = ImRaii.PushColor(ImGuiCol.Border, ColorId.FolderLine.Value());
using var combo = ImRaii.Combo("##optionSelector", _editor.Option.FullName);
using var combo = ImRaii.Combo("##optionSelector", _editor.Option!.GetFullName());
if (!combo)
return ret;
foreach (var (option, idx) in Mod!.AllSubMods.WithIndex())
foreach (var (option, idx) in Mod!.AllDataContainers.WithIndex())
{
using var id = ImRaii.PushId(idx);
if (ImGui.Selectable(option.FullName, option == _editor.Option))
if (ImGui.Selectable(option.GetFullName(), option == _editor.Option))
{
var (groupIdx, optionIdx) = option.GetIndices();
_editor.LoadOption(groupIdx, optionIdx);
var (groupIdx, dataIdx) = option.GetDataIndices();
_editor.LoadOption(groupIdx, dataIdx);
ret = true;
}
}
@ -455,7 +455,7 @@ public partial class ModEditWindow : Window, IDisposable
var tt = setsEqual ? "No changes staged." : "Apply the currently staged changes to the option.";
ImGui.NewLine();
if (ImGuiUtil.DrawDisabledButton("Apply Changes", Vector2.Zero, tt, setsEqual))
_editor.SwapEditor.Apply(_editor.Mod!, _editor.GroupIdx, _editor.OptionIdx);
_editor.SwapEditor.Apply(_editor.Mod!, _editor.GroupIdx, _editor.DataIdx);
ImGui.SameLine();
tt = setsEqual ? "No changes staged." : "Revert all currently staged changes.";
@ -569,7 +569,7 @@ public partial class ModEditWindow : Window, IDisposable
}
if (Mod != null)
foreach (var option in Mod.AllSubMods)
foreach (var option in Mod.AllDataContainers)
{
foreach (var path in option.Files.Keys)
{

View file

@ -50,8 +50,7 @@ public class ModMergeTab(ModMerger modMerger)
ImGui.SameLine();
DrawCombo(size - ImGui.GetItemRectSize().X - ImGui.GetStyle().ItemSpacing.X);
var width = ImGui.GetItemRectSize();
using (var g = ImRaii.Group())
using (ImRaii.Group())
{
using var disabled = ImRaii.Disabled(modMerger.MergeFromMod.HasOptions);
var buttonWidth = (size - ImGui.GetStyle().ItemSpacing.X) / 2;
@ -124,13 +123,13 @@ public class ModMergeTab(ModMerger modMerger)
ImGui.Dummy(Vector2.One);
var buttonSize = new Vector2((size - 2 * ImGui.GetStyle().ItemSpacing.X) / 3, 0);
if (ImGui.Button("Select All", buttonSize))
modMerger.SelectedOptions.UnionWith(modMerger.MergeFromMod!.AllSubMods);
modMerger.SelectedOptions.UnionWith(modMerger.MergeFromMod!.AllDataContainers);
ImGui.SameLine();
if (ImGui.Button("Unselect All", buttonSize))
modMerger.SelectedOptions.Clear();
ImGui.SameLine();
if (ImGui.Button("Invert Selection", buttonSize))
modMerger.SelectedOptions.SymmetricExceptWith(modMerger.MergeFromMod!.AllSubMods);
modMerger.SelectedOptions.SymmetricExceptWith(modMerger.MergeFromMod!.AllDataContainers);
DrawOptionTable(size);
}
@ -144,7 +143,7 @@ public class ModMergeTab(ModMerger modMerger)
private void DrawOptionTable(float size)
{
var options = modMerger.MergeFromMod!.AllSubMods.ToList();
var options = modMerger.MergeFromMod!.AllDataContainers.ToList();
var height = modMerger.Warnings.Count == 0 && modMerger.Error == null
? ImGui.GetContentRegionAvail().Y - 3 * ImGui.GetFrameHeightWithSpacing()
: 8 * ImGui.GetFrameHeightWithSpacing();
@ -176,47 +175,41 @@ public class ModMergeTab(ModMerger modMerger)
if (ImGui.Checkbox("##check", ref selected))
Handle(option, selected);
if (option.IsDefault)
if (option.Group is not { } group)
{
ImGuiUtil.DrawTableColumn(option.FullName);
ImGuiUtil.DrawTableColumn(option.GetFullName());
ImGui.TableNextColumn();
}
else
{
ImGuiUtil.DrawTableColumn(option.Name);
var group = option.Group;
var optionEnumerator = group switch
{
SingleModGroup single => single.OptionData,
MultiModGroup multi => multi.PrioritizedOptions.Select(o => o.Mod),
_ => [],
};
ImGuiUtil.DrawTableColumn(option.GetName());
ImGui.TableNextColumn();
ImGui.Selectable(group.Name, false);
if (ImGui.BeginPopupContextItem("##groupContext"))
{
if (ImGui.MenuItem("Select All"))
// ReSharper disable once PossibleMultipleEnumeration
foreach (var opt in optionEnumerator)
foreach (var opt in group.DataContainers)
Handle(opt, true);
if (ImGui.MenuItem("Unselect All"))
// ReSharper disable once PossibleMultipleEnumeration
foreach (var opt in optionEnumerator)
foreach (var opt in group.DataContainers)
Handle(opt, false);
ImGui.EndPopup();
}
}
ImGui.TableNextColumn();
ImGuiUtil.RightAlign(option.FileData.Count.ToString(), 3 * ImGuiHelpers.GlobalScale);
ImGuiUtil.RightAlign(option.Files.Count.ToString(), 3 * ImGuiHelpers.GlobalScale);
ImGui.TableNextColumn();
ImGuiUtil.RightAlign(option.FileSwapData.Count.ToString(), 3 * ImGuiHelpers.GlobalScale);
ImGuiUtil.RightAlign(option.FileSwaps.Count.ToString(), 3 * ImGuiHelpers.GlobalScale);
ImGui.TableNextColumn();
ImGuiUtil.RightAlign(option.Manipulations.Count.ToString(), 3 * ImGuiHelpers.GlobalScale);
continue;
void Handle(SubMod option2, bool selected2)
void Handle(IModDataContainer option2, bool selected2)
{
if (selected2)
modMerger.SelectedOptions.Add(option2);

View file

@ -486,7 +486,7 @@ public class ModPanelEditTab(
EditOption(panel, single, groupIdx, optionIdx);
break;
case MultiModGroup multi:
for (var optionIdx = 0; optionIdx < multi.PrioritizedOptions.Count; ++optionIdx)
for (var optionIdx = 0; optionIdx < multi.OptionData.Count; ++optionIdx)
EditOption(panel, multi, groupIdx, optionIdx);
break;
}
@ -542,7 +542,7 @@ public class ModPanelEditTab(
if (group is not MultiModGroup multi)
return;
if (Input.Priority("##Priority", groupIdx, optionIdx, multi.PrioritizedOptions[optionIdx].Priority, out var priority,
if (Input.Priority("##Priority", groupIdx, optionIdx, multi.OptionData[optionIdx].Priority, out var priority,
50 * UiHelpers.Scale))
panel._modManager.OptionEditor.ChangeOptionPriority(panel._mod, groupIdx, optionIdx, priority);
@ -557,7 +557,7 @@ public class ModPanelEditTab(
var count = group switch
{
SingleModGroup single => single.OptionData.Count,
MultiModGroup multi => multi.PrioritizedOptions.Count,
MultiModGroup multi => multi.OptionData.Count,
_ => throw new Exception($"Dragging options to an option group of type {group.GetType()} is not supported."),
};
ImGui.TableNextColumn();
@ -591,6 +591,9 @@ public class ModPanelEditTab(
// Handle drag and drop to move options inside a group or into another group.
private static void Source(IModGroup group, int groupIdx, int optionIdx)
{
if (group is not ITexToolsGroup)
return;
using var source = ImRaii.DragDropSource();
if (!source)
return;
@ -606,6 +609,9 @@ public class ModPanelEditTab(
private static void Target(ModPanelEditTab panel, IModGroup group, int groupIdx, int optionIdx)
{
if (group is not ITexToolsGroup)
return;
using var target = ImRaii.DragDropTarget();
if (!target.Success || !ImGuiUtil.IsDropping(DragDropLabel))
return;
@ -624,22 +630,12 @@ public class ModPanelEditTab(
var sourceGroupIdx = _dragDropGroupIdx;
var sourceOption = _dragDropOptionIdx;
var sourceGroup = panel._mod.Groups[sourceGroupIdx];
var currentCount = group switch
{
SingleModGroup single => single.OptionData.Count,
MultiModGroup multi => multi.PrioritizedOptions.Count,
_ => throw new Exception($"Dragging options to an option group of type {group.GetType()} is not supported."),
};
var (option, priority) = sourceGroup switch
{
SingleModGroup single => (single.OptionData[_dragDropOptionIdx], ModPriority.Default),
MultiModGroup multi => multi.PrioritizedOptions[_dragDropOptionIdx],
_ => throw new Exception($"Dragging options from an option group of type {sourceGroup.GetType()} is not supported."),
};
var currentCount = group.DataContainers.Count;
var option = ((ITexToolsGroup) sourceGroup).OptionData[_dragDropOptionIdx];
panel._delayedActions.Enqueue(() =>
{
panel._modManager.OptionEditor.DeleteOption(panel._mod, sourceGroupIdx, sourceOption);
panel._modManager.OptionEditor.AddOption(panel._mod, groupIdx, option, priority);
panel._modManager.OptionEditor.AddOption(panel._mod, groupIdx, option);
panel._modManager.OptionEditor.MoveOption(panel._mod, groupIdx, currentCount, optionIdx);
});
}

View file

@ -114,7 +114,7 @@ public class ModPanelTabBar
if (ImGui.TabItemButton("Advanced Editing", ImGuiTabItemFlags.Trailing | ImGuiTabItemFlags.NoTooltip))
{
_modEditWindow.ChangeMod(mod);
_modEditWindow.ChangeOption((SubMod)mod.Default);
_modEditWindow.ChangeOption(mod.Default);
_modEditWindow.IsOpen = true;
}