Remove static Config.

This commit is contained in:
Ottermandias 2023-04-21 23:52:31 +02:00
parent aa4bc45641
commit be3c1c85aa
30 changed files with 363 additions and 440 deletions

View file

@ -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);
}
}
}
}