Mod Edit Window: Highlight paths of files on player

This commit is contained in:
Exter-N 2023-11-29 14:31:47 +01:00
parent 43c6b52d0b
commit 18d38a9974
5 changed files with 45 additions and 14 deletions

View file

@ -101,24 +101,25 @@ public static class TextureDrawer
}
}
public sealed class PathSelectCombo : FilterComboCache<(string, bool)>
public sealed class PathSelectCombo : FilterComboCache<(string Path, bool Game, bool IsOnPlayer)>
{
private int _skipPrefix = 0;
public PathSelectCombo(TextureManager textures, ModEditor editor)
: base(() => CreateFiles(textures, editor), Penumbra.Log)
public PathSelectCombo(TextureManager textures, ModEditor editor, Func<ISet<string>> getPlayerResources)
: base(() => CreateFiles(textures, editor, getPlayerResources), Penumbra.Log)
{ }
protected override string ToString((string, bool) obj)
=> obj.Item1;
protected override string ToString((string Path, bool Game, bool IsOnPlayer) obj)
=> obj.Path;
protected override bool DrawSelectable(int globalIdx, bool selected)
{
var (path, game) = Items[globalIdx];
var (path, game, isOnPlayer) = Items[globalIdx];
bool ret;
using (var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.FolderExpanded.Value(), game))
{
var equals = string.Equals(CurrentSelection.Item1, path, StringComparison.OrdinalIgnoreCase);
color.Push(ImGuiCol.Text, ColorId.HandledConflictMod.Value(), isOnPlayer);
var equals = string.Equals(CurrentSelection.Path, path, StringComparison.OrdinalIgnoreCase);
var p = game ? $"--> {path}" : path[_skipPrefix..];
ret = ImGui.Selectable(p, selected) && !equals;
}
@ -129,11 +130,16 @@ public static class TextureDrawer
return ret;
}
private static IReadOnlyList<(string, bool)> CreateFiles(TextureManager textures, ModEditor editor)
=> editor.Files.Tex.SelectMany(f => f.SubModUsage.Select(p => (p.Item2.ToString(), true))
private static IReadOnlyList<(string Path, bool Game, bool IsOnPlayer)> CreateFiles(TextureManager textures, ModEditor editor, Func<ISet<string>> getPlayerResources)
{
var playerResources = getPlayerResources();
return editor.Files.Tex.SelectMany(f => f.SubModUsage.Select(p => (p.Item2.ToString(), true))
.Prepend((f.File.FullName, false)))
.Where(p => p.Item2 ? textures.GameFileExists(p.Item1) : File.Exists(p.Item1))
.Select(p => (p.Item1, p.Item2, playerResources.Contains(p.Item1)))
.ToList();
}
public bool Draw(string label, string tooltip, string current, int skipPrefix, out string newPath)
{

View file

@ -10,6 +10,7 @@ public class FileRegistry : IEquatable<FileRegistry>
public Utf8RelPath RelPath { get; private init; }
public long FileSize { get; private init; }
public int CurrentUsage;
public bool IsOnPlayer;
public static bool FromFile(DirectoryInfo modPath, FileInfo file, [NotNullWhen(true)] out FileRegistry? registry)
{
@ -26,6 +27,7 @@ public class FileRegistry : IEquatable<FileRegistry>
RelPath = relPath,
FileSize = file.Length,
CurrentUsage = 0,
IsOnPlayer = false,
};
return true;
}

View file

@ -285,7 +285,9 @@ public class FileEditor<T> : IDisposable where T : class, IWritable
protected override bool DrawSelectable(int globalIdx, bool selected)
{
var file = Items[globalIdx];
var ret = ImGui.Selectable(file.RelPath.ToString(), selected);
bool ret;
using (var c = ImRaii.PushColor(ImGuiCol.Text, ColorId.HandledConflictMod.Value(), file.IsOnPlayer))
ret = ImGui.Selectable(file.RelPath.ToString(), selected);
if (ImGui.IsItemHovered())
{

View file

@ -3,6 +3,7 @@ using ImGuiNET;
using Lumina.Data;
using OtterGui;
using OtterGui.Raii;
using Penumbra.Api.Enums;
using Penumbra.GameData.Files;
using Penumbra.Interop.ResourceTree;
using Penumbra.Mods;
@ -19,6 +20,25 @@ public partial class ModEditWindow
private readonly Dictionary<FullPath, IWritable?> _quickImportWritables = new();
private readonly Dictionary<(Utf8GamePath, IWritable?), QuickImportAction> _quickImportActions = new();
private HashSet<string> GetPlayerResourcesOfType(ResourceType type)
{
var resources = ResourceTreeApiHelper.GetResourcesOfType(_resourceTreeFactory.FromObjectTable(ResourceTreeFactory.Flags.LocalPlayerRelatedOnly), type)
.Values
.SelectMany(resources => resources.Values)
.Select(resource => resource.Item1);
return new(resources, StringComparer.OrdinalIgnoreCase);
}
private IReadOnlyList<FileRegistry> PopulateIsOnPlayer(IReadOnlyList<FileRegistry> files, ResourceType type)
{
var playerResources = GetPlayerResourcesOfType(type);
foreach (var file in files)
file.IsOnPlayer = playerResources.Contains(file.File.ToPath());
return files;
}
private void DrawQuickImportTab()
{
using var tab = ImRaii.TabItem("Import from Screen");

View file

@ -7,6 +7,7 @@ using Dalamud.Plugin.Services;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.Api.Enums;
using Penumbra.Collections.Manager;
using Penumbra.Communication;
using Penumbra.GameData.Enums;
@ -569,15 +570,15 @@ public partial class ModEditWindow : Window, IDisposable
_fileDialog = fileDialog;
_gameEvents = gameEvents;
_materialTab = new FileEditor<MtrlTab>(this, gameData, config, _editor.Compactor, _fileDialog, "Materials", ".mtrl",
() => _editor.Files.Mtrl, DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty,
() => PopulateIsOnPlayer(_editor.Files.Mtrl, ResourceType.Mtrl), DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty,
(bytes, path, writable) => new MtrlTab(this, new MtrlFile(bytes), path, writable));
_modelTab = new FileEditor<MdlFile>(this, gameData, config, _editor.Compactor, _fileDialog, "Models", ".mdl",
() => _editor.Files.Mdl, DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty, (bytes, _, _) => new MdlFile(bytes));
() => PopulateIsOnPlayer(_editor.Files.Mdl, ResourceType.Mdl), DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty, (bytes, _, _) => new MdlFile(bytes));
_shaderPackageTab = new FileEditor<ShpkTab>(this, gameData, config, _editor.Compactor, _fileDialog, "Shaders", ".shpk",
() => _editor.Files.Shpk, DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty,
() => PopulateIsOnPlayer(_editor.Files.Shpk, ResourceType.Shpk), DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty,
(bytes, _, _) => new ShpkTab(_fileDialog, bytes));
_center = new CombinedTexture(_left, _right);
_textureSelectCombo = new TextureDrawer.PathSelectCombo(textures, editor);
_textureSelectCombo = new TextureDrawer.PathSelectCombo(textures, editor, () => GetPlayerResourcesOfType(ResourceType.Tex));
_resourceTreeFactory = resourceTreeFactory;
_quickImportViewer =
new ResourceTreeViewer(_config, resourceTreeFactory, changedItemDrawer, 2, OnQuickImportRefresh, DrawQuickImportActions);