From 8d597f9da55a5a2d07984bacbfecc5e1dcf8ae9e Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 5 Oct 2022 12:31:40 +0200 Subject: [PATCH] Add buttons to export and import all colorset rows at once, changelog. --- Penumbra/UI/Classes/ModEditWindow.FileEdit.cs | 73 ++++++++++++++++++- Penumbra/UI/ConfigWindow.Changelog.cs | 13 ++++ 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs b/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs index 170b710e..29ca6897 100644 --- a/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs +++ b/Penumbra/UI/Classes/ModEditWindow.FileEdit.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Numerics; +using System.Runtime.InteropServices; using Dalamud.Interface; using ImGuiNET; using OtterGui; @@ -260,11 +261,14 @@ public partial class ModEditWindow private static bool DrawMaterialColorSetChange( MtrlFile file, bool disabled ) { - if( !file.ColorSets.Any(c => c.HasRows ) ) + if( !file.ColorSets.Any( c => c.HasRows ) ) { return false; } + ColorSetCopyAllClipboardButton( file, 0 ); + ImGui.SameLine(); + var ret = ColorSetPasteAllClipboardButton( file, 0 ); using var table = ImRaii.Table( "##ColorSets", 10, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInnerV ); if( !table ) @@ -293,7 +297,6 @@ public partial class ModEditWindow ImGui.TableNextColumn(); ImGui.TableHeader( "Dye" ); - var ret = false; for( var j = 0; j < file.ColorSets.Length; ++j ) { using var _ = ImRaii.PushId( j ); @@ -307,6 +310,68 @@ public partial class ModEditWindow return ret; } + private static void ColorSetCopyAllClipboardButton( MtrlFile file, int colorSetIdx ) + { + if( !ImGui.Button( "Export All Rows to Clipboard" ) ) + { + return; + } + + try + { + var data1 = file.ColorSets[ colorSetIdx ].Rows.AsBytes(); + var data2 = file.ColorDyeSets.Length > colorSetIdx ? file.ColorDyeSets[ colorSetIdx ].Rows.AsBytes() : ReadOnlySpan< byte >.Empty; + var array = new byte[data1.Length + data2.Length]; + data1.TryCopyTo( array ); + data2.TryCopyTo( array.AsSpan( data1.Length ) ); + var text = Convert.ToBase64String( array ); + ImGui.SetClipboardText( text ); + } + catch + { + // ignored + } + } + + private static unsafe bool ColorSetPasteAllClipboardButton( MtrlFile file, int colorSetIdx ) + { + if( !ImGui.Button( "Import All Rows from Clipboard" ) || file.ColorSets.Length <= colorSetIdx ) + { + return false; + } + + try + { + var text = ImGui.GetClipboardText(); + var data = Convert.FromBase64String( text ); + if( data.Length < Marshal.SizeOf< MtrlFile.ColorSet.RowArray >() ) + { + return false; + } + + ref var rows = ref file.ColorSets[ colorSetIdx ].Rows; + fixed( void* ptr = data, output = &rows ) + { + Functions.MemCpyUnchecked( output, ptr, Marshal.SizeOf< MtrlFile.ColorSet.RowArray >() ); + if( data.Length >= Marshal.SizeOf< MtrlFile.ColorSet.RowArray >() + Marshal.SizeOf< MtrlFile.ColorDyeSet.RowArray >() + && file.ColorDyeSets.Length > colorSetIdx) + { + ref var dyeRows = ref file.ColorDyeSets[ colorSetIdx ].Rows; + fixed( void* output2 = &dyeRows ) + { + Functions.MemCpyUnchecked( output2, (byte*) ptr + Marshal.SizeOf(), Marshal.SizeOf() ); + } + } + } + + return true; + } + catch + { + return false; + } + } + private static unsafe void ColorSetCopyClipboardButton( MtrlFile.ColorSet.Row row, MtrlFile.ColorDyeSet.Row dye ) { if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Clipboard.ToIconString(), ImGui.GetFrameHeight() * Vector2.One, @@ -407,7 +472,7 @@ public partial class ModEditWindow ImGui.SameLine(); var tmpFloat = row.SpecularStrength; ImGui.SetNextItemWidth( floatSize ); - if( ImGui.DragFloat( "##SpecularStrength", ref tmpFloat, 0.1f, 0f ) && FixFloat(ref tmpFloat, row.SpecularStrength) ) + if( ImGui.DragFloat( "##SpecularStrength", ref tmpFloat, 0.1f, 0f ) && FixFloat( ref tmpFloat, row.SpecularStrength ) ) { file.ColorSets[ colorSetIdx ].Rows[ rowIdx ].SpecularStrength = tmpFloat; ret = true; @@ -465,7 +530,7 @@ public partial class ModEditWindow ImGui.TableNextColumn(); tmpFloat = row.MaterialRepeat.X; ImGui.SetNextItemWidth( floatSize ); - if( ImGui.DragFloat( "##RepeatX", ref tmpFloat, 0.1f, 0f ) && FixFloat(ref tmpFloat, row.MaterialRepeat.X) ) + if( ImGui.DragFloat( "##RepeatX", ref tmpFloat, 0.1f, 0f ) && FixFloat( ref tmpFloat, row.MaterialRepeat.X ) ) { file.ColorSets[ colorSetIdx ].Rows[ rowIdx ].MaterialRepeat = row.MaterialRepeat with { X = tmpFloat }; ret = true; diff --git a/Penumbra/UI/ConfigWindow.Changelog.cs b/Penumbra/UI/ConfigWindow.Changelog.cs index 09dc4a08..3ffb6f48 100644 --- a/Penumbra/UI/ConfigWindow.Changelog.cs +++ b/Penumbra/UI/ConfigWindow.Changelog.cs @@ -25,6 +25,19 @@ public partial class ConfigWindow return ret; } + private static void Add5_10_0( Changelog log ) + => log.NextVersion( "Version 0.5.10.0" ) + .RegisterEntry( "Renamed backup functionality to export functionality." ) + .RegisterEntry( "A default export directory can now optionally be specified." ) + .RegisterEntry( "If left blank, exports will still be stored in your mod directory.", 1 ) + .RegisterEntry( "Existing exports corresponding to existing mods will be moved automatically if the export directory is changed.", + 1 ) + .RegisterEntry( "Added buttons to export and import all color set rows at once during material editing." ) + .RegisterEntry( "Fixed texture import being case sensitive on the extension." ) + .RegisterEntry( "Fixed special collection selector increasing in size on non-default UI styling." ) + .RegisterEntry( "Fixed color set rows not importing the dye values during material editing." ) + .RegisterEntry( "Other miscallaneous small fixes." ); + private static void Add5_9_0( Changelog log ) => log.NextVersion( "Version 0.5.9.0" ) .RegisterEntry( "Special Collections are now split between male and female." )