mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Remove static Config.
This commit is contained in:
parent
aa4bc45641
commit
be3c1c85aa
30 changed files with 363 additions and 440 deletions
|
|
@ -218,7 +218,7 @@ public class CollectionCache : IDisposable
|
|||
if (addMetaChanges)
|
||||
{
|
||||
++_collection.ChangeCounter;
|
||||
if ((mod is TemporaryMod temp ? temp.TotalManipulations : Penumbra.ModCaches[mod.Index].TotalManipulations) > 0)
|
||||
if (mod.TotalManipulations > 0)
|
||||
AddMetaFiles();
|
||||
|
||||
_manager.MetaFileManager.ApplyDefaultFiles(_collection);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ using OtterGui.Widgets;
|
|||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Import.Structs;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI;
|
||||
using Penumbra.UI.Classes;
|
||||
|
|
@ -106,6 +105,7 @@ public class Configuration : IPluginConfiguration, ISavable
|
|||
{
|
||||
_saveService = saveService;
|
||||
Load(fileNames, migrator);
|
||||
UI.Classes.Colors.SetColors(this);
|
||||
}
|
||||
|
||||
public void Load(FilenameService fileNames, ConfigMigrationService migrator)
|
||||
|
|
|
|||
|
|
@ -94,12 +94,12 @@ public partial class TexToolsImporter
|
|||
ImGui.TableNextColumn();
|
||||
if( ex == null )
|
||||
{
|
||||
using var color = ImRaii.PushColor( ImGuiCol.Text, ColorId.FolderExpanded.Value(Penumbra.Config) );
|
||||
using var color = ImRaii.PushColor( ImGuiCol.Text, ColorId.FolderExpanded.Value() );
|
||||
ImGui.TextUnformatted( dir?.FullName[ ( _baseDirectory.FullName.Length + 1 ).. ] ?? "Unknown Directory" );
|
||||
}
|
||||
else
|
||||
{
|
||||
using var color = ImRaii.PushColor( ImGuiCol.Text, ColorId.ConflictingMod.Value(Penumbra.Config) );
|
||||
using var color = ImRaii.PushColor( ImGuiCol.Text, ColorId.ConflictingMod.Value() );
|
||||
ImGui.TextUnformatted( ex.Message );
|
||||
ImGuiUtil.HoverTooltip( ex.ToString() );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public sealed class Texture : IDisposable
|
|||
|
||||
// The pixels of the main image in RGBA order.
|
||||
// Empty if LoadError != null or Path is empty.
|
||||
public byte[] RGBAPixels = Array.Empty< byte >();
|
||||
public byte[] RGBAPixels = Array.Empty<byte>();
|
||||
|
||||
// The ImGui wrapper to load the image.
|
||||
// null if LoadError != null or Path is empty.
|
||||
|
|
@ -53,101 +53,97 @@ public sealed class Texture : IDisposable
|
|||
public bool IsLoaded
|
||||
=> TextureWrap != null;
|
||||
|
||||
public void Draw( Vector2 size )
|
||||
public void Draw(Vector2 size)
|
||||
{
|
||||
if( TextureWrap != null )
|
||||
if (TextureWrap != null)
|
||||
{
|
||||
size = size.X < TextureWrap.Width
|
||||
? size with { Y = TextureWrap.Height * size.X / TextureWrap.Width }
|
||||
: new Vector2( TextureWrap.Width, TextureWrap.Height );
|
||||
: new Vector2(TextureWrap.Width, TextureWrap.Height);
|
||||
|
||||
ImGui.Image( TextureWrap.ImGuiHandle, size );
|
||||
ImGui.Image(TextureWrap.ImGuiHandle, size);
|
||||
DrawData();
|
||||
}
|
||||
else if( LoadError != null )
|
||||
else if (LoadError != null)
|
||||
{
|
||||
ImGui.TextUnformatted( "Could not load file:" );
|
||||
ImGuiUtil.TextColored( Colors.RegexWarningBorder, LoadError.ToString() );
|
||||
ImGui.TextUnformatted("Could not load file:");
|
||||
ImGuiUtil.TextColored(Colors.RegexWarningBorder, LoadError.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawData()
|
||||
{
|
||||
using var table = ImRaii.Table( "##data", 2, ImGuiTableFlags.SizingFixedFit );
|
||||
ImGuiUtil.DrawTableColumn( "Width" );
|
||||
ImGuiUtil.DrawTableColumn( TextureWrap!.Width.ToString() );
|
||||
ImGuiUtil.DrawTableColumn( "Height" );
|
||||
ImGuiUtil.DrawTableColumn( TextureWrap!.Height.ToString() );
|
||||
ImGuiUtil.DrawTableColumn( "File Type" );
|
||||
ImGuiUtil.DrawTableColumn( Type.ToString() );
|
||||
ImGuiUtil.DrawTableColumn( "Bitmap Size" );
|
||||
ImGuiUtil.DrawTableColumn( $"{Functions.HumanReadableSize( RGBAPixels.Length )} ({RGBAPixels.Length} Bytes)" );
|
||||
switch( BaseImage )
|
||||
using var table = ImRaii.Table("##data", 2, ImGuiTableFlags.SizingFixedFit);
|
||||
ImGuiUtil.DrawTableColumn("Width");
|
||||
ImGuiUtil.DrawTableColumn(TextureWrap!.Width.ToString());
|
||||
ImGuiUtil.DrawTableColumn("Height");
|
||||
ImGuiUtil.DrawTableColumn(TextureWrap!.Height.ToString());
|
||||
ImGuiUtil.DrawTableColumn("File Type");
|
||||
ImGuiUtil.DrawTableColumn(Type.ToString());
|
||||
ImGuiUtil.DrawTableColumn("Bitmap Size");
|
||||
ImGuiUtil.DrawTableColumn($"{Functions.HumanReadableSize(RGBAPixels.Length)} ({RGBAPixels.Length} Bytes)");
|
||||
switch (BaseImage)
|
||||
{
|
||||
case ScratchImage s:
|
||||
ImGuiUtil.DrawTableColumn( "Format" );
|
||||
ImGuiUtil.DrawTableColumn( s.Meta.Format.ToString() );
|
||||
ImGuiUtil.DrawTableColumn( "Mip Levels" );
|
||||
ImGuiUtil.DrawTableColumn( s.Meta.MipLevels.ToString() );
|
||||
ImGuiUtil.DrawTableColumn( "Data Size" );
|
||||
ImGuiUtil.DrawTableColumn( $"{Functions.HumanReadableSize( s.Pixels.Length )} ({s.Pixels.Length} Bytes)" );
|
||||
ImGuiUtil.DrawTableColumn( "Number of Images" );
|
||||
ImGuiUtil.DrawTableColumn( s.Images.Length.ToString() );
|
||||
ImGuiUtil.DrawTableColumn("Format");
|
||||
ImGuiUtil.DrawTableColumn(s.Meta.Format.ToString());
|
||||
ImGuiUtil.DrawTableColumn("Mip Levels");
|
||||
ImGuiUtil.DrawTableColumn(s.Meta.MipLevels.ToString());
|
||||
ImGuiUtil.DrawTableColumn("Data Size");
|
||||
ImGuiUtil.DrawTableColumn($"{Functions.HumanReadableSize(s.Pixels.Length)} ({s.Pixels.Length} Bytes)");
|
||||
ImGuiUtil.DrawTableColumn("Number of Images");
|
||||
ImGuiUtil.DrawTableColumn(s.Images.Length.ToString());
|
||||
break;
|
||||
case TexFile t:
|
||||
ImGuiUtil.DrawTableColumn( "Format" );
|
||||
ImGuiUtil.DrawTableColumn( t.Header.Format.ToString() );
|
||||
ImGuiUtil.DrawTableColumn( "Mip Levels" );
|
||||
ImGuiUtil.DrawTableColumn( t.Header.MipLevels.ToString() );
|
||||
ImGuiUtil.DrawTableColumn( "Data Size" );
|
||||
ImGuiUtil.DrawTableColumn( $"{Functions.HumanReadableSize( t.ImageData.Length )} ({t.ImageData.Length} Bytes)" );
|
||||
ImGuiUtil.DrawTableColumn("Format");
|
||||
ImGuiUtil.DrawTableColumn(t.Header.Format.ToString());
|
||||
ImGuiUtil.DrawTableColumn("Mip Levels");
|
||||
ImGuiUtil.DrawTableColumn(t.Header.MipLevels.ToString());
|
||||
ImGuiUtil.DrawTableColumn("Data Size");
|
||||
ImGuiUtil.DrawTableColumn($"{Functions.HumanReadableSize(t.ImageData.Length)} ({t.ImageData.Length} Bytes)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Clean()
|
||||
{
|
||||
RGBAPixels = Array.Empty< byte >();
|
||||
RGBAPixels = Array.Empty<byte>();
|
||||
TextureWrap?.Dispose();
|
||||
TextureWrap = null;
|
||||
( BaseImage as IDisposable )?.Dispose();
|
||||
(BaseImage as IDisposable)?.Dispose();
|
||||
BaseImage = null;
|
||||
Type = FileType.Unknown;
|
||||
Loaded?.Invoke( false );
|
||||
Loaded?.Invoke(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> Clean();
|
||||
|
||||
public event Action< bool >? Loaded;
|
||||
public event Action<bool>? Loaded;
|
||||
|
||||
private void Load( string path )
|
||||
private void Load(string path)
|
||||
{
|
||||
_tmpPath = null;
|
||||
if( path == Path )
|
||||
{
|
||||
if (path == Path)
|
||||
return;
|
||||
}
|
||||
|
||||
Path = path;
|
||||
Clean();
|
||||
if( path.Length == 0 )
|
||||
{
|
||||
if (path.Length == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var _ = System.IO.Path.GetExtension( Path ).ToLowerInvariant() switch
|
||||
var _ = System.IO.Path.GetExtension(Path).ToLowerInvariant() switch
|
||||
{
|
||||
".dds" => LoadDds(),
|
||||
".png" => LoadPng(),
|
||||
".tex" => LoadTex(),
|
||||
_ => throw new Exception( $"Extension {System.IO.Path.GetExtension( Path )} unknown." ),
|
||||
_ => throw new Exception($"Extension {System.IO.Path.GetExtension(Path)} unknown."),
|
||||
};
|
||||
Loaded?.Invoke( true );
|
||||
Loaded?.Invoke(true);
|
||||
}
|
||||
catch( Exception e )
|
||||
catch (Exception e)
|
||||
{
|
||||
LoadError = e;
|
||||
Clean();
|
||||
|
|
@ -157,11 +153,11 @@ public sealed class Texture : IDisposable
|
|||
private bool LoadDds()
|
||||
{
|
||||
Type = FileType.Dds;
|
||||
var scratch = ScratchImage.LoadDDS( Path );
|
||||
var scratch = ScratchImage.LoadDDS(Path);
|
||||
BaseImage = scratch;
|
||||
var rgba = scratch.GetRGBA( out var f ).ThrowIfError( f );
|
||||
RGBAPixels = rgba.Pixels[ ..( f.Meta.Width * f.Meta.Height * f.Meta.Format.BitsPerPixel() / 8 ) ].ToArray();
|
||||
CreateTextureWrap( f.Meta.Width, f.Meta.Height );
|
||||
var rgba = scratch.GetRGBA(out var f).ThrowIfError(f);
|
||||
RGBAPixels = rgba.Pixels[..(f.Meta.Width * f.Meta.Height * f.Meta.Format.BitsPerPixel() / 8)].ToArray();
|
||||
CreateTextureWrap(f.Meta.Width, f.Meta.Height);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -169,11 +165,11 @@ public sealed class Texture : IDisposable
|
|||
{
|
||||
Type = FileType.Png;
|
||||
BaseImage = null;
|
||||
using var stream = File.OpenRead( Path );
|
||||
using var png = Image.Load< Rgba32 >( stream );
|
||||
using var stream = File.OpenRead(Path);
|
||||
using var png = Image.Load<Rgba32>(stream);
|
||||
RGBAPixels = new byte[png.Height * png.Width * 4];
|
||||
png.CopyPixelDataTo( RGBAPixels );
|
||||
CreateTextureWrap( png.Width, png.Height );
|
||||
png.CopyPixelDataTo(RGBAPixels);
|
||||
CreateTextureWrap(png.Width, png.Height);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -181,113 +177,100 @@ public sealed class Texture : IDisposable
|
|||
{
|
||||
Type = FileType.Tex;
|
||||
using var stream = OpenTexStream();
|
||||
var scratch = TexFileParser.Parse( stream );
|
||||
var scratch = TexFileParser.Parse(stream);
|
||||
BaseImage = scratch;
|
||||
var rgba = scratch.GetRGBA( out var f ).ThrowIfError( f );
|
||||
RGBAPixels = rgba.Pixels[ ..( f.Meta.Width * f.Meta.Height * f.Meta.Format.BitsPerPixel() / 8 ) ].ToArray();
|
||||
CreateTextureWrap( scratch.Meta.Width, scratch.Meta.Height );
|
||||
var rgba = scratch.GetRGBA(out var f).ThrowIfError(f);
|
||||
RGBAPixels = rgba.Pixels[..(f.Meta.Width * f.Meta.Height * f.Meta.Format.BitsPerPixel() / 8)].ToArray();
|
||||
CreateTextureWrap(scratch.Meta.Width, scratch.Meta.Height);
|
||||
return true;
|
||||
}
|
||||
|
||||
private Stream OpenTexStream()
|
||||
{
|
||||
if( System.IO.Path.IsPathRooted( Path ) )
|
||||
{
|
||||
return File.OpenRead( Path );
|
||||
}
|
||||
if (System.IO.Path.IsPathRooted(Path))
|
||||
return File.OpenRead(Path);
|
||||
|
||||
var file = DalamudServices.SGameData.GetFile( Path );
|
||||
return file != null ? new MemoryStream( file.Data ) : throw new Exception( $"Unable to obtain \"{Path}\" from game files." );
|
||||
var file = DalamudServices.SGameData.GetFile(Path);
|
||||
return file != null ? new MemoryStream(file.Data) : throw new Exception($"Unable to obtain \"{Path}\" from game files.");
|
||||
}
|
||||
|
||||
private void CreateTextureWrap( int width, int height )
|
||||
=> TextureWrap = DalamudServices.PluginInterface.UiBuilder.LoadImageRaw( RGBAPixels, width, height, 4 );
|
||||
private void CreateTextureWrap(int width, int height)
|
||||
=> TextureWrap = DalamudServices.PluginInterface.UiBuilder.LoadImageRaw(RGBAPixels, width, height, 4);
|
||||
|
||||
private string? _tmpPath;
|
||||
|
||||
public void PathSelectBox( string label, string tooltip, IEnumerable< (string, bool) > paths, int skipPrefix )
|
||||
public void PathSelectBox(string label, string tooltip, IEnumerable<(string, bool)> paths, int skipPrefix)
|
||||
{
|
||||
ImGui.SetNextItemWidth( -0.0001f );
|
||||
ImGui.SetNextItemWidth(-0.0001f);
|
||||
var startPath = Path.Length > 0 ? Path : "Choose a modded texture from this mod here...";
|
||||
using var combo = ImRaii.Combo( label, startPath );
|
||||
if( combo )
|
||||
{
|
||||
foreach( var ((path, game), idx) in paths.WithIndex() )
|
||||
using var combo = ImRaii.Combo(label, startPath);
|
||||
if (combo)
|
||||
foreach (var ((path, game), idx) in paths.WithIndex())
|
||||
{
|
||||
if( game )
|
||||
if (game)
|
||||
{
|
||||
if( !DalamudServices.SGameData.FileExists( path ) )
|
||||
{
|
||||
if (!DalamudServices.SGameData.FileExists(path))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if( !File.Exists( path ) )
|
||||
else if (!File.Exists(path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
using var id = ImRaii.PushId( idx );
|
||||
using( var color = ImRaii.PushColor( ImGuiCol.Text, ColorId.FolderExpanded.Value(Penumbra.Config), game ) )
|
||||
using var id = ImRaii.PushId(idx);
|
||||
using (var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.FolderExpanded.Value(), game))
|
||||
{
|
||||
var p = game ? $"--> {path}" : path[ skipPrefix.. ];
|
||||
if( ImGui.Selectable( p, path == startPath ) && path != startPath )
|
||||
{
|
||||
Load( path );
|
||||
}
|
||||
var p = game ? $"--> {path}" : path[skipPrefix..];
|
||||
if (ImGui.Selectable(p, path == startPath) && path != startPath)
|
||||
Load(path);
|
||||
}
|
||||
|
||||
ImGuiUtil.HoverTooltip( game
|
||||
ImGuiUtil.HoverTooltip(game
|
||||
? "This is a game path and refers to an unmanipulated file from your game data."
|
||||
: "This is a path to a modded file on your file system." );
|
||||
: "This is a path to a modded file on your file system.");
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiUtil.HoverTooltip( tooltip );
|
||||
ImGuiUtil.HoverTooltip(tooltip);
|
||||
}
|
||||
|
||||
public void PathInputBox( string label, string hint, string tooltip, string startPath, FileDialogService fileDialog )
|
||||
public void PathInputBox(string label, string hint, string tooltip, string startPath, FileDialogService fileDialog,
|
||||
string defaultModImportPath)
|
||||
{
|
||||
_tmpPath ??= Path;
|
||||
using var spacing = ImRaii.PushStyle( ImGuiStyleVar.ItemSpacing,
|
||||
new Vector2( UiHelpers.ScaleX3, ImGui.GetStyle().ItemSpacing.Y ) );
|
||||
ImGui.SetNextItemWidth( -2 * ImGui.GetFrameHeight() - 7 * UiHelpers.Scale );
|
||||
ImGui.InputTextWithHint( label, hint, ref _tmpPath, Utf8GamePath.MaxGamePathLength );
|
||||
if( ImGui.IsItemDeactivatedAfterEdit() )
|
||||
{
|
||||
Load( _tmpPath );
|
||||
}
|
||||
using var spacing = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
|
||||
new Vector2(UiHelpers.ScaleX3, ImGui.GetStyle().ItemSpacing.Y));
|
||||
ImGui.SetNextItemWidth(-2 * ImGui.GetFrameHeight() - 7 * UiHelpers.Scale);
|
||||
ImGui.InputTextWithHint(label, hint, ref _tmpPath, Utf8GamePath.MaxGamePathLength);
|
||||
if (ImGui.IsItemDeactivatedAfterEdit())
|
||||
Load(_tmpPath);
|
||||
|
||||
ImGuiUtil.HoverTooltip( tooltip );
|
||||
ImGuiUtil.HoverTooltip(tooltip);
|
||||
ImGui.SameLine();
|
||||
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Folder.ToIconString(), new Vector2( ImGui.GetFrameHeight() ), string.Empty, false,
|
||||
true ) )
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Folder.ToIconString(), new Vector2(ImGui.GetFrameHeight()), string.Empty, false,
|
||||
true))
|
||||
{
|
||||
if( Penumbra.Config.DefaultModImportPath.Length > 0 )
|
||||
{
|
||||
startPath = Penumbra.Config.DefaultModImportPath;
|
||||
}
|
||||
if (defaultModImportPath.Length > 0)
|
||||
startPath = defaultModImportPath;
|
||||
|
||||
var texture = this;
|
||||
|
||||
void UpdatePath( bool success, List< string > paths )
|
||||
void UpdatePath(bool success, List<string> paths)
|
||||
{
|
||||
if( success && paths.Count > 0 )
|
||||
{
|
||||
texture.Load( paths[ 0 ] );
|
||||
}
|
||||
if (success && paths.Count > 0)
|
||||
texture.Load(paths[0]);
|
||||
}
|
||||
|
||||
fileDialog.OpenFilePicker( "Open Image...", "Textures{.png,.dds,.tex}", UpdatePath, 1, startPath, false );
|
||||
fileDialog.OpenFilePicker("Open Image...", "Textures{.png,.dds,.tex}", UpdatePath, 1, startPath, false);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Recycle.ToIconString(), new Vector2( ImGui.GetFrameHeight() ),
|
||||
"Reload the currently selected path.", false,
|
||||
true ) )
|
||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Recycle.ToIconString(), new Vector2(ImGui.GetFrameHeight()),
|
||||
"Reload the currently selected path.", false,
|
||||
true))
|
||||
{
|
||||
var path = Path;
|
||||
Path = string.Empty;
|
||||
Load( path );
|
||||
Load(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Memory;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Cache;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Import;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Services;
|
||||
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
|
||||
|
||||
|
|
@ -37,6 +41,33 @@ public unsafe class MetaFileManager
|
|||
SignatureHelper.Initialise(this);
|
||||
}
|
||||
|
||||
public void WriteAllTexToolsMeta(Mod mod)
|
||||
{
|
||||
try
|
||||
{
|
||||
TexToolsMeta.WriteTexToolsMeta(this, mod.Default.Manipulations, mod.ModPath);
|
||||
foreach (var group in mod.Groups)
|
||||
{
|
||||
var dir = ModCreator.NewOptionDirectory(mod.ModPath, group.Name);
|
||||
if (!dir.Exists)
|
||||
dir.Create();
|
||||
|
||||
foreach (var option in group.OfType<SubMod>())
|
||||
{
|
||||
var optionDir = ModCreator.NewOptionDirectory(dir, option.Name);
|
||||
if (!optionDir.Exists)
|
||||
optionDir.Create();
|
||||
|
||||
TexToolsMeta.WriteTexToolsMeta(this, option.Manipulations, optionDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Error writing TexToolsMeta:\n{e}");
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public void SetFile(MetaBaseFile? file, MetaIndex metaIndex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,5 +13,8 @@ public interface IMod
|
|||
public ISubMod Default { get; }
|
||||
public IReadOnlyList< IModGroup > Groups { get; }
|
||||
|
||||
public IEnumerable< SubMod > AllSubMods { get; }
|
||||
public IEnumerable< SubMod > AllSubMods { get; }
|
||||
|
||||
// Cache
|
||||
public int TotalManipulations { get; }
|
||||
}
|
||||
|
|
@ -13,7 +13,6 @@ namespace Penumbra.Mods;
|
|||
public class ModNormalizer
|
||||
{
|
||||
private readonly ModManager _modManager;
|
||||
private readonly ModCacheManager _modCacheManager;
|
||||
private readonly List<List<Dictionary<Utf8GamePath, FullPath>>> _redirections = new();
|
||||
|
||||
public Mod Mod { get; private set; } = null!;
|
||||
|
|
@ -26,11 +25,8 @@ public class ModNormalizer
|
|||
public bool Running
|
||||
=> Step < TotalSteps;
|
||||
|
||||
public ModNormalizer(ModManager modManager, ModCacheManager modCacheManager)
|
||||
{
|
||||
_modManager = modManager;
|
||||
_modCacheManager = modCacheManager;
|
||||
}
|
||||
public ModNormalizer(ModManager modManager)
|
||||
=> _modManager = modManager;
|
||||
|
||||
public void Normalize(Mod mod)
|
||||
{
|
||||
|
|
@ -41,7 +37,7 @@ public class ModNormalizer
|
|||
_normalizationDirName = Path.Combine(Mod.ModPath.FullName, "TmpNormalization");
|
||||
_oldDirName = Path.Combine(Mod.ModPath.FullName, "TmpNormalizationOld");
|
||||
Step = 0;
|
||||
TotalSteps = _modCacheManager[mod].TotalFileCount + 5;
|
||||
TotalSteps = mod.TotalFileCount + 5;
|
||||
|
||||
Task.Run(NormalizeSync);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
|
@ -12,14 +11,12 @@ using Penumbra.Services;
|
|||
|
||||
namespace Penumbra.Mods.Manager;
|
||||
|
||||
public class ModCacheManager : IDisposable, IReadOnlyList<ModCache>
|
||||
public class ModCacheManager : IDisposable
|
||||
{
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly IdentifierService _identifier;
|
||||
private readonly ModStorage _modManager;
|
||||
|
||||
private readonly List<ModCache> _cache = new();
|
||||
|
||||
public ModCacheManager(CommunicatorService communicator, IdentifierService identifier, ModStorage modStorage)
|
||||
{
|
||||
_communicator = communicator;
|
||||
|
|
@ -35,20 +32,6 @@ public class ModCacheManager : IDisposable, IReadOnlyList<ModCache>
|
|||
OnModDiscoveryFinished();
|
||||
}
|
||||
|
||||
public IEnumerator<ModCache> GetEnumerator()
|
||||
=> _cache.Take(Count).GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> GetEnumerator();
|
||||
|
||||
public int Count { get; private set; }
|
||||
|
||||
public ModCache this[int index]
|
||||
=> _cache[index];
|
||||
|
||||
public ModCache this[Mod mod]
|
||||
=> _cache[mod.Index];
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_communicator.ModOptionChanged.Unsubscribe(OnModOptionChange);
|
||||
|
|
@ -127,35 +110,30 @@ public class ModCacheManager : IDisposable, IReadOnlyList<ModCache>
|
|||
|
||||
private void OnModOptionChange(ModOptionChangeType type, Mod mod, int groupIdx, int _, int _2)
|
||||
{
|
||||
ModCache cache;
|
||||
switch (type)
|
||||
{
|
||||
case ModOptionChangeType.GroupAdded:
|
||||
case ModOptionChangeType.GroupDeleted:
|
||||
case ModOptionChangeType.OptionAdded:
|
||||
case ModOptionChangeType.OptionDeleted:
|
||||
cache = EnsureCount(mod);
|
||||
UpdateChangedItems(cache, mod);
|
||||
UpdateCounts(cache, mod);
|
||||
UpdateChangedItems(mod);
|
||||
UpdateCounts(mod);
|
||||
break;
|
||||
case ModOptionChangeType.GroupTypeChanged:
|
||||
UpdateHasOptions(EnsureCount(mod), mod);
|
||||
UpdateHasOptions(mod);
|
||||
break;
|
||||
case ModOptionChangeType.OptionFilesChanged:
|
||||
case ModOptionChangeType.OptionFilesAdded:
|
||||
cache = EnsureCount(mod);
|
||||
UpdateChangedItems(cache, mod);
|
||||
UpdateFileCount(cache, mod);
|
||||
UpdateChangedItems(mod);
|
||||
UpdateFileCount(mod);
|
||||
break;
|
||||
case ModOptionChangeType.OptionSwapsChanged:
|
||||
cache = EnsureCount(mod);
|
||||
UpdateChangedItems(cache, mod);
|
||||
UpdateSwapCount(cache, mod);
|
||||
UpdateChangedItems(mod);
|
||||
UpdateSwapCount(mod);
|
||||
break;
|
||||
case ModOptionChangeType.OptionMetaChanged:
|
||||
cache = EnsureCount(mod);
|
||||
UpdateChangedItems(cache, mod);
|
||||
UpdateMetaCount(cache, mod);
|
||||
UpdateChangedItems(mod);
|
||||
UpdateMetaCount(mod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -166,106 +144,79 @@ public class ModCacheManager : IDisposable, IReadOnlyList<ModCache>
|
|||
{
|
||||
case ModPathChangeType.Added:
|
||||
case ModPathChangeType.Reloaded:
|
||||
Refresh(EnsureCount(mod), mod);
|
||||
break;
|
||||
case ModPathChangeType.Deleted:
|
||||
--Count;
|
||||
var oldCache = _cache[mod.Index];
|
||||
oldCache.Reset();
|
||||
for (var i = mod.Index; i < Count; ++i)
|
||||
_cache[i] = _cache[i + 1];
|
||||
_cache[Count] = oldCache;
|
||||
Refresh(mod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnModDataChange(ModDataChangeType type, Mod mod, string? _)
|
||||
private static void OnModDataChange(ModDataChangeType type, Mod mod, string? _)
|
||||
{
|
||||
if ((type & (ModDataChangeType.LocalTags | ModDataChangeType.ModTags)) != 0)
|
||||
UpdateTags(EnsureCount(mod), mod);
|
||||
UpdateTags(mod);
|
||||
}
|
||||
|
||||
private void OnModDiscoveryFinished()
|
||||
{
|
||||
if (_modManager.Count > _cache.Count)
|
||||
_cache.AddRange(Enumerable.Range(0, _modManager.Count - _cache.Count).Select(_ => new ModCache()));
|
||||
|
||||
Parallel.ForEach(Enumerable.Range(0, _modManager.Count), idx => { Refresh(_cache[idx], _modManager[idx]); });
|
||||
Count = _modManager.Count;
|
||||
}
|
||||
=> Parallel.ForEach(_modManager, Refresh);
|
||||
|
||||
private void OnIdentifierCreation()
|
||||
{
|
||||
Parallel.ForEach(Enumerable.Range(0, _modManager.Count), idx => { UpdateChangedItems(_cache[idx], _modManager[idx]); });
|
||||
Parallel.ForEach(_modManager, UpdateChangedItems);
|
||||
_identifier.FinishedCreation -= OnIdentifierCreation;
|
||||
}
|
||||
|
||||
private static void UpdateFileCount(ModCache cache, Mod mod)
|
||||
=> cache.TotalFileCount = mod.AllSubMods.Sum(s => s.Files.Count);
|
||||
private static void UpdateFileCount(Mod mod)
|
||||
=> mod.TotalFileCount = mod.AllSubMods.Sum(s => s.Files.Count);
|
||||
|
||||
private static void UpdateSwapCount(ModCache cache, Mod mod)
|
||||
=> cache.TotalFileCount = mod.AllSubMods.Sum(s => s.FileSwaps.Count);
|
||||
private static void UpdateSwapCount(Mod mod)
|
||||
=> mod.TotalFileCount = mod.AllSubMods.Sum(s => s.FileSwaps.Count);
|
||||
|
||||
private static void UpdateMetaCount(ModCache cache, Mod mod)
|
||||
=> cache.TotalFileCount = mod.AllSubMods.Sum(s => s.Manipulations.Count);
|
||||
private static void UpdateMetaCount(Mod mod)
|
||||
=> mod.TotalFileCount = mod.AllSubMods.Sum(s => s.Manipulations.Count);
|
||||
|
||||
private static void UpdateHasOptions(ModCache cache, Mod mod)
|
||||
=> cache.HasOptions = mod.Groups.Any(o => o.IsOption);
|
||||
private static void UpdateHasOptions(Mod mod)
|
||||
=> mod.HasOptions = mod.Groups.Any(o => o.IsOption);
|
||||
|
||||
private static void UpdateTags(ModCache cache, Mod mod)
|
||||
=> cache.AllTagsLower = string.Join('\0', mod.ModTags.Concat(mod.LocalTags).Select(s => s.ToLowerInvariant()));
|
||||
private static void UpdateTags(Mod mod)
|
||||
=> mod.AllTagsLower = string.Join('\0', mod.ModTags.Concat(mod.LocalTags).Select(s => s.ToLowerInvariant()));
|
||||
|
||||
private void UpdateChangedItems(ModCache cache, Mod mod)
|
||||
private void UpdateChangedItems(Mod mod)
|
||||
{
|
||||
cache.ChangedItems.Clear();
|
||||
var changedItems = (SortedList<string, object?>)mod.ChangedItems;
|
||||
changedItems.Clear();
|
||||
if (!_identifier.Valid)
|
||||
return;
|
||||
|
||||
foreach (var gamePath in mod.AllSubMods.SelectMany(m => m.Files.Keys.Concat(m.FileSwaps.Keys)))
|
||||
_identifier.AwaitedService.Identify(cache.ChangedItems, gamePath.ToString());
|
||||
_identifier.AwaitedService.Identify(changedItems, gamePath.ToString());
|
||||
|
||||
foreach (var manip in mod.AllSubMods.SelectMany(m => m.Manipulations))
|
||||
ComputeChangedItems(_identifier.AwaitedService, cache.ChangedItems, manip);
|
||||
ComputeChangedItems(_identifier.AwaitedService, changedItems, manip);
|
||||
|
||||
cache.LowerChangedItemsString = string.Join("\0", cache.ChangedItems.Keys.Select(k => k.ToLowerInvariant()));
|
||||
mod.LowerChangedItemsString = string.Join("\0", mod.ChangedItems.Keys.Select(k => k.ToLowerInvariant()));
|
||||
}
|
||||
|
||||
private static void UpdateCounts(ModCache cache, Mod mod)
|
||||
private static void UpdateCounts(Mod mod)
|
||||
{
|
||||
cache.TotalFileCount = mod.Default.Files.Count;
|
||||
cache.TotalSwapCount = mod.Default.FileSwaps.Count;
|
||||
cache.TotalManipulations = mod.Default.Manipulations.Count;
|
||||
cache.HasOptions = false;
|
||||
mod.TotalFileCount = mod.Default.Files.Count;
|
||||
mod.TotalSwapCount = mod.Default.FileSwaps.Count;
|
||||
mod.TotalManipulations = mod.Default.Manipulations.Count;
|
||||
mod.HasOptions = false;
|
||||
foreach (var group in mod.Groups)
|
||||
{
|
||||
cache.HasOptions |= group.IsOption;
|
||||
mod.HasOptions |= group.IsOption;
|
||||
foreach (var s in group)
|
||||
{
|
||||
cache.TotalFileCount += s.Files.Count;
|
||||
cache.TotalSwapCount += s.FileSwaps.Count;
|
||||
cache.TotalManipulations += s.Manipulations.Count;
|
||||
mod.TotalFileCount += s.Files.Count;
|
||||
mod.TotalSwapCount += s.FileSwaps.Count;
|
||||
mod.TotalManipulations += s.Manipulations.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Refresh(ModCache cache, Mod mod)
|
||||
private void Refresh(Mod mod)
|
||||
{
|
||||
UpdateTags(cache, mod);
|
||||
UpdateCounts(cache, mod);
|
||||
UpdateChangedItems(cache, mod);
|
||||
}
|
||||
|
||||
private ModCache EnsureCount(Mod mod)
|
||||
{
|
||||
if (mod.Index < Count)
|
||||
return _cache[mod.Index];
|
||||
|
||||
|
||||
if (mod.Index >= _cache.Count)
|
||||
_cache.AddRange(Enumerable.Range(0, mod.Index + 1 - _cache.Count).Select(_ => new ModCache()));
|
||||
for (var i = Count; i < mod.Index; ++i)
|
||||
Refresh(_cache[i], _modManager[i]);
|
||||
Count = mod.Index + 1;
|
||||
return _cache[mod.Index];
|
||||
UpdateTags(mod);
|
||||
UpdateCounts(mod);
|
||||
UpdateChangedItems(mod);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.Collections.Cache;
|
||||
using Penumbra.Import;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.String.Classes;
|
||||
|
|
@ -21,8 +22,10 @@ public sealed partial class Mod : IMod
|
|||
|
||||
// Main Data
|
||||
public DirectoryInfo ModPath { get; internal set; }
|
||||
|
||||
public string Identifier
|
||||
=> Index >= 0 ? ModPath.Name : Name;
|
||||
|
||||
public int Index { get; internal set; } = -1;
|
||||
|
||||
public bool IsTemporary
|
||||
|
|
@ -32,12 +35,15 @@ public sealed partial class Mod : IMod
|
|||
public int Priority
|
||||
=> 0;
|
||||
|
||||
public Mod(DirectoryInfo modPath)
|
||||
internal Mod(DirectoryInfo modPath)
|
||||
{
|
||||
ModPath = modPath;
|
||||
Default = new SubMod(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
=> Name.Text;
|
||||
|
||||
// Meta Data
|
||||
public LowerString Name { get; internal set; } = "New Mod";
|
||||
public LowerString Author { get; internal set; } = LowerString.Empty;
|
||||
|
|
@ -80,35 +86,14 @@ public sealed partial class Mod : IMod
|
|||
.ToList();
|
||||
}
|
||||
|
||||
// Access
|
||||
public override string ToString()
|
||||
=> Name.Text;
|
||||
// Cache
|
||||
public readonly IReadOnlyDictionary<string, object?> ChangedItems = new SortedList<string, object?>();
|
||||
|
||||
public void WriteAllTexToolsMeta(MetaFileManager manager)
|
||||
{
|
||||
try
|
||||
{
|
||||
TexToolsMeta.WriteTexToolsMeta(manager, Default.Manipulations, ModPath);
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
var dir = ModCreator.NewOptionDirectory(ModPath, group.Name);
|
||||
if (!dir.Exists)
|
||||
dir.Create();
|
||||
|
||||
foreach (var option in group.OfType<SubMod>())
|
||||
{
|
||||
var optionDir = ModCreator.NewOptionDirectory(dir, option.Name);
|
||||
if (!optionDir.Exists)
|
||||
optionDir.Create();
|
||||
|
||||
TexToolsMeta.WriteTexToolsMeta(manager, option.Manipulations, optionDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Error writing TexToolsMeta:\n{e}");
|
||||
}
|
||||
}
|
||||
public string LowerChangedItemsString { get; internal set; } = string.Empty;
|
||||
public string AllTagsLower { get; internal set; } = string.Empty;
|
||||
|
||||
public int TotalFileCount { get; internal set; }
|
||||
public int TotalSwapCount { get; internal set; }
|
||||
public int TotalManipulations { get; internal set; }
|
||||
public bool HasOptions { get; internal set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public class ModCache
|
||||
{
|
||||
public int TotalFileCount;
|
||||
public int TotalSwapCount;
|
||||
public int TotalManipulations;
|
||||
public bool HasOptions;
|
||||
|
||||
public readonly SortedList<string, object?> ChangedItems = new();
|
||||
public string LowerChangedItemsString = string.Empty;
|
||||
public string AllTagsLower = string.Empty;
|
||||
|
||||
public ModCache()
|
||||
{}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
TotalFileCount = 0;
|
||||
TotalSwapCount = 0;
|
||||
TotalManipulations = 0;
|
||||
HasOptions = false;
|
||||
ChangedItems.Clear();
|
||||
LowerChangedItemsString = string.Empty;
|
||||
AllTagsLower = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -36,10 +36,8 @@ public class Penumbra : IDalamudPlugin
|
|||
|
||||
public static Logger Log { get; private set; } = null!;
|
||||
public static ChatService ChatService { get; private set; } = null!;
|
||||
public static Configuration Config { get; private set; } = null!;
|
||||
|
||||
public static CharacterUtility CharacterUtility { get; private set; } = null!;
|
||||
public static ModCacheManager ModCaches { get; private set; } = null!;
|
||||
public static CollectionManager CollectionManager { get; private set; } = null!;
|
||||
public static ActorManager Actors { get; private set; } = null!;
|
||||
|
||||
|
|
@ -53,6 +51,7 @@ public class Penumbra : IDalamudPlugin
|
|||
private readonly TempModManager _tempMods;
|
||||
private readonly TempCollectionManager _tempCollections;
|
||||
private readonly ModManager _modManager;
|
||||
private readonly Configuration _config;
|
||||
private PenumbraWindowSystem? _windowSystem;
|
||||
private bool _disposed;
|
||||
|
||||
|
|
@ -67,7 +66,7 @@ public class Penumbra : IDalamudPlugin
|
|||
ChatService = _tmp.Services.GetRequiredService<ChatService>();
|
||||
_validityChecker = _tmp.Services.GetRequiredService<ValidityChecker>();
|
||||
_tmp.Services.GetRequiredService<BackupService>();
|
||||
Config = _tmp.Services.GetRequiredService<Configuration>();
|
||||
_config = _tmp.Services.GetRequiredService<Configuration>();
|
||||
CharacterUtility = _tmp.Services.GetRequiredService<CharacterUtility>();
|
||||
Actors = _tmp.Services.GetRequiredService<ActorService>().AwaitedService;
|
||||
_tempMods = _tmp.Services.GetRequiredService<TempModManager>();
|
||||
|
|
@ -78,8 +77,8 @@ public class Penumbra : IDalamudPlugin
|
|||
_tempCollections = _tmp.Services.GetRequiredService<TempCollectionManager>();
|
||||
ModFileSystem = _tmp.Services.GetRequiredService<ModFileSystem>();
|
||||
RedrawService = _tmp.Services.GetRequiredService<RedrawService>();
|
||||
_tmp.Services.GetRequiredService<ResourceService>();
|
||||
ModCaches = _tmp.Services.GetRequiredService<ModCacheManager>();
|
||||
_tmp.Services.GetRequiredService<ResourceService>(); // Initialize because not required anywhere else.
|
||||
_tmp.Services.GetRequiredService<ModCacheManager>(); // Initialize because not required anywhere else.
|
||||
using (var t = _tmp.Services.GetRequiredService<StartTracker>().Measure(StartTimeType.PathResolver))
|
||||
{
|
||||
_tmp.Services.GetRequiredService<PathResolver>();
|
||||
|
|
@ -146,10 +145,10 @@ public class Penumbra : IDalamudPlugin
|
|||
|
||||
public bool SetEnabled(bool enabled)
|
||||
{
|
||||
if (enabled == Config.EnableMods)
|
||||
if (enabled == _config.EnableMods)
|
||||
return false;
|
||||
|
||||
Config.EnableMods = enabled;
|
||||
_config.EnableMods = enabled;
|
||||
if (enabled)
|
||||
{
|
||||
if (CharacterUtility.Ready)
|
||||
|
|
@ -169,7 +168,7 @@ public class Penumbra : IDalamudPlugin
|
|||
}
|
||||
}
|
||||
|
||||
Config.Save();
|
||||
_config.Save();
|
||||
EnabledChange?.Invoke(enabled);
|
||||
|
||||
return true;
|
||||
|
|
@ -190,33 +189,33 @@ public class Penumbra : IDalamudPlugin
|
|||
public string GatherSupportInformation()
|
||||
{
|
||||
var sb = new StringBuilder(10240);
|
||||
var exists = Config.ModDirectory.Length > 0 && Directory.Exists(Config.ModDirectory);
|
||||
var drive = exists ? new DriveInfo(new DirectoryInfo(Config.ModDirectory).Root.FullName) : null;
|
||||
var exists = _config.ModDirectory.Length > 0 && Directory.Exists(_config.ModDirectory);
|
||||
var drive = exists ? new DriveInfo(new DirectoryInfo(_config.ModDirectory).Root.FullName) : null;
|
||||
sb.AppendLine("**Settings**");
|
||||
sb.Append($"> **`Plugin Version: `** {_validityChecker.Version}\n");
|
||||
sb.Append($"> **`Commit Hash: `** {_validityChecker.CommitHash}\n");
|
||||
sb.Append($"> **`Enable Mods: `** {Config.EnableMods}\n");
|
||||
sb.Append($"> **`Enable HTTP API: `** {Config.EnableHttpApi}\n");
|
||||
sb.Append($"> **`Enable Mods: `** {_config.EnableMods}\n");
|
||||
sb.Append($"> **`Enable HTTP API: `** {_config.EnableHttpApi}\n");
|
||||
sb.Append($"> **`Operating System: `** {(DalamudUtil.IsLinux() ? "Mac/Linux (Wine)" : "Windows")}\n");
|
||||
sb.Append($"> **`Root Directory: `** `{Config.ModDirectory}`, {(exists ? "Exists" : "Not Existing")}\n");
|
||||
sb.Append($"> **`Root Directory: `** `{_config.ModDirectory}`, {(exists ? "Exists" : "Not Existing")}\n");
|
||||
sb.Append(
|
||||
$"> **`Free Drive Space: `** {(drive != null ? Functions.HumanReadableSize(drive.AvailableFreeSpace) : "Unknown")}\n");
|
||||
sb.Append($"> **`Auto-Deduplication: `** {Config.AutoDeduplicateOnImport}\n");
|
||||
sb.Append($"> **`Debug Mode: `** {Config.DebugMode}\n");
|
||||
sb.Append($"> **`Auto-Deduplication: `** {_config.AutoDeduplicateOnImport}\n");
|
||||
sb.Append($"> **`Debug Mode: `** {_config.DebugMode}\n");
|
||||
sb.Append(
|
||||
$"> **`Synchronous Load (Dalamud): `** {(_tmp.Services.GetRequiredService<DalamudServices>().GetDalamudConfig(DalamudServices.WaitingForPluginsOption, out bool v) ? v.ToString() : "Unknown")}\n");
|
||||
sb.Append(
|
||||
$"> **`Logging: `** Log: {Config.EnableResourceLogging}, Watcher: {Config.EnableResourceWatcher} ({Config.MaxResourceWatcherRecords})\n");
|
||||
sb.Append($"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n");
|
||||
$"> **`Logging: `** Log: {_config.EnableResourceLogging}, Watcher: {_config.EnableResourceWatcher} ({_config.MaxResourceWatcherRecords})\n");
|
||||
sb.Append($"> **`Use Ownership: `** {_config.UseOwnerNameForCharacterCollection}\n");
|
||||
sb.AppendLine("**Mods**");
|
||||
sb.Append($"> **`Installed Mods: `** {_modManager.Count}\n");
|
||||
sb.Append($"> **`Mods with Config: `** {ModCaches.Count(m => m.HasOptions)}\n");
|
||||
sb.Append($"> **`Mods with Config: `** {_modManager.Count(m => m.HasOptions)}\n");
|
||||
sb.Append(
|
||||
$"> **`Mods with File Redirections: `** {ModCaches.Count(m => m.TotalFileCount > 0)}, Total: {ModCaches.Sum(m => m.TotalFileCount)}\n");
|
||||
$"> **`Mods with File Redirections: `** {_modManager.Count(m => m.TotalFileCount > 0)}, Total: {_modManager.Sum(m => m.TotalFileCount)}\n");
|
||||
sb.Append(
|
||||
$"> **`Mods with FileSwaps: `** {ModCaches.Count(m => m.TotalSwapCount > 0)}, Total: {ModCaches.Sum(m => m.TotalSwapCount)}\n");
|
||||
$"> **`Mods with FileSwaps: `** {_modManager.Count(m => m.TotalSwapCount > 0)}, Total: {_modManager.Sum(m => m.TotalSwapCount)}\n");
|
||||
sb.Append(
|
||||
$"> **`Mods with Meta Manipulations:`** {ModCaches.Count(m => m.TotalManipulations > 0)}, Total {ModCaches.Sum(m => m.TotalManipulations)}\n");
|
||||
$"> **`Mods with Meta Manipulations:`** {_modManager.Count(m => m.TotalManipulations > 0)}, Total {_modManager.Sum(m => m.TotalManipulations)}\n");
|
||||
sb.Append($"> **`IMC Exceptions Thrown: `** {_validityChecker.ImcExceptions.Count}\n");
|
||||
sb.Append(
|
||||
$"> **`#Temp Mods: `** {_tempMods.Mods.Sum(kvp => kvp.Value.Count) + _tempMods.ModsForAllCollections.Count}\n");
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ public class FileEditor<T> where T : class, IWritable
|
|||
ImGui.TableNextColumn();
|
||||
UiHelpers.Text(gamePath.Path);
|
||||
ImGui.TableNextColumn();
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value(_config));
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
|
||||
ImGui.TextUnformatted(option.FullName);
|
||||
}
|
||||
}
|
||||
|
|
@ -294,7 +294,7 @@ public class FileEditor<T> where T : class, IWritable
|
|||
if (file.SubModUsage.Count > 0)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value(_config));
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
|
||||
ImGuiUtil.RightAlign(file.SubModUsage[0].Item2.Path.ToString());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public partial class ModEditWindow
|
|||
return f.SubModUsage.Count == 0
|
||||
? Enumerable.Repeat((file, "Unused", string.Empty, 0x40000080u), 1)
|
||||
: f.SubModUsage.Select(s => (file, s.Item2.ToString(), s.Item1.FullName,
|
||||
_editor.Option! == s.Item1 && _modCaches[_mod!].HasOptions ? 0x40008000u : 0u));
|
||||
_editor.Option! == s.Item1 && _mod!.HasOptions ? 0x40008000u : 0u));
|
||||
});
|
||||
|
||||
void DrawLine((string, string, string, uint) data)
|
||||
|
|
@ -179,7 +179,7 @@ public partial class ModEditWindow
|
|||
var selected = _selectedFiles.Contains(registry);
|
||||
var color = registry.SubModUsage.Count == 0 ? ColorId.ConflictingMod :
|
||||
registry.CurrentUsage == registry.SubModUsage.Count ? ColorId.NewMod : ColorId.InheritedMod;
|
||||
using var c = ImRaii.PushColor(ImGuiCol.Text, color.Value(Penumbra.Config));
|
||||
using var c = ImRaii.PushColor(ImGuiCol.Text, color.Value());
|
||||
if (UiHelpers.Selectable(registry.RelPath.Path, selected))
|
||||
{
|
||||
if (selected)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public partial class ModEditWindow
|
|||
CopyToClipboardButton("Copy all current manipulations to clipboard.", _iconSize, _editor.MetaEditor.Recombine());
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Write as TexTools Files"))
|
||||
_mod!.WriteAllTexToolsMeta(_metaFileManager);
|
||||
_metaFileManager.WriteAllTexToolsMeta(_mod!);
|
||||
|
||||
using var child = ImRaii.Child("##meta", -Vector2.One, true);
|
||||
if (!child)
|
||||
|
|
@ -776,7 +776,7 @@ public partial class ModEditWindow
|
|||
var value = meta.Entry;
|
||||
ImGui.SetNextItemWidth(FloatWidth);
|
||||
using var color = ImRaii.PushColor(ImGuiCol.FrameBg,
|
||||
def < value ? ColorId.IncreasedMetaValue.Value(Penumbra.Config) : ColorId.DecreasedMetaValue.Value(Penumbra.Config),
|
||||
def < value ? ColorId.IncreasedMetaValue.Value() : ColorId.DecreasedMetaValue.Value(),
|
||||
def != value);
|
||||
if (ImGui.DragFloat("##rspValue", ref value, 0.001f, 0.01f, 8f) && value is >= 0.01f and <= 8f)
|
||||
editor.MetaEditor.Change(meta.Copy(value));
|
||||
|
|
@ -805,7 +805,7 @@ public partial class ModEditWindow
|
|||
private static bool Checkmark(string label, string tooltip, bool currentValue, bool defaultValue, out bool newValue)
|
||||
{
|
||||
using var color = ImRaii.PushColor(ImGuiCol.FrameBg,
|
||||
defaultValue ? ColorId.DecreasedMetaValue.Value(Penumbra.Config) : ColorId.IncreasedMetaValue.Value(Penumbra.Config),
|
||||
defaultValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value(),
|
||||
defaultValue != currentValue);
|
||||
newValue = currentValue;
|
||||
ImGui.Checkbox(label, ref newValue);
|
||||
|
|
@ -820,7 +820,7 @@ public partial class ModEditWindow
|
|||
{
|
||||
newValue = currentValue;
|
||||
using var color = ImRaii.PushColor(ImGuiCol.FrameBg,
|
||||
defaultValue > currentValue ? ColorId.DecreasedMetaValue.Value(Penumbra.Config) : ColorId.IncreasedMetaValue.Value(Penumbra.Config),
|
||||
defaultValue > currentValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value(),
|
||||
defaultValue != currentValue);
|
||||
ImGui.SetNextItemWidth(width);
|
||||
if (ImGui.DragInt(label, ref newValue, speed, minValue, maxValue))
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public partial class ModEditWindow
|
|||
ImGui.NewLine();
|
||||
|
||||
tex.PathInputBox("##input", "Import Image...", "Can import game paths as well as your own files.", _mod!.ModPath.FullName,
|
||||
_fileDialog);
|
||||
_fileDialog, _config.DefaultModImportPath);
|
||||
var files = _editor.Files.Tex.SelectMany(f => f.SubModUsage.Select(p => (p.Item2.ToString(), true))
|
||||
.Prepend((f.File.FullName, false)));
|
||||
tex.PathSelectBox("##combo", "Select the textures included in this mod on your drive or the ones they replace from the game files.",
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ public partial class ModEditWindow : Window, IDisposable
|
|||
|
||||
private readonly PerformanceTracker _performance;
|
||||
private readonly ModEditor _editor;
|
||||
private readonly ModCacheManager _modCaches;
|
||||
private readonly Configuration _config;
|
||||
private readonly ItemSwapTab _itemSwapTab;
|
||||
private readonly DataManager _gameData;
|
||||
|
|
@ -277,7 +276,7 @@ public partial class ModEditWindow : Window, IDisposable
|
|||
var modifier = _config.DeleteModModifier.IsActive();
|
||||
|
||||
var tt = _allowReduplicate ? desc :
|
||||
modifier ? desc : desc + $"\n\nNo duplicates detected! Hold {Penumbra.Config.DeleteModModifier} to force normalization anyway.";
|
||||
modifier ? desc : desc + $"\n\nNo duplicates detected! Hold {_config.DeleteModModifier} to force normalization anyway.";
|
||||
|
||||
if (ImGuiUtil.DrawDisabledButton("Re-Duplicate and Normalize Mod", Vector2.Zero, tt, !_allowReduplicate && !modifier))
|
||||
{
|
||||
|
|
@ -497,25 +496,26 @@ public partial class ModEditWindow : Window, IDisposable
|
|||
}
|
||||
|
||||
public ModEditWindow(PerformanceTracker performance, FileDialogService fileDialog, ItemSwapTab itemSwapTab, DataManager gameData,
|
||||
Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, ModCacheManager modCaches, MetaFileManager metaFileManager, StainService stainService)
|
||||
Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, MetaFileManager metaFileManager,
|
||||
StainService stainService)
|
||||
: base(WindowBaseLabel)
|
||||
{
|
||||
_performance = performance;
|
||||
_itemSwapTab = itemSwapTab;
|
||||
_config = config;
|
||||
_editor = editor;
|
||||
_modCaches = modCaches;
|
||||
_metaFileManager = metaFileManager;
|
||||
_stainService = stainService;
|
||||
_gameData = gameData;
|
||||
_fileDialog = fileDialog;
|
||||
_performance = performance;
|
||||
_itemSwapTab = itemSwapTab;
|
||||
_config = config;
|
||||
_editor = editor;
|
||||
_metaFileManager = metaFileManager;
|
||||
_stainService = stainService;
|
||||
_gameData = gameData;
|
||||
_fileDialog = fileDialog;
|
||||
_materialTab = new FileEditor<MtrlTab>(this, gameData, config, _fileDialog, "Materials", ".mtrl",
|
||||
() => _editor.Files.Mtrl, DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty,
|
||||
bytes => new MtrlTab(this, new MtrlFile(bytes)));
|
||||
_modelTab = new FileEditor<MdlFile>(this, gameData, config, _fileDialog, "Models", ".mdl",
|
||||
() => _editor.Files.Mdl, DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty, bytes => new MdlFile(bytes));
|
||||
_shaderPackageTab = new FileEditor<ShpkTab>(this, gameData, config, _fileDialog, "Shader Packages", ".shpk",
|
||||
() => _editor.Files.Shpk, DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty, bytes => new ShpkTab(_fileDialog, bytes));
|
||||
() => _editor.Files.Shpk, DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty,
|
||||
bytes => new ShpkTab(_fileDialog, bytes));
|
||||
_center = new CombinedTexture(_left, _right);
|
||||
_quickImportViewer = new ResourceTreeViewer(_config, resourceTreeFactory, 2, OnQuickImportRefresh, DrawQuickImportActions);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Penumbra.UI.Classes;
|
||||
|
||||
|
|
@ -64,6 +65,13 @@ public static class Colors
|
|||
// @formatter:on
|
||||
};
|
||||
|
||||
public static uint Value(this ColorId color, Configuration config)
|
||||
=> config.Colors.TryGetValue(color, out var value) ? value : color.Data().DefaultColor;
|
||||
private static IReadOnlyDictionary<ColorId, uint> _colors = new Dictionary<ColorId, uint>();
|
||||
|
||||
/// <summary> Obtain the configured value for a color. </summary>
|
||||
public static uint Value(this ColorId color)
|
||||
=> _colors.TryGetValue(color, out var value) ? value : color.Data().DefaultColor;
|
||||
|
||||
/// <summary> Set the configurable colors dictionary to a value. </summary>
|
||||
public static void SetColors(Configuration config)
|
||||
=> _colors = config.Colors;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ namespace Penumbra.UI.CollectionTab;
|
|||
|
||||
public sealed class CollectionPanel : IDisposable
|
||||
{
|
||||
private readonly Configuration _config;
|
||||
private readonly CollectionStorage _collections;
|
||||
private readonly ActiveCollections _active;
|
||||
private readonly CollectionSelector _selector;
|
||||
|
|
@ -39,10 +38,9 @@ public sealed class CollectionPanel : IDisposable
|
|||
private static readonly IReadOnlyList<(CollectionType, bool, bool, string, uint)> AdvancedTree = CreateTree();
|
||||
private readonly List<(CollectionType Type, ActorIdentifier Identifier)> _inUseCache = new();
|
||||
|
||||
public CollectionPanel(DalamudPluginInterface pi, Configuration config, CommunicatorService communicator, CollectionManager manager,
|
||||
public CollectionPanel(DalamudPluginInterface pi, CommunicatorService communicator, CollectionManager manager,
|
||||
CollectionSelector selector, ActorService actors, TargetManager targets, ModStorage mods)
|
||||
{
|
||||
_config = config;
|
||||
_collections = manager.Storage;
|
||||
_active = manager.Active;
|
||||
_selector = selector;
|
||||
|
|
@ -50,7 +48,7 @@ public sealed class CollectionPanel : IDisposable
|
|||
_targets = targets;
|
||||
_mods = mods;
|
||||
_individualAssignmentUi = new IndividualAssignmentUi(communicator, actors, manager);
|
||||
_inheritanceUi = new InheritanceUi(_config, manager, _selector);
|
||||
_inheritanceUi = new InheritanceUi(manager, _selector);
|
||||
_nameFont = pi.UiBuilder.GetGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Jupiter23));
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +79,7 @@ public sealed class CollectionPanel : IDisposable
|
|||
DrawSimpleCollectionButton(CollectionType.MaleNonPlayerCharacter, buttonWidth);
|
||||
DrawSimpleCollectionButton(CollectionType.FemaleNonPlayerCharacter, buttonWidth);
|
||||
|
||||
ImGuiUtil.DrawColoredText(("Individual ", ColorId.NewMod.Value(_config)),
|
||||
ImGuiUtil.DrawColoredText(("Individual ", ColorId.NewMod.Value()),
|
||||
("Assignments take precedence before anything else and only apply to one specific character or monster.", 0));
|
||||
ImGui.Dummy(Vector2.UnitX);
|
||||
|
||||
|
|
@ -254,13 +252,13 @@ public sealed class CollectionPanel : IDisposable
|
|||
collection ??= _active.ByType(type, id);
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Button,
|
||||
collection == null
|
||||
? ColorId.NoAssignment.Value(_config)
|
||||
? ColorId.NoAssignment.Value()
|
||||
: redundancy.Length > 0
|
||||
? ColorId.RedundantAssignment.Value(_config)
|
||||
? ColorId.RedundantAssignment.Value()
|
||||
: collection == _active.Current
|
||||
? ColorId.SelectedCollection.Value(_config)
|
||||
? ColorId.SelectedCollection.Value()
|
||||
: collection == ModCollection.Empty
|
||||
? ColorId.NoModsAssignment.Value(_config)
|
||||
? ColorId.NoModsAssignment.Value()
|
||||
: ImGui.GetColorU32(ImGuiCol.Button), !invalid)
|
||||
.Push(ImGuiCol.Border, borderColor == 0 ? ImGui.GetColorU32(ImGuiCol.TextDisabled) : borderColor);
|
||||
using var disabled = ImRaii.Disabled(invalid);
|
||||
|
|
@ -295,27 +293,27 @@ public sealed class CollectionPanel : IDisposable
|
|||
ImGui.TextUnformatted("Overruled by any other Assignment.");
|
||||
break;
|
||||
case CollectionType.Yourself:
|
||||
ImGuiUtil.DrawColoredText(("Overruled by ", 0), ("Individual ", ColorId.NewMod.Value(_config)), ("Assignments.", 0));
|
||||
ImGuiUtil.DrawColoredText(("Overruled by ", 0), ("Individual ", ColorId.NewMod.Value()), ("Assignments.", 0));
|
||||
break;
|
||||
case CollectionType.MalePlayerCharacter:
|
||||
ImGuiUtil.DrawColoredText(("Overruled by ", 0), ("Male Racial Player", Colors.DiscordColor), (", ", 0),
|
||||
("Your Character", ColorId.HandledConflictMod.Value(_config)), (", or ", 0),
|
||||
("Individual ", ColorId.NewMod.Value(_config)), ("Assignments.", 0));
|
||||
("Your Character", ColorId.HandledConflictMod.Value()), (", or ", 0),
|
||||
("Individual ", ColorId.NewMod.Value()), ("Assignments.", 0));
|
||||
break;
|
||||
case CollectionType.FemalePlayerCharacter:
|
||||
ImGuiUtil.DrawColoredText(("Overruled by ", 0), ("Female Racial Player", Colors.ReniColorActive), (", ", 0),
|
||||
("Your Character", ColorId.HandledConflictMod.Value(_config)), (", or ", 0),
|
||||
("Individual ", ColorId.NewMod.Value(_config)), ("Assignments.", 0));
|
||||
("Your Character", ColorId.HandledConflictMod.Value()), (", or ", 0),
|
||||
("Individual ", ColorId.NewMod.Value()), ("Assignments.", 0));
|
||||
break;
|
||||
case CollectionType.MaleNonPlayerCharacter:
|
||||
ImGuiUtil.DrawColoredText(("Overruled by ", 0), ("Male Racial NPC", Colors.DiscordColor), (", ", 0),
|
||||
("Children", ColorId.FolderLine.Value(_config)), (", ", 0), ("Elderly", Colors.MetaInfoText), (", or ", 0),
|
||||
("Individual ", ColorId.NewMod.Value(_config)), ("Assignments.", 0));
|
||||
("Children", ColorId.FolderLine.Value()), (", ", 0), ("Elderly", Colors.MetaInfoText), (", or ", 0),
|
||||
("Individual ", ColorId.NewMod.Value()), ("Assignments.", 0));
|
||||
break;
|
||||
case CollectionType.FemaleNonPlayerCharacter:
|
||||
ImGuiUtil.DrawColoredText(("Overruled by ", 0), ("Female Racial NPC", Colors.ReniColorActive), (", ", 0),
|
||||
("Children", ColorId.FolderLine.Value(_config)), (", ", 0), ("Elderly", Colors.MetaInfoText), (", or ", 0),
|
||||
("Individual ", ColorId.NewMod.Value(_config)), ("Assignments.", 0));
|
||||
("Children", ColorId.FolderLine.Value()), (", ", 0), ("Elderly", Colors.MetaInfoText), (", or ", 0),
|
||||
("Individual ", ColorId.NewMod.Value()), ("Assignments.", 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
|
|||
|
||||
protected override bool OnDraw(int idx)
|
||||
{
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Header, ColorId.SelectedCollection.Value(_config));
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Header, ColorId.SelectedCollection.Value());
|
||||
var ret = ImGui.Selectable(Name(Items[idx]), idx == CurrentIdx);
|
||||
using var source = ImRaii.DragDropSource();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,13 @@ public class InheritanceUi
|
|||
private const int InheritedCollectionHeight = 9;
|
||||
private const string InheritanceDragDropLabel = "##InheritanceMove";
|
||||
|
||||
private readonly Configuration _config;
|
||||
private readonly CollectionStorage _collections;
|
||||
private readonly ActiveCollections _active;
|
||||
private readonly InheritanceManager _inheritance;
|
||||
private readonly CollectionSelector _selector;
|
||||
|
||||
public InheritanceUi(Configuration config, CollectionManager collectionManager, CollectionSelector selector)
|
||||
public InheritanceUi(CollectionManager collectionManager, CollectionSelector selector)
|
||||
{
|
||||
_config = config;
|
||||
_selector = selector;
|
||||
_collections = collectionManager.Storage;
|
||||
_active = collectionManager.Active;
|
||||
|
|
@ -37,7 +35,7 @@ public class InheritanceUi
|
|||
public void Draw()
|
||||
{
|
||||
using var id = ImRaii.PushId("##Inheritance");
|
||||
ImGuiUtil.DrawColoredText(($"The {TutorialService.SelectedCollection} ", 0), (Name(_active.Current), ColorId.SelectedCollection.Value(_config) | 0xFF000000), (" inherits from:", 0));
|
||||
ImGuiUtil.DrawColoredText(($"The {TutorialService.SelectedCollection} ", 0), (Name(_active.Current), ColorId.SelectedCollection.Value() | 0xFF000000), (" inherits from:", 0));
|
||||
ImGui.Dummy(Vector2.One);
|
||||
|
||||
DrawCurrentCollectionInheritance();
|
||||
|
|
@ -124,7 +122,7 @@ public class InheritanceUi
|
|||
foreach (var inheritance in collection.GetFlattenedInheritance().Skip(1))
|
||||
{
|
||||
// Draw the child, already seen collections are colored as conflicts.
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.HandledConflictMod.Value(Penumbra.Config),
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.HandledConflictMod.Value(),
|
||||
_seenInheritedCollections.Contains(inheritance));
|
||||
_seenInheritedCollections.Add(inheritance);
|
||||
|
||||
|
|
@ -150,7 +148,7 @@ public class InheritanceUi
|
|||
/// <summary> Draw a single primary inherited collection. </summary>
|
||||
private void DrawInheritance(ModCollection collection)
|
||||
{
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.HandledConflictMod.Value(Penumbra.Config),
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.HandledConflictMod.Value(),
|
||||
_seenInheritedCollections.Contains(collection));
|
||||
_seenInheritedCollections.Add(collection);
|
||||
using var tree = ImRaii.TreeNode($"{Name(collection)}###{collection.Name}", ImGuiTreeNodeFlags.NoTreePushOnOpen);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
private readonly Configuration _config;
|
||||
private readonly FileDialogService _fileDialog;
|
||||
private readonly ModManager _modManager;
|
||||
private readonly ModCacheManager _modCaches;
|
||||
private readonly CollectionManager _collectionManager;
|
||||
private readonly TutorialService _tutorial;
|
||||
private readonly ModImportManager _modImportManager;
|
||||
|
|
@ -37,7 +36,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
|
||||
public ModFileSystemSelector(CommunicatorService communicator, ModFileSystem fileSystem, ModManager modManager,
|
||||
CollectionManager collectionManager, Configuration config, TutorialService tutorial, FileDialogService fileDialog, ChatService chat,
|
||||
ModCacheManager modCaches, ModImportManager modImportManager)
|
||||
ModImportManager modImportManager)
|
||||
: base(fileSystem, DalamudServices.KeyState, HandleException)
|
||||
{
|
||||
_communicator = communicator;
|
||||
|
|
@ -47,7 +46,6 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
_tutorial = tutorial;
|
||||
_fileDialog = fileDialog;
|
||||
_chat = chat;
|
||||
_modCaches = modCaches;
|
||||
_modImportManager = modImportManager;
|
||||
|
||||
// @formatter:off
|
||||
|
|
@ -73,7 +71,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
SetFilterTooltip();
|
||||
|
||||
SelectionChanged += OnSelectionChange;
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.ModSettingChanged.Subscribe(OnSettingChange);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnInheritanceChange);
|
||||
_communicator.ModDataChanged.Subscribe(OnModDataChange);
|
||||
|
|
@ -103,13 +101,13 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
=> _config.SortMode;
|
||||
|
||||
protected override uint ExpandedFolderColor
|
||||
=> ColorId.FolderExpanded.Value(_config);
|
||||
=> ColorId.FolderExpanded.Value();
|
||||
|
||||
protected override uint CollapsedFolderColor
|
||||
=> ColorId.FolderCollapsed.Value(_config);
|
||||
=> ColorId.FolderCollapsed.Value();
|
||||
|
||||
protected override uint FolderLineColor
|
||||
=> ColorId.FolderLine.Value(_config);
|
||||
=> ColorId.FolderLine.Value();
|
||||
|
||||
protected override bool FoldersDefaultOpen
|
||||
=> _config.OpenFoldersByDefault;
|
||||
|
|
@ -138,7 +136,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
protected override void DrawLeafName(FileSystem<Mod>.Leaf leaf, in ModState state, bool selected)
|
||||
{
|
||||
var flags = selected ? ImGuiTreeNodeFlags.Selected | LeafFlags : LeafFlags;
|
||||
using var c = ImRaii.PushColor(ImGuiCol.Text, state.Color.Value(_config))
|
||||
using var c = ImRaii.PushColor(ImGuiCol.Text, state.Color.Value())
|
||||
.Push(ImGuiCol.HeaderHovered, 0x4000FFFF, leaf.Value.Favorite);
|
||||
using var id = ImRaii.PushId(leaf.Value.Index);
|
||||
ImRaii.TreeNode(leaf.Value.Name, flags).Dispose();
|
||||
|
|
@ -285,7 +283,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
if (leaf == null)
|
||||
throw new Exception("Mod was not found at root.");
|
||||
|
||||
var folder = FileSystem.FindOrCreateAllFolders(Penumbra.Config.DefaultImportFolder);
|
||||
var folder = FileSystem.FindOrCreateAllFolders(_config.DefaultImportFolder);
|
||||
FileSystem.Move(leaf, folder);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
@ -315,19 +313,19 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
ImGui.BulletText("Select a mod to obtain more information or change settings.");
|
||||
ImGui.BulletText("Names are colored according to your config and their current state in the collection:");
|
||||
indent.Push();
|
||||
ImGuiUtil.BulletTextColored(ColorId.EnabledMod.Value(_config), "enabled in the current collection.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.DisabledMod.Value(_config), "disabled in the current collection.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.InheritedMod.Value(_config), "enabled due to inheritance from another collection.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.InheritedDisabledMod.Value(_config), "disabled due to inheritance from another collection.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.UndefinedMod.Value(_config), "unconfigured in all inherited collections.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.NewMod.Value(_config),
|
||||
ImGuiUtil.BulletTextColored(ColorId.EnabledMod.Value(), "enabled in the current collection.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.DisabledMod.Value(), "disabled in the current collection.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.InheritedMod.Value(), "enabled due to inheritance from another collection.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.InheritedDisabledMod.Value(), "disabled due to inheritance from another collection.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.UndefinedMod.Value(), "unconfigured in all inherited collections.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.NewMod.Value(),
|
||||
"newly imported during this session. Will go away when first enabling a mod or when Penumbra is reloaded.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.HandledConflictMod.Value(_config),
|
||||
ImGuiUtil.BulletTextColored(ColorId.HandledConflictMod.Value(),
|
||||
"enabled and conflicting with another enabled Mod, but on different priorities (i.e. the conflict is solved).");
|
||||
ImGuiUtil.BulletTextColored(ColorId.ConflictingMod.Value(_config),
|
||||
ImGuiUtil.BulletTextColored(ColorId.ConflictingMod.Value(),
|
||||
"enabled and conflicting with another enabled Mod on the same priority.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.FolderExpanded.Value(_config), "expanded mod folder.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.FolderCollapsed.Value(_config), "collapsed mod folder");
|
||||
ImGuiUtil.BulletTextColored(ColorId.FolderExpanded.Value(), "expanded mod folder.");
|
||||
ImGuiUtil.BulletTextColored(ColorId.FolderCollapsed.Value(), "collapsed mod folder");
|
||||
indent.Pop(1);
|
||||
ImGui.BulletText("Right-click a mod to enter its sort order, which is its name by default, possibly with a duplicate number.");
|
||||
indent.Push();
|
||||
|
|
@ -359,7 +357,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
private void OnSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx, bool inherited)
|
||||
{
|
||||
if (collection != _collectionManager.Active.Current)
|
||||
return;
|
||||
return;
|
||||
|
||||
SetFilterDirty();
|
||||
if (mod == Selected)
|
||||
|
|
@ -383,7 +381,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
private void OnInheritanceChange(ModCollection collection, bool _)
|
||||
{
|
||||
if (collection != _collectionManager.Active.Current)
|
||||
return;
|
||||
return;
|
||||
|
||||
SetFilterDirty();
|
||||
OnSelectionChange(Selected, Selected, default);
|
||||
|
|
@ -524,8 +522,8 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
0 => !(leaf.FullName().Contains(_modFilter.Lower, IgnoreCase) || mod.Name.Contains(_modFilter)),
|
||||
1 => !mod.Name.Contains(_modFilter),
|
||||
2 => !mod.Author.Contains(_modFilter),
|
||||
3 => !_modCaches[mod].LowerChangedItemsString.Contains(_modFilter.Lower),
|
||||
4 => !_modCaches[mod].AllTagsLower.Contains(_modFilter.Lower),
|
||||
3 => !mod.LowerChangedItemsString.Contains(_modFilter.Lower),
|
||||
4 => !mod.AllTagsLower.Contains(_modFilter.Lower),
|
||||
_ => false, // Should never happen
|
||||
};
|
||||
}
|
||||
|
|
@ -554,13 +552,12 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
private bool CheckStateFilters(Mod mod, ModSettings? settings, ModCollection collection, ref ModState state)
|
||||
{
|
||||
var isNew = _modManager.IsNew(mod);
|
||||
var cache = _modCaches[mod.Index];
|
||||
// Handle mod details.
|
||||
if (CheckFlags(cache.TotalFileCount, ModFilter.HasNoFiles, ModFilter.HasFiles)
|
||||
|| CheckFlags(cache.TotalSwapCount, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps)
|
||||
|| CheckFlags(cache.TotalManipulations, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations)
|
||||
|| CheckFlags(cache.HasOptions ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig)
|
||||
|| CheckFlags(isNew ? 1 : 0, ModFilter.NotNew, ModFilter.IsNew))
|
||||
if (CheckFlags(mod.TotalFileCount, ModFilter.HasNoFiles, ModFilter.HasFiles)
|
||||
|| CheckFlags(mod.TotalSwapCount, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps)
|
||||
|| CheckFlags(mod.TotalManipulations, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations)
|
||||
|| CheckFlags(mod.HasOptions ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig)
|
||||
|| CheckFlags(isNew ? 1 : 0, ModFilter.NotNew, ModFilter.IsNew))
|
||||
return true;
|
||||
|
||||
// Handle Favoritism
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
|
|
@ -14,20 +15,18 @@ public class ModPanelChangedItemsTab : ITab
|
|||
{
|
||||
private readonly ModFileSystemSelector _selector;
|
||||
private readonly PenumbraApi _api;
|
||||
private readonly ModCacheManager _modCaches;
|
||||
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Changed Items"u8;
|
||||
|
||||
public ModPanelChangedItemsTab(PenumbraApi api, ModFileSystemSelector selector, ModCacheManager modCaches)
|
||||
public ModPanelChangedItemsTab(PenumbraApi api, ModFileSystemSelector selector)
|
||||
{
|
||||
_api = api;
|
||||
_selector = selector;
|
||||
_modCaches = modCaches;
|
||||
_api = api;
|
||||
_selector = selector;
|
||||
}
|
||||
|
||||
public bool IsVisible
|
||||
=> _modCaches[_selector.Selected!].ChangedItems.Count > 0;
|
||||
=> _selector.Selected!.ChangedItems.Count > 0;
|
||||
|
||||
public void DrawContent()
|
||||
{
|
||||
|
|
@ -35,7 +34,7 @@ public class ModPanelChangedItemsTab : ITab
|
|||
if (!list)
|
||||
return;
|
||||
|
||||
var zipList = ZipList.FromSortedList(_modCaches[_selector.Selected!].ChangedItems);
|
||||
var zipList = ZipList.FromSortedList((SortedList<string, object?>)_selector.Selected!.ChangedItems);
|
||||
var height = ImGui.GetTextLineHeight();
|
||||
ImGuiClip.ClippedDraw(zipList, kvp => UiHelpers.DrawChangedItem(_api, kvp.Item1, kvp.Item2, true), height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using Lumina.Data.Parsing.Layer;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
|
|
@ -15,15 +14,13 @@ namespace Penumbra.UI.ModsTab;
|
|||
|
||||
public class ModPanelCollectionsTab : ITab
|
||||
{
|
||||
private readonly Configuration _config;
|
||||
private readonly ModFileSystemSelector _selector;
|
||||
private readonly CollectionStorage _collections;
|
||||
|
||||
private readonly List<(ModCollection, ModCollection, uint, string)> _cache = new();
|
||||
|
||||
public ModPanelCollectionsTab(Configuration config, CollectionStorage storage, ModFileSystemSelector selector)
|
||||
public ModPanelCollectionsTab(CollectionStorage storage, ModFileSystemSelector selector)
|
||||
{
|
||||
_config = config;
|
||||
_collections = storage;
|
||||
_selector = selector;
|
||||
}
|
||||
|
|
@ -42,9 +39,8 @@ public class ModPanelCollectionsTab : ITab
|
|||
else
|
||||
ImGui.TextUnformatted($"This Mod is directly configured in {direct} collections.");
|
||||
if (inherited > 0)
|
||||
{
|
||||
ImGui.TextUnformatted($"It is also implicitly used in {inherited} {(inherited == 1 ? "collection" : "collections")} through inheritance.");
|
||||
}
|
||||
ImGui.TextUnformatted(
|
||||
$"It is also implicitly used in {inherited} {(inherited == 1 ? "collection" : "collections")} through inheritance.");
|
||||
|
||||
ImGui.NewLine();
|
||||
ImGui.Separator();
|
||||
|
|
@ -79,13 +75,13 @@ public class ModPanelCollectionsTab : ITab
|
|||
private (int Direct, int Inherited) CountUsage(Mod mod)
|
||||
{
|
||||
_cache.Clear();
|
||||
var undefined = ColorId.UndefinedMod.Value(_config);
|
||||
var enabled = ColorId.EnabledMod.Value(_config);
|
||||
var inherited = ColorId.InheritedMod.Value(_config);
|
||||
var disabled = ColorId.DisabledMod.Value(_config);
|
||||
var disInherited = ColorId.InheritedDisabledMod.Value(_config);
|
||||
var directCount = 0;
|
||||
var inheritedCount = 0;
|
||||
var undefined = ColorId.UndefinedMod.Value();
|
||||
var enabled = ColorId.EnabledMod.Value();
|
||||
var inherited = ColorId.InheritedMod.Value();
|
||||
var disabled = ColorId.DisabledMod.Value();
|
||||
var disInherited = ColorId.InheritedDisabledMod.Value();
|
||||
var directCount = 0;
|
||||
var inheritedCount = 0;
|
||||
foreach (var collection in _collections)
|
||||
{
|
||||
var (settings, parent) = collection[mod.Index];
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class ModPanelConflictsTab : ITab
|
|||
|
||||
ImGui.SameLine();
|
||||
using (var color = ImRaii.PushColor(ImGuiCol.Text,
|
||||
conflict.HasPriority ? ColorId.HandledConflictMod.Value(Penumbra.Config) : ColorId.ConflictingMod.Value(Penumbra.Config)))
|
||||
conflict.HasPriority ? ColorId.HandledConflictMod.Value() : ColorId.ConflictingMod.Value()))
|
||||
{
|
||||
var priority = conflict.Mod2.Index < 0
|
||||
? conflict.Mod2.Priority
|
||||
|
|
|
|||
|
|
@ -18,18 +18,18 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
public ResourceWatcherTable(Configuration config, ICollection<Record> records)
|
||||
: base("##records",
|
||||
records,
|
||||
new PathColumn { Label = "Path" },
|
||||
new RecordTypeColumn(config) { Label = "Record" },
|
||||
new CollectionColumn { Label = "Collection" },
|
||||
new ObjectColumn { Label = "Game Object" },
|
||||
new CustomLoadColumn { Label = "Custom" },
|
||||
new SynchronousLoadColumn { Label = "Sync" },
|
||||
new OriginalPathColumn { Label = "Original Path" },
|
||||
new ResourceCategoryColumn { Label = "Category" },
|
||||
new ResourceTypeColumn { Label = "Type" },
|
||||
new HandleColumn { Label = "Resource" },
|
||||
new RefCountColumn { Label = "#Ref" },
|
||||
new DateColumn { Label = "Time" }
|
||||
new PathColumn { Label = "Path" },
|
||||
new RecordTypeColumn(config) { Label = "Record" },
|
||||
new CollectionColumn { Label = "Collection" },
|
||||
new ObjectColumn { Label = "Game Object" },
|
||||
new CustomLoadColumn { Label = "Custom" },
|
||||
new SynchronousLoadColumn { Label = "Sync" },
|
||||
new OriginalPathColumn { Label = "Original Path" },
|
||||
new ResourceCategoryColumn(config) { Label = "Category" },
|
||||
new ResourceTypeColumn(config) { Label = "Type" },
|
||||
new HandleColumn { Label = "Resource" },
|
||||
new RefCountColumn { Label = "#Ref" },
|
||||
new DateColumn { Label = "Time" }
|
||||
)
|
||||
{ }
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
else
|
||||
_config.ResourceWatcherRecordTypes &= ~value;
|
||||
|
||||
Penumbra.Config.Save();
|
||||
_config.Save();
|
||||
}
|
||||
|
||||
public override void DrawColumn(Record item, int idx)
|
||||
|
|
@ -175,8 +175,13 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
|
||||
private sealed class ResourceCategoryColumn : ColumnFlags<ResourceCategoryFlag, Record>
|
||||
{
|
||||
public ResourceCategoryColumn()
|
||||
=> AllFlags = ResourceExtensions.AllResourceCategories;
|
||||
private readonly Configuration _config;
|
||||
|
||||
public ResourceCategoryColumn(Configuration config)
|
||||
{
|
||||
_config = config;
|
||||
AllFlags = ResourceExtensions.AllResourceCategories;
|
||||
}
|
||||
|
||||
public override float Width
|
||||
=> 80 * UiHelpers.Scale;
|
||||
|
|
@ -185,16 +190,16 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
=> FilterValue.HasFlag(item.Category);
|
||||
|
||||
public override ResourceCategoryFlag FilterValue
|
||||
=> Penumbra.Config.ResourceWatcherResourceCategories;
|
||||
=> _config.ResourceWatcherResourceCategories;
|
||||
|
||||
protected override void SetValue(ResourceCategoryFlag value, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
Penumbra.Config.ResourceWatcherResourceCategories |= value;
|
||||
_config.ResourceWatcherResourceCategories |= value;
|
||||
else
|
||||
Penumbra.Config.ResourceWatcherResourceCategories &= ~value;
|
||||
_config.ResourceWatcherResourceCategories &= ~value;
|
||||
|
||||
Penumbra.Config.Save();
|
||||
_config.Save();
|
||||
}
|
||||
|
||||
public override void DrawColumn(Record item, int idx)
|
||||
|
|
@ -205,8 +210,11 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
|
||||
private sealed class ResourceTypeColumn : ColumnFlags<ResourceTypeFlag, Record>
|
||||
{
|
||||
public ResourceTypeColumn()
|
||||
private readonly Configuration _config;
|
||||
|
||||
public ResourceTypeColumn(Configuration config)
|
||||
{
|
||||
_config = config;
|
||||
AllFlags = Enum.GetValues<ResourceTypeFlag>().Aggregate((v, f) => v | f);
|
||||
for (var i = 0; i < Names.Length; ++i)
|
||||
Names[i] = Names[i].ToLowerInvariant();
|
||||
|
|
@ -219,16 +227,16 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
=> FilterValue.HasFlag(item.ResourceType);
|
||||
|
||||
public override ResourceTypeFlag FilterValue
|
||||
=> Penumbra.Config.ResourceWatcherResourceTypes;
|
||||
=> _config.ResourceWatcherResourceTypes;
|
||||
|
||||
protected override void SetValue(ResourceTypeFlag value, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
Penumbra.Config.ResourceWatcherResourceTypes |= value;
|
||||
_config.ResourceWatcherResourceTypes |= value;
|
||||
else
|
||||
Penumbra.Config.ResourceWatcherResourceTypes &= ~value;
|
||||
_config.ResourceWatcherResourceTypes &= ~value;
|
||||
|
||||
Penumbra.Config.Save();
|
||||
_config.Save();
|
||||
}
|
||||
|
||||
public override void DrawColumn(Record item, int idx)
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class ChangedItemsTab : ITab
|
|||
if (!UiHelpers.GetChangedItemObject(item.Value.Item2, out var text))
|
||||
return;
|
||||
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value(Penumbra.Config));
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ItemId.Value());
|
||||
ImGuiUtil.RightAlign(text);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public class CollectionsTab : IDisposable, ITab
|
|||
_config = configuration;
|
||||
_tutorial = tutorial;
|
||||
_selector = new CollectionSelector(configuration, communicator, collectionManager.Storage, collectionManager.Active, _tutorial);
|
||||
_panel = new CollectionPanel(pi, configuration, communicator, collectionManager, _selector, actors, targets, modStorage);
|
||||
_panel = new CollectionPanel(pi, communicator, collectionManager, _selector, actors, targets, modStorage);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -116,8 +116,8 @@ public class CollectionsTab : IDisposable, ITab
|
|||
ImGui.SameLine();
|
||||
|
||||
style.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale);
|
||||
color.Push(ImGuiCol.Text, ColorId.FolderExpanded.Value(_config))
|
||||
.Push(ImGuiCol.Border, ColorId.FolderExpanded.Value(_config));
|
||||
color.Push(ImGuiCol.Text, ColorId.FolderExpanded.Value())
|
||||
.Push(ImGuiCol.Border, ColorId.FolderExpanded.Value());
|
||||
if (ImGuiUtil.DrawDisabledButton(
|
||||
$"{(_selector.IncognitoMode ? FontAwesomeIcon.Eye : FontAwesomeIcon.EyeSlash).ToIconString()}###IncognitoMode",
|
||||
buttonSize with { X = withSpacing }, string.Empty, false, true))
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public class ModsTab : ITab
|
|||
|
||||
private void DrawRedrawLine()
|
||||
{
|
||||
if (Penumbra.Config.HideRedrawBar)
|
||||
if (_config.HideRedrawBar)
|
||||
{
|
||||
_tutorial.SkipTutorial(BasicTutorialSteps.Redrawing);
|
||||
return;
|
||||
|
|
@ -172,7 +172,7 @@ public class ModsTab : ITab
|
|||
ImGui.SameLine();
|
||||
DrawInheritedCollectionButton(3 * buttonSize);
|
||||
ImGui.SameLine();
|
||||
_collectionCombo.Draw("##collectionSelector", 2 * buttonSize.X, ColorId.SelectedCollection.Value(_config));
|
||||
_collectionCombo.Draw("##collectionSelector", 2 * buttonSize.X, ColorId.SelectedCollection.Value());
|
||||
}
|
||||
|
||||
_tutorial.OpenTutorial(BasicTutorialSteps.CollectionSelectors);
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ public class SettingsTab : ITab
|
|||
return;
|
||||
|
||||
DrawEnabledBox();
|
||||
Checkbox("Lock Main Window", "Prevent the main window from being resized or moved.", Penumbra.Config.FixMainWindow,
|
||||
v => Penumbra.Config.FixMainWindow = v);
|
||||
Checkbox("Lock Main Window", "Prevent the main window from being resized or moved.", _config.FixMainWindow,
|
||||
v => _config.FixMainWindow = v);
|
||||
|
||||
ImGui.NewLine();
|
||||
DrawRootFolder();
|
||||
|
|
@ -220,7 +220,7 @@ public class SettingsTab : ITab
|
|||
|
||||
if (_config.ModDirectory != _newModDirectory
|
||||
&& _newModDirectory.Length != 0
|
||||
&& DrawPressEnterWarning(_newModDirectory, Penumbra.Config.ModDirectory, pos, save, selected))
|
||||
&& DrawPressEnterWarning(_newModDirectory, _config.ModDirectory, pos, save, selected))
|
||||
_modManager.DiscoverMods(_newModDirectory);
|
||||
}
|
||||
|
||||
|
|
@ -344,14 +344,14 @@ public class SettingsTab : ITab
|
|||
_dalamud.UiBuilder.DisableUserUiHide = !v;
|
||||
});
|
||||
Checkbox("Hide Config Window when in Cutscenes",
|
||||
"Hide the penumbra main window when you are currently watching a cutscene.", Penumbra.Config.HideUiInCutscenes,
|
||||
"Hide the penumbra main window when you are currently watching a cutscene.", _config.HideUiInCutscenes,
|
||||
v =>
|
||||
{
|
||||
_config.HideUiInCutscenes = v;
|
||||
_dalamud.UiBuilder.DisableCutsceneUiHide = !v;
|
||||
});
|
||||
Checkbox("Hide Config Window when in GPose",
|
||||
"Hide the penumbra main window when you are currently in GPose mode.", Penumbra.Config.HideUiInGPose,
|
||||
"Hide the penumbra main window when you are currently in GPose mode.", _config.HideUiInGPose,
|
||||
v =>
|
||||
{
|
||||
_config.HideUiInGPose = v;
|
||||
|
|
@ -481,7 +481,7 @@ public class SettingsTab : ITab
|
|||
|
||||
Widget.DoubleModifierSelector("Mod Deletion Modifier",
|
||||
"A modifier you need to hold while clicking the Delete Mod button for it to take effect.", UiHelpers.InputTextWidth.X,
|
||||
Penumbra.Config.DeleteModModifier,
|
||||
_config.DeleteModModifier,
|
||||
v =>
|
||||
{
|
||||
_config.DeleteModModifier = v;
|
||||
|
|
@ -742,8 +742,8 @@ public class SettingsTab : ITab
|
|||
ImGui.SetCursorPos(new Vector2(xPos, 3 * ImGui.GetFrameHeightWithSpacing()));
|
||||
if (ImGui.Button("Restart Tutorial", new Vector2(width, 0)))
|
||||
{
|
||||
Penumbra.Config.TutorialStep = 0;
|
||||
Penumbra.Config.Save();
|
||||
_config.TutorialStep = 0;
|
||||
_config.Save();
|
||||
}
|
||||
|
||||
ImGui.SetCursorPos(new Vector2(xPos, 4 * ImGui.GetFrameHeightWithSpacing()));
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public static class UiHelpers
|
|||
return;
|
||||
|
||||
ImGui.SameLine(ImGui.GetContentRegionAvail().X);
|
||||
ImGuiUtil.RightJustify(text, ColorId.ItemId.Value(Penumbra.Config));
|
||||
ImGuiUtil.RightJustify(text, ColorId.ItemId.Value());
|
||||
}
|
||||
|
||||
/// <summary> Return more detailed object information in text, if it exists. </summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue