mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Replace all occurences of ImGuiCol.
This commit is contained in:
parent
a4302c9145
commit
74d35870e2
46 changed files with 1586 additions and 1475 deletions
2
Luna
2
Luna
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1ffa8c5de118f94b609f7d6352e3b63de463398c
|
Subproject commit ec5cc05211c5083f276e32816d8c3eb8c09d04b4
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3a9406bc634228cc0815ddb6fe5e20419cafb864
|
Subproject commit 182cca56a49411430233d73d7a8a6bb3d983f8f0
|
||||||
|
|
@ -54,8 +54,8 @@ public static class FeatureChecker
|
||||||
const int numButtons = 5;
|
const int numButtons = 5;
|
||||||
var innerSpacing = ImGui.GetStyle().ItemInnerSpacing;
|
var innerSpacing = ImGui.GetStyle().ItemInnerSpacing;
|
||||||
var size = new Vector2((width - (numButtons - 1) * innerSpacing.X) / numButtons, 0);
|
var size = new Vector2((width - (numButtons - 1) * innerSpacing.X) / numButtons, 0);
|
||||||
var buttonColor = ImGui.GetColorU32(ImGuiCol.FrameBg);
|
var buttonColor = Im.Style[ImGuiColor.FrameBackground];
|
||||||
var textColor = ImGui.GetColorU32(ImGuiCol.TextDisabled);
|
var textColor = Im.Style[ImGuiColor.TextDisabled];
|
||||||
using (var style = ImStyleBorder.Frame.Push(ColorId.FolderLine.Value(), 0)
|
using (var style = ImStyleBorder.Frame.Push(ColorId.FolderLine.Value(), 0)
|
||||||
.Push(ImStyleDouble.ItemSpacing, innerSpacing)
|
.Push(ImStyleDouble.ItemSpacing, innerSpacing)
|
||||||
.Push(ImGuiColor.Button, buttonColor)
|
.Push(ImGuiColor.Button, buttonColor)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,103 @@ using FileSystemChangeType = OtterGui.Filesystem.FileSystemChangeType;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Manager;
|
namespace Penumbra.Mods.Manager;
|
||||||
|
|
||||||
|
//public sealed class ModFileSystem2 : BaseFileSystem
|
||||||
|
//{
|
||||||
|
// private readonly Configuration _config;
|
||||||
|
// private readonly SaveService _saveService;
|
||||||
|
// public ModFileSystem2(FileSystemChanged @event, DataNodePathChange dataChangeEvent, Configuration config, SaveService saveService, IComparer<ReadOnlySpan<char>>? comparer = null)
|
||||||
|
// : base(@event, dataChangeEvent, comparer)
|
||||||
|
// {
|
||||||
|
// _config = config;
|
||||||
|
// _saveService = saveService;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void Dispose()
|
||||||
|
// {
|
||||||
|
// _communicator.ModPathChanged.Unsubscribe(OnModPathChange);
|
||||||
|
// _communicator.ModDiscoveryFinished.Unsubscribe(Reload);
|
||||||
|
// _communicator.ModDataChanged.Unsubscribe(OnModDataChange);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Save the filesystem on every filesystem change except full reloading.
|
||||||
|
// private void OnChange(FileSystemChangeType type, IPath _1, IPath? _2, IPath? _3)
|
||||||
|
// {
|
||||||
|
// if (type != FileSystemChangeType.Reload)
|
||||||
|
// _saveService.DelaySave(this);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Update sort order when defaulted mod names change.
|
||||||
|
// private void OnModDataChange(in ModDataChanged.Arguments arguments)
|
||||||
|
// {
|
||||||
|
// if (!arguments.Type.HasFlag(ModDataChangeType.Name) || arguments.OldName == null || !TryGetValue(arguments.Mod, out var leaf))
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// var old = Extensions.FixName(arguments.OldName);
|
||||||
|
// if (old == leaf.Name || Extensions.IsDuplicateName(leaf.Name, out var baseName, out _) && baseName == old)
|
||||||
|
// RenameWithDuplicates(leaf, arguments.Mod.Name);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Update the filesystem if a mod has been added or removed.
|
||||||
|
// // Save it, if the mod directory has been moved, since this will change the save format.
|
||||||
|
// private void OnModPathChange(in ModPathChanged.Arguments arguments)
|
||||||
|
// {
|
||||||
|
// switch (arguments.Type)
|
||||||
|
// {
|
||||||
|
// case ModPathChangeType.Added:
|
||||||
|
// var parent = Root;
|
||||||
|
// if (_config.DefaultImportFolder.Length != 0)
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// parent = FindOrCreateAllFolders(_config.DefaultImportFolder);
|
||||||
|
// }
|
||||||
|
// catch (Exception e)
|
||||||
|
// {
|
||||||
|
// Penumbra.Messager.NotificationMessage(e,
|
||||||
|
// $"Could not move newly imported mod {arguments.Mod.Name} to default import folder {_config.DefaultImportFolder}.",
|
||||||
|
// NotificationType.Warning);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// CreateDuplicateLeaf(parent, arguments.Mod.Name, arguments.Mod);
|
||||||
|
// break;
|
||||||
|
// case ModPathChangeType.Deleted:
|
||||||
|
// if (arguments.Mod.Node is not null)
|
||||||
|
// Delete(arguments.Mod.Node);
|
||||||
|
// break;
|
||||||
|
// case ModPathChangeType.Moved:
|
||||||
|
// _saveService.DelaySave(this);
|
||||||
|
// break;
|
||||||
|
// case ModPathChangeType.Reloaded:
|
||||||
|
// // Nothing
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public struct ImportDate : ISortMode
|
||||||
|
// {
|
||||||
|
// public ReadOnlySpan<byte> Name
|
||||||
|
// => "Import Date (Older First)"u8;
|
||||||
|
//
|
||||||
|
// public ReadOnlySpan<byte> Description
|
||||||
|
// => "In each folder, sort all subfolders lexicographically, then sort all leaves using their import date."u8;
|
||||||
|
//
|
||||||
|
// public IEnumerable<IFileSystemNode> GetChildren(IFileSystemFolder f)
|
||||||
|
// => f.GetSubFolders().Cast<IFileSystemNode>().Concat(f.GetLeaves().OfType<IFileSystemData<Mod>>().OrderBy(l => l.Value.ImportDate));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public struct InverseImportDate : ISortMode
|
||||||
|
// {
|
||||||
|
// public ReadOnlySpan<byte> Name
|
||||||
|
// => "Import Date (Newer First)"u8;
|
||||||
|
//
|
||||||
|
// public ReadOnlySpan<byte> Description
|
||||||
|
// => "In each folder, sort all subfolders lexicographically, then sort all leaves using their inverse import date."u8;
|
||||||
|
//
|
||||||
|
// public IEnumerable<IFileSystemNode> GetChildren(IFileSystemFolder f)
|
||||||
|
// => f.GetSubFolders().Cast<IFileSystemNode>().Concat(f.GetLeaves().OfType<IFileSystemData<Mod>>().OrderByDescending(l => l.Value.ImportDate));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
public sealed class ModFileSystem : FileSystem<Mod>, IDisposable, ISavable, IService
|
public sealed class ModFileSystem : FileSystem<Mod>, IDisposable, ISavable, IService
|
||||||
{
|
{
|
||||||
private readonly ModManager _modManager;
|
private readonly ModManager _modManager;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public enum FeatureFlags : ulong
|
||||||
Invalid = 1ul << 62,
|
Invalid = 1ul << 62,
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class Mod : IMod
|
public sealed class Mod : IMod, IFileSystemValue<Mod>
|
||||||
{
|
{
|
||||||
public static readonly TemporaryMod ForcedFiles = new()
|
public static readonly TemporaryMod ForcedFiles = new()
|
||||||
{
|
{
|
||||||
|
|
@ -69,6 +69,7 @@ public sealed class Mod : IMod
|
||||||
|
|
||||||
|
|
||||||
// Local Data
|
// Local Data
|
||||||
|
public string FullPath { get; set; } = string.Empty;
|
||||||
public long ImportDate { get; internal set; } = DateTimeOffset.UnixEpoch.ToUnixTimeMilliseconds();
|
public long ImportDate { get; internal set; } = DateTimeOffset.UnixEpoch.ToUnixTimeMilliseconds();
|
||||||
public IReadOnlyList<string> LocalTags { get; internal set; } = [];
|
public IReadOnlyList<string> LocalTags { get; internal set; } = [];
|
||||||
public string Note { get; internal set; } = string.Empty;
|
public string Note { get; internal set; } = string.Empty;
|
||||||
|
|
@ -130,14 +131,15 @@ public sealed class Mod : IMod
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
|
public IFileSystemData<Mod>? Node { get; set; }
|
||||||
public readonly SortedList<string, IIdentifiedObjectData> ChangedItems = new();
|
public readonly SortedList<string, IIdentifiedObjectData> ChangedItems = new();
|
||||||
|
|
||||||
public string LowerChangedItemsString { get; internal set; } = string.Empty;
|
public string LowerChangedItemsString { get; internal set; } = string.Empty;
|
||||||
public string AllTagsLower { get; internal set; } = string.Empty;
|
public string AllTagsLower { get; internal set; } = string.Empty;
|
||||||
|
|
||||||
public int TotalFileCount { get; internal set; }
|
public int TotalFileCount { get; internal set; }
|
||||||
public int TotalSwapCount { get; internal set; }
|
public int TotalSwapCount { get; internal set; }
|
||||||
public int TotalManipulations { get; internal set; }
|
public int TotalManipulations { get; internal set; }
|
||||||
public ushort LastChangedItemsUpdate { get; internal set; }
|
public ushort LastChangedItemsUpdate { get; internal set; }
|
||||||
public bool HasOptions { get; internal set; }
|
public bool HasOptions { get; internal set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,131 +1,139 @@
|
||||||
using Newtonsoft.Json;
|
using Luna;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json;
|
||||||
using Penumbra.GameData.Structs;
|
using Newtonsoft.Json.Linq;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Services;
|
using Penumbra.Mods.Manager;
|
||||||
|
using Penumbra.Services;
|
||||||
namespace Penumbra.Mods;
|
|
||||||
|
namespace Penumbra.Mods;
|
||||||
public readonly struct ModLocalData(Mod mod) : ISavable
|
|
||||||
{
|
public readonly struct ModLocalData(Mod mod) : ISavable
|
||||||
public const int FileVersion = 3;
|
{
|
||||||
|
public const int FileVersion = 3;
|
||||||
public string ToFilePath(FilenameService fileNames)
|
|
||||||
=> fileNames.LocalDataFile(mod);
|
public string ToFilePath(FilenameService fileNames)
|
||||||
|
=> fileNames.LocalDataFile(mod);
|
||||||
public void Save(StreamWriter writer)
|
|
||||||
{
|
public void Save(StreamWriter writer)
|
||||||
var jObject = new JObject
|
{
|
||||||
{
|
var jObject = new JObject
|
||||||
{ nameof(FileVersion), JToken.FromObject(FileVersion) },
|
{
|
||||||
{ nameof(Mod.ImportDate), JToken.FromObject(mod.ImportDate) },
|
{ nameof(FileVersion), JToken.FromObject(FileVersion) },
|
||||||
{ nameof(Mod.LocalTags), JToken.FromObject(mod.LocalTags) },
|
{ nameof(Mod.ImportDate), JToken.FromObject(mod.ImportDate) },
|
||||||
{ nameof(Mod.Note), JToken.FromObject(mod.Note) },
|
{ nameof(Mod.LocalTags), JToken.FromObject(mod.LocalTags) },
|
||||||
{ nameof(Mod.Favorite), JToken.FromObject(mod.Favorite) },
|
{ nameof(Mod.Note), JToken.FromObject(mod.Note) },
|
||||||
{ nameof(Mod.PreferredChangedItems), JToken.FromObject(mod.PreferredChangedItems) },
|
{ nameof(Mod.Favorite), JToken.FromObject(mod.Favorite) },
|
||||||
};
|
{ nameof(Mod.PreferredChangedItems), JToken.FromObject(mod.PreferredChangedItems) },
|
||||||
using var jWriter = new JsonTextWriter(writer);
|
};
|
||||||
jWriter.Formatting = Formatting.Indented;
|
|
||||||
jObject.WriteTo(jWriter);
|
if (mod.FullPath.Length > 0)
|
||||||
}
|
{
|
||||||
|
var baseName = mod.FullPath.GetBaseName(mod.Name, out var folder);
|
||||||
public static ModDataChangeType Load(ModDataEditor editor, Mod mod)
|
jObject[nameof(Mod.FullPath)] = folder.Length > 0 ? $"{folder}/{baseName}" : baseName.ToString();
|
||||||
{
|
}
|
||||||
var dataFile = editor.SaveService.FileNames.LocalDataFile(mod);
|
|
||||||
|
using var jWriter = new JsonTextWriter(writer);
|
||||||
var importDate = 0L;
|
jWriter.Formatting = Formatting.Indented;
|
||||||
var localTags = Enumerable.Empty<string>();
|
jObject.WriteTo(jWriter);
|
||||||
var favorite = false;
|
}
|
||||||
var note = string.Empty;
|
|
||||||
|
public static ModDataChangeType Load(ModDataEditor editor, Mod mod)
|
||||||
HashSet<CustomItemId> preferredChangedItems = [];
|
{
|
||||||
|
var dataFile = editor.SaveService.FileNames.LocalDataFile(mod);
|
||||||
var save = true;
|
|
||||||
if (File.Exists(dataFile))
|
var importDate = 0L;
|
||||||
try
|
var localTags = Enumerable.Empty<string>();
|
||||||
{
|
var favorite = false;
|
||||||
var text = File.ReadAllText(dataFile);
|
var note = string.Empty;
|
||||||
var json = JObject.Parse(text);
|
|
||||||
|
HashSet<CustomItemId> preferredChangedItems = [];
|
||||||
importDate = json[nameof(Mod.ImportDate)]?.Value<long>() ?? importDate;
|
|
||||||
favorite = json[nameof(Mod.Favorite)]?.Value<bool>() ?? favorite;
|
var save = true;
|
||||||
note = json[nameof(Mod.Note)]?.Value<string>() ?? note;
|
if (File.Exists(dataFile))
|
||||||
localTags = (json[nameof(Mod.LocalTags)] as JArray)?.Values<string>().OfType<string>() ?? localTags;
|
try
|
||||||
preferredChangedItems = (json[nameof(Mod.PreferredChangedItems)] as JArray)?.Values<ulong>().Select(i => (CustomItemId) i).ToHashSet() ?? mod.DefaultPreferredItems;
|
{
|
||||||
save = false;
|
var text = File.ReadAllText(dataFile);
|
||||||
}
|
var json = JObject.Parse(text);
|
||||||
catch (Exception e)
|
|
||||||
{
|
importDate = json[nameof(Mod.ImportDate)]?.Value<long>() ?? importDate;
|
||||||
Penumbra.Log.Error($"Could not load local mod data:\n{e}");
|
favorite = json[nameof(Mod.Favorite)]?.Value<bool>() ?? favorite;
|
||||||
}
|
note = json[nameof(Mod.Note)]?.Value<string>() ?? note;
|
||||||
else
|
localTags = (json[nameof(Mod.LocalTags)] as JArray)?.Values<string>().OfType<string>() ?? localTags;
|
||||||
{
|
preferredChangedItems =
|
||||||
preferredChangedItems = mod.DefaultPreferredItems;
|
(json[nameof(Mod.PreferredChangedItems)] as JArray)?.Values<ulong>().Select(i => (CustomItemId)i).ToHashSet()
|
||||||
}
|
?? mod.DefaultPreferredItems;
|
||||||
|
save = false;
|
||||||
if (importDate == 0)
|
}
|
||||||
importDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
catch (Exception e)
|
||||||
|
{
|
||||||
ModDataChangeType changes = 0;
|
Penumbra.Log.Error($"Could not load local mod data:\n{e}");
|
||||||
if (mod.ImportDate != importDate)
|
}
|
||||||
{
|
else
|
||||||
mod.ImportDate = importDate;
|
preferredChangedItems = mod.DefaultPreferredItems;
|
||||||
changes |= ModDataChangeType.ImportDate;
|
|
||||||
}
|
if (importDate == 0)
|
||||||
|
importDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
changes |= UpdateTags(mod, null, localTags);
|
|
||||||
|
ModDataChangeType changes = 0;
|
||||||
if (mod.Favorite != favorite)
|
if (mod.ImportDate != importDate)
|
||||||
{
|
{
|
||||||
mod.Favorite = favorite;
|
mod.ImportDate = importDate;
|
||||||
changes |= ModDataChangeType.Favorite;
|
changes |= ModDataChangeType.ImportDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mod.Note != note)
|
changes |= UpdateTags(mod, null, localTags);
|
||||||
{
|
|
||||||
mod.Note = note;
|
if (mod.Favorite != favorite)
|
||||||
changes |= ModDataChangeType.Note;
|
{
|
||||||
}
|
mod.Favorite = favorite;
|
||||||
|
changes |= ModDataChangeType.Favorite;
|
||||||
if (!preferredChangedItems.SetEquals(mod.PreferredChangedItems))
|
}
|
||||||
{
|
|
||||||
mod.PreferredChangedItems = preferredChangedItems;
|
if (mod.Note != note)
|
||||||
changes |= ModDataChangeType.PreferredChangedItems;
|
{
|
||||||
}
|
mod.Note = note;
|
||||||
|
changes |= ModDataChangeType.Note;
|
||||||
if (save)
|
}
|
||||||
editor.SaveService.QueueSave(new ModLocalData(mod));
|
|
||||||
|
if (!preferredChangedItems.SetEquals(mod.PreferredChangedItems))
|
||||||
return changes;
|
{
|
||||||
}
|
mod.PreferredChangedItems = preferredChangedItems;
|
||||||
|
changes |= ModDataChangeType.PreferredChangedItems;
|
||||||
internal static ModDataChangeType UpdateTags(Mod mod, IEnumerable<string>? newModTags, IEnumerable<string>? newLocalTags)
|
}
|
||||||
{
|
|
||||||
if (newModTags == null && newLocalTags == null)
|
if (save)
|
||||||
return 0;
|
editor.SaveService.QueueSave(new ModLocalData(mod));
|
||||||
|
|
||||||
ModDataChangeType type = 0;
|
return changes;
|
||||||
if (newModTags != null)
|
}
|
||||||
{
|
|
||||||
var modTags = newModTags.Where(t => t.Length > 0).Distinct().ToArray();
|
internal static ModDataChangeType UpdateTags(Mod mod, IEnumerable<string>? newModTags, IEnumerable<string>? newLocalTags)
|
||||||
if (!modTags.SequenceEqual(mod.ModTags))
|
{
|
||||||
{
|
if (newModTags == null && newLocalTags == null)
|
||||||
newLocalTags ??= mod.LocalTags;
|
return 0;
|
||||||
mod.ModTags = modTags;
|
|
||||||
type |= ModDataChangeType.ModTags;
|
ModDataChangeType type = 0;
|
||||||
}
|
if (newModTags != null)
|
||||||
}
|
{
|
||||||
|
var modTags = newModTags.Where(t => t.Length > 0).Distinct().ToArray();
|
||||||
if (newLocalTags != null)
|
if (!modTags.SequenceEqual(mod.ModTags))
|
||||||
{
|
{
|
||||||
var localTags = newLocalTags!.Where(t => t.Length > 0 && !mod.ModTags.Contains(t)).Distinct().ToArray();
|
newLocalTags ??= mod.LocalTags;
|
||||||
if (!localTags.SequenceEqual(mod.LocalTags))
|
mod.ModTags = modTags;
|
||||||
{
|
type |= ModDataChangeType.ModTags;
|
||||||
mod.LocalTags = localTags;
|
}
|
||||||
type |= ModDataChangeType.LocalTags;
|
}
|
||||||
}
|
|
||||||
}
|
if (newLocalTags != null)
|
||||||
|
{
|
||||||
return type;
|
var localTags = newLocalTags!.Where(t => t.Length > 0 && !mod.ModTags.Contains(t)).Distinct().ToArray();
|
||||||
}
|
if (!localTags.SequenceEqual(mod.LocalTags))
|
||||||
}
|
{
|
||||||
|
mod.LocalTags = localTags;
|
||||||
|
type |= ModDataChangeType.LocalTags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public static class StaticServiceManager
|
||||||
{
|
{
|
||||||
public static ServiceManager CreateProvider(Penumbra penumbra, IDalamudPluginInterface pi, Logger log)
|
public static ServiceManager CreateProvider(Penumbra penumbra, IDalamudPluginInterface pi, Logger log)
|
||||||
{
|
{
|
||||||
var services = new ServiceManager(log)
|
var services = new ServiceManager(log, Logger.GlobalPluginName)
|
||||||
.AddDalamudServices(pi)
|
.AddDalamudServices(pi)
|
||||||
.AddExistingService(log)
|
.AddExistingService(log)
|
||||||
.AddExistingService(penumbra);
|
.AddExistingService(penumbra);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public partial class MtrlTab
|
||||||
for (var j = 0; j < 8; ++j)
|
for (var j = 0; j < 8; ++j)
|
||||||
{
|
{
|
||||||
var pairIndex = i + j;
|
var pairIndex = i + j;
|
||||||
using (ImRaii.PushColor(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.ButtonActive), pairIndex == _colorTableSelectedPair))
|
using (ImGuiColor.Button.Push(Im.Style[ImGuiColor.ButtonActive], pairIndex == _colorTableSelectedPair))
|
||||||
{
|
{
|
||||||
if (ImUtf8.Button($"#{pairIndex + 1}".PadLeft(3 + spacePadding),
|
if (ImUtf8.Button($"#{pairIndex + 1}".PadLeft(3 + spacePadding),
|
||||||
new Vector2(buttonWidth, ImGui.GetFrameHeightWithSpacing() + frameHeight)))
|
new Vector2(buttonWidth, ImGui.GetFrameHeightWithSpacing() + frameHeight)))
|
||||||
|
|
@ -101,6 +101,7 @@ public partial class MtrlTab
|
||||||
{
|
{
|
||||||
retA |= DrawRowHeader(rowAIdx, disabled);
|
retA |= DrawRowHeader(rowAIdx, disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
columns.Next();
|
columns.Next();
|
||||||
using (ImUtf8.PushId("RowHeaderB"u8))
|
using (ImUtf8.PushId("RowHeaderB"u8))
|
||||||
{
|
{
|
||||||
|
|
@ -232,8 +233,8 @@ public partial class MtrlTab
|
||||||
/// <remarks> Padding styles do not seem to apply to this component. It is recommended to prepend two spaces. </remarks>
|
/// <remarks> Padding styles do not seem to apply to this component. It is recommended to prepend two spaces. </remarks>
|
||||||
private static void DrawHeader(ReadOnlySpan<byte> label)
|
private static void DrawHeader(ReadOnlySpan<byte> label)
|
||||||
{
|
{
|
||||||
var headerColor = ImGui.GetColorU32(ImGuiCol.Header);
|
var headerColor = Im.Style[ImGuiColor.Header];
|
||||||
using var _ = ImRaii.PushColor(ImGuiCol.HeaderHovered, headerColor).Push(ImGuiCol.HeaderActive, headerColor);
|
using var _ = ImGuiColor.HeaderHovered.Push(headerColor).Push(ImGuiColor.HeaderActive, headerColor);
|
||||||
ImUtf8.CollapsingHeader(label, ImGuiTreeNodeFlags.Leaf);
|
ImUtf8.CollapsingHeader(label, ImGuiTreeNodeFlags.Leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ public partial class MtrlTab
|
||||||
var style = ImGui.GetStyle();
|
var style = ImGui.GetStyle();
|
||||||
var frameRounding = style.FrameRounding;
|
var frameRounding = style.FrameRounding;
|
||||||
var frameThickness = style.FrameBorderSize;
|
var frameThickness = style.FrameBorderSize;
|
||||||
var borderColor = ImGui.GetColorU32(ImGuiCol.Border);
|
var borderColor = ImGuiColor.Border.Get();
|
||||||
var drawList = ImGui.GetWindowDrawList();
|
var drawList = ImGui.GetWindowDrawList();
|
||||||
if (topColor == bottomColor)
|
if (topColor == bottomColor)
|
||||||
{
|
{
|
||||||
|
|
@ -328,7 +328,7 @@ public partial class MtrlTab
|
||||||
bottomColor, frameRounding, ImDrawFlags.RoundCornersBottomLeft | ImDrawFlags.RoundCornersBottomRight);
|
bottomColor, frameRounding, ImDrawFlags.RoundCornersBottomLeft | ImDrawFlags.RoundCornersBottomRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawList.AddRect(rcMin, rcMax, borderColor, frameRounding, ImDrawFlags.RoundCornersDefault, frameThickness);
|
drawList.AddRect(rcMin, rcMax, borderColor.Color, frameRounding, ImDrawFlags.RoundCornersDefault, frameThickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool CtColorPicker(ReadOnlySpan<byte> label, ReadOnlySpan<byte> description, HalfColor current, Action<HalfColor> setter,
|
private static bool CtColorPicker(ReadOnlySpan<byte> label, ReadOnlySpan<byte> description, HalfColor current, Action<HalfColor> setter,
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,15 @@ public partial class MtrlTab
|
||||||
if (disabled)
|
if (disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ImUtf8.Button("Reload live preview"u8))
|
if (Im.Button("Reload live preview"u8))
|
||||||
BindToMaterialInstances();
|
BindToMaterialInstances();
|
||||||
|
|
||||||
if (_materialPreviewers.Count != 0 || _colorTablePreviewers.Count != 0)
|
if (_materialPreviewers.Count != 0 || _colorTablePreviewers.Count != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
using var c = ImRaii.PushColor(ImGuiCol.Text, Colors.RegexWarningBorder);
|
Im.Text("The current material has not been found on your character. Please check the Import from Screen tab for more information."u8,
|
||||||
ImUtf8.Text(
|
Colors.RegexWarningBorder);
|
||||||
"The current material has not been found on your character. Please check the Import from Screen tab for more information."u8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void BindToMaterialInstances()
|
private unsafe void BindToMaterialInstances()
|
||||||
|
|
@ -292,7 +291,7 @@ public partial class MtrlTab
|
||||||
{
|
{
|
||||||
var level = (MathF.Sin(time * 2.0f * MathF.PI) + 2.0f) / 3.0f / 255.0f;
|
var level = (MathF.Sin(time * 2.0f * MathF.PI) + 2.0f) / 3.0f / 255.0f;
|
||||||
var baseColor = colorId.Value();
|
var baseColor = colorId.Value();
|
||||||
var color = level * new Vector3(baseColor & 0xFF, (baseColor >> 8) & 0xFF, (baseColor >> 16) & 0xFF);
|
var color = level * new Vector3(baseColor.R, baseColor.G, baseColor.B);
|
||||||
var halfColor = (HalfColor)(color * color);
|
var halfColor = (HalfColor)(color * color);
|
||||||
|
|
||||||
row.DiffuseColor = halfColor;
|
row.DiffuseColor = halfColor;
|
||||||
|
|
|
||||||
|
|
@ -1,273 +1,274 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Newtonsoft.Json.Linq;
|
using ImSharp;
|
||||||
using OtterGui.Raii;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Text;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Collections.Cache;
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.Collections.Cache;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Meta;
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Meta.Files;
|
using Penumbra.Meta;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Files;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.Mods.Editor;
|
||||||
|
using Penumbra.UI.Classes;
|
||||||
namespace Penumbra.UI.AdvancedWindow.Meta;
|
|
||||||
|
namespace Penumbra.UI.AdvancedWindow.Meta;
|
||||||
public sealed class AtrMetaDrawer(ModMetaEditor editor, MetaFileManager metaFiles)
|
|
||||||
: MetaDrawer<AtrIdentifier, AtrEntry>(editor, metaFiles), Luna.IService
|
public sealed class AtrMetaDrawer(ModMetaEditor editor, MetaFileManager metaFiles)
|
||||||
{
|
: MetaDrawer<AtrIdentifier, AtrEntry>(editor, metaFiles), Luna.IService
|
||||||
public override ReadOnlySpan<byte> Label
|
{
|
||||||
=> "Attributes(ATR)###ATR"u8;
|
public override ReadOnlySpan<byte> Label
|
||||||
|
=> "Attributes(ATR)###ATR"u8;
|
||||||
private ShapeAttributeString _buffer = ShapeAttributeString.TryRead("atrx_"u8, out var s) ? s : ShapeAttributeString.Empty;
|
|
||||||
private bool _identifierValid;
|
private ShapeAttributeString _buffer = ShapeAttributeString.TryRead("atrx_"u8, out var s) ? s : ShapeAttributeString.Empty;
|
||||||
|
private bool _identifierValid;
|
||||||
public override int NumColumns
|
|
||||||
=> 7;
|
public override int NumColumns
|
||||||
|
=> 7;
|
||||||
public override float ColumnHeight
|
|
||||||
=> ImUtf8.FrameHeightSpacing;
|
public override float ColumnHeight
|
||||||
|
=> ImUtf8.FrameHeightSpacing;
|
||||||
protected override void Initialize()
|
|
||||||
{
|
protected override void Initialize()
|
||||||
Identifier = new AtrIdentifier(HumanSlot.Unknown, null, ShapeAttributeString.Empty, GenderRace.Unknown);
|
{
|
||||||
Entry = AtrEntry.True;
|
Identifier = new AtrIdentifier(HumanSlot.Unknown, null, ShapeAttributeString.Empty, GenderRace.Unknown);
|
||||||
}
|
Entry = AtrEntry.True;
|
||||||
|
}
|
||||||
protected override void DrawNew()
|
|
||||||
{
|
protected override void DrawNew()
|
||||||
ImGui.TableNextColumn();
|
{
|
||||||
CopyToClipboardButton("Copy all current ATR manipulations to clipboard."u8,
|
ImGui.TableNextColumn();
|
||||||
new Lazy<JToken?>(() => MetaDictionary.SerializeTo([], Editor.Atr)));
|
CopyToClipboardButton("Copy all current ATR manipulations to clipboard."u8,
|
||||||
|
new Lazy<JToken?>(() => MetaDictionary.SerializeTo([], Editor.Atr)));
|
||||||
ImGui.TableNextColumn();
|
|
||||||
var canAdd = !Editor.Contains(Identifier) && _identifierValid;
|
ImGui.TableNextColumn();
|
||||||
var tt = canAdd
|
var canAdd = !Editor.Contains(Identifier) && _identifierValid;
|
||||||
? "Stage this edit."u8
|
var tt = canAdd
|
||||||
: _identifierValid
|
? "Stage this edit."u8
|
||||||
? "This entry does not contain a valid attribute."u8
|
: _identifierValid
|
||||||
: "This entry is already edited."u8;
|
? "This entry does not contain a valid attribute."u8
|
||||||
if (ImUtf8.IconButton(FontAwesomeIcon.Plus, tt, disabled: !canAdd))
|
: "This entry is already edited."u8;
|
||||||
Editor.Changes |= Editor.TryAdd(Identifier, AtrEntry.False);
|
if (ImUtf8.IconButton(FontAwesomeIcon.Plus, tt, disabled: !canAdd))
|
||||||
|
Editor.Changes |= Editor.TryAdd(Identifier, AtrEntry.False);
|
||||||
DrawIdentifierInput(ref Identifier);
|
|
||||||
DrawEntry(ref Entry, true);
|
DrawIdentifierInput(ref Identifier);
|
||||||
}
|
DrawEntry(ref Entry, true);
|
||||||
|
}
|
||||||
protected override void DrawEntry(AtrIdentifier identifier, AtrEntry entry)
|
|
||||||
{
|
protected override void DrawEntry(AtrIdentifier identifier, AtrEntry entry)
|
||||||
DrawMetaButtons(identifier, entry);
|
{
|
||||||
DrawIdentifier(identifier);
|
DrawMetaButtons(identifier, entry);
|
||||||
|
DrawIdentifier(identifier);
|
||||||
if (DrawEntry(ref entry, false))
|
|
||||||
Editor.Changes |= Editor.Update(identifier, entry);
|
if (DrawEntry(ref entry, false))
|
||||||
}
|
Editor.Changes |= Editor.Update(identifier, entry);
|
||||||
|
}
|
||||||
protected override IEnumerable<(AtrIdentifier, AtrEntry)> Enumerate()
|
|
||||||
=> Editor.Atr
|
protected override IEnumerable<(AtrIdentifier, AtrEntry)> Enumerate()
|
||||||
.OrderBy(kvp => kvp.Key.Attribute)
|
=> Editor.Atr
|
||||||
.ThenBy(kvp => kvp.Key.Slot)
|
.OrderBy(kvp => kvp.Key.Attribute)
|
||||||
.ThenBy(kvp => kvp.Key.Id)
|
.ThenBy(kvp => kvp.Key.Slot)
|
||||||
.Select(kvp => (kvp.Key, kvp.Value));
|
.ThenBy(kvp => kvp.Key.Id)
|
||||||
|
.Select(kvp => (kvp.Key, kvp.Value));
|
||||||
protected override int Count
|
|
||||||
=> Editor.Atr.Count;
|
protected override int Count
|
||||||
|
=> Editor.Atr.Count;
|
||||||
private bool DrawIdentifierInput(ref AtrIdentifier identifier)
|
|
||||||
{
|
private bool DrawIdentifierInput(ref AtrIdentifier identifier)
|
||||||
ImGui.TableNextColumn();
|
{
|
||||||
var changes = DrawHumanSlot(ref identifier);
|
ImGui.TableNextColumn();
|
||||||
|
var changes = DrawHumanSlot(ref identifier);
|
||||||
ImGui.TableNextColumn();
|
|
||||||
changes |= DrawGenderRaceConditionInput(ref identifier);
|
ImGui.TableNextColumn();
|
||||||
|
changes |= DrawGenderRaceConditionInput(ref identifier);
|
||||||
ImGui.TableNextColumn();
|
|
||||||
changes |= DrawPrimaryId(ref identifier);
|
ImGui.TableNextColumn();
|
||||||
|
changes |= DrawPrimaryId(ref identifier);
|
||||||
ImGui.TableNextColumn();
|
|
||||||
changes |= DrawAttributeKeyInput(ref identifier, ref _buffer, ref _identifierValid);
|
ImGui.TableNextColumn();
|
||||||
return changes;
|
changes |= DrawAttributeKeyInput(ref identifier, ref _buffer, ref _identifierValid);
|
||||||
}
|
return changes;
|
||||||
|
}
|
||||||
private static void DrawIdentifier(AtrIdentifier identifier)
|
|
||||||
{
|
private static void DrawIdentifier(AtrIdentifier identifier)
|
||||||
ImGui.TableNextColumn();
|
{
|
||||||
|
ImGui.TableNextColumn();
|
||||||
ImUtf8.TextFramed(ShpMetaDrawer.SlotName(identifier.Slot), FrameColor);
|
|
||||||
ImUtf8.HoverTooltip("Model Slot"u8);
|
ImUtf8.TextFramed(ShpMetaDrawer.SlotName(identifier.Slot), FrameColor);
|
||||||
|
ImUtf8.HoverTooltip("Model Slot"u8);
|
||||||
ImGui.TableNextColumn();
|
|
||||||
if (identifier.GenderRaceCondition is not GenderRace.Unknown)
|
ImGui.TableNextColumn();
|
||||||
{
|
if (identifier.GenderRaceCondition is not GenderRace.Unknown)
|
||||||
ImUtf8.TextFramed($"{identifier.GenderRaceCondition.ToName()} ({identifier.GenderRaceCondition.ToRaceCode()})", FrameColor);
|
{
|
||||||
ImUtf8.HoverTooltip("Gender & Race Code for this attribute to be set.");
|
ImUtf8.TextFramed($"{identifier.GenderRaceCondition.ToName()} ({identifier.GenderRaceCondition.ToRaceCode()})", FrameColor);
|
||||||
}
|
ImUtf8.HoverTooltip("Gender & Race Code for this attribute to be set.");
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
ImUtf8.TextFramed("Any Gender & Race"u8, FrameColor);
|
{
|
||||||
}
|
ImUtf8.TextFramed("Any Gender & Race"u8, FrameColor);
|
||||||
|
}
|
||||||
ImGui.TableNextColumn();
|
|
||||||
if (identifier.Id.HasValue)
|
ImGui.TableNextColumn();
|
||||||
ImUtf8.TextFramed($"{identifier.Id.Value.Id}", FrameColor);
|
if (identifier.Id.HasValue)
|
||||||
else
|
ImUtf8.TextFramed($"{identifier.Id.Value.Id}", FrameColor);
|
||||||
ImUtf8.TextFramed("All IDs"u8, FrameColor);
|
else
|
||||||
ImUtf8.HoverTooltip("Primary ID"u8);
|
ImUtf8.TextFramed("All IDs"u8, FrameColor);
|
||||||
|
ImUtf8.HoverTooltip("Primary ID"u8);
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImUtf8.TextFramed(identifier.Attribute.AsSpan, FrameColor);
|
ImGui.TableNextColumn();
|
||||||
}
|
ImUtf8.TextFramed(identifier.Attribute.AsSpan, FrameColor);
|
||||||
|
}
|
||||||
private static bool DrawEntry(ref AtrEntry entry, bool disabled)
|
|
||||||
{
|
private static bool DrawEntry(ref AtrEntry entry, bool disabled)
|
||||||
using var dis = ImRaii.Disabled(disabled);
|
{
|
||||||
ImGui.TableNextColumn();
|
using var dis = ImRaii.Disabled(disabled);
|
||||||
var value = entry.Value;
|
ImGui.TableNextColumn();
|
||||||
var changes = ImUtf8.Checkbox("##atrEntry"u8, ref value);
|
var value = entry.Value;
|
||||||
if (changes)
|
var changes = ImUtf8.Checkbox("##atrEntry"u8, ref value);
|
||||||
entry = new AtrEntry(value);
|
if (changes)
|
||||||
ImUtf8.HoverTooltip("Whether to enable or disable this attribute for the selected items.");
|
entry = new AtrEntry(value);
|
||||||
return changes;
|
ImUtf8.HoverTooltip("Whether to enable or disable this attribute for the selected items.");
|
||||||
}
|
return changes;
|
||||||
|
}
|
||||||
public static bool DrawPrimaryId(ref AtrIdentifier identifier, float unscaledWidth = 100)
|
|
||||||
{
|
public static bool DrawPrimaryId(ref AtrIdentifier identifier, float unscaledWidth = 100)
|
||||||
var allSlots = identifier.Slot is HumanSlot.Unknown;
|
{
|
||||||
var all = !identifier.Id.HasValue;
|
var allSlots = identifier.Slot is HumanSlot.Unknown;
|
||||||
var ret = false;
|
var all = !identifier.Id.HasValue;
|
||||||
using (ImRaii.Disabled(allSlots))
|
var ret = false;
|
||||||
{
|
using (ImRaii.Disabled(allSlots))
|
||||||
if (ImUtf8.Checkbox("##atrAll"u8, ref all))
|
{
|
||||||
{
|
if (ImUtf8.Checkbox("##atrAll"u8, ref all))
|
||||||
identifier = identifier with { Id = all ? null : 0 };
|
{
|
||||||
ret = true;
|
identifier = identifier with { Id = all ? null : 0 };
|
||||||
}
|
ret = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ImUtf8.HoverTooltip(allSlots
|
|
||||||
? "When using all slots, you also need to use all IDs."u8
|
ImUtf8.HoverTooltip(allSlots
|
||||||
: "Enable this attribute for all model IDs."u8);
|
? "When using all slots, you also need to use all IDs."u8
|
||||||
|
: "Enable this attribute for all model IDs."u8);
|
||||||
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X);
|
|
||||||
if (all)
|
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X);
|
||||||
{
|
if (all)
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.05f, 0.5f));
|
{
|
||||||
ImUtf8.TextFramed("All IDs"u8, ImGui.GetColorU32(ImGuiCol.FrameBg, all || allSlots ? ImGui.GetStyle().DisabledAlpha : 1f),
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.05f, 0.5f));
|
||||||
new Vector2(unscaledWidth, 0), ImGui.GetColorU32(ImGuiCol.TextDisabled));
|
ImUtf8.TextFramed("All IDs"u8, ImGuiColor.FrameBackground.Get(all || allSlots ? ImGui.GetStyle().DisabledAlpha : 1f).Color,
|
||||||
}
|
new Vector2(unscaledWidth, 0), ImGuiColor.TextDisabled.Get().Color);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
var max = identifier.Slot.ToSpecificEnum() is BodySlot ? byte.MaxValue : ExpandedEqpGmpBase.Count - 1;
|
{
|
||||||
if (IdInput("##atrPrimaryId"u8, unscaledWidth, identifier.Id.GetValueOrDefault(0).Id, out var setId, 0, max, false))
|
var max = identifier.Slot.ToSpecificEnum() is BodySlot ? byte.MaxValue : ExpandedEqpGmpBase.Count - 1;
|
||||||
{
|
if (IdInput("##atrPrimaryId"u8, unscaledWidth, identifier.Id.GetValueOrDefault(0).Id, out var setId, 0, max, false))
|
||||||
identifier = identifier with { Id = setId };
|
{
|
||||||
ret = true;
|
identifier = identifier with { Id = setId };
|
||||||
}
|
ret = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ImUtf8.HoverTooltip("Primary ID - You can usually find this as the 'e####' part of an item path or similar for customizations."u8);
|
|
||||||
|
ImUtf8.HoverTooltip("Primary ID - You can usually find this as the 'e####' part of an item path or similar for customizations."u8);
|
||||||
return ret;
|
|
||||||
}
|
return ret;
|
||||||
|
}
|
||||||
public bool DrawHumanSlot(ref AtrIdentifier identifier, float unscaledWidth = 150)
|
|
||||||
{
|
public bool DrawHumanSlot(ref AtrIdentifier identifier, float unscaledWidth = 150)
|
||||||
var ret = false;
|
{
|
||||||
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
var ret = false;
|
||||||
using (var combo = ImUtf8.Combo("##atrSlot"u8, ShpMetaDrawer.SlotName(identifier.Slot)))
|
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
||||||
{
|
using (var combo = ImUtf8.Combo("##atrSlot"u8, ShpMetaDrawer.SlotName(identifier.Slot)))
|
||||||
if (combo)
|
{
|
||||||
foreach (var slot in ShpMetaDrawer.AvailableSlots)
|
if (combo)
|
||||||
{
|
foreach (var slot in ShpMetaDrawer.AvailableSlots)
|
||||||
if (!ImUtf8.Selectable(ShpMetaDrawer.SlotName(slot), slot == identifier.Slot) || slot == identifier.Slot)
|
{
|
||||||
continue;
|
if (!ImUtf8.Selectable(ShpMetaDrawer.SlotName(slot), slot == identifier.Slot) || slot == identifier.Slot)
|
||||||
|
continue;
|
||||||
ret = true;
|
|
||||||
if (slot is HumanSlot.Unknown)
|
ret = true;
|
||||||
{
|
if (slot is HumanSlot.Unknown)
|
||||||
identifier = identifier with
|
{
|
||||||
{
|
identifier = identifier with
|
||||||
Id = null,
|
{
|
||||||
Slot = slot,
|
Id = null,
|
||||||
};
|
Slot = slot,
|
||||||
}
|
};
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
identifier = identifier with
|
{
|
||||||
{
|
identifier = identifier with
|
||||||
Id = identifier.Id.HasValue
|
{
|
||||||
? (PrimaryId)Math.Clamp(identifier.Id.Value.Id, 0,
|
Id = identifier.Id.HasValue
|
||||||
slot.ToSpecificEnum() is BodySlot ? byte.MaxValue : ExpandedEqpGmpBase.Count - 1)
|
? (PrimaryId)Math.Clamp(identifier.Id.Value.Id, 0,
|
||||||
: null,
|
slot.ToSpecificEnum() is BodySlot ? byte.MaxValue : ExpandedEqpGmpBase.Count - 1)
|
||||||
Slot = slot,
|
: null,
|
||||||
};
|
Slot = slot,
|
||||||
ret = true;
|
};
|
||||||
}
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ImUtf8.HoverTooltip("Model Slot"u8);
|
|
||||||
return ret;
|
ImUtf8.HoverTooltip("Model Slot"u8);
|
||||||
}
|
return ret;
|
||||||
|
}
|
||||||
private static bool DrawGenderRaceConditionInput(ref AtrIdentifier identifier, float unscaledWidth = 250)
|
|
||||||
{
|
private static bool DrawGenderRaceConditionInput(ref AtrIdentifier identifier, float unscaledWidth = 250)
|
||||||
var ret = false;
|
{
|
||||||
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
var ret = false;
|
||||||
|
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
||||||
using (var combo = ImUtf8.Combo("##shpGenderRace"u8,
|
|
||||||
identifier.GenderRaceCondition is GenderRace.Unknown
|
using (var combo = ImUtf8.Combo("##shpGenderRace"u8,
|
||||||
? "Any Gender & Race"
|
identifier.GenderRaceCondition is GenderRace.Unknown
|
||||||
: $"{identifier.GenderRaceCondition.ToName()} ({identifier.GenderRaceCondition.ToRaceCode()})"))
|
? "Any Gender & Race"
|
||||||
{
|
: $"{identifier.GenderRaceCondition.ToName()} ({identifier.GenderRaceCondition.ToRaceCode()})"))
|
||||||
if (combo)
|
{
|
||||||
{
|
if (combo)
|
||||||
if (ImUtf8.Selectable("Any Gender & Race"u8, identifier.GenderRaceCondition is GenderRace.Unknown)
|
{
|
||||||
&& identifier.GenderRaceCondition is not GenderRace.Unknown)
|
if (ImUtf8.Selectable("Any Gender & Race"u8, identifier.GenderRaceCondition is GenderRace.Unknown)
|
||||||
{
|
&& identifier.GenderRaceCondition is not GenderRace.Unknown)
|
||||||
identifier = identifier with { GenderRaceCondition = GenderRace.Unknown };
|
{
|
||||||
ret = true;
|
identifier = identifier with { GenderRaceCondition = GenderRace.Unknown };
|
||||||
}
|
ret = true;
|
||||||
|
}
|
||||||
foreach (var gr in ShapeAttributeHashSet.GenderRaceValues.Skip(1))
|
|
||||||
{
|
foreach (var gr in ShapeAttributeHashSet.GenderRaceValues.Skip(1))
|
||||||
if (ImUtf8.Selectable($"{gr.ToName()} ({gr.ToRaceCode()})", identifier.GenderRaceCondition == gr)
|
{
|
||||||
&& identifier.GenderRaceCondition != gr)
|
if (ImUtf8.Selectable($"{gr.ToName()} ({gr.ToRaceCode()})", identifier.GenderRaceCondition == gr)
|
||||||
{
|
&& identifier.GenderRaceCondition != gr)
|
||||||
identifier = identifier with { GenderRaceCondition = gr };
|
{
|
||||||
ret = true;
|
identifier = identifier with { GenderRaceCondition = gr };
|
||||||
}
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ImUtf8.HoverTooltip(
|
|
||||||
"Only activate this attribute for this gender & race code."u8);
|
ImUtf8.HoverTooltip(
|
||||||
|
"Only activate this attribute for this gender & race code."u8);
|
||||||
return ret;
|
|
||||||
}
|
return ret;
|
||||||
|
}
|
||||||
public static unsafe bool DrawAttributeKeyInput(ref AtrIdentifier identifier, ref ShapeAttributeString buffer, ref bool valid,
|
|
||||||
float unscaledWidth = 150)
|
public static unsafe bool DrawAttributeKeyInput(ref AtrIdentifier identifier, ref ShapeAttributeString buffer, ref bool valid,
|
||||||
{
|
float unscaledWidth = 150)
|
||||||
var ret = false;
|
{
|
||||||
var ptr = Unsafe.AsPointer(ref buffer);
|
var ret = false;
|
||||||
var span = new Span<byte>(ptr, ShapeAttributeString.MaxLength + 1);
|
var ptr = Unsafe.AsPointer(ref buffer);
|
||||||
using (new ImRaii.ColorStyle().Push(ImGuiCol.Border, Colors.RegexWarningBorder, !valid).Push(ImGuiStyleVar.FrameBorderSize, 1f, !valid))
|
var span = new Span<byte>(ptr, ShapeAttributeString.MaxLength + 1);
|
||||||
{
|
using (ImStyleBorder.Frame.Push(Colors.RegexWarningBorder, Im.Style.GlobalScale, !valid))
|
||||||
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
{
|
||||||
if (ImUtf8.InputText("##atrAttribute"u8, span, out int newLength, "Attribute..."u8))
|
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
||||||
{
|
if (ImUtf8.InputText("##atrAttribute"u8, span, out int newLength, "Attribute..."u8))
|
||||||
buffer.ForceLength((byte)newLength);
|
{
|
||||||
valid = buffer.ValidateCustomAttributeString();
|
buffer.ForceLength((byte)newLength);
|
||||||
if (valid)
|
valid = buffer.ValidateCustomAttributeString();
|
||||||
identifier = identifier with { Attribute = buffer };
|
if (valid)
|
||||||
ret = true;
|
identifier = identifier with { Attribute = buffer };
|
||||||
}
|
ret = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ImUtf8.HoverTooltip("Supported attribute need to have the format `atrx_*` and a maximum length of 30 characters."u8);
|
|
||||||
return ret;
|
ImUtf8.HoverTooltip("Supported attribute need to have the format `atrx_*` and a maximum length of 30 characters."u8);
|
||||||
}
|
return ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,165 +1,163 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Newtonsoft.Json.Linq;
|
using ImSharp;
|
||||||
using OtterGui;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Raii;
|
using OtterGui;
|
||||||
using OtterGui.Text;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Api.Api;
|
using OtterGui.Text;
|
||||||
using Penumbra.Meta;
|
using Penumbra.Api.Api;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.Mods.Editor;
|
||||||
|
using Penumbra.UI.Classes;
|
||||||
namespace Penumbra.UI.AdvancedWindow.Meta;
|
|
||||||
|
namespace Penumbra.UI.AdvancedWindow.Meta;
|
||||||
public interface IMetaDrawer
|
|
||||||
{
|
public interface IMetaDrawer
|
||||||
public ReadOnlySpan<byte> Label { get; }
|
{
|
||||||
public int NumColumns { get; }
|
public ReadOnlySpan<byte> Label { get; }
|
||||||
public float ColumnHeight { get; }
|
public int NumColumns { get; }
|
||||||
public void Draw();
|
public float ColumnHeight { get; }
|
||||||
}
|
public void Draw();
|
||||||
|
}
|
||||||
public abstract class MetaDrawer<TIdentifier, TEntry>(ModMetaEditor editor, MetaFileManager metaFiles) : IMetaDrawer
|
|
||||||
where TIdentifier : unmanaged, IMetaIdentifier
|
public abstract class MetaDrawer<TIdentifier, TEntry>(ModMetaEditor editor, MetaFileManager metaFiles) : IMetaDrawer
|
||||||
where TEntry : unmanaged
|
where TIdentifier : unmanaged, IMetaIdentifier
|
||||||
{
|
where TEntry : unmanaged
|
||||||
protected const uint FrameColor = 0;
|
{
|
||||||
|
protected const uint FrameColor = 0;
|
||||||
protected readonly ModMetaEditor Editor = editor;
|
|
||||||
protected readonly MetaFileManager MetaFiles = metaFiles;
|
protected readonly ModMetaEditor Editor = editor;
|
||||||
protected TIdentifier Identifier;
|
protected readonly MetaFileManager MetaFiles = metaFiles;
|
||||||
protected TEntry Entry;
|
protected TIdentifier Identifier;
|
||||||
private bool _initialized;
|
protected TEntry Entry;
|
||||||
|
private bool _initialized;
|
||||||
public void Draw()
|
|
||||||
{
|
public void Draw()
|
||||||
if (!_initialized)
|
{
|
||||||
{
|
if (!_initialized)
|
||||||
Initialize();
|
{
|
||||||
_initialized = true;
|
Initialize();
|
||||||
}
|
_initialized = true;
|
||||||
|
}
|
||||||
using var id = ImUtf8.PushId((int)Identifier.Type);
|
|
||||||
DrawNew();
|
using var id = ImUtf8.PushId((int)Identifier.Type);
|
||||||
|
DrawNew();
|
||||||
var height = ColumnHeight;
|
|
||||||
var skips = ImGuiClip.GetNecessarySkipsAtPos(height, ImGui.GetCursorPosY(), Count);
|
var height = ColumnHeight;
|
||||||
if (skips < Count)
|
var skips = ImGuiClip.GetNecessarySkipsAtPos(height, ImGui.GetCursorPosY(), Count);
|
||||||
{
|
if (skips < Count)
|
||||||
var remainder = ImGuiClip.ClippedTableDraw(Enumerate(), skips, DrawLine, Count);
|
{
|
||||||
if (remainder > 0)
|
var remainder = ImGuiClip.ClippedTableDraw(Enumerate(), skips, DrawLine, Count);
|
||||||
ImGuiClip.DrawEndDummy(remainder, height);
|
if (remainder > 0)
|
||||||
}
|
ImGuiClip.DrawEndDummy(remainder, height);
|
||||||
|
}
|
||||||
void DrawLine((TIdentifier Identifier, TEntry Value) pair)
|
|
||||||
=> DrawEntry(pair.Identifier, pair.Value);
|
void DrawLine((TIdentifier Identifier, TEntry Value) pair)
|
||||||
}
|
=> DrawEntry(pair.Identifier, pair.Value);
|
||||||
|
}
|
||||||
public abstract ReadOnlySpan<byte> Label { get; }
|
|
||||||
public abstract int NumColumns { get; }
|
public abstract ReadOnlySpan<byte> Label { get; }
|
||||||
|
public abstract int NumColumns { get; }
|
||||||
public virtual float ColumnHeight
|
|
||||||
=> ImUtf8.FrameHeightSpacing;
|
public virtual float ColumnHeight
|
||||||
|
=> ImUtf8.FrameHeightSpacing;
|
||||||
protected abstract void DrawNew();
|
|
||||||
protected abstract void Initialize();
|
protected abstract void DrawNew();
|
||||||
protected abstract void DrawEntry(TIdentifier identifier, TEntry entry);
|
protected abstract void Initialize();
|
||||||
|
protected abstract void DrawEntry(TIdentifier identifier, TEntry entry);
|
||||||
protected abstract IEnumerable<(TIdentifier, TEntry)> Enumerate();
|
|
||||||
protected abstract int Count { get; }
|
protected abstract IEnumerable<(TIdentifier, TEntry)> Enumerate();
|
||||||
|
protected abstract int Count { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A number input for ids with an optional max id of given width.
|
/// <summary>
|
||||||
/// Returns true if newId changed against currentId.
|
/// A number input for ids with an optional max id of given width.
|
||||||
/// </summary>
|
/// Returns true if newId changed against currentId.
|
||||||
protected static bool IdInput(ReadOnlySpan<byte> label, float unscaledWidth, ushort currentId, out ushort newId, int minId, int maxId,
|
/// </summary>
|
||||||
bool border)
|
protected static bool IdInput(ReadOnlySpan<byte> label, float unscaledWidth, ushort currentId, out ushort newId, int minId, int maxId,
|
||||||
{
|
bool border)
|
||||||
int tmp = currentId;
|
{
|
||||||
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
int tmp = currentId;
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, UiHelpers.Scale, border);
|
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.RegexWarningBorder, border);
|
using var style = ImStyleBorder.Frame.Push(Colors.RegexWarningBorder, Im.Style.GlobalScale, border);
|
||||||
if (ImUtf8.InputScalar(label, ref tmp))
|
if (ImUtf8.InputScalar(label, ref tmp))
|
||||||
tmp = Math.Clamp(tmp, minId, maxId);
|
tmp = Math.Clamp(tmp, minId, maxId);
|
||||||
|
|
||||||
newId = (ushort)tmp;
|
newId = (ushort)tmp;
|
||||||
return newId != currentId;
|
return newId != currentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A dragging int input of given width that compares against a default value, shows a tooltip and clamps against min and max.
|
/// A dragging int input of given width that compares against a default value, shows a tooltip and clamps against min and max.
|
||||||
/// Returns true if newValue changed against currentValue.
|
/// Returns true if newValue changed against currentValue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected static bool DragInput<T>(ReadOnlySpan<byte> label, ReadOnlySpan<byte> tooltip, float width, T currentValue, T defaultValue,
|
protected static bool DragInput<T>(ReadOnlySpan<byte> label, ReadOnlySpan<byte> tooltip, float width, T currentValue, T defaultValue,
|
||||||
out T newValue, T minValue, T maxValue, float speed, bool addDefault) where T : unmanaged, INumber<T>
|
out T newValue, T minValue, T maxValue, float speed, bool addDefault) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
newValue = currentValue;
|
newValue = currentValue;
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.FrameBg,
|
var c = defaultValue > currentValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value();
|
||||||
defaultValue > currentValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value(),
|
using var color = ImGuiColor.FrameBackground.Push(c, defaultValue != currentValue);
|
||||||
defaultValue != currentValue);
|
ImGui.SetNextItemWidth(width);
|
||||||
ImGui.SetNextItemWidth(width);
|
if (ImUtf8.DragScalar(label, ref newValue, minValue, maxValue, speed))
|
||||||
if (ImUtf8.DragScalar(label, ref newValue, minValue, maxValue, speed))
|
newValue = newValue <= minValue ? minValue : newValue >= maxValue ? maxValue : newValue;
|
||||||
newValue = newValue <= minValue ? minValue : newValue >= maxValue ? maxValue : newValue;
|
|
||||||
|
if (addDefault)
|
||||||
if (addDefault)
|
ImUtf8.HoverTooltip($"{tooltip}\nDefault Value: {defaultValue}");
|
||||||
ImUtf8.HoverTooltip($"{tooltip}\nDefault Value: {defaultValue}");
|
else
|
||||||
else
|
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, tooltip);
|
||||||
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, tooltip);
|
|
||||||
|
return newValue != currentValue;
|
||||||
return newValue != currentValue;
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
/// <summary>
|
/// A checkmark that compares against a default value and shows a tooltip.
|
||||||
/// A checkmark that compares against a default value and shows a tooltip.
|
/// Returns true if newValue is changed against currentValue.
|
||||||
/// Returns true if newValue is changed against currentValue.
|
/// </summary>
|
||||||
/// </summary>
|
protected static bool Checkmark(ReadOnlySpan<byte> label, ReadOnlySpan<byte> tooltip, bool currentValue, bool defaultValue,
|
||||||
protected static bool Checkmark(ReadOnlySpan<byte> label, ReadOnlySpan<byte> tooltip, bool currentValue, bool defaultValue,
|
out bool newValue)
|
||||||
out bool newValue)
|
{
|
||||||
{
|
var c = defaultValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value();
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.FrameBg,
|
using var color = ImGuiColor.FrameBackground.Push(c, defaultValue != currentValue);
|
||||||
defaultValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value(),
|
newValue = currentValue;
|
||||||
defaultValue != currentValue);
|
ImUtf8.Checkbox(label, ref newValue);
|
||||||
newValue = currentValue;
|
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, tooltip);
|
||||||
ImUtf8.Checkbox(label, ref newValue);
|
return newValue != currentValue;
|
||||||
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, tooltip);
|
}
|
||||||
return newValue != currentValue;
|
|
||||||
}
|
/// <summary>
|
||||||
|
/// A checkmark that compares against a default value and shows a tooltip.
|
||||||
/// <summary>
|
/// Returns true if newValue is changed against currentValue.
|
||||||
/// A checkmark that compares against a default value and shows a tooltip.
|
/// </summary>
|
||||||
/// Returns true if newValue is changed against currentValue.
|
protected static bool Checkmark(ReadOnlySpan<byte> label, ReadOnlySpan<char> tooltip, bool currentValue, bool defaultValue,
|
||||||
/// </summary>
|
out bool newValue)
|
||||||
protected static bool Checkmark(ReadOnlySpan<byte> label, ReadOnlySpan<char> tooltip, bool currentValue, bool defaultValue,
|
{
|
||||||
out bool newValue)
|
var c = defaultValue != currentValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value();
|
||||||
{
|
using var color = ImGuiColor.FrameBackground.Push(c, defaultValue != currentValue);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.FrameBg,
|
newValue = currentValue;
|
||||||
defaultValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value(),
|
ImUtf8.Checkbox(label, ref newValue);
|
||||||
defaultValue != currentValue);
|
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, tooltip);
|
||||||
newValue = currentValue;
|
return newValue != currentValue;
|
||||||
ImUtf8.Checkbox(label, ref newValue);
|
}
|
||||||
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, tooltip);
|
|
||||||
return newValue != currentValue;
|
protected void DrawMetaButtons(TIdentifier identifier, TEntry entry)
|
||||||
}
|
{
|
||||||
|
ImGui.TableNextColumn();
|
||||||
protected void DrawMetaButtons(TIdentifier identifier, TEntry entry)
|
CopyToClipboardButton("Copy this manipulation to clipboard."u8,
|
||||||
{
|
new Lazy<JToken?>(() => new JArray { MetaDictionary.Serialize(identifier, entry)! }));
|
||||||
ImGui.TableNextColumn();
|
|
||||||
CopyToClipboardButton("Copy this manipulation to clipboard."u8, new Lazy<JToken?>(() => new JArray { MetaDictionary.Serialize(identifier, entry)! }));
|
ImGui.TableNextColumn();
|
||||||
|
if (ImUtf8.IconButton(FontAwesomeIcon.Trash, "Delete this meta manipulation."u8))
|
||||||
ImGui.TableNextColumn();
|
Editor.Changes |= Editor.Remove(identifier);
|
||||||
if (ImUtf8.IconButton(FontAwesomeIcon.Trash, "Delete this meta manipulation."u8))
|
}
|
||||||
Editor.Changes |= Editor.Remove(identifier);
|
|
||||||
}
|
protected void CopyToClipboardButton(ReadOnlySpan<byte> tooltip, Lazy<JToken?> manipulations)
|
||||||
|
{
|
||||||
protected void CopyToClipboardButton(ReadOnlySpan<byte> tooltip, Lazy<JToken?> manipulations)
|
if (!ImUtf8.IconButton(FontAwesomeIcon.Clipboard, tooltip))
|
||||||
{
|
return;
|
||||||
if (!ImUtf8.IconButton(FontAwesomeIcon.Clipboard, tooltip))
|
|
||||||
return;
|
var text = Functions.ToCompressedBase64(manipulations.Value, 0);
|
||||||
|
if (text.Length > 0)
|
||||||
var text = Functions.ToCompressedBase64(manipulations.Value, 0);
|
ImGui.SetClipboardText(text);
|
||||||
if (text.Length > 0)
|
}
|
||||||
ImGui.SetClipboardText(text);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
|
using ImSharp;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
|
|
@ -161,8 +162,8 @@ public sealed class ShpMetaDrawer(ModMetaEditor editor, MetaFileManager metaFile
|
||||||
if (all)
|
if (all)
|
||||||
{
|
{
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.05f, 0.5f));
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0.05f, 0.5f));
|
||||||
ImUtf8.TextFramed("All IDs"u8, ImGui.GetColorU32(ImGuiCol.FrameBg, all || allSlots ? ImGui.GetStyle().DisabledAlpha : 1f),
|
ImUtf8.TextFramed("All IDs"u8, ImGuiColor.FrameBackground.Get(all || allSlots ? ImGui.GetStyle().DisabledAlpha : 1f).Color,
|
||||||
new Vector2(unscaledWidth, 0), ImGui.GetColorU32(ImGuiCol.TextDisabled));
|
new Vector2(unscaledWidth, 0), ImGuiColor.TextDisabled.Get().Color);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -232,7 +233,7 @@ public sealed class ShpMetaDrawer(ModMetaEditor editor, MetaFileManager metaFile
|
||||||
var ret = false;
|
var ret = false;
|
||||||
var ptr = Unsafe.AsPointer(ref buffer);
|
var ptr = Unsafe.AsPointer(ref buffer);
|
||||||
var span = new Span<byte>(ptr, ShapeAttributeString.MaxLength + 1);
|
var span = new Span<byte>(ptr, ShapeAttributeString.MaxLength + 1);
|
||||||
using (new ImRaii.ColorStyle().Push(ImGuiCol.Border, Colors.RegexWarningBorder, !valid).Push(ImGuiStyleVar.FrameBorderSize, 1f, !valid))
|
using (ImStyleBorder.Frame.Push(Colors.RegexWarningBorder, Im.Style.GlobalScale, !valid))
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale);
|
||||||
if (ImUtf8.InputText("##shpShape"u8, span, out int newLength, "Shape Key..."u8))
|
if (ImUtf8.InputText("##shpShape"u8, span, out int newLength, "Shape Key..."u8))
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ public partial class ModEditWindow
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
using var id = ImUtf8.PushId(index);
|
using var id = ImUtf8.PushId(index);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), deformer.RacialDeformer.IsEmpty);
|
using var color = ImGuiColor.Text.Push(Im.Style[ImGuiColor.TextDisabled], deformer.RacialDeformer.IsEmpty);
|
||||||
if (ImUtf8.Selectable(name, deformer.GenderRace == _pbdData.SelectedRaceCode))
|
if (ImUtf8.Selectable(name, deformer.GenderRace == _pbdData.SelectedRaceCode))
|
||||||
{
|
{
|
||||||
_pbdData.SelectedRaceCode = deformer.GenderRace;
|
_pbdData.SelectedRaceCode = deformer.GenderRace;
|
||||||
|
|
@ -61,7 +61,7 @@ public partial class ModEditWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
color.Push(ImGuiCol.Text, metaColor);
|
color.Push(ImGuiColor.Text, metaColor);
|
||||||
ImUtf8.TextRightAligned(raceCode);
|
ImUtf8.TextRightAligned(raceCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -142,7 +142,7 @@ public partial class ModEditWindow
|
||||||
var ret = false;
|
var ret = false;
|
||||||
ImUtf8.TextFrameAligned("Copy the values of the bone "u8);
|
ImUtf8.TextFrameAligned("Copy the values of the bone "u8);
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
using (ImRaii.PushColor(ImGuiCol.Text, ColorId.NewMod.Value()))
|
using (ImGuiColor.Text.Push(ColorId.NewMod.Value()))
|
||||||
{
|
{
|
||||||
ImUtf8.TextFrameAligned(_pbdData.SelectedBone);
|
ImUtf8.TextFrameAligned(_pbdData.SelectedBone);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ public partial class ModEditWindow
|
||||||
var selected = _selectedFiles.Contains(registry);
|
var selected = _selectedFiles.Contains(registry);
|
||||||
var color = registry.SubModUsage.Count == 0 ? ColorId.ConflictingMod :
|
var color = registry.SubModUsage.Count == 0 ? ColorId.ConflictingMod :
|
||||||
registry.CurrentUsage == registry.SubModUsage.Count ? ColorId.NewMod : ColorId.InheritedMod;
|
registry.CurrentUsage == registry.SubModUsage.Count ? ColorId.NewMod : ColorId.InheritedMod;
|
||||||
using (ImRaii.PushColor(ImGuiCol.Text, color.Value()))
|
using (ImGuiColor.Text.Push(color.Value()))
|
||||||
{
|
{
|
||||||
if (Im.Selectable(registry.RelPath.Path.Span, selected))
|
if (Im.Selectable(registry.RelPath.Path.Span, selected))
|
||||||
{
|
{
|
||||||
|
|
@ -290,9 +290,9 @@ public partial class ModEditWindow
|
||||||
{
|
{
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
ImGui.SetCursorPosX(pos);
|
ImGui.SetCursorPosX(pos);
|
||||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
{
|
{
|
||||||
ImGuiUtil.TextColored(0xFF00B0B0, FontAwesomeIcon.ExclamationCircle.ToIconString());
|
ImGuiUtil.TextColored(0xFF00B0B0, FontAwesomeIcon.ExclamationCircle.ToIconString());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImUtf8.HoverTooltip("The game path and the file do not have the same extension."u8);
|
ImUtf8.HoverTooltip("The game path and the file do not have the same extension."u8);
|
||||||
|
|
@ -333,9 +333,9 @@ public partial class ModEditWindow
|
||||||
{
|
{
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
ImGui.SetCursorPosX(pos);
|
ImGui.SetCursorPosX(pos);
|
||||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
{
|
{
|
||||||
ImGuiUtil.TextColored(0xFF00B0B0, FontAwesomeIcon.ExclamationCircle.ToIconString());
|
ImGuiUtil.TextColored(0xFF00B0B0, FontAwesomeIcon.ExclamationCircle.ToIconString());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImUtf8.HoverTooltip("The game path and the file do not have the same extension."u8);
|
ImUtf8.HoverTooltip("The game path and the file do not have the same extension."u8);
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ public partial class ModEditWindow
|
||||||
var text = $"{otherOptionData.TotalCount} Edits in other Options";
|
var text = $"{otherOptionData.TotalCount} Edits in other Options";
|
||||||
var size = ImGui.CalcTextSize(text).X;
|
var size = ImGui.CalcTextSize(text).X;
|
||||||
ImGui.SetCursorPos(new Vector2(ImGui.GetContentRegionAvail().X - size, oldPos + ImGui.GetStyle().FramePadding.Y));
|
ImGui.SetCursorPos(new Vector2(ImGui.GetContentRegionAvail().X - size, oldPos + ImGui.GetStyle().FramePadding.Y));
|
||||||
ImGuiUtil.TextColored(ColorId.RedundantAssignment.Value() | 0xFF000000, text);
|
Im.Text(text, ColorId.RedundantAssignment.Value().FullAlpha());
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
{
|
{
|
||||||
using var tt = ImUtf8.Tooltip();
|
using var tt = ImUtf8.Tooltip();
|
||||||
|
|
|
||||||
|
|
@ -275,9 +275,9 @@ public partial class ModEditWindow
|
||||||
if (tab.GamePaths!.Count == 1)
|
if (tab.GamePaths!.Count == 1)
|
||||||
{
|
{
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0, 0.5f));
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0, 0.5f));
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.FrameBg))
|
using var color = ImGuiColor.Button.Push(Im.Style[ImGuiColor.FrameBackground])
|
||||||
.Push(ImGuiCol.ButtonHovered, ImGui.GetColorU32(ImGuiCol.FrameBgHovered))
|
.Push(ImGuiColor.ButtonHovered, Im.Style[ImGuiColor.FrameBackgroundHovered])
|
||||||
.Push(ImGuiCol.ButtonActive, ImGui.GetColorU32(ImGuiCol.FrameBgActive));
|
.Push(ImGuiColor.ButtonActive, Im.Style[ImGuiColor.FrameBackgroundActive]);
|
||||||
using var group = ImRaii.Group();
|
using var group = ImRaii.Group();
|
||||||
ImGui.Button(preview, new Vector2(buttonWidth, 0));
|
ImGui.Button(preview, new Vector2(buttonWidth, 0));
|
||||||
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X);
|
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X);
|
||||||
|
|
@ -310,7 +310,7 @@ public partial class ModEditWindow
|
||||||
var width = ImGui.CalcTextSize(text).X + framePadding.X * 2;
|
var width = ImGui.CalcTextSize(text).X + framePadding.X * 2;
|
||||||
|
|
||||||
// Draw the link button. We set the background colour to transparent to mimic the look of a link.
|
// Draw the link button. We set the background colour to transparent to mimic the look of a link.
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button, 0x00000000);
|
using var color = ImGuiColor.Button.Push(Vector4.Zero);
|
||||||
SupportButton.Link(Penumbra.Messager, text, address, width, ""u8);
|
SupportButton.Link(Penumbra.Messager, text, address, width, ""u8);
|
||||||
|
|
||||||
// Draw an underline for the text.
|
// Draw an underline for the text.
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,7 @@ public partial class ModEditWindow
|
||||||
|
|
||||||
var ret = ImUtf8.CollapsingHeader(label);
|
var ret = ImUtf8.CollapsingHeader(label);
|
||||||
ImGui.GetWindowDrawList()
|
ImGui.GetWindowDrawList()
|
||||||
.AddText(UiBuilder.DefaultFont, UiBuilder.DefaultFont.FontSize, pos, ImGui.GetColorU32(ImGuiCol.Text), "Layout");
|
.AddText(UiBuilder.DefaultFont, UiBuilder.DefaultFont.FontSize, pos, ImGuiColor.Text.Get().Color, "Layout");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,7 +403,7 @@ public partial class ModEditWindow
|
||||||
ImGui.TableSetupColumn("w", ImGuiTableColumnFlags.WidthFixed, 250 * UiHelpers.Scale);
|
ImGui.TableSetupColumn("w", ImGuiTableColumnFlags.WidthFixed, 250 * UiHelpers.Scale);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
var textColorStart = ImGui.GetColorU32(ImGuiCol.Text);
|
var textColorStart = ImGuiColor.Text.Get().Color;
|
||||||
|
|
||||||
var ret = false;
|
var ret = false;
|
||||||
for (var i = 0; i < tab.Matrix.GetLength(0); ++i)
|
for (var i = 0; i < tab.Matrix.GetLength(0); ++i)
|
||||||
|
|
@ -424,7 +424,7 @@ public partial class ModEditWindow
|
||||||
var deletable = !disabled && idx >= 0;
|
var deletable = !disabled && idx >= 0;
|
||||||
using (ImRaii.PushFont(UiBuilder.MonoFont, tooltip.Length > 0))
|
using (ImRaii.PushFont(UiBuilder.MonoFont, tooltip.Length > 0))
|
||||||
{
|
{
|
||||||
using (ImRaii.PushColor(ImGuiCol.Text, color))
|
using (ImGuiColor.Text.Push(color))
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImUtf8.Selectable(name);
|
ImUtf8.Selectable(name);
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ public partial class ModEditWindow
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using var id = ImRaii.PushId(label);
|
using var id = ImRaii.PushId(label);
|
||||||
ImGuiUtil.DrawTextButton(label, new Vector2(-1, 0), ImGui.GetColorU32(ImGuiCol.FrameBg));
|
ImEx.TextFramed(label, new Vector2(-1, 0), ImGuiColor.FrameBackground.Get());
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
||||||
using (ImRaii.Disabled(!_center.SaveTask.IsCompleted))
|
using (ImRaii.Disabled(!_center.SaveTask.IsCompleted))
|
||||||
|
|
@ -206,7 +206,7 @@ public partial class ModEditWindow
|
||||||
case TaskStatus.Faulted:
|
case TaskStatus.Faulted:
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted("Could not save file:");
|
ImGui.TextUnformatted("Could not save file:");
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, 0xFF0000FF);
|
using var color = ImGuiColor.Text.Push(new Vector4(1, 0, 0, 1));
|
||||||
ImGuiUtil.TextWrapped(_center.SaveTask.Exception?.ToString() ?? "Unknown Error");
|
ImGuiUtil.TextWrapped(_center.SaveTask.Exception?.ToString() ?? "Unknown Error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ public partial class ModEditWindow : Window, IDisposable, Luna.IUiService
|
||||||
var offsetX = ImGui.GetContentRegionAvail().X / 2 - radius;
|
var offsetX = ImGui.GetContentRegionAvail().X / 2 - radius;
|
||||||
var offsetY = ImGui.GetContentRegionAvail().Y / 2 - radius;
|
var offsetY = ImGui.GetContentRegionAvail().Y / 2 - radius;
|
||||||
ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(offsetX, offsetY));
|
ImGui.SetCursorPos(ImGui.GetCursorPos() + new Vector2(offsetX, offsetY));
|
||||||
ImUtf8.Spinner("##spinner"u8, radius, thickness, ImGui.GetColorU32(ImGuiCol.Text));
|
ImEx.Spinner("##spinner"u8, radius, thickness, ImGuiColor.Text.Get());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -501,7 +501,7 @@ public partial class ModEditWindow : Window, IDisposable, Luna.IUiService
|
||||||
{
|
{
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
ImGuiUtil.DrawTextButton($"There are {otherSwaps} file swaps configured in other options.", Vector2.Zero,
|
ImGuiUtil.DrawTextButton($"There are {otherSwaps} file swaps configured in other options.", Vector2.Zero,
|
||||||
ColorId.RedundantAssignment.Value());
|
ColorId.RedundantAssignment.Value().Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
using var child = ImRaii.Child("##swaps", -Vector2.One, true);
|
using var child = ImRaii.Child("##swaps", -Vector2.One, true);
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ public class ModMergeTab(ModMerger modMerger) : Luna.IUiService
|
||||||
var color = group != null || modMerger.OptionGroupName.Length == 0 && modMerger.OptionName.Length == 0
|
var color = group != null || modMerger.OptionGroupName.Length == 0 && modMerger.OptionName.Length == 0
|
||||||
? Colors.PressEnterWarningBg
|
? Colors.PressEnterWarningBg
|
||||||
: Colors.DiscordColor;
|
: Colors.DiscordColor;
|
||||||
using var c = ImRaii.PushColor(ImGuiCol.Border, color);
|
using var c = ImGuiColor.Border.Push(color);
|
||||||
ImGui.SetNextItemWidth(buttonWidth);
|
ImGui.SetNextItemWidth(buttonWidth);
|
||||||
ImGui.InputTextWithHint("##optionGroupInput", "Target Option Group", ref modMerger.OptionGroupName, 64);
|
ImGui.InputTextWithHint("##optionGroupInput", "Target Option Group", ref modMerger.OptionGroupName, 64);
|
||||||
ImGuiUtil.HoverTooltip(
|
ImGuiUtil.HoverTooltip(
|
||||||
|
|
@ -96,7 +96,7 @@ public class ModMergeTab(ModMerger modMerger) : Luna.IUiService
|
||||||
: group == null || group.Options.Any(o => o.Name == modMerger.OptionName)
|
: group == null || group.Options.Any(o => o.Name == modMerger.OptionName)
|
||||||
? Colors.PressEnterWarningBg
|
? Colors.PressEnterWarningBg
|
||||||
: Colors.DiscordColor;
|
: Colors.DiscordColor;
|
||||||
c.Push(ImGuiCol.Border, color);
|
c.Push(ImGuiColor.Border, color);
|
||||||
ImGui.SetNextItemWidth(buttonWidth);
|
ImGui.SetNextItemWidth(buttonWidth);
|
||||||
ImGui.InputTextWithHint("##optionInput", "Target Option Name", ref modMerger.OptionName, 64);
|
ImGui.InputTextWithHint("##optionInput", "Target Option Name", ref modMerger.OptionName, 64);
|
||||||
ImGuiUtil.HoverTooltip(
|
ImGuiUtil.HoverTooltip(
|
||||||
|
|
@ -249,7 +249,7 @@ public class ModMergeTab(ModMerger modMerger) : Luna.IUiService
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.Dummy(Vector2.One);
|
ImGui.Dummy(Vector2.One);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, Colors.TutorialBorder);
|
using var color = ImGuiColor.Text.Push(Colors.TutorialBorder);
|
||||||
foreach (var warning in modMerger.Warnings.SkipLast(1))
|
foreach (var warning in modMerger.Warnings.SkipLast(1))
|
||||||
{
|
{
|
||||||
ImGuiUtil.TextWrapped(warning);
|
ImGuiUtil.TextWrapped(warning);
|
||||||
|
|
@ -266,7 +266,7 @@ public class ModMergeTab(ModMerger modMerger) : Luna.IUiService
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.Dummy(Vector2.One);
|
ImGui.Dummy(Vector2.One);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, Colors.RegexWarningBorder);
|
using var color = ImGuiColor.Text.Push(Colors.RegexWarningBorder);
|
||||||
ImGuiUtil.TextWrapped(modMerger.Error.ToString());
|
ImGuiUtil.TextWrapped(modMerger.Error.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using OtterGui.Raii;
|
using ImSharp;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
using MouseWheelType = OtterGui.Widgets.MouseWheelType;
|
||||||
|
|
||||||
namespace Penumbra.UI.AdvancedWindow;
|
namespace Penumbra.UI.AdvancedWindow;
|
||||||
|
|
||||||
|
|
@ -11,12 +12,12 @@ public sealed class OptionSelectCombo(ModEditor editor, ModEditWindow window)
|
||||||
: FilterComboCache<(string FullName, (int Group, int Data) Index)>(
|
: FilterComboCache<(string FullName, (int Group, int Data) Index)>(
|
||||||
() => window.Mod!.AllDataContainers.Select(c => (c.GetFullName(), c.GetDataIndices())).ToList(), MouseWheelType.Control, Penumbra.Log)
|
() => window.Mod!.AllDataContainers.Select(c => (c.GetFullName(), c.GetDataIndices())).ToList(), MouseWheelType.Control, Penumbra.Log)
|
||||||
{
|
{
|
||||||
private ImRaii.ColorStyle _border;
|
private readonly Im.ColorStyleDisposable _border = new();
|
||||||
|
|
||||||
protected override void DrawCombo(string label, string preview, string tooltip, int currentSelected, float previewWidth, float itemHeight,
|
protected override void DrawCombo(string label, string preview, string tooltip, int currentSelected, float previewWidth, float itemHeight,
|
||||||
ImGuiComboFlags flags)
|
ImGuiComboFlags flags)
|
||||||
{
|
{
|
||||||
_border = ImRaii.PushFrameBorder(ImUtf8.GlobalScale, ColorId.FolderLine.Value());
|
_border.PushBorder(ImStyleBorder.Frame, ColorId.FolderLine.Value());
|
||||||
base.DrawCombo(label, preview, tooltip, currentSelected, previewWidth, itemHeight, flags);
|
base.DrawCombo(label, preview, tooltip, currentSelected, previewWidth, itemHeight, flags);
|
||||||
_border.Dispose();
|
_border.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ public class ResourceTreeViewer(
|
||||||
else if (_task.Exception != null)
|
else if (_task.Exception != null)
|
||||||
{
|
{
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, Colors.RegexWarningBorder);
|
using var color = ImGuiColor.Text.Push(Colors.RegexWarningBorder);
|
||||||
ImGui.TextUnformatted($"Error during calculation of character list:\n\n{_task.Exception}");
|
ImGui.TextUnformatted($"Error during calculation of character list:\n\n{_task.Exception}");
|
||||||
}
|
}
|
||||||
else if (_task.IsCompletedSuccessfully)
|
else if (_task.IsCompletedSuccessfully)
|
||||||
|
|
@ -82,7 +82,7 @@ public class ResourceTreeViewer(
|
||||||
if (!_categoryFilter.HasFlag(category) || !tree.Name.Contains(_nameFilter, StringComparison.OrdinalIgnoreCase))
|
if (!_categoryFilter.HasFlag(category) || !tree.Name.Contains(_nameFilter, StringComparison.OrdinalIgnoreCase))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
using (var c = ImRaii.PushColor(ImGuiCol.Text, CategoryColor(category).Value()))
|
using (ImGuiColor.Text.Push(CategoryColor(category).Value()))
|
||||||
{
|
{
|
||||||
var isOpen = ImGui.CollapsingHeader($"{(incognito.IncognitoMode ? tree.AnonymizedName : tree.Name)}###{index}",
|
var isOpen = ImGui.CollapsingHeader($"{(incognito.IncognitoMode ? tree.AnonymizedName : tree.Name)}###{index}",
|
||||||
index == 0 ? ImGuiTreeNodeFlags.DefaultOpen : 0);
|
index == 0 ? ImGuiTreeNodeFlags.DefaultOpen : 0);
|
||||||
|
|
@ -164,7 +164,7 @@ public class ResourceTreeViewer(
|
||||||
if (!gameData.HasModifiedGameDataFiles)
|
if (!gameData.HasModifiedGameDataFiles)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using var style = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudOrange);
|
using var style = ImGuiColor.Text.Push(ImGuiColors.DalamudOrange);
|
||||||
|
|
||||||
ImUtf8.TextWrapped(
|
ImUtf8.TextWrapped(
|
||||||
"Dalamud is reporting your FFXIV installation has modified game files. Any mods installed through TexTools will produce this message."u8);
|
"Dalamud is reporting your FFXIV installation has modified game files. Any mods installed through TexTools will produce this message."u8);
|
||||||
|
|
@ -189,18 +189,18 @@ public class ResourceTreeViewer(
|
||||||
var checkPadding = 10 * ImGuiHelpers.GlobalScale + ImGui.GetStyle().ItemSpacing.X;
|
var checkPadding = 10 * ImGuiHelpers.GlobalScale + ImGui.GetStyle().ItemSpacing.X;
|
||||||
ImGui.SameLine(0, checkPadding);
|
ImGui.SameLine(0, checkPadding);
|
||||||
|
|
||||||
using (var id = ImRaii.PushId("TreeCategoryFilter"))
|
using (ImRaii.PushId("TreeCategoryFilter"))
|
||||||
{
|
{
|
||||||
var categoryFilter = (uint)_categoryFilter;
|
var categoryFilter = (uint)_categoryFilter;
|
||||||
foreach (var category in Enum.GetValues<TreeCategory>())
|
foreach (var category in Enum.GetValues<TreeCategory>())
|
||||||
{
|
{
|
||||||
using var c = ImRaii.PushColor(ImGuiCol.CheckMark, CategoryColor(category).Value());
|
using var c = ImGuiColor.CheckMark.Push(CategoryColor(category).Value());
|
||||||
ImGui.CheckboxFlags($"##{category}", ref categoryFilter, (uint)category);
|
ImGui.CheckboxFlags($"##{category}", ref categoryFilter, (uint)category);
|
||||||
ImGuiUtil.HoverTooltip(CategoryFilterDescription(category));
|
ImGuiUtil.HoverTooltip(CategoryFilterDescription(category));
|
||||||
ImGui.SameLine(0.0f, checkSpacing);
|
ImGui.SameLine(0.0f, checkSpacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
_categoryFilter = (TreeCategory)categoryFilter;
|
_categoryFilter = (TreeCategory)categoryFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine(0, checkPadding);
|
ImGui.SameLine(0, checkPadding);
|
||||||
|
|
@ -257,7 +257,7 @@ public class ResourceTreeViewer(
|
||||||
if (visibility == NodeVisibility.Hidden)
|
if (visibility == NodeVisibility.Hidden)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
using var mutedColor = ImRaii.PushColor(ImGuiCol.Text, ImGuiUtil.HalfTransparentText(), resourceNode.Internal);
|
using var mutedColor = ImGuiColor.Text.Push(ImGuiUtil.HalfTransparentText(), resourceNode.Internal);
|
||||||
|
|
||||||
var filterIcon = resourceNode.IconFlag != 0 ? resourceNode.IconFlag : parentFilterIconFlag;
|
var filterIcon = resourceNode.IconFlag != 0 ? resourceNode.IconFlag : parentFilterIconFlag;
|
||||||
|
|
||||||
|
|
@ -335,7 +335,7 @@ public class ResourceTreeViewer(
|
||||||
var modName = $"[{(hasMod ? mod!.Name : resourceNode.ModName)}]";
|
var modName = $"[{(hasMod ? mod!.Name : resourceNode.ModName)}]";
|
||||||
var textPos = ImGui.GetCursorPosX() + ImUtf8.CalcTextSize(modName).X + ImGui.GetStyle().ItemInnerSpacing.X;
|
var textPos = ImGui.GetCursorPosX() + ImUtf8.CalcTextSize(modName).X + ImGui.GetStyle().ItemInnerSpacing.X;
|
||||||
using var group = ImUtf8.Group();
|
using var group = ImUtf8.Group();
|
||||||
using (var color = ImRaii.PushColor(ImGuiCol.Text, (hasMod ? ColorId.NewMod : ColorId.DisabledMod).Value()))
|
using (ImGuiColor.Text.Push((hasMod ? ColorId.NewMod : ColorId.DisabledMod).Value()))
|
||||||
{
|
{
|
||||||
ImUtf8.Selectable(modName, false, ImGuiSelectableFlags.AllowItemOverlap,
|
ImUtf8.Selectable(modName, false, ImGuiSelectableFlags.AllowItemOverlap,
|
||||||
new Vector2(ImGui.GetContentRegionAvail().X, frameHeight));
|
new Vector2(ImGui.GetContentRegionAvail().X, frameHeight));
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ public class ChangedItemDrawer : IDisposable, IUiService
|
||||||
|
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
using var color = ImGuiColor.Text.Push(ColorId.ItemId.Value());
|
using var color = ImGuiColor.Text.Push(ColorId.ItemId.Value());
|
||||||
Im.Cursor.Y += height - Im.Style.TextHeight / 2;
|
Im.Cursor.Y += (height - Im.Style.TextHeight) / 2;
|
||||||
ImEx.TextRightAligned(additionalData, Im.Style.ItemInnerSpacing.X);
|
ImEx.TextRightAligned(additionalData, Im.Style.ItemInnerSpacing.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,7 +156,7 @@ public class ChangedItemDrawer : IDisposable, IUiService
|
||||||
|
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
using var color = ImGuiColor.Text.Push(ColorId.ItemId.Value());
|
using var color = ImGuiColor.Text.Push(ColorId.ItemId.Value());
|
||||||
Im.Cursor.Y += height - Im.Style.TextHeight / 2;
|
Im.Cursor.Y += (height - Im.Style.TextHeight) / 2;
|
||||||
ImEx.TextRightAligned(text, Im.Style.ItemInnerSpacing.X);
|
ImEx.TextRightAligned(text, Im.Style.ItemInnerSpacing.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ public class MigrationSectionDrawer(MigrationManager migrationManager, Configura
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
ImUtf8.Spinner("Spinner"u8, ImGui.GetTextLineHeight() / 2, 2, ImGui.GetColorU32(ImGuiCol.Text));
|
ImEx.Spinner("Spinner"u8, ImGui.GetTextLineHeight() / 2, 2, ImGuiColor.Text.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawCancelButton(MigrationManager.TaskType task, ReadOnlySpan<byte> tooltip)
|
private void DrawCancelButton(MigrationManager.TaskType task, ReadOnlySpan<byte> tooltip)
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@ public sealed class CollectionPanel(
|
||||||
if (!context)
|
if (!context)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using (var color = ImRaii.PushColor(ImGuiCol.Text, Colors.DiscordColor))
|
using (var color = ImGuiColor.Text.Push(Colors.DiscordColor))
|
||||||
{
|
{
|
||||||
if (ImGui.MenuItem("Use no mods."))
|
if (ImGui.MenuItem("Use no mods."))
|
||||||
_active.SetCollection(ModCollection.Empty, type, _active.Individuals.GetGroup(identifier));
|
_active.SetCollection(ModCollection.Empty, type, _active.Individuals.GetGroup(identifier));
|
||||||
|
|
@ -291,7 +291,7 @@ public sealed class CollectionPanel(
|
||||||
|
|
||||||
if (collection != null && type.CanBeRemoved())
|
if (collection != null && type.CanBeRemoved())
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, Colors.RegexWarningBorder);
|
using var color = ImGuiColor.Text.Push(Colors.RegexWarningBorder);
|
||||||
if (ImGui.MenuItem("Remove this assignment."))
|
if (ImGui.MenuItem("Remove this assignment."))
|
||||||
_active.SetCollection(null, type, _active.Individuals.GetGroup(identifier));
|
_active.SetCollection(null, type, _active.Individuals.GetGroup(identifier));
|
||||||
}
|
}
|
||||||
|
|
@ -303,15 +303,15 @@ public sealed class CollectionPanel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DrawButton(string text, CollectionType type, Vector2 width, uint borderColor, ActorIdentifier id, char suffix,
|
private bool DrawButton(string text, CollectionType type, Vector2 width, Rgba32 borderColor, ActorIdentifier id, char suffix,
|
||||||
ModCollection? collection = null)
|
ModCollection? collection = null)
|
||||||
{
|
{
|
||||||
using var group = ImRaii.Group();
|
using var group = ImRaii.Group();
|
||||||
var invalid = type == CollectionType.Individual && !id.IsValid;
|
var invalid = type == CollectionType.Individual && !id.IsValid;
|
||||||
var redundancy = _active.RedundancyCheck(type, id);
|
var redundancy = _active.RedundancyCheck(type, id);
|
||||||
collection ??= _active.ByType(type, id);
|
collection ??= _active.ByType(type, id);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button,
|
using var color = ImGuiColor.Button.Push(
|
||||||
collection == null
|
collection is null
|
||||||
? ColorId.NoAssignment.Value()
|
? ColorId.NoAssignment.Value()
|
||||||
: redundancy.Length > 0
|
: redundancy.Length > 0
|
||||||
? ColorId.RedundantAssignment.Value()
|
? ColorId.RedundantAssignment.Value()
|
||||||
|
|
@ -319,8 +319,8 @@ public sealed class CollectionPanel(
|
||||||
? ColorId.SelectedCollection.Value()
|
? ColorId.SelectedCollection.Value()
|
||||||
: collection == ModCollection.Empty
|
: collection == ModCollection.Empty
|
||||||
? ColorId.NoModsAssignment.Value()
|
? ColorId.NoModsAssignment.Value()
|
||||||
: ImGui.GetColorU32(ImGuiCol.Button), !invalid)
|
: ImGuiColor.Button.Get(), !invalid)
|
||||||
.Push(ImGuiCol.Border, borderColor == 0 ? ImGui.GetColorU32(ImGuiCol.TextDisabled) : borderColor);
|
.Push(ImGuiColor.Border, borderColor == 0 ? ImGuiColor.TextDisabled.Get().Color : borderColor);
|
||||||
using var disabled = ImRaii.Disabled(invalid);
|
using var disabled = ImRaii.Disabled(invalid);
|
||||||
var button = ImGui.Button(text, width) || ImGui.IsItemClicked(ImGuiMouseButton.Right);
|
var button = ImGui.Button(text, width) || ImGui.IsItemClicked(ImGuiMouseButton.Right);
|
||||||
var hovered = redundancy.Length > 0 && ImGui.IsItemHovered();
|
var hovered = redundancy.Length > 0 && ImGui.IsItemHovered();
|
||||||
|
|
@ -332,7 +332,7 @@ public sealed class CollectionPanel(
|
||||||
var name = Name(collection);
|
var name = Name(collection);
|
||||||
var size = ImGui.CalcTextSize(name);
|
var size = ImGui.CalcTextSize(name);
|
||||||
var textPos = ImGui.GetItemRectMax() - size - ImGui.GetStyle().FramePadding;
|
var textPos = ImGui.GetItemRectMax() - size - ImGui.GetStyle().FramePadding;
|
||||||
ImGui.GetWindowDrawList().AddText(textPos, ImGui.GetColorU32(ImGuiCol.Text), name);
|
ImGui.GetWindowDrawList().AddText(textPos, ImGuiColor.Text.Get().Color, name);
|
||||||
DrawContext(button, collection, type, id, text, suffix);
|
DrawContext(button, collection, type, id, text, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -484,7 +484,7 @@ public sealed class CollectionPanel(
|
||||||
private void DrawCollectionName(ModCollection collection)
|
private void DrawCollectionName(ModCollection collection)
|
||||||
{
|
{
|
||||||
ImGui.Dummy(Vector2.One);
|
ImGui.Dummy(Vector2.One);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.MetaInfoText);
|
using var color = ImGuiColor.Border.Push(Colors.MetaInfoText);
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * UiHelpers.Scale);
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * UiHelpers.Scale);
|
||||||
using var f = _nameFont.Push();
|
using var f = _nameFont.Push();
|
||||||
var name = Name(collection);
|
var name = Name(collection);
|
||||||
|
|
@ -574,7 +574,7 @@ public sealed class CollectionPanel(
|
||||||
|
|
||||||
using var f = _nameFont.Push();
|
using var f = _nameFont.Push();
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale);
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.MetaInfoText);
|
using var color = ImGuiColor.Border.Push(Colors.MetaInfoText);
|
||||||
ImGuiUtil.DrawTextButton(Name(collection.Inheritance.DirectlyInheritedBy[0]), Vector2.Zero, 0);
|
ImGuiUtil.DrawTextButton(Name(collection.Inheritance.DirectlyInheritedBy[0]), Vector2.Zero, 0);
|
||||||
var constOffset = (ImGui.GetStyle().FramePadding.X + ImGuiHelpers.GlobalScale) * 2
|
var constOffset = (ImGui.GetStyle().FramePadding.X + ImGuiHelpers.GlobalScale) * 2
|
||||||
+ ImGui.GetStyle().ItemSpacing.X
|
+ ImGui.GetStyle().ItemSpacing.X
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
|
using ImSharp;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
|
|
@ -75,7 +76,7 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
|
||||||
|
|
||||||
protected override bool OnDraw(int idx)
|
protected override bool OnDraw(int idx)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Header, ColorId.SelectedCollection.Value());
|
using var color = ImGuiColor.Header.Push(ColorId.SelectedCollection.Value());
|
||||||
var ret = ImGui.Selectable(Name(Items[idx]), idx == CurrentIdx);
|
var ret = ImGui.Selectable(Name(Items[idx]), idx == CurrentIdx);
|
||||||
using var source = ImRaii.DragDropSource();
|
using var source = ImRaii.DragDropSource();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId("##Inheritance");
|
using var id = ImRaii.PushId("##Inheritance");
|
||||||
ImGuiUtil.DrawColoredText(($"The {TutorialService.SelectedCollection} ", 0),
|
ImGuiUtil.DrawColoredText(($"The {TutorialService.SelectedCollection} ", 0),
|
||||||
(Name(_active.Current), ColorId.SelectedCollection.Value() | 0xFF000000), (" inherits from:", 0));
|
(Name(_active.Current), ColorId.SelectedCollection.Value().FullAlpha().Color), (" inherits from:", 0));
|
||||||
ImGui.Dummy(Vector2.One);
|
ImGui.Dummy(Vector2.One);
|
||||||
|
|
||||||
DrawCurrentCollectionInheritance();
|
DrawCurrentCollectionInheritance();
|
||||||
|
|
@ -111,7 +111,7 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService
|
||||||
foreach (var inheritance in collection.Inheritance.FlatHierarchy.Skip(1))
|
foreach (var inheritance in collection.Inheritance.FlatHierarchy.Skip(1))
|
||||||
{
|
{
|
||||||
// Draw the child, already seen collections are colored as conflicts.
|
// Draw the child, already seen collections are colored as conflicts.
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.HandledConflictMod.Value(),
|
using var color = ImGuiColor.Text.Push(ColorId.HandledConflictMod.Value(),
|
||||||
_seenInheritedCollections.Contains(inheritance));
|
_seenInheritedCollections.Contains(inheritance));
|
||||||
_seenInheritedCollections.Add(inheritance);
|
_seenInheritedCollections.Add(inheritance);
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService
|
||||||
/// <summary> Draw a single primary inherited collection. </summary>
|
/// <summary> Draw a single primary inherited collection. </summary>
|
||||||
private void DrawInheritance(ModCollection collection)
|
private void DrawInheritance(ModCollection collection)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.HandledConflictMod.Value(),
|
using var color = ImGuiColor.Text.Push(ColorId.HandledConflictMod.Value(),
|
||||||
_seenInheritedCollections.Contains(collection));
|
_seenInheritedCollections.Contains(collection));
|
||||||
_seenInheritedCollections.Add(collection);
|
_seenInheritedCollections.Add(collection);
|
||||||
using var tree = ImRaii.TreeNode($"{Name(collection)}###{collection.Identity.Name}", ImGuiTreeNodeFlags.NoTreePushOnOpen);
|
using var tree = ImRaii.TreeNode($"{Name(collection)}###{collection.Identity.Name}", ImGuiTreeNodeFlags.NoTreePushOnOpen);
|
||||||
|
|
@ -172,10 +172,10 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService
|
||||||
private void DrawInheritanceTrashButton()
|
private void DrawInheritanceTrashButton()
|
||||||
{
|
{
|
||||||
var size = UiHelpers.IconButtonSize with { Y = ImGui.GetTextLineHeightWithSpacing() * InheritedCollectionHeight };
|
var size = UiHelpers.IconButtonSize with { Y = ImGui.GetTextLineHeightWithSpacing() * InheritedCollectionHeight };
|
||||||
var buttonColor = ImGui.GetColorU32(ImGuiCol.Button);
|
var buttonColor = Im.Style[ImGuiColor.Button];
|
||||||
// Prevent hovering from highlighting the button.
|
// Prevent hovering from highlighting the button.
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.ButtonActive, buttonColor)
|
using var color = ImGuiColor.ButtonActive.Push(buttonColor)
|
||||||
.Push(ImGuiCol.ButtonHovered, buttonColor);
|
.Push(ImGuiColor.ButtonHovered, buttonColor);
|
||||||
ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), size,
|
ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), size,
|
||||||
"Drag primary inheritance here to remove it from the list.", false, true);
|
"Drag primary inheritance here to remove it from the list.", false, true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ public sealed class ConfigWindow : Window, Luna.IUiService
|
||||||
|
|
||||||
private void DrawProblemWindow(string text)
|
private void DrawProblemWindow(string text)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, Colors.RegexWarningBorder);
|
using var color = ImGuiColor.Text.Push(Colors.RegexWarningBorder);
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
ImUtf8.TextWrapped(text);
|
ImUtf8.TextWrapped(text);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public readonly struct ImcModGroupEditDrawer(ModGroupEditDrawer editor, ImcModGr
|
||||||
var changes = false;
|
var changes = false;
|
||||||
|
|
||||||
var width = editor.AvailableWidth.X - 3 * ImUtf8.ItemInnerSpacing.X - ImUtf8.ItemSpacing.X - ImUtf8.CalcTextSize("All Variants"u8).X - ImUtf8.CalcTextSize("Only Attributes"u8).X - 2 * ImUtf8.FrameHeight;
|
var width = editor.AvailableWidth.X - 3 * ImUtf8.ItemInnerSpacing.X - ImUtf8.ItemSpacing.X - ImUtf8.CalcTextSize("All Variants"u8).X - ImUtf8.CalcTextSize("Only Attributes"u8).X - 2 * ImUtf8.FrameHeight;
|
||||||
ImUtf8.TextFramed(identifier.ToString(), 0, new Vector2(width, 0), borderColor: ImGui.GetColorU32(ImGuiCol.Border));
|
ImEx.TextFramed(identifier.ToString(), new Vector2(width, 0), Rgba32.Transparent);
|
||||||
|
|
||||||
ImUtf8.SameLineInner();
|
ImUtf8.SameLineInner();
|
||||||
var allVariants = group.AllVariants;
|
var allVariants = group.AllVariants;
|
||||||
|
|
@ -175,7 +175,7 @@ public readonly struct ImcModGroupEditDrawer(ModGroupEditDrawer editor, ImcModGr
|
||||||
protected override void RenderSymbol(bool value, Vector2 position, float size)
|
protected override void RenderSymbol(bool value, Vector2 position, float size)
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
SymbolHelpers.RenderCross(ImGui.GetWindowDrawList(), position, ImGui.GetColorU32(ImGuiCol.CheckMark), size);
|
SymbolHelpers.RenderCross(ImGui.GetWindowDrawList(), position, ImGuiColor.CheckMark.Get().Color, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool NextValue(bool value)
|
protected override bool NextValue(bool value)
|
||||||
|
|
|
||||||
|
|
@ -836,7 +836,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
||||||
|
|
||||||
ImGui.SetCursorPos(comboPos);
|
ImGui.SetCursorPos(comboPos);
|
||||||
// Draw combo button
|
// Draw combo button
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button, Colors.FilterActive, !everything);
|
using var color = ImGuiColor.Button.Push(Colors.FilterActive, !everything);
|
||||||
var rightClick = DrawFilterCombo(ref everything);
|
var rightClick = DrawFilterCombo(ref everything);
|
||||||
_tutorial.OpenTutorial(BasicTutorialSteps.ModFilters);
|
_tutorial.OpenTutorial(BasicTutorialSteps.ModFilters);
|
||||||
if (rightClick)
|
if (rightClick)
|
||||||
|
|
|
||||||
|
|
@ -1,347 +1,356 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using OtterGui;
|
using ImSharp;
|
||||||
using OtterGui.Services;
|
using Luna;
|
||||||
using OtterGui.Text;
|
using OtterGui;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Services;
|
||||||
using Penumbra.GameData.Data;
|
using OtterGui.Text;
|
||||||
using Penumbra.GameData.Enums;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.Mods;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.String;
|
using Penumbra.Mods;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.Mods.Manager;
|
||||||
|
using Penumbra.String;
|
||||||
namespace Penumbra.UI.ModsTab;
|
using Penumbra.UI.Classes;
|
||||||
|
|
||||||
public class ModPanelChangedItemsTab(
|
namespace Penumbra.UI.ModsTab;
|
||||||
ModFileSystemSelector selector,
|
|
||||||
ChangedItemDrawer drawer,
|
public class ModPanelChangedItemsTab(
|
||||||
ImGuiCacheService cacheService,
|
ModFileSystemSelector selector,
|
||||||
Configuration config,
|
ChangedItemDrawer drawer,
|
||||||
ModDataEditor dataEditor)
|
ImGuiCacheService cacheService,
|
||||||
: ITab, Luna.IUiService
|
Configuration config,
|
||||||
{
|
ModDataEditor dataEditor)
|
||||||
private readonly ImGuiCacheService.CacheId _cacheId = cacheService.GetNewId();
|
: ITab, Luna.IUiService
|
||||||
|
{
|
||||||
private class ChangedItemsCache
|
private readonly ImGuiCacheService.CacheId _cacheId = cacheService.GetNewId();
|
||||||
{
|
|
||||||
private Mod? _lastSelected;
|
private class ChangedItemsCache
|
||||||
private ushort _lastUpdate;
|
{
|
||||||
private ChangedItemIconFlag _filter = ChangedItemFlagExtensions.DefaultFlags;
|
private Mod? _lastSelected;
|
||||||
private ChangedItemMode _lastMode;
|
private ushort _lastUpdate;
|
||||||
private bool _reset;
|
private ChangedItemIconFlag _filter = ChangedItemFlagExtensions.DefaultFlags;
|
||||||
public readonly List<Container> Data = [];
|
private ChangedItemMode _lastMode;
|
||||||
public bool AnyExpandable { get; private set; }
|
private bool _reset;
|
||||||
|
public readonly List<Container> Data = [];
|
||||||
public record struct Container
|
public bool AnyExpandable { get; private set; }
|
||||||
{
|
|
||||||
public IIdentifiedObjectData Data;
|
public record struct Container
|
||||||
public ByteString Text;
|
{
|
||||||
public ByteString ModelData;
|
public IIdentifiedObjectData Data;
|
||||||
public uint Id;
|
public ByteString Text;
|
||||||
public int Children;
|
public ByteString ModelData;
|
||||||
public ChangedItemIconFlag Icon;
|
public uint Id;
|
||||||
public bool Expandable;
|
public int Children;
|
||||||
public bool Expanded;
|
public ChangedItemIconFlag Icon;
|
||||||
public bool Child;
|
public bool Expandable;
|
||||||
|
public bool Expanded;
|
||||||
public static Container Single(string text, IIdentifiedObjectData data)
|
public bool Child;
|
||||||
=> new()
|
|
||||||
{
|
public static Container Single(string text, IIdentifiedObjectData data)
|
||||||
Child = false,
|
=> new()
|
||||||
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
{
|
||||||
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
Child = false,
|
||||||
Icon = data.GetIcon().ToFlag(),
|
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
||||||
Expandable = false,
|
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
||||||
Expanded = false,
|
Icon = data.GetIcon().ToFlag(),
|
||||||
Data = data,
|
Expandable = false,
|
||||||
Id = 0,
|
Expanded = false,
|
||||||
Children = 0,
|
Data = data,
|
||||||
};
|
Id = 0,
|
||||||
|
Children = 0,
|
||||||
public static Container Parent(string text, IIdentifiedObjectData data, uint id, int children, bool expanded)
|
};
|
||||||
=> new()
|
|
||||||
{
|
public static Container Parent(string text, IIdentifiedObjectData data, uint id, int children, bool expanded)
|
||||||
Child = false,
|
=> new()
|
||||||
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
{
|
||||||
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
Child = false,
|
||||||
Icon = data.GetIcon().ToFlag(),
|
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
||||||
Expandable = true,
|
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
||||||
Expanded = expanded,
|
Icon = data.GetIcon().ToFlag(),
|
||||||
Data = data,
|
Expandable = true,
|
||||||
Id = id,
|
Expanded = expanded,
|
||||||
Children = children,
|
Data = data,
|
||||||
};
|
Id = id,
|
||||||
|
Children = children,
|
||||||
public static Container Indent(string text, IIdentifiedObjectData data)
|
};
|
||||||
=> new()
|
|
||||||
{
|
public static Container Indent(string text, IIdentifiedObjectData data)
|
||||||
Child = true,
|
=> new()
|
||||||
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
{
|
||||||
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
Child = true,
|
||||||
Icon = data.GetIcon().ToFlag(),
|
Text = ByteString.FromStringUnsafe(data.ToName(text), false),
|
||||||
Expandable = false,
|
ModelData = ByteString.FromStringUnsafe(data.AdditionalData, false),
|
||||||
Expanded = false,
|
Icon = data.GetIcon().ToFlag(),
|
||||||
Data = data,
|
Expandable = false,
|
||||||
Id = 0,
|
Expanded = false,
|
||||||
Children = 0,
|
Data = data,
|
||||||
};
|
Id = 0,
|
||||||
}
|
Children = 0,
|
||||||
|
};
|
||||||
public void Reset()
|
}
|
||||||
=> _reset = true;
|
|
||||||
|
public void Reset()
|
||||||
public void Update(Mod? mod, ChangedItemDrawer drawer, ChangedItemIconFlag filter, ChangedItemMode mode)
|
=> _reset = true;
|
||||||
{
|
|
||||||
if (mod == _lastSelected
|
public void Update(Mod? mod, ChangedItemDrawer drawer, ChangedItemIconFlag filter, ChangedItemMode mode)
|
||||||
&& _lastSelected!.LastChangedItemsUpdate == _lastUpdate
|
{
|
||||||
&& _filter == filter
|
if (mod == _lastSelected
|
||||||
&& !_reset
|
&& _lastSelected!.LastChangedItemsUpdate == _lastUpdate
|
||||||
&& _lastMode == mode)
|
&& _filter == filter
|
||||||
return;
|
&& !_reset
|
||||||
|
&& _lastMode == mode)
|
||||||
_reset = false;
|
return;
|
||||||
Data.Clear();
|
|
||||||
AnyExpandable = false;
|
_reset = false;
|
||||||
_lastSelected = mod;
|
Data.Clear();
|
||||||
_filter = filter;
|
AnyExpandable = false;
|
||||||
_lastMode = mode;
|
_lastSelected = mod;
|
||||||
if (_lastSelected == null)
|
_filter = filter;
|
||||||
return;
|
_lastMode = mode;
|
||||||
|
if (_lastSelected == null)
|
||||||
_lastUpdate = _lastSelected.LastChangedItemsUpdate;
|
return;
|
||||||
|
|
||||||
if (mode is ChangedItemMode.Alphabetical)
|
_lastUpdate = _lastSelected.LastChangedItemsUpdate;
|
||||||
{
|
|
||||||
foreach (var (s, i) in _lastSelected.ChangedItems)
|
if (mode is ChangedItemMode.Alphabetical)
|
||||||
{
|
{
|
||||||
if (drawer.FilterChangedItem(s, i, string.Empty))
|
foreach (var (s, i) in _lastSelected.ChangedItems)
|
||||||
Data.Add(Container.Single(s, i));
|
{
|
||||||
}
|
if (drawer.FilterChangedItem(s, i, string.Empty))
|
||||||
|
Data.Add(Container.Single(s, i));
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
return;
|
||||||
var tmp = new Dictionary<(PrimaryId, FullEquipType), List<IdentifiedItem>>();
|
}
|
||||||
var defaultExpansion = _lastMode is ChangedItemMode.GroupedExpanded;
|
|
||||||
foreach (var (s, i) in _lastSelected.ChangedItems)
|
var tmp = new Dictionary<(PrimaryId, FullEquipType), List<IdentifiedItem>>();
|
||||||
{
|
var defaultExpansion = _lastMode is ChangedItemMode.GroupedExpanded;
|
||||||
if (i is not IdentifiedItem item)
|
foreach (var (s, i) in _lastSelected.ChangedItems)
|
||||||
continue;
|
{
|
||||||
|
if (i is not IdentifiedItem item)
|
||||||
if (!drawer.FilterChangedItem(s, item, string.Empty))
|
continue;
|
||||||
continue;
|
|
||||||
|
if (!drawer.FilterChangedItem(s, item, string.Empty))
|
||||||
if (tmp.TryGetValue((item.Item.PrimaryId, item.Item.Type), out var p))
|
continue;
|
||||||
p.Add(item);
|
|
||||||
else
|
if (tmp.TryGetValue((item.Item.PrimaryId, item.Item.Type), out var p))
|
||||||
tmp[(item.Item.PrimaryId, item.Item.Type)] = [item];
|
p.Add(item);
|
||||||
}
|
else
|
||||||
|
tmp[(item.Item.PrimaryId, item.Item.Type)] = [item];
|
||||||
foreach (var list in tmp.Values)
|
}
|
||||||
{
|
|
||||||
list.Sort((i1, i2) =>
|
foreach (var list in tmp.Values)
|
||||||
{
|
{
|
||||||
// reversed
|
list.Sort((i1, i2) =>
|
||||||
var preferred = _lastSelected.PreferredChangedItems.Contains(i2.Item.Id)
|
{
|
||||||
.CompareTo(_lastSelected.PreferredChangedItems.Contains(i1.Item.Id));
|
// reversed
|
||||||
if (preferred != 0)
|
var preferred = _lastSelected.PreferredChangedItems.Contains(i2.Item.Id)
|
||||||
return preferred;
|
.CompareTo(_lastSelected.PreferredChangedItems.Contains(i1.Item.Id));
|
||||||
|
if (preferred != 0)
|
||||||
// reversed
|
return preferred;
|
||||||
var count = i2.Count.CompareTo(i1.Count);
|
|
||||||
if (count != 0)
|
// reversed
|
||||||
return count;
|
var count = i2.Count.CompareTo(i1.Count);
|
||||||
|
if (count != 0)
|
||||||
return string.Compare(i1.Item.Name, i2.Item.Name, StringComparison.Ordinal);
|
return count;
|
||||||
});
|
|
||||||
}
|
return string.Compare(i1.Item.Name, i2.Item.Name, StringComparison.Ordinal);
|
||||||
|
});
|
||||||
var sortedTmp = tmp.Values.OrderBy(s => s[0].Item.Name).ToArray();
|
}
|
||||||
|
|
||||||
var sortedTmpIdx = 0;
|
var sortedTmp = tmp.Values.OrderBy(s => s[0].Item.Name).ToArray();
|
||||||
foreach (var (s, i) in _lastSelected.ChangedItems)
|
|
||||||
{
|
var sortedTmpIdx = 0;
|
||||||
if (i is IdentifiedItem)
|
foreach (var (s, i) in _lastSelected.ChangedItems)
|
||||||
continue;
|
{
|
||||||
|
if (i is IdentifiedItem)
|
||||||
if (!drawer.FilterChangedItem(s, i, string.Empty))
|
continue;
|
||||||
continue;
|
|
||||||
|
if (!drawer.FilterChangedItem(s, i, string.Empty))
|
||||||
while (sortedTmpIdx < sortedTmp.Length
|
continue;
|
||||||
&& string.Compare(sortedTmp[sortedTmpIdx][0].Item.Name, s, StringComparison.Ordinal) <= 0)
|
|
||||||
AddList(sortedTmp[sortedTmpIdx++]);
|
while (sortedTmpIdx < sortedTmp.Length
|
||||||
|
&& string.Compare(sortedTmp[sortedTmpIdx][0].Item.Name, s, StringComparison.Ordinal) <= 0)
|
||||||
Data.Add(Container.Single(s, i));
|
AddList(sortedTmp[sortedTmpIdx++]);
|
||||||
}
|
|
||||||
|
Data.Add(Container.Single(s, i));
|
||||||
for (; sortedTmpIdx < sortedTmp.Length; ++sortedTmpIdx)
|
}
|
||||||
AddList(sortedTmp[sortedTmpIdx]);
|
|
||||||
return;
|
for (; sortedTmpIdx < sortedTmp.Length; ++sortedTmpIdx)
|
||||||
|
AddList(sortedTmp[sortedTmpIdx]);
|
||||||
void AddList(List<IdentifiedItem> list)
|
return;
|
||||||
{
|
|
||||||
var mainItem = list[0];
|
void AddList(List<IdentifiedItem> list)
|
||||||
if (list.Count == 1)
|
{
|
||||||
{
|
var mainItem = list[0];
|
||||||
Data.Add(Container.Single(mainItem.Item.Name, mainItem));
|
if (list.Count == 1)
|
||||||
}
|
{
|
||||||
else
|
Data.Add(Container.Single(mainItem.Item.Name, mainItem));
|
||||||
{
|
}
|
||||||
var id = ImUtf8.GetId($"{mainItem.Item.PrimaryId}{(int)mainItem.Item.Type}");
|
else
|
||||||
var expanded = ImGui.GetStateStorage().GetBool(id, defaultExpansion);
|
{
|
||||||
Data.Add(Container.Parent(mainItem.Item.Name, mainItem, id, list.Count - 1, expanded));
|
var id = ImUtf8.GetId($"{mainItem.Item.PrimaryId}{(int)mainItem.Item.Type}");
|
||||||
AnyExpandable = true;
|
var expanded = ImGui.GetStateStorage().GetBool(id, defaultExpansion);
|
||||||
if (!expanded)
|
Data.Add(Container.Parent(mainItem.Item.Name, mainItem, id, list.Count - 1, expanded));
|
||||||
return;
|
AnyExpandable = true;
|
||||||
|
if (!expanded)
|
||||||
foreach (var item in list.Skip(1))
|
return;
|
||||||
Data.Add(Container.Indent(item.Item.Name, item));
|
|
||||||
}
|
foreach (var item in list.Skip(1))
|
||||||
}
|
Data.Add(Container.Indent(item.Item.Name, item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public ReadOnlySpan<byte> Label
|
}
|
||||||
=> "Changed Items"u8;
|
|
||||||
|
public ReadOnlySpan<byte> Label
|
||||||
public bool IsVisible
|
=> "Changed Items"u8;
|
||||||
=> selector.Selected!.ChangedItems.Count > 0;
|
|
||||||
|
public bool IsVisible
|
||||||
private ImGuiStoragePtr _stateStorage;
|
=> selector.Selected!.ChangedItems.Count > 0;
|
||||||
|
|
||||||
private Vector2 _buttonSize;
|
private ImGuiStoragePtr _stateStorage;
|
||||||
private uint _starColor;
|
|
||||||
|
private Vector2 _buttonSize;
|
||||||
public void DrawContent()
|
private Rgba32 _starColor;
|
||||||
{
|
|
||||||
if (cacheService.Cache(_cacheId, () => (new ChangedItemsCache(), "ModPanelChangedItemsCache")) is not { } cache)
|
public void DrawContent()
|
||||||
return;
|
{
|
||||||
|
if (cacheService.Cache(_cacheId, () => (new ChangedItemsCache(), "ModPanelChangedItemsCache")) is not { } cache)
|
||||||
drawer.DrawTypeFilter();
|
return;
|
||||||
|
|
||||||
_stateStorage = ImGui.GetStateStorage();
|
drawer.DrawTypeFilter();
|
||||||
cache.Update(selector.Selected, drawer, config.Ephemeral.ChangedItemFilter, config.ChangedItemDisplay);
|
|
||||||
ImGui.Separator();
|
_stateStorage = ImGui.GetStateStorage();
|
||||||
_buttonSize = new Vector2(ImGui.GetStyle().ItemSpacing.Y + ImGui.GetFrameHeight());
|
cache.Update(selector.Selected, drawer, config.Ephemeral.ChangedItemFilter, config.ChangedItemDisplay);
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.CellPadding, Vector2.Zero)
|
ImGui.Separator();
|
||||||
.Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
_buttonSize = new Vector2(ImGui.GetStyle().ItemSpacing.Y + ImGui.GetFrameHeight());
|
||||||
.Push(ImGuiStyleVar.FramePadding, Vector2.Zero)
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.CellPadding, Vector2.Zero)
|
||||||
.Push(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.01f, 0.5f));
|
.Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button, 0);
|
.Push(ImGuiStyleVar.FramePadding, Vector2.Zero)
|
||||||
|
.Push(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.01f, 0.5f));
|
||||||
using var table = ImUtf8.Table("##changedItems"u8, cache.AnyExpandable ? 2 : 1, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY,
|
using var color = ImGuiColor.Button.Push(Rgba32.Transparent)
|
||||||
new Vector2(ImGui.GetContentRegionAvail().X, -1));
|
.Push(ImGuiColor.ButtonActive, Rgba32.Transparent)
|
||||||
if (!table)
|
.Push(ImGuiColor.ButtonHovered, Rgba32.Transparent);
|
||||||
return;
|
|
||||||
|
using var table = ImUtf8.Table("##changedItems"u8, cache.AnyExpandable ? 2 : 1, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY,
|
||||||
_starColor = ColorId.ChangedItemPreferenceStar.Value();
|
new Vector2(ImGui.GetContentRegionAvail().X, -1));
|
||||||
if (cache.AnyExpandable)
|
if (!table)
|
||||||
{
|
return;
|
||||||
ImUtf8.TableSetupColumn("##exp"u8, ImGuiTableColumnFlags.WidthFixed, _buttonSize.Y);
|
|
||||||
ImUtf8.TableSetupColumn("##text"u8, ImGuiTableColumnFlags.WidthStretch);
|
_starColor = ColorId.ChangedItemPreferenceStar.Value();
|
||||||
ImGuiClip.ClippedDraw(cache.Data, DrawContainerExpandable, _buttonSize.Y);
|
if (cache.AnyExpandable)
|
||||||
}
|
{
|
||||||
else
|
ImUtf8.TableSetupColumn("##exp"u8, ImGuiTableColumnFlags.WidthFixed, _buttonSize.Y);
|
||||||
{
|
ImUtf8.TableSetupColumn("##text"u8, ImGuiTableColumnFlags.WidthStretch);
|
||||||
ImGuiClip.ClippedDraw(cache.Data, DrawContainer, _buttonSize.Y);
|
ImGuiClip.ClippedDraw(cache.Data, DrawContainerExpandable, _buttonSize.Y);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
private void DrawContainerExpandable(ChangedItemsCache.Container obj, int idx)
|
ImGuiClip.ClippedDraw(cache.Data, DrawContainer, _buttonSize.Y);
|
||||||
{
|
}
|
||||||
using var id = ImUtf8.PushId(idx);
|
}
|
||||||
ImGui.TableNextColumn();
|
|
||||||
if (obj.Expandable)
|
private void DrawContainerExpandable(ChangedItemsCache.Container obj, int idx)
|
||||||
{
|
{
|
||||||
if (ImUtf8.IconButton(obj.Expanded ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight,
|
using var id = ImUtf8.PushId(idx);
|
||||||
obj.Expanded ? "Hide the other items using the same model." :
|
ImGui.TableNextColumn();
|
||||||
obj.Children > 1 ? $"Show {obj.Children} other items using the same model." :
|
if (obj.Expandable)
|
||||||
"Show one other item using the same model.",
|
{
|
||||||
_buttonSize))
|
if (ImUtf8.IconButton(obj.Expanded ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight,
|
||||||
{
|
obj.Expanded ? "Hide the other items using the same model." :
|
||||||
_stateStorage.SetBool(obj.Id, !obj.Expanded);
|
obj.Children > 1 ? $"Show {obj.Children} other items using the same model." :
|
||||||
if (cacheService.TryGetCache<ChangedItemsCache>(_cacheId, out var cache))
|
"Show one other item using the same model.",
|
||||||
cache.Reset();
|
_buttonSize))
|
||||||
}
|
{
|
||||||
}
|
_stateStorage.SetBool(obj.Id, !obj.Expanded);
|
||||||
else if (obj is { Child: true, Data: IdentifiedItem item })
|
if (cacheService.TryGetCache<ChangedItemsCache>(_cacheId, out var cache))
|
||||||
{
|
cache.Reset();
|
||||||
DrawPreferredButton(item, idx);
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (obj is { Child: true, Data: IdentifiedItem item })
|
||||||
{
|
{
|
||||||
ImGui.Dummy(_buttonSize);
|
DrawPreferredButton(item, idx);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
DrawBaseContainer(obj, idx);
|
{
|
||||||
}
|
ImGui.Dummy(_buttonSize);
|
||||||
|
}
|
||||||
private void DrawContainer(ChangedItemsCache.Container obj, int idx)
|
|
||||||
{
|
DrawBaseContainer(obj, idx);
|
||||||
using var id = ImUtf8.PushId(idx);
|
}
|
||||||
DrawBaseContainer(obj, idx);
|
|
||||||
}
|
private void DrawContainer(ChangedItemsCache.Container obj, int idx)
|
||||||
|
{
|
||||||
private void DrawPreferredButton(IdentifiedItem item, int idx)
|
using var id = ImUtf8.PushId(idx);
|
||||||
{
|
DrawBaseContainer(obj, idx);
|
||||||
if (ImUtf8.IconButton(FontAwesomeIcon.Star, "Prefer displaying this item instead of the current primary item.\n\nRight-click for more options."u8, _buttonSize,
|
}
|
||||||
false, _starColor))
|
|
||||||
dataEditor.AddPreferredItem(selector.Selected!, item.Item.Id, false, true);
|
private void DrawPreferredButton(IdentifiedItem item, int idx)
|
||||||
using var context = ImUtf8.PopupContextItem("StarContext"u8);
|
{
|
||||||
if (!context)
|
var textColor = Im.Mouse.IsHoveringRectangle(Rectangle.FromSize(Im.Cursor.ScreenPosition, _buttonSize))
|
||||||
return;
|
? LunaStyle.FavoriteColor
|
||||||
|
: _starColor;
|
||||||
if (cacheService.TryGetCache<ChangedItemsCache>(_cacheId, out var cache))
|
|
||||||
for (--idx; idx >= 0; --idx)
|
if (ImEx.Icon.Button(LunaStyle.FavoriteIcon,
|
||||||
{
|
"Prefer displaying this item instead of the current primary item.\n\nRight-click for more options."u8,
|
||||||
if (!cache.Data[idx].Expanded)
|
textColor: textColor, size: _buttonSize))
|
||||||
continue;
|
dataEditor.AddPreferredItem(selector.Selected!, item.Item.Id, false, true);
|
||||||
|
using var context = ImUtf8.PopupContextItem("StarContext"u8);
|
||||||
if (cache.Data[idx].Data is IdentifiedItem it)
|
if (!context)
|
||||||
{
|
return;
|
||||||
if (selector.Selected!.PreferredChangedItems.Contains(it.Item.Id)
|
|
||||||
&& ImUtf8.MenuItem("Remove Parent from Local Preferred Items"u8))
|
if (cacheService.TryGetCache<ChangedItemsCache>(_cacheId, out var cache))
|
||||||
dataEditor.RemovePreferredItem(selector.Selected!, it.Item.Id, false);
|
for (--idx; idx >= 0; --idx)
|
||||||
if (selector.Selected!.DefaultPreferredItems.Contains(it.Item.Id)
|
{
|
||||||
&& ImUtf8.MenuItem("Remove Parent from Default Preferred Items"u8))
|
if (!cache.Data[idx].Expanded)
|
||||||
dataEditor.RemovePreferredItem(selector.Selected!, it.Item.Id, true);
|
continue;
|
||||||
}
|
|
||||||
|
if (cache.Data[idx].Data is IdentifiedItem it)
|
||||||
break;
|
{
|
||||||
}
|
if (selector.Selected!.PreferredChangedItems.Contains(it.Item.Id)
|
||||||
|
&& ImUtf8.MenuItem("Remove Parent from Local Preferred Items"u8))
|
||||||
var enabled = !selector.Selected!.DefaultPreferredItems.Contains(item.Item.Id);
|
dataEditor.RemovePreferredItem(selector.Selected!, it.Item.Id, false);
|
||||||
if (enabled)
|
if (selector.Selected!.DefaultPreferredItems.Contains(it.Item.Id)
|
||||||
{
|
&& ImUtf8.MenuItem("Remove Parent from Default Preferred Items"u8))
|
||||||
if (ImUtf8.MenuItem("Add to Local and Default Preferred Changed Items"u8))
|
dataEditor.RemovePreferredItem(selector.Selected!, it.Item.Id, true);
|
||||||
dataEditor.AddPreferredItem(selector.Selected!, item.Item.Id, true, true);
|
}
|
||||||
}
|
|
||||||
else
|
break;
|
||||||
{
|
}
|
||||||
if (ImUtf8.MenuItem("Remove from Default Preferred Changed Items"u8))
|
|
||||||
dataEditor.RemovePreferredItem(selector.Selected!, item.Item.Id, true);
|
var enabled = !selector.Selected!.DefaultPreferredItems.Contains(item.Item.Id);
|
||||||
}
|
if (enabled)
|
||||||
|
{
|
||||||
if (ImUtf8.MenuItem("Reset Local Preferred Items to Default"u8))
|
if (ImUtf8.MenuItem("Add to Local and Default Preferred Changed Items"u8))
|
||||||
dataEditor.ResetPreferredItems(selector.Selected!);
|
dataEditor.AddPreferredItem(selector.Selected!, item.Item.Id, true, true);
|
||||||
|
}
|
||||||
if (ImUtf8.MenuItem("Clear Local and Default Preferred Items not Changed by the Mod"u8))
|
else
|
||||||
dataEditor.ClearInvalidPreferredItems(selector.Selected!);
|
{
|
||||||
}
|
if (ImUtf8.MenuItem("Remove from Default Preferred Changed Items"u8))
|
||||||
|
dataEditor.RemovePreferredItem(selector.Selected!, item.Item.Id, true);
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void DrawBaseContainer(in ChangedItemsCache.Container obj, int _)
|
if (ImUtf8.MenuItem("Reset Local Preferred Items to Default"u8))
|
||||||
{
|
dataEditor.ResetPreferredItems(selector.Selected!);
|
||||||
ImGui.TableNextColumn();
|
|
||||||
using var indent = ImRaii.PushIndent(1, obj.Child);
|
if (ImUtf8.MenuItem("Clear Local and Default Preferred Items not Changed by the Mod"u8))
|
||||||
drawer.DrawCategoryIcon(obj.Icon, _buttonSize.Y);
|
dataEditor.ClearInvalidPreferredItems(selector.Selected!);
|
||||||
ImGui.SameLine(0, 0);
|
}
|
||||||
var clicked = ImUtf8.Selectable(obj.Text.Span, false, ImGuiSelectableFlags.None, _buttonSize with { X = 0 });
|
|
||||||
drawer.ChangedItemHandling(obj.Data, clicked);
|
|
||||||
ChangedItemDrawer.DrawModelData(obj.ModelData.Span, _buttonSize.Y);
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
}
|
private void DrawBaseContainer(in ChangedItemsCache.Container obj, int _)
|
||||||
}
|
{
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
using var indent = ImRaii.PushIndent(1, obj.Child);
|
||||||
|
drawer.DrawCategoryIcon(obj.Icon, _buttonSize.Y);
|
||||||
|
ImGui.SameLine(0, 0);
|
||||||
|
var clicked = ImUtf8.Selectable(obj.Text.Span, false, ImGuiSelectableFlags.None, _buttonSize with { X = 0 });
|
||||||
|
drawer.ChangedItemHandling(obj.Data, clicked);
|
||||||
|
ChangedItemDrawer.DrawModelData(obj.ModelData.Span, _buttonSize.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,206 +1,205 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using ImSharp;
|
using ImSharp;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.Collections.Cache;
|
using Penumbra.Collections.Cache;
|
||||||
using Penumbra.Collections.Manager;
|
using Penumbra.Collections.Manager;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.Mods.Settings;
|
using Penumbra.Mods.Settings;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
||||||
namespace Penumbra.UI.ModsTab;
|
namespace Penumbra.UI.ModsTab;
|
||||||
|
|
||||||
public class ModPanelConflictsTab(CollectionManager collectionManager, ModFileSystemSelector selector) : ITab, Luna.IUiService
|
public class ModPanelConflictsTab(CollectionManager collectionManager, ModFileSystemSelector selector) : ITab, Luna.IUiService
|
||||||
{
|
{
|
||||||
private int? _currentPriority;
|
private int? _currentPriority;
|
||||||
|
|
||||||
public ReadOnlySpan<byte> Label
|
public ReadOnlySpan<byte> Label
|
||||||
=> "Conflicts"u8;
|
=> "Conflicts"u8;
|
||||||
|
|
||||||
public bool IsVisible
|
public bool IsVisible
|
||||||
=> collectionManager.Active.Current.Conflicts(selector.Selected!).Any(c => !GetPriority(c).IsHidden);
|
=> collectionManager.Active.Current.Conflicts(selector.Selected!).Any(c => !GetPriority(c).IsHidden);
|
||||||
|
|
||||||
private readonly ConditionalWeakTable<IMod, object> _expandedMods = [];
|
private readonly ConditionalWeakTable<IMod, object> _expandedMods = [];
|
||||||
|
|
||||||
private ModPriority GetPriority(ModConflicts conflicts)
|
private ModPriority GetPriority(ModConflicts conflicts)
|
||||||
{
|
{
|
||||||
if (conflicts.Mod2.Index < 0)
|
if (conflicts.Mod2.Index < 0)
|
||||||
return conflicts.Mod2.Priority;
|
return conflicts.Mod2.Priority;
|
||||||
|
|
||||||
return collectionManager.Active.Current.GetActualSettings(conflicts.Mod2.Index).Settings?.Priority ?? ModPriority.Default;
|
return collectionManager.Active.Current.GetActualSettings(conflicts.Mod2.Index).Settings?.Priority ?? ModPriority.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawContent()
|
public void DrawContent()
|
||||||
{
|
{
|
||||||
using var table = ImRaii.Table("conflicts", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, ImGui.GetContentRegionAvail());
|
using var table = ImRaii.Table("conflicts", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, ImGui.GetContentRegionAvail());
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var buttonSize = new Vector2(ImGui.GetFrameHeight());
|
var buttonSize = new Vector2(ImGui.GetFrameHeight());
|
||||||
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y };
|
var spacing = ImGui.GetStyle().ItemInnerSpacing with { Y = ImGui.GetStyle().ItemSpacing.Y };
|
||||||
var priorityRowWidth = ImGui.CalcTextSize("Priority").X + 20 * ImGuiHelpers.GlobalScale + 2 * buttonSize.X;
|
var priorityRowWidth = ImGui.CalcTextSize("Priority").X + 20 * ImGuiHelpers.GlobalScale + 2 * buttonSize.X;
|
||||||
var priorityWidth = priorityRowWidth - 2 * (buttonSize.X + spacing.X);
|
var priorityWidth = priorityRowWidth - 2 * (buttonSize.X + spacing.X);
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing);
|
||||||
ImGui.TableSetupColumn("Conflicting Mod", ImGuiTableColumnFlags.WidthStretch);
|
ImGui.TableSetupColumn("Conflicting Mod", ImGuiTableColumnFlags.WidthStretch);
|
||||||
ImGui.TableSetupColumn("Priority", ImGuiTableColumnFlags.WidthFixed, priorityRowWidth);
|
ImGui.TableSetupColumn("Priority", ImGuiTableColumnFlags.WidthFixed, priorityRowWidth);
|
||||||
ImGui.TableSetupColumn("Files", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Files").X + spacing.X);
|
ImGui.TableSetupColumn("Files", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("Files").X + spacing.X);
|
||||||
|
|
||||||
ImGui.TableSetupScrollFreeze(2, 2);
|
ImGui.TableSetupScrollFreeze(2, 2);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
DrawCurrentRow(priorityWidth);
|
DrawCurrentRow(priorityWidth);
|
||||||
|
|
||||||
// Can not be null because otherwise the tab bar is never drawn.
|
// Can not be null because otherwise the tab bar is never drawn.
|
||||||
var mod = selector.Selected!;
|
var mod = selector.Selected!;
|
||||||
foreach (var (index, conflict) in collectionManager.Active.Current.Conflicts(mod).Where(c => !c.Mod2.Priority.IsHidden)
|
foreach (var (index, conflict) in collectionManager.Active.Current.Conflicts(mod).Where(c => !c.Mod2.Priority.IsHidden)
|
||||||
.OrderByDescending(GetPriority)
|
.OrderByDescending(GetPriority)
|
||||||
.ThenBy(c => c.Mod2.Name, StringComparer.OrdinalIgnoreCase).Index())
|
.ThenBy(c => c.Mod2.Name, StringComparer.OrdinalIgnoreCase).Index())
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId(index);
|
using var id = ImRaii.PushId(index);
|
||||||
DrawConflictRow(conflict, priorityWidth, buttonSize);
|
DrawConflictRow(conflict, priorityWidth, buttonSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawCurrentRow(float priorityWidth)
|
private void DrawCurrentRow(float priorityWidth)
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
using var c = ImRaii.PushColor(ImGuiCol.Text, ColorId.FolderLine.Value());
|
using var c = ImGuiColor.Text.Push(ColorId.FolderLine.Value());
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.TextUnformatted(selector.Selected!.Name);
|
ImGui.TextUnformatted(selector.Selected!.Name);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var actualSettings = collectionManager.Active.Current.GetActualSettings(selector.Selected!.Index).Settings!;
|
var actualSettings = collectionManager.Active.Current.GetActualSettings(selector.Selected!.Index).Settings!;
|
||||||
var priority = actualSettings.Priority.Value;
|
var priority = actualSettings.Priority.Value;
|
||||||
// TODO
|
// TODO
|
||||||
using (ImRaii.Disabled(actualSettings is TemporaryModSettings))
|
using (ImRaii.Disabled(actualSettings is TemporaryModSettings))
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth(priorityWidth);
|
ImGui.SetNextItemWidth(priorityWidth);
|
||||||
if (ImGui.InputInt("##priority", ref priority, 0, 0, flags: ImGuiInputTextFlags.EnterReturnsTrue))
|
if (ImGui.InputInt("##priority", ref priority, 0, 0, flags: ImGuiInputTextFlags.EnterReturnsTrue))
|
||||||
_currentPriority = priority;
|
_currentPriority = priority;
|
||||||
|
|
||||||
if (ImGui.IsItemDeactivatedAfterEdit() && _currentPriority.HasValue)
|
if (ImGui.IsItemDeactivatedAfterEdit() && _currentPriority.HasValue)
|
||||||
{
|
{
|
||||||
if (_currentPriority != actualSettings.Priority.Value)
|
if (_currentPriority != actualSettings.Priority.Value)
|
||||||
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, selector.Selected!,
|
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, selector.Selected!,
|
||||||
new ModPriority(_currentPriority.Value));
|
new ModPriority(_currentPriority.Value));
|
||||||
|
|
||||||
_currentPriority = null;
|
_currentPriority = null;
|
||||||
}
|
}
|
||||||
else if (ImGui.IsItemDeactivated())
|
else if (ImGui.IsItemDeactivated())
|
||||||
{
|
{
|
||||||
_currentPriority = null;
|
_currentPriority = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawConflictSelectable(ModConflicts conflict)
|
private void DrawConflictSelectable(ModConflicts conflict)
|
||||||
{
|
{
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
if (ImGui.Selectable(conflict.Mod2.Name) && conflict.Mod2 is Mod otherMod)
|
if (ImGui.Selectable(conflict.Mod2.Name) && conflict.Mod2 is Mod otherMod)
|
||||||
selector.SelectByValue(otherMod);
|
selector.SelectByValue(otherMod);
|
||||||
var hovered = ImGui.IsItemHovered();
|
var hovered = ImGui.IsItemHovered();
|
||||||
var rightClicked = ImGui.IsItemClicked(ImGuiMouseButton.Right);
|
var rightClicked = ImGui.IsItemClicked(ImGuiMouseButton.Right);
|
||||||
if (conflict.Mod2 is Mod otherMod2)
|
if (conflict.Mod2 is Mod otherMod2)
|
||||||
{
|
{
|
||||||
if (hovered)
|
if (hovered)
|
||||||
ImGui.SetTooltip("Click to jump to mod, Control + Right-Click to disable mod.");
|
ImGui.SetTooltip("Click to jump to mod, Control + Right-Click to disable mod.");
|
||||||
if (rightClicked && ImGui.GetIO().KeyCtrl)
|
if (rightClicked && ImGui.GetIO().KeyCtrl)
|
||||||
collectionManager.Editor.SetModState(collectionManager.Active.Current, otherMod2, false);
|
collectionManager.Editor.SetModState(collectionManager.Active.Current, otherMod2, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DrawExpandedFiles(ModConflicts conflict)
|
private bool DrawExpandedFiles(ModConflicts conflict)
|
||||||
{
|
{
|
||||||
if (!_expandedMods.TryGetValue(conflict.Mod2, out _))
|
if (!_expandedMods.TryGetValue(conflict.Mod2, out _))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
using var indent = ImRaii.PushIndent(30f);
|
using var indent = ImRaii.PushIndent(30f);
|
||||||
foreach (var data in conflict.Conflicts)
|
foreach (var data in conflict.Conflicts)
|
||||||
{
|
{
|
||||||
_ = data switch
|
_ = data switch
|
||||||
{
|
{
|
||||||
Utf8GamePath p => ImUtf8.Selectable(p.Path.Span, false),
|
Utf8GamePath p => ImUtf8.Selectable(p.Path.Span, false),
|
||||||
IMetaIdentifier m => ImUtf8.Selectable(m.ToString(), false),
|
IMetaIdentifier m => ImUtf8.Selectable(m.ToString(), false),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawConflictRow(ModConflicts conflict, float priorityWidth, Vector2 buttonSize)
|
private void DrawConflictRow(ModConflicts conflict, float priorityWidth, Vector2 buttonSize)
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
DrawConflictSelectable(conflict);
|
DrawConflictSelectable(conflict);
|
||||||
var expanded = DrawExpandedFiles(conflict);
|
var expanded = DrawExpandedFiles(conflict);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var conflictPriority = DrawPriorityInput(conflict, priorityWidth);
|
var conflictPriority = DrawPriorityInput(conflict, priorityWidth);
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
var selectedPriority = collectionManager.Active.Current.GetActualSettings(selector.Selected!.Index).Settings!.Priority.Value;
|
var selectedPriority = collectionManager.Active.Current.GetActualSettings(selector.Selected!.Index).Settings!.Priority.Value;
|
||||||
DrawPriorityButtons(conflict.Mod2 as Mod, conflictPriority, selectedPriority, buttonSize);
|
DrawPriorityButtons(conflict.Mod2 as Mod, conflictPriority, selectedPriority, buttonSize);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
DrawExpandButton(conflict.Mod2, expanded, buttonSize);
|
DrawExpandButton(conflict.Mod2, expanded, buttonSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawExpandButton(IMod mod, bool expanded, Vector2 buttonSize)
|
private void DrawExpandButton(IMod mod, bool expanded, Vector2 buttonSize)
|
||||||
{
|
{
|
||||||
var (icon, tt) = expanded
|
var (icon, tt) = expanded
|
||||||
? (FontAwesomeIcon.CaretUp.ToIconString(), "Hide the conflicting files for this mod.")
|
? (FontAwesomeIcon.CaretUp.ToIconString(), "Hide the conflicting files for this mod.")
|
||||||
: (FontAwesomeIcon.CaretDown.ToIconString(), "Show the conflicting files for this mod.");
|
: (FontAwesomeIcon.CaretDown.ToIconString(), "Show the conflicting files for this mod.");
|
||||||
if (ImGuiUtil.DrawDisabledButton(icon, buttonSize, tt, false, true))
|
if (ImGuiUtil.DrawDisabledButton(icon, buttonSize, tt, false, true))
|
||||||
{
|
{
|
||||||
if (expanded)
|
if (expanded)
|
||||||
_expandedMods.Remove(mod);
|
_expandedMods.Remove(mod);
|
||||||
else
|
else
|
||||||
_expandedMods.Add(mod, new object());
|
_expandedMods.Add(mod, new object());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int DrawPriorityInput(ModConflicts conflict, float priorityWidth)
|
private int DrawPriorityInput(ModConflicts conflict, float priorityWidth)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text,
|
using var color = ImGuiColor.Text.Push(conflict.HasPriority ? ColorId.HandledConflictMod.Value() : ColorId.ConflictingMod.Value());
|
||||||
conflict.HasPriority ? ColorId.HandledConflictMod.Value() : ColorId.ConflictingMod.Value());
|
using var disabled = ImRaii.Disabled(conflict.Mod2.Index < 0);
|
||||||
using var disabled = ImRaii.Disabled(conflict.Mod2.Index < 0);
|
var priority = _currentPriority ?? GetPriority(conflict).Value;
|
||||||
var priority = _currentPriority ?? GetPriority(conflict).Value;
|
|
||||||
|
ImGui.SetNextItemWidth(priorityWidth);
|
||||||
ImGui.SetNextItemWidth(priorityWidth);
|
if (ImGui.InputInt("##priority", ref priority, 0, 0, flags: ImGuiInputTextFlags.EnterReturnsTrue))
|
||||||
if (ImGui.InputInt("##priority", ref priority, 0, 0, flags: ImGuiInputTextFlags.EnterReturnsTrue))
|
_currentPriority = priority;
|
||||||
_currentPriority = priority;
|
|
||||||
|
if (ImGui.IsItemDeactivatedAfterEdit() && _currentPriority.HasValue)
|
||||||
if (ImGui.IsItemDeactivatedAfterEdit() && _currentPriority.HasValue)
|
{
|
||||||
{
|
if (_currentPriority != GetPriority(conflict).Value)
|
||||||
if (_currentPriority != GetPriority(conflict).Value)
|
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, (Mod)conflict.Mod2,
|
||||||
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, (Mod)conflict.Mod2,
|
new ModPriority(_currentPriority.Value));
|
||||||
new ModPriority(_currentPriority.Value));
|
|
||||||
|
_currentPriority = null;
|
||||||
_currentPriority = null;
|
}
|
||||||
}
|
else if (ImGui.IsItemDeactivated())
|
||||||
else if (ImGui.IsItemDeactivated())
|
{
|
||||||
{
|
_currentPriority = null;
|
||||||
_currentPriority = null;
|
}
|
||||||
}
|
|
||||||
|
return priority;
|
||||||
return priority;
|
}
|
||||||
}
|
|
||||||
|
private void DrawPriorityButtons(Mod? conflict, int conflictPriority, int selectedPriority, Vector2 buttonSize)
|
||||||
private void DrawPriorityButtons(Mod? conflict, int conflictPriority, int selectedPriority, Vector2 buttonSize)
|
{
|
||||||
{
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.SortNumericUpAlt.ToIconString(), buttonSize,
|
||||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.SortNumericUpAlt.ToIconString(), buttonSize,
|
$"Set the priority of the currently selected mod to this mods priority plus one. ({selectedPriority} -> {conflictPriority + 1})",
|
||||||
$"Set the priority of the currently selected mod to this mods priority plus one. ({selectedPriority} -> {conflictPriority + 1})",
|
selectedPriority > conflictPriority, true))
|
||||||
selectedPriority > conflictPriority, true))
|
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, selector.Selected!,
|
||||||
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, selector.Selected!,
|
new ModPriority(conflictPriority + 1));
|
||||||
new ModPriority(conflictPriority + 1));
|
Im.Line.Same();
|
||||||
Im.Line.Same();
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.SortNumericDownAlt.ToIconString(), buttonSize,
|
||||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.SortNumericDownAlt.ToIconString(), buttonSize,
|
$"Set the priority of this mod to the currently selected mods priority minus one. ({conflictPriority} -> {selectedPriority - 1})",
|
||||||
$"Set the priority of this mod to the currently selected mods priority minus one. ({conflictPriority} -> {selectedPriority - 1})",
|
selectedPriority > conflictPriority || conflict == null, true))
|
||||||
selectedPriority > conflictPriority || conflict == null, true))
|
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, conflict!, new ModPriority(selectedPriority - 1));
|
||||||
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, conflict!, new ModPriority(selectedPriority - 1));
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -208,8 +208,8 @@ public class ModPanelEditTab(
|
||||||
|
|
||||||
private void DrawImportDate()
|
private void DrawImportDate()
|
||||||
{
|
{
|
||||||
ImUtf8.TextFramed($"{DateTimeOffset.FromUnixTimeMilliseconds(_mod.ImportDate).ToLocalTime():yyyy/MM/dd HH:mm}",
|
ImEx.TextFramed($"{DateTimeOffset.FromUnixTimeMilliseconds(_mod.ImportDate).ToLocalTime():yyyy/MM/dd HH:mm}",
|
||||||
ImGui.GetColorU32(ImGuiCol.FrameBg, 0.5f), new Vector2(UiHelpers.InputTextMinusButton3, 0));
|
new Vector2(UiHelpers.InputTextMinusButton3, 0), ImGuiColor.FrameBackground.Get(0.5f));
|
||||||
ImGui.SameLine(0, 3 * ImUtf8.GlobalScale);
|
ImGui.SameLine(0, 3 * ImUtf8.GlobalScale);
|
||||||
|
|
||||||
var canRefresh = config.DeleteModModifier.IsActive();
|
var canRefresh = config.DeleteModModifier.IsActive();
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,7 @@ public class ModPanelHeader : IDisposable
|
||||||
ImGui.SetCursorPosX(offset);
|
ImGui.SetCursorPosX(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.MetaInfoText);
|
using var style = ImStyleBorder.Frame.Push(Colors.MetaInfoText, 2 * Im.Style.GlobalScale);
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, 2 * UiHelpers.Scale);
|
|
||||||
using var f = _nameFont.Push();
|
using var f = _nameFont.Push();
|
||||||
ImGuiUtil.DrawTextButton(_modName, Vector2.Zero, 0);
|
ImGuiUtil.DrawTextButton(_modName, Vector2.Zero, 0);
|
||||||
_nameWidth = ImGui.GetItemRectSize().X;
|
_nameWidth = ImGui.GetItemRectSize().X;
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ public class ModPanelSettingsTab(
|
||||||
if (!_inherited)
|
if (!_inherited)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button, Colors.PressEnterWarningBg);
|
using var color = ImGuiColor.Button.Push(Colors.PressEnterWarningBg);
|
||||||
var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);
|
var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);
|
||||||
if (ImUtf8.ButtonEx($"These settings are inherited from {selection.Collection.Identity.Name}.", width, _locked))
|
if (ImUtf8.ButtonEx($"These settings are inherited from {selection.Collection.Identity.Name}.", width, _locked))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,158 +1,158 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using OtterGui;
|
using ImSharp;
|
||||||
using OtterGui.Raii;
|
using Luna;
|
||||||
using OtterGui.Widgets;
|
using OtterGui;
|
||||||
using Penumbra.Mods;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Mods.Manager;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.UI.AdvancedWindow;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Mods.Manager;
|
||||||
namespace Penumbra.UI.ModsTab;
|
using Penumbra.UI.AdvancedWindow;
|
||||||
|
using ImGuiColor = ImSharp.ImGuiColor;
|
||||||
public class ModPanelTabBar : Luna.IUiService
|
|
||||||
{
|
namespace Penumbra.UI.ModsTab;
|
||||||
private enum ModPanelTabType
|
|
||||||
{
|
public class ModPanelTabBar : IUiService
|
||||||
Description,
|
{
|
||||||
Settings,
|
private enum ModPanelTabType
|
||||||
ChangedItems,
|
{
|
||||||
Conflicts,
|
Description,
|
||||||
Collections,
|
Settings,
|
||||||
Edit,
|
ChangedItems,
|
||||||
};
|
Conflicts,
|
||||||
|
Collections,
|
||||||
public readonly ModPanelSettingsTab Settings;
|
Edit,
|
||||||
public readonly ModPanelDescriptionTab Description;
|
};
|
||||||
public readonly ModPanelCollectionsTab Collections;
|
|
||||||
public readonly ModPanelConflictsTab Conflicts;
|
public readonly ModPanelSettingsTab Settings;
|
||||||
public readonly ModPanelChangedItemsTab ChangedItems;
|
public readonly ModPanelDescriptionTab Description;
|
||||||
public readonly ModPanelEditTab Edit;
|
public readonly ModPanelCollectionsTab Collections;
|
||||||
private readonly ModEditWindow _modEditWindow;
|
public readonly ModPanelConflictsTab Conflicts;
|
||||||
private readonly ModManager _modManager;
|
public readonly ModPanelChangedItemsTab ChangedItems;
|
||||||
private readonly TutorialService _tutorial;
|
public readonly ModPanelEditTab Edit;
|
||||||
|
private readonly ModEditWindow _modEditWindow;
|
||||||
public readonly ITab[] Tabs;
|
private readonly ModManager _modManager;
|
||||||
private ModPanelTabType _preferredTab = ModPanelTabType.Settings;
|
private readonly TutorialService _tutorial;
|
||||||
private Mod? _lastMod;
|
|
||||||
|
public readonly ITab[] Tabs;
|
||||||
public ModPanelTabBar(ModEditWindow modEditWindow, ModPanelSettingsTab settings, ModPanelDescriptionTab description,
|
private ModPanelTabType _preferredTab = ModPanelTabType.Settings;
|
||||||
ModPanelConflictsTab conflicts, ModPanelChangedItemsTab changedItems, ModPanelEditTab edit, ModManager modManager,
|
private Mod? _lastMod;
|
||||||
TutorialService tutorial, ModPanelCollectionsTab collections)
|
|
||||||
{
|
public ModPanelTabBar(ModEditWindow modEditWindow, ModPanelSettingsTab settings, ModPanelDescriptionTab description,
|
||||||
_modEditWindow = modEditWindow;
|
ModPanelConflictsTab conflicts, ModPanelChangedItemsTab changedItems, ModPanelEditTab edit, ModManager modManager,
|
||||||
Settings = settings;
|
TutorialService tutorial, ModPanelCollectionsTab collections)
|
||||||
Description = description;
|
{
|
||||||
Conflicts = conflicts;
|
_modEditWindow = modEditWindow;
|
||||||
ChangedItems = changedItems;
|
Settings = settings;
|
||||||
Edit = edit;
|
Description = description;
|
||||||
_modManager = modManager;
|
Conflicts = conflicts;
|
||||||
_tutorial = tutorial;
|
ChangedItems = changedItems;
|
||||||
Collections = collections;
|
Edit = edit;
|
||||||
|
_modManager = modManager;
|
||||||
Tabs =
|
_tutorial = tutorial;
|
||||||
[
|
Collections = collections;
|
||||||
Settings,
|
|
||||||
Description,
|
Tabs =
|
||||||
Conflicts,
|
[
|
||||||
ChangedItems,
|
Settings,
|
||||||
Collections,
|
Description,
|
||||||
Edit,
|
Conflicts,
|
||||||
];
|
ChangedItems,
|
||||||
}
|
Collections,
|
||||||
|
Edit,
|
||||||
public void Draw(Mod mod)
|
];
|
||||||
{
|
}
|
||||||
var tabBarHeight = ImGui.GetCursorPosY();
|
|
||||||
if (_lastMod != mod)
|
public void Draw(Mod mod)
|
||||||
{
|
{
|
||||||
_lastMod = mod;
|
var tabBarHeight = ImGui.GetCursorPosY();
|
||||||
TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ToLabel(_preferredTab), out _, () => DrawAdvancedEditingButton(mod), Tabs);
|
if (_lastMod != mod)
|
||||||
}
|
{
|
||||||
else
|
_lastMod = mod;
|
||||||
{
|
TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ToLabel(_preferredTab), out _, () => DrawAdvancedEditingButton(mod), Tabs);
|
||||||
TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ReadOnlySpan<byte>.Empty, out var label, () => DrawAdvancedEditingButton(mod),
|
}
|
||||||
Tabs);
|
else
|
||||||
_preferredTab = ToType(label);
|
{
|
||||||
}
|
TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ReadOnlySpan<byte>.Empty, out var label, () => DrawAdvancedEditingButton(mod),
|
||||||
|
Tabs);
|
||||||
DrawFavoriteButton(mod, tabBarHeight);
|
_preferredTab = ToType(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReadOnlySpan<byte> ToLabel(ModPanelTabType type)
|
DrawFavoriteButton(mod, tabBarHeight);
|
||||||
=> type switch
|
}
|
||||||
{
|
|
||||||
ModPanelTabType.Description => Description.Label,
|
private ReadOnlySpan<byte> ToLabel(ModPanelTabType type)
|
||||||
ModPanelTabType.Settings => Settings.Label,
|
=> type switch
|
||||||
ModPanelTabType.ChangedItems => ChangedItems.Label,
|
{
|
||||||
ModPanelTabType.Conflicts => Conflicts.Label,
|
ModPanelTabType.Description => Description.Label,
|
||||||
ModPanelTabType.Collections => Collections.Label,
|
ModPanelTabType.Settings => Settings.Label,
|
||||||
ModPanelTabType.Edit => Edit.Label,
|
ModPanelTabType.ChangedItems => ChangedItems.Label,
|
||||||
_ => ReadOnlySpan<byte>.Empty,
|
ModPanelTabType.Conflicts => Conflicts.Label,
|
||||||
};
|
ModPanelTabType.Collections => Collections.Label,
|
||||||
|
ModPanelTabType.Edit => Edit.Label,
|
||||||
private ModPanelTabType ToType(ReadOnlySpan<byte> label)
|
_ => ReadOnlySpan<byte>.Empty,
|
||||||
{
|
};
|
||||||
if (label == Description.Label)
|
|
||||||
return ModPanelTabType.Description;
|
private ModPanelTabType ToType(ReadOnlySpan<byte> label)
|
||||||
if (label == Settings.Label)
|
{
|
||||||
return ModPanelTabType.Settings;
|
if (label == Description.Label)
|
||||||
if (label == ChangedItems.Label)
|
return ModPanelTabType.Description;
|
||||||
return ModPanelTabType.ChangedItems;
|
if (label == Settings.Label)
|
||||||
if (label == Conflicts.Label)
|
return ModPanelTabType.Settings;
|
||||||
return ModPanelTabType.Conflicts;
|
if (label == ChangedItems.Label)
|
||||||
if (label == Collections.Label)
|
return ModPanelTabType.ChangedItems;
|
||||||
return ModPanelTabType.Collections;
|
if (label == Conflicts.Label)
|
||||||
if (label == Edit.Label)
|
return ModPanelTabType.Conflicts;
|
||||||
return ModPanelTabType.Edit;
|
if (label == Collections.Label)
|
||||||
|
return ModPanelTabType.Collections;
|
||||||
return 0;
|
if (label == Edit.Label)
|
||||||
}
|
return ModPanelTabType.Edit;
|
||||||
|
|
||||||
private void DrawAdvancedEditingButton(Mod mod)
|
return 0;
|
||||||
{
|
}
|
||||||
if (ImGui.TabItemButton("Advanced Editing", ImGuiTabItemFlags.Trailing | ImGuiTabItemFlags.NoTooltip))
|
|
||||||
{
|
private void DrawAdvancedEditingButton(Mod mod)
|
||||||
_modEditWindow.ChangeMod(mod);
|
{
|
||||||
_modEditWindow.ChangeOption(mod.Default);
|
if (ImGui.TabItemButton("Advanced Editing", ImGuiTabItemFlags.Trailing | ImGuiTabItemFlags.NoTooltip))
|
||||||
_modEditWindow.IsOpen = true;
|
{
|
||||||
}
|
_modEditWindow.ChangeMod(mod);
|
||||||
|
_modEditWindow.ChangeOption(mod.Default);
|
||||||
ImGuiUtil.HoverTooltip(
|
_modEditWindow.IsOpen = true;
|
||||||
"Clicking this will open a new window in which you can\nedit the following things per option for this mod:\n\n"
|
}
|
||||||
+ "\t\t- file redirections\n"
|
|
||||||
+ "\t\t- file swaps\n"
|
ImGuiUtil.HoverTooltip(
|
||||||
+ "\t\t- metadata manipulations\n"
|
"Clicking this will open a new window in which you can\nedit the following things per option for this mod:\n\n"
|
||||||
+ "\t\t- model materials\n"
|
+ "\t\t- file redirections\n"
|
||||||
+ "\t\t- duplicates\n"
|
+ "\t\t- file swaps\n"
|
||||||
+ "\t\t- textures");
|
+ "\t\t- metadata manipulations\n"
|
||||||
}
|
+ "\t\t- model materials\n"
|
||||||
|
+ "\t\t- duplicates\n"
|
||||||
private void DrawFavoriteButton(Mod mod, float height)
|
+ "\t\t- textures");
|
||||||
{
|
}
|
||||||
using (var font = ImRaii.PushFont(UiBuilder.IconFont))
|
|
||||||
{
|
private void DrawFavoriteButton(Mod mod, float height)
|
||||||
var size = ImGui.CalcTextSize(FontAwesomeIcon.Star.ToIconString()) + ImGui.GetStyle().FramePadding * 2;
|
{
|
||||||
var newPos = new Vector2(ImGui.GetWindowWidth() - size.X - ImGui.GetStyle().ItemSpacing.X, height);
|
var size = ImEx.Icon.CalculateSize(LunaStyle.FavoriteIcon) + ImGui.GetStyle().FramePadding * 2;
|
||||||
if (ImGui.GetScrollMaxX() > 0)
|
var newPos = new Vector2(ImGui.GetWindowWidth() - size.X - ImGui.GetStyle().ItemSpacing.X, height);
|
||||||
newPos.X += ImGui.GetScrollX();
|
if (ImGui.GetScrollMaxX() > 0)
|
||||||
|
newPos.X += ImGui.GetScrollX();
|
||||||
var rectUpper = ImGui.GetWindowPos() + newPos;
|
|
||||||
var color = ImGui.IsMouseHoveringRect(rectUpper, rectUpper + size) ? ImGui.GetColorU32(ImGuiCol.Text) :
|
var rectUpper = ImGui.GetWindowPos() + newPos;
|
||||||
mod.Favorite ? 0xFF00FFFF : ImGui.GetColorU32(ImGuiCol.TextDisabled);
|
var color = ImGui.IsMouseHoveringRect(rectUpper, rectUpper + size) ? Im.Style[ImGuiColor.Text] :
|
||||||
using var c = ImRaii.PushColor(ImGuiCol.Text, color)
|
mod.Favorite ? LunaStyle.FavoriteColor : Im.Style[ImGuiColor.TextDisabled];
|
||||||
.Push(ImGuiCol.Button, 0)
|
using var c = ImGuiColor.Text.Push(color)
|
||||||
.Push(ImGuiCol.ButtonHovered, 0)
|
.Push(ImGuiColor.Button, Vector4.Zero)
|
||||||
.Push(ImGuiCol.ButtonActive, 0);
|
.Push(ImGuiColor.ButtonHovered, Vector4.Zero)
|
||||||
|
.Push(ImGuiColor.ButtonActive, Vector4.Zero);
|
||||||
ImGui.SetCursorPos(newPos);
|
|
||||||
if (ImGui.Button(FontAwesomeIcon.Star.ToIconString()))
|
ImGui.SetCursorPos(newPos);
|
||||||
_modManager.DataEditor.ChangeModFavorite(mod, !mod.Favorite);
|
if (ImEx.Icon.Button(LunaStyle.FavoriteIcon))
|
||||||
}
|
_modManager.DataEditor.ChangeModFavorite(mod, !mod.Favorite);
|
||||||
|
|
||||||
var hovered = ImGui.IsItemHovered();
|
var hovered = ImGui.IsItemHovered();
|
||||||
_tutorial.OpenTutorial(BasicTutorialSteps.Favorites);
|
_tutorial.OpenTutorial(BasicTutorialSteps.Favorites);
|
||||||
|
|
||||||
if (hovered)
|
if (hovered)
|
||||||
ImGui.SetTooltip("Favorite");
|
ImGui.SetTooltip("Favorite");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ public sealed class PredefinedTagManager : ISavable, IReadOnlyList<string>, ISer
|
||||||
private readonly SaveService _saveService;
|
private readonly SaveService _saveService;
|
||||||
|
|
||||||
private bool _isListOpen;
|
private bool _isListOpen;
|
||||||
private uint _enabledColor;
|
private Rgba32 _enabledColor;
|
||||||
private uint _disabledColor;
|
private Rgba32 _disabledColor;
|
||||||
|
|
||||||
private readonly SortedList<string, TagData> _predefinedTags = [];
|
private readonly SortedList<string, TagData> _predefinedTags = [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
|
using ImSharp;
|
||||||
using Luna;
|
using Luna;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
|
|
@ -336,17 +337,13 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
||||||
$"Successfully loaded ({(byte)item.LoadState})."),
|
$"Successfully loaded ({(byte)item.LoadState})."),
|
||||||
LoadState.FailedSubResource => (FontAwesomeIcon.ExclamationCircle, ColorId.DecreasedMetaValue.Value(),
|
LoadState.FailedSubResource => (FontAwesomeIcon.ExclamationCircle, ColorId.DecreasedMetaValue.Value(),
|
||||||
$"Dependencies failed to load ({(byte)item.LoadState})."),
|
$"Dependencies failed to load ({(byte)item.LoadState})."),
|
||||||
<= LoadState.Constructed => (FontAwesomeIcon.QuestionCircle, ColorId.UndefinedMod.Value(), $"Not yet loaded ({(byte)item.LoadState})."),
|
<= LoadState.Constructed => (FontAwesomeIcon.QuestionCircle, ColorId.UndefinedMod.Value(),
|
||||||
|
$"Not yet loaded ({(byte)item.LoadState})."),
|
||||||
< LoadState.Success => (FontAwesomeIcon.Clock, ColorId.FolderLine.Value(), $"Loading asynchronously ({(byte)item.LoadState})."),
|
< LoadState.Success => (FontAwesomeIcon.Clock, ColorId.FolderLine.Value(), $"Loading asynchronously ({(byte)item.LoadState})."),
|
||||||
> LoadState.Success => (FontAwesomeIcon.Times, ColorId.DecreasedMetaValue.Value(),
|
> LoadState.Success => (FontAwesomeIcon.Times, ColorId.DecreasedMetaValue.Value(),
|
||||||
$"Failed to load ({(byte)item.LoadState})."),
|
$"Failed to load ({(byte)item.LoadState})."),
|
||||||
};
|
};
|
||||||
using (var font = ImRaii.PushFont(UiBuilder.IconFont))
|
ImEx.Icon.Draw(icon.Icon(), color);
|
||||||
{
|
|
||||||
using var c = ImRaii.PushColor(ImGuiCol.Text, color);
|
|
||||||
ImGui.TextUnformatted(icon.ToIconString());
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGuiUtil.HoverTooltip(tt);
|
ImGuiUtil.HoverTooltip(tt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,29 +86,30 @@ public sealed class CollectionsTab : IDisposable, ITab, Luna.IUiService
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0).Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0).Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
||||||
var buttonSize = new Vector2((ImGui.GetContentRegionAvail().X - withSpacing) / 4f, ImGui.GetFrameHeight());
|
var buttonSize = new Vector2((ImGui.GetContentRegionAvail().X - withSpacing) / 4f, ImGui.GetFrameHeight());
|
||||||
|
|
||||||
using var _ = ImRaii.Group();
|
using var _ = ImRaii.Group();
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.TabActive), Mode is PanelMode.SimpleAssignment);
|
var tabSelectedColor = Im.Style[ImGuiColor.TabSelected];
|
||||||
|
using var color = ImGuiColor.Button.Push(tabSelectedColor, Mode is PanelMode.SimpleAssignment);
|
||||||
if (ImGui.Button("Simple Assignments", buttonSize))
|
if (ImGui.Button("Simple Assignments", buttonSize))
|
||||||
Mode = PanelMode.SimpleAssignment;
|
Mode = PanelMode.SimpleAssignment;
|
||||||
color.Pop();
|
color.Pop();
|
||||||
_tutorial.OpenTutorial(BasicTutorialSteps.SimpleAssignments);
|
_tutorial.OpenTutorial(BasicTutorialSteps.SimpleAssignments);
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
|
|
||||||
color.Push(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.TabActive), Mode is PanelMode.IndividualAssignment);
|
color.Push(ImGuiColor.Button, tabSelectedColor, Mode is PanelMode.IndividualAssignment);
|
||||||
if (ImGui.Button("Individual Assignments", buttonSize))
|
if (ImGui.Button("Individual Assignments", buttonSize))
|
||||||
Mode = PanelMode.IndividualAssignment;
|
Mode = PanelMode.IndividualAssignment;
|
||||||
color.Pop();
|
color.Pop();
|
||||||
_tutorial.OpenTutorial(BasicTutorialSteps.IndividualAssignments);
|
_tutorial.OpenTutorial(BasicTutorialSteps.IndividualAssignments);
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
|
|
||||||
color.Push(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.TabActive), Mode is PanelMode.GroupAssignment);
|
color.Push(ImGuiColor.Button, tabSelectedColor, Mode is PanelMode.GroupAssignment);
|
||||||
if (ImGui.Button("Group Assignments", buttonSize))
|
if (ImGui.Button("Group Assignments", buttonSize))
|
||||||
Mode = PanelMode.GroupAssignment;
|
Mode = PanelMode.GroupAssignment;
|
||||||
color.Pop();
|
color.Pop();
|
||||||
_tutorial.OpenTutorial(BasicTutorialSteps.GroupAssignments);
|
_tutorial.OpenTutorial(BasicTutorialSteps.GroupAssignments);
|
||||||
Im.Line.Same();
|
Im.Line.Same();
|
||||||
|
|
||||||
color.Push(ImGuiCol.Button, ImGui.GetColorU32(ImGuiCol.TabActive), Mode is PanelMode.Details);
|
color.Push(ImGuiColor.Button, tabSelectedColor, Mode is PanelMode.Details);
|
||||||
if (ImGui.Button("Collection Details", buttonSize))
|
if (ImGui.Button("Collection Details", buttonSize))
|
||||||
Mode = PanelMode.Details;
|
Mode = PanelMode.Details;
|
||||||
color.Pop();
|
color.Pop();
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ using Penumbra.Mods.Manager;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.String;
|
using Penumbra.String;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
using static OtterGui.Raii.ImRaii;
|
|
||||||
using CharacterBase = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase;
|
using CharacterBase = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase;
|
||||||
using ImGuiClip = OtterGui.ImGuiClip;
|
using ImGuiClip = OtterGui.ImGuiClip;
|
||||||
using Penumbra.Api.IpcTester;
|
using Penumbra.Api.IpcTester;
|
||||||
|
|
@ -68,7 +67,7 @@ public class Diagnostics(ServiceManager provider) : IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DebugTab : Window, ITab, IUiService
|
public class DebugTab : Window, ITab
|
||||||
{
|
{
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly CollectionManager _collectionManager;
|
private readonly CollectionManager _collectionManager;
|
||||||
|
|
@ -180,7 +179,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
public void DrawContent()
|
public void DrawContent()
|
||||||
{
|
{
|
||||||
using var child = Child("##DebugTab", -Vector2.One);
|
using var child = Im.Child.Begin("##DebugTab"u8, -Vector2.One);
|
||||||
if (!child)
|
if (!child)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -218,9 +217,9 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
{
|
{
|
||||||
if (collection.HasCache)
|
if (collection.HasCache)
|
||||||
{
|
{
|
||||||
using var color = PushColor(ImGuiCol.Text, ColorId.FolderExpanded.Value());
|
using var color = ImGuiColor.Text.Push(ColorId.FolderExpanded.Value());
|
||||||
using var node =
|
using var node =
|
||||||
TreeNode($"{collection.Identity.Name} (Change Counter {collection.Counters.Change})###{collection.Identity.Name}");
|
Im.Tree.Node($"{collection.Identity.Name} (Change Counter {collection.Counters.Change})###{collection.Identity.Name}");
|
||||||
if (!node)
|
if (!node)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -272,24 +271,24 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
if (modNode)
|
if (modNode)
|
||||||
foreach (var (mod, paths, manips) in collection._cache!.ModData.Data.OrderBy(t => t.Item1.Name))
|
foreach (var (mod, paths, manips) in collection._cache!.ModData.Data.OrderBy(t => t.Item1.Name))
|
||||||
{
|
{
|
||||||
using var id = mod is TemporaryMod t ? PushId(t.Priority.Value) : PushId(((Mod)mod).ModPath.Name);
|
using var id = mod is TemporaryMod t ? Im.Id.Push(t.Priority.Value) : Im.Id.Push(((Mod)mod).ModPath.Name);
|
||||||
using var node2 = TreeNode(mod.Name);
|
using var node2 = Im.Tree.Node(mod.Name);
|
||||||
if (!node2)
|
if (!node2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
foreach (var path in paths)
|
foreach (var path in paths)
|
||||||
|
|
||||||
TreeNode(path.ToString(), ImGuiTreeNodeFlags.Bullet | ImGuiTreeNodeFlags.Leaf).Dispose();
|
Im.Tree.Node(path.Path.Span, TreeNodeFlags.Bullet | TreeNodeFlags.Leaf).Dispose();
|
||||||
|
|
||||||
foreach (var manip in manips)
|
foreach (var manip in manips)
|
||||||
TreeNode(manip.ToString(), ImGuiTreeNodeFlags.Bullet | ImGuiTreeNodeFlags.Leaf).Dispose();
|
Im.Tree.Node($"{manip}", TreeNodeFlags.Bullet | TreeNodeFlags.Leaf).Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using var color = PushColor(ImGuiCol.Text, ColorId.UndefinedMod.Value());
|
using var color = ImGuiColor.Text.Push(ColorId.UndefinedMod.Value());
|
||||||
TreeNode($"{collection.Identity.Name} (Change Counter {collection.Counters.Change})",
|
Im.Tree.Node($"{collection.Identity.Name} (Change Counter {collection.Counters.Change})",
|
||||||
ImGuiTreeNodeFlags.Bullet | ImGuiTreeNodeFlags.Leaf).Dispose();
|
TreeNodeFlags.Bullet | TreeNodeFlags.Leaf).Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -308,7 +307,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
_config.Ephemeral.Save();
|
_config.Ephemeral.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var table = Table("##DebugGeneralTable", 2, ImGuiTableFlags.SizingFixedFit))
|
using (var table = Im.Table.Begin("##DebugGeneralTable"u8, 2, TableFlags.SizingFixedFit))
|
||||||
{
|
{
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
|
|
@ -329,11 +328,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
|
|
||||||
var issues = _modManager.Index().Count(p => p.Index != p.Item.Index);
|
var issues = _modManager.Index().Count(p => p.Index != p.Item.Index);
|
||||||
using (var tree = TreeNode($"Mods ({issues} Issues)###Mods"))
|
using (var tree = Im.Tree.Node($"Mods ({issues} Issues)###Mods"))
|
||||||
{
|
{
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
using var table = Table("##DebugModsTable", 3, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("##DebugModsTable"u8, 3, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
var lastIndex = -1;
|
var lastIndex = -1;
|
||||||
|
|
@ -350,11 +349,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var tree = TreeNode("Mod Import"))
|
using (var tree = Im.Tree.Node("Mod Import"u8))
|
||||||
{
|
{
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
using var table = Table("##DebugModImport", 2, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("##DebugModImport"u8, 2, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
var importing = _modImporter.IsImporting(out var importer);
|
var importing = _modImporter.IsImporting(out var importer);
|
||||||
|
|
@ -384,11 +383,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var tree = TreeNode("Framework"))
|
using (var tree = Im.Tree.Node("Framework"u8))
|
||||||
{
|
{
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
using var table = Table("##DebugFramework", 2, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("##DebugFramework"u8, 2, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
foreach (var important in _framework.Important)
|
foreach (var important in _framework.Important)
|
||||||
|
|
@ -406,11 +405,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var tree = TreeNode($"Texture Manager {_textureManager.Tasks.Count}###Texture Manager"))
|
using (var tree = Im.Tree.Node($"Texture Manager {_textureManager.Tasks.Count}###Texture Manager"))
|
||||||
{
|
{
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
using var table = Table("##Tasks", 2, ImGuiTableFlags.RowBg);
|
using var table = Im.Table.Begin("##Tasks"u8, 2, TableFlags.RowBackground);
|
||||||
if (table)
|
if (table)
|
||||||
foreach (var task in _textureManager.Tasks)
|
foreach (var task in _textureManager.Tasks)
|
||||||
{
|
{
|
||||||
|
|
@ -420,11 +419,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var tree = TreeNode("Redraw Service"))
|
using (var tree = Im.Tree.Node("Redraw Service"u8))
|
||||||
{
|
{
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
using var table = Table("##redraws", 3, ImGuiTableFlags.RowBg);
|
using var table = Im.Table.Begin("##redraws"u8, 3, TableFlags.RowBackground);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn("In GPose");
|
ImGuiUtil.DrawTableColumn("In GPose");
|
||||||
|
|
@ -494,7 +493,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
if (!ImGui.CollapsingHeader("Performance"))
|
if (!ImGui.CollapsingHeader("Performance"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using (var start = TreeNode("Startup Performance", ImGuiTreeNodeFlags.DefaultOpen))
|
using (var start = Im.Tree.Node("Startup Performance"u8, TreeNodeFlags.DefaultOpen))
|
||||||
{
|
{
|
||||||
if (start)
|
if (start)
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
@ -512,7 +511,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
{
|
{
|
||||||
_objects.DrawDebug();
|
_objects.DrawDebug();
|
||||||
|
|
||||||
using var table = Table("##actors", 8, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit,
|
using var table = Im.Table.Begin("##actors"u8, 8, TableFlags.RowBackground | TableFlags.SizingFixedFit,
|
||||||
-Vector2.UnitX);
|
-Vector2.UnitX);
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
@ -581,11 +580,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
ImGui.TextUnformatted(
|
ImGui.TextUnformatted(
|
||||||
$"Last Game Object: 0x{_collectionResolver.IdentifyLastGameObjectCollection(true).AssociatedGameObject:X} ({_collectionResolver.IdentifyLastGameObjectCollection(true).ModCollection.Identity.Name})");
|
$"Last Game Object: 0x{_collectionResolver.IdentifyLastGameObjectCollection(true).AssociatedGameObject:X} ({_collectionResolver.IdentifyLastGameObjectCollection(true).ModCollection.Identity.Name})");
|
||||||
using (var drawTree = TreeNode("Draw Object to Object"))
|
using (var drawTree = Im.Tree.Node("Draw Object to Object"u8))
|
||||||
{
|
{
|
||||||
if (drawTree)
|
if (drawTree)
|
||||||
{
|
{
|
||||||
using var table = Table("###DrawObjectResolverTable", 8, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("###DrawObjectResolverTable"u8, 8, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
foreach (var (drawObject, (gameObjectPtr, idx, child)) in _drawObjectState
|
foreach (var (drawObject, (gameObjectPtr, idx, child)) in _drawObjectState
|
||||||
.OrderBy(kvp => kvp.Value.Item2.Index)
|
.OrderBy(kvp => kvp.Value.Item2.Index)
|
||||||
|
|
@ -595,7 +594,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImUtf8.CopyOnClickSelectable($"{drawObject}");
|
ImUtf8.CopyOnClickSelectable($"{drawObject}");
|
||||||
ImUtf8.DrawTableColumn($"{gameObjectPtr.Index}");
|
ImUtf8.DrawTableColumn($"{gameObjectPtr.Index}");
|
||||||
using (ImRaii.PushColor(ImGuiCol.Text, 0xFF0000FF, gameObjectPtr.Index != idx))
|
using (ImGuiColor.Text.Push(new Vector4(1, 0, 0, 1), gameObjectPtr.Index != idx))
|
||||||
{
|
{
|
||||||
ImUtf8.DrawTableColumn($"{idx}");
|
ImUtf8.DrawTableColumn($"{idx}");
|
||||||
}
|
}
|
||||||
|
|
@ -603,7 +602,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
ImUtf8.DrawTableColumn(child ? "Child"u8 : "Main"u8);
|
ImUtf8.DrawTableColumn(child ? "Child"u8 : "Main"u8);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImUtf8.CopyOnClickSelectable($"{gameObjectPtr}");
|
ImUtf8.CopyOnClickSelectable($"{gameObjectPtr}");
|
||||||
using (ImRaii.PushColor(ImGuiCol.Text, 0xFF0000FF, _objects[idx] != gameObjectPtr))
|
using (ImGuiColor.Text.Push(new Vector4(1, 0, 0, 1), _objects[idx] != gameObjectPtr))
|
||||||
{
|
{
|
||||||
ImUtf8.DrawTableColumn($"{_objects[idx]}");
|
ImUtf8.DrawTableColumn($"{_objects[idx]}");
|
||||||
}
|
}
|
||||||
|
|
@ -615,11 +614,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var pathTree = TreeNode("Path Collections"))
|
using (var pathTree = Im.Tree.Node("Path Collections"u8))
|
||||||
{
|
{
|
||||||
if (pathTree)
|
if (pathTree)
|
||||||
{
|
{
|
||||||
using var table = Table("###PathCollectionResolverTable", 2, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("###PathCollectionResolverTable"u8, 2, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
foreach (var data in _pathState.CurrentData)
|
foreach (var data in _pathState.CurrentData)
|
||||||
{
|
{
|
||||||
|
|
@ -631,11 +630,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var resourceTree = TreeNode("Subfile Collections"))
|
using (var resourceTree = Im.Tree.Node("Subfile Collections"u8))
|
||||||
{
|
{
|
||||||
if (resourceTree)
|
if (resourceTree)
|
||||||
{
|
{
|
||||||
using var table = Table("###ResourceCollectionResolverTable", 4, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("###ResourceCollectionResolverTable"u8, 4, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn("Current Mtrl Data");
|
ImGuiUtil.DrawTableColumn("Current Mtrl Data");
|
||||||
|
|
@ -664,11 +663,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var identifiedTree = TreeNode("Identified Collections"))
|
using (var identifiedTree = Im.Tree.Node("Identified Collections"u8))
|
||||||
{
|
{
|
||||||
if (identifiedTree)
|
if (identifiedTree)
|
||||||
{
|
{
|
||||||
using var table = Table("##PathCollectionsIdentifiedTable", 4, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("##PathCollectionsIdentifiedTable"u8, 4, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
foreach (var (address, identifier, collection) in _identifiedCollectionCache
|
foreach (var (address, identifier, collection) in _identifiedCollectionCache
|
||||||
.OrderBy(kvp => ((GameObject*)kvp.Address)->ObjectIndex))
|
.OrderBy(kvp => ((GameObject*)kvp.Address)->ObjectIndex))
|
||||||
|
|
@ -681,11 +680,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var cutsceneTree = TreeNode("Cutscene Actors"))
|
using (var cutsceneTree = Im.Tree.Node("Cutscene Actors"u8))
|
||||||
{
|
{
|
||||||
if (cutsceneTree)
|
if (cutsceneTree)
|
||||||
{
|
{
|
||||||
using var table = Table("###PCutsceneResolverTable", 2, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("###PCutsceneResolverTable"u8, 2, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
foreach (var (idx, actor) in _cutsceneService.Actors)
|
foreach (var (idx, actor) in _cutsceneService.Actors)
|
||||||
{
|
{
|
||||||
|
|
@ -695,11 +694,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var groupTree = TreeNode("Group"))
|
using (var groupTree = Im.Tree.Node("Group"u8))
|
||||||
{
|
{
|
||||||
if (groupTree)
|
if (groupTree)
|
||||||
{
|
{
|
||||||
using var table = Table("###PGroupTable", 2, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("###PGroupTable"u8, 2, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
ImGuiUtil.DrawTableColumn("Group Members");
|
ImGuiUtil.DrawTableColumn("Group Members");
|
||||||
|
|
@ -714,7 +713,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var bannerTree = TreeNode("Party Banner"))
|
using (var bannerTree = Im.Tree.Node("Party Banner"u8))
|
||||||
{
|
{
|
||||||
if (bannerTree)
|
if (bannerTree)
|
||||||
{
|
{
|
||||||
|
|
@ -727,7 +726,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
Penumbra.Dynamis.DrawPointer((nint)agent);
|
Penumbra.Dynamis.DrawPointer((nint)agent);
|
||||||
if (agent->Data != null)
|
if (agent->Data != null)
|
||||||
{
|
{
|
||||||
using var table = Table("###PBannerTable", 2, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("###PBannerTable"u8, 2, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
for (var i = 0; i < 8; ++i)
|
for (var i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -744,11 +743,11 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var tmbCache = TreeNode("TMB Cache"))
|
using (var tmbCache = Im.Tree.Node("TMB Cache"u8))
|
||||||
{
|
{
|
||||||
if (tmbCache)
|
if (tmbCache)
|
||||||
{
|
{
|
||||||
using var table = Table("###TmbTable", 2, ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("###TmbTable"u8, 2, TableFlags.SizingFixedFit);
|
||||||
if (table)
|
if (table)
|
||||||
foreach (var (id, name) in _schedulerService.ListedTmbs.OrderBy(kvp => kvp.Key))
|
foreach (var (id, name) in _schedulerService.ListedTmbs.OrderBy(kvp => kvp.Key))
|
||||||
{
|
{
|
||||||
|
|
@ -777,7 +776,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
private void DrawFileTest()
|
private void DrawFileTest()
|
||||||
{
|
{
|
||||||
using var node = TreeNode("Game File Test");
|
using var node = Im.Tree.Node("Game File Test"u8);
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -803,7 +802,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
private void DrawChangedItemTest()
|
private void DrawChangedItemTest()
|
||||||
{
|
{
|
||||||
using var node = TreeNode("Changed Item Test");
|
using var node = Im.Tree.Node("Changed Item Test"u8);
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -855,13 +854,13 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
private void DrawEmotes()
|
private void DrawEmotes()
|
||||||
{
|
{
|
||||||
using var mainTree = TreeNode("Emotes");
|
using var mainTree = Im.Tree.Node("Emotes"u8);
|
||||||
if (!mainTree)
|
if (!mainTree)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGui.InputText("File Name", ref _emoteSearchFile, 256);
|
ImGui.InputText("File Name", ref _emoteSearchFile, 256);
|
||||||
ImGui.InputText("Emote Name", ref _emoteSearchName, 256);
|
ImGui.InputText("Emote Name", ref _emoteSearchName, 256);
|
||||||
using var table = Table("##table", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit,
|
using var table = Im.Table.Begin("##table"u8, 2, TableFlags.RowBackground | TableFlags.ScrollY | TableFlags.SizingFixedFit,
|
||||||
new Vector2(-1, 12 * ImGui.GetTextLineHeightWithSpacing()));
|
new Vector2(-1, 12 * ImGui.GetTextLineHeightWithSpacing()));
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
@ -886,13 +885,13 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
private void DrawActionTmbs()
|
private void DrawActionTmbs()
|
||||||
{
|
{
|
||||||
using var mainTree = TreeNode("Action TMBs");
|
using var mainTree = Im.Tree.Node("Action TMBs"u8);
|
||||||
if (!mainTree)
|
if (!mainTree)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ImGui.InputText("Key", ref _tmbKeyFilter, 256))
|
if (ImGui.InputText("Key", ref _tmbKeyFilter, 256))
|
||||||
_tmbKeyFilterU8 = CiByteString.FromString(_tmbKeyFilter, out var r, MetaDataComputation.All) ? r : CiByteString.Empty;
|
_tmbKeyFilterU8 = CiByteString.FromString(_tmbKeyFilter, out var r, MetaDataComputation.All) ? r : CiByteString.Empty;
|
||||||
using var table = Table("##table", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedFit,
|
using var table = Im.Table.Begin("##table"u8, 2, TableFlags.RowBackground | TableFlags.ScrollY | TableFlags.SizingFixedFit,
|
||||||
new Vector2(-1, 12 * ImGui.GetTextLineHeightWithSpacing()));
|
new Vector2(-1, 12 * ImGui.GetTextLineHeightWithSpacing()));
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
@ -910,17 +909,17 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
private void DrawStainTemplates()
|
private void DrawStainTemplates()
|
||||||
{
|
{
|
||||||
using var mainTree = TreeNode("Staining Templates");
|
using var mainTree = Im.Tree.Node("Staining Templates"u8);
|
||||||
if (!mainTree)
|
if (!mainTree)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using (var legacyTree = TreeNode("stainingtemplate.stm"))
|
using (var legacyTree = Im.Tree.Node("stainingtemplate.stm"u8))
|
||||||
{
|
{
|
||||||
if (legacyTree)
|
if (legacyTree)
|
||||||
DrawStainTemplatesFile(_stains.LegacyStmFile);
|
DrawStainTemplatesFile(_stains.LegacyStmFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var gudTree = TreeNode("stainingtemplate_gud.stm"))
|
using (var gudTree = Im.Tree.Node("stainingtemplate_gud.stm"u8))
|
||||||
{
|
{
|
||||||
if (gudTree)
|
if (gudTree)
|
||||||
DrawStainTemplatesFile(_stains.GudStmFile);
|
DrawStainTemplatesFile(_stains.GudStmFile);
|
||||||
|
|
@ -931,12 +930,12 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
{
|
{
|
||||||
foreach (var (key, data) in stmFile.Entries)
|
foreach (var (key, data) in stmFile.Entries)
|
||||||
{
|
{
|
||||||
using var tree = TreeNode($"Template {key}");
|
using var tree = Im.Tree.Node($"Template {key}");
|
||||||
if (!tree)
|
if (!tree)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
using var table = Table("##table", data.Colors.Length + data.Scalars.Length,
|
using var table = Im.Table.Begin("##table"u8, data.Colors.Length + data.Scalars.Length,
|
||||||
ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
|
TableFlags.SizingFixedFit | TableFlags.RowBackground);
|
||||||
if (!table)
|
if (!table)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -974,7 +973,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
if (!enableShaderReplacementFixer)
|
if (!enableShaderReplacementFixer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using var table = Table("##ShaderReplacementFixer", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit,
|
using var table = Im.Table.Begin("##ShaderReplacementFixer"u8, 3, TableFlags.RowBackground | TableFlags.SizingFixedFit,
|
||||||
-Vector2.UnitX);
|
-Vector2.UnitX);
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1066,7 +1065,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
DrawCopyableAddress("CharacterBase"u8, model);
|
DrawCopyableAddress("CharacterBase"u8, model);
|
||||||
|
|
||||||
using (var t1 = Table("##table", 2, ImGuiTableFlags.SizingFixedFit))
|
using (var t1 = Im.Table.Begin("##table"u8, 2, TableFlags.SizingFixedFit))
|
||||||
{
|
{
|
||||||
if (t1)
|
if (t1)
|
||||||
{
|
{
|
||||||
|
|
@ -1079,7 +1078,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using var table = Table($"##{name}DrawTable", 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin($"##{name}DrawTable", 5, TableFlags.RowBackground | TableFlags.SizingFixedFit);
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1120,7 +1119,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
private string _crcInput = string.Empty;
|
private string _crcInput = string.Empty;
|
||||||
private FullPath _crcPath = FullPath.Empty;
|
private FullPath _crcPath = FullPath.Empty;
|
||||||
|
|
||||||
private unsafe void DrawCrcCache()
|
private void DrawCrcCache()
|
||||||
{
|
{
|
||||||
var header = ImUtf8.CollapsingHeader("CRC Cache"u8);
|
var header = ImUtf8.CollapsingHeader("CRC Cache"u8);
|
||||||
if (!header)
|
if (!header)
|
||||||
|
|
@ -1188,7 +1187,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
if (!header)
|
if (!header)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using var table = Table("##ProblemsTable", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit);
|
using var table = Im.Table.Begin("##ProblemsTable"u8, 6, TableFlags.RowBackground | TableFlags.SizingFixedFit);
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1240,10 +1239,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
ImUtf8.Text($"Is Cloud Synced? {_cloudTesterReturn}");
|
ImUtf8.Text($"Is Cloud Synced? {_cloudTesterReturn}");
|
||||||
|
|
||||||
if (_cloudTesterError is not null)
|
if (_cloudTesterError is not null)
|
||||||
{
|
Im.Text($"{_cloudTesterError}", ImGuiColors.DalamudRed);
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
|
||||||
ImUtf8.Text($"{_cloudTesterError}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ public class RenderTargetDrawer(RenderTargetHdrEnabler renderTargetHdrEnabler, D
|
||||||
+ record.Offset);
|
+ record.Offset);
|
||||||
if (texture != null)
|
if (texture != null)
|
||||||
{
|
{
|
||||||
using var color = Dalamud.Interface.Utility.Raii.ImRaii.PushColor(ImGuiCol.Text, ImGuiUtil.HalfBlendText(0xFF),
|
using var color = ImGuiColor.Text.Push(ImGuiUtil.HalfBlendText(0xFF),
|
||||||
texture->TextureFormat != record.OriginalTextureFormat);
|
texture->TextureFormat != record.OriginalTextureFormat);
|
||||||
ImUtf8.Text($"{texture->TextureFormat}");
|
ImUtf8.Text($"{texture->TextureFormat}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
using ImSharp;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using Penumbra.Collections.Cache;
|
using Penumbra.Collections.Cache;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
@ -90,10 +91,10 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
private static void DrawValues(in ShapeAttributeString shapeAttribute, ShapeAttributeHashSet set)
|
private static void DrawValues(in ShapeAttributeString shapeAttribute, ShapeAttributeHashSet set)
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
var disabledColor = Im.Style[ImGuiColor.TextDisabled];
|
||||||
if (set.All is { } value)
|
if (set.All is { } value)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !value);
|
using var color = ImGuiColor.Text.Push(disabledColor, !value);
|
||||||
ImUtf8.Text("All, "u8);
|
ImUtf8.Text("All, "u8);
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +104,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
if (set[slot] is not { } value2)
|
if (set[slot] is not { } value2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !value2);
|
using var color = ImGuiColor.Text.Push(disabledColor, !value2);
|
||||||
ImUtf8.Text($"All {slot.ToName()}, ");
|
ImUtf8.Text($"All {slot.ToName()}, ");
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +113,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
{
|
{
|
||||||
if (set[gr] is { } value3)
|
if (set[gr] is { } value3)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !value3);
|
using var color = ImGuiColor.Text.Push(disabledColor, !value3);
|
||||||
ImUtf8.Text($"All {gr.ToName()}, ");
|
ImUtf8.Text($"All {gr.ToName()}, ");
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +124,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
if (set[slot, gr] is not { } value4)
|
if (set[slot, gr] is not { } value4)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !value4);
|
using var color = ImGuiColor.Text.Push(disabledColor, !value4);
|
||||||
ImUtf8.Text($"All {gr.ToName()} {slot.ToName()}, ");
|
ImUtf8.Text($"All {gr.ToName()} {slot.ToName()}, ");
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +139,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
|
|
||||||
if (set[slot, GenderRace.Unknown] != enabled)
|
if (set[slot, GenderRace.Unknown] != enabled)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !enabled);
|
using var color = ImGuiColor.Text.Push(disabledColor, !enabled);
|
||||||
ImUtf8.Text($"{slot.ToName()} {id.Id:D4}, ");
|
ImUtf8.Text($"{slot.ToName()} {id.Id:D4}, ");
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +154,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
var gr = ShapeAttributeHashSet.GenderRaceValues[currentIndex];
|
var gr = ShapeAttributeHashSet.GenderRaceValues[currentIndex];
|
||||||
if (set[slot, gr] != enabled)
|
if (set[slot, gr] != enabled)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), !enabled);
|
using var color = ImGuiColor.Text.Push(disabledColor, !enabled);
|
||||||
ImUtf8.Text($"{gr.ToName()} {slot.ToName()} #{id.Id:D4}, ");
|
ImUtf8.Text($"{gr.ToName()} {slot.ToName()} #{id.Id:D4}, ");
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +187,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
|
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
var disabledColor = ImGui.GetColorU32(ImGuiCol.TextDisabled);
|
var disabledColor = Im.Style[ImGuiColor.TextDisabled];
|
||||||
for (var i = 0; i < human.AsHuman->SlotCount; ++i)
|
for (var i = 0; i < human.AsHuman->SlotCount; ++i)
|
||||||
{
|
{
|
||||||
ImUtf8.DrawTableColumn($"{(uint)i:D2}");
|
ImUtf8.DrawTableColumn($"{(uint)i:D2}");
|
||||||
|
|
@ -205,7 +206,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
foreach (var (idx, (shape, flag)) in model->ModelResourceHandle->Shapes.Index())
|
foreach (var (idx, (shape, flag)) in model->ModelResourceHandle->Shapes.Index())
|
||||||
{
|
{
|
||||||
var disabled = (mask & (1u << flag)) is 0;
|
var disabled = (mask & (1u << flag)) is 0;
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, disabledColor, disabled);
|
using var color = ImGuiColor.Text.Push(disabledColor, disabled);
|
||||||
ImUtf8.Text(shape.AsSpan());
|
ImUtf8.Text(shape.AsSpan());
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
ImUtf8.Text(", "u8);
|
ImUtf8.Text(", "u8);
|
||||||
|
|
@ -243,7 +244,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
|
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
var disabledColor = ImGui.GetColorU32(ImGuiCol.TextDisabled);
|
var disabledColor = Im.Style[ImGuiColor.TextDisabled];
|
||||||
for (var i = 0; i < human.AsHuman->SlotCount; ++i)
|
for (var i = 0; i < human.AsHuman->SlotCount; ++i)
|
||||||
{
|
{
|
||||||
ImUtf8.DrawTableColumn($"{(uint)i:D2}");
|
ImUtf8.DrawTableColumn($"{(uint)i:D2}");
|
||||||
|
|
@ -262,7 +263,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
|
||||||
foreach (var (idx, (attribute, flag)) in model->ModelResourceHandle->Attributes.Index())
|
foreach (var (idx, (attribute, flag)) in model->ModelResourceHandle->Attributes.Index())
|
||||||
{
|
{
|
||||||
var disabled = (mask & (1u << flag)) is 0;
|
var disabled = (mask & (1u << flag)) is 0;
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, disabledColor, disabled);
|
using var color = ImGuiColor.Text.Push(disabledColor, disabled);
|
||||||
ImUtf8.Text(attribute.AsSpan());
|
ImUtf8.Text(attribute.AsSpan());
|
||||||
ImGui.SameLine(0, 0);
|
ImGui.SameLine(0, 0);
|
||||||
ImUtf8.Text(", "u8);
|
ImUtf8.Text(", "u8);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Dalamud.Bindings.ImGui;
|
using Dalamud.Bindings.ImGui;
|
||||||
using Dalamud.Interface.DragDrop;
|
using Dalamud.Interface.DragDrop;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
using ImSharp;
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
using OtterGui.Text;
|
using OtterGui.Text;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
@ -47,7 +48,7 @@ public class TexHeaderDrawer(IDragDropManager dragDrop) : Luna.IUiService
|
||||||
|
|
||||||
if (_exception != null)
|
if (_exception != null)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, Colors.RegexWarningBorder);
|
using var color = ImGuiColor.Text.Push(Colors.RegexWarningBorder);
|
||||||
ImUtf8.TextWrapped($"Failure to load file:\n{_exception}");
|
ImUtf8.TextWrapped($"Failure to load file:\n{_exception}");
|
||||||
}
|
}
|
||||||
else if (_tex != null)
|
else if (_tex != null)
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ public class ModsTab(
|
||||||
}
|
}
|
||||||
|
|
||||||
var frameHeight = new Vector2(0, ImGui.GetFrameHeight());
|
var frameHeight = new Vector2(0, ImGui.GetFrameHeight());
|
||||||
var frameColor = ImGui.GetColorU32(ImGuiCol.FrameBg);
|
var frameColor = ImGuiColor.FrameBackground.Get().Color;
|
||||||
using (var _ = ImRaii.Group())
|
using (var _ = ImRaii.Group())
|
||||||
{
|
{
|
||||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ public class SettingsTab : ITab, IUiService
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool DrawPressEnterWarning(string newName, string old, float width, bool saved, bool selected)
|
private bool DrawPressEnterWarning(string newName, string old, float width, bool saved, bool selected)
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Button, Colors.PressEnterWarningBg);
|
using var color = ImGuiColor.Button.Push(Colors.PressEnterWarningBg);
|
||||||
var w = new Vector2(width, 0);
|
var w = new Vector2(width, 0);
|
||||||
var (text, valid) = CheckRootDirectoryPath(newName, old, selected);
|
var (text, valid) = CheckRootDirectoryPath(newName, old, selected);
|
||||||
|
|
||||||
|
|
@ -339,10 +339,9 @@ public class SettingsTab : ITab, IUiService
|
||||||
using (ImRaii.Group())
|
using (ImRaii.Group())
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth(UiHelpers.InputTextMinusButton3);
|
ImGui.SetNextItemWidth(UiHelpers.InputTextMinusButton3);
|
||||||
using (ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale, !_modManager.Valid))
|
using (var color = ImStyleBorder.Frame.Push(Colors.RegexWarningBorder, Im.Style.GlobalScale, !_modManager.Valid))
|
||||||
{
|
{
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.RegexWarningBorder)
|
color.Push(ImGuiColor.TextDisabled, Colors.RegexWarningBorder, !_modManager.Valid);
|
||||||
.Push(ImGuiCol.TextDisabled, Colors.RegexWarningBorder, !_modManager.Valid);
|
|
||||||
save = ImGui.InputTextWithHint("##rootDirectory", "Enter Root Directory here (MANDATORY)...", ref _newModDirectory,
|
save = ImGui.InputTextWithHint("##rootDirectory", "Enter Root Directory here (MANDATORY)...", ref _newModDirectory,
|
||||||
RootDirectoryMaxLength, ImGuiInputTextFlags.EnterReturnsTrue);
|
RootDirectoryMaxLength, ImGuiInputTextFlags.EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue