From 9bceed3d571075336345514938c877578634456b Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 18 May 2022 23:03:32 +0200 Subject: [PATCH] Fix some bugs, add clipboard options to meta changes. --- OtterGui | 2 +- Penumbra/Collections/CollectionManager.cs | 3 +- Penumbra/Mods/Editor/Mod.Editor.Meta.cs | 7 +- Penumbra/Mods/Mod.BasePath.cs | 1 + Penumbra/Mods/Mod.Creation.cs | 2 +- Penumbra/UI/Classes/ModEditWindow.Meta.cs | 129 +++++++++++++++------- Penumbra/UI/Classes/ModEditWindow.cs | 7 ++ 7 files changed, 106 insertions(+), 45 deletions(-) diff --git a/OtterGui b/OtterGui index 732c9a3b..d6fcf1f5 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 732c9a3bd7c967ca427e24f4b8df65f722fe72d2 +Subproject commit d6fcf1f53888d5eec8196eaba2dbb3853534d3bf diff --git a/Penumbra/Collections/CollectionManager.cs b/Penumbra/Collections/CollectionManager.cs index 775a0b2c..ce8fa113 100644 --- a/Penumbra/Collections/CollectionManager.cs +++ b/Penumbra/Collections/CollectionManager.cs @@ -224,10 +224,9 @@ public partial class ModCollection OnModAddedActive( mod.TotalManipulations > 0 ); break; case ModPathChangeType.Deleted: - var settings = new List< ModSettings? >( _collections.Count ); + var settings = this.Select( c => c[mod.Index].Settings ).ToList(); foreach( var collection in this ) { - settings.Add( collection._settings[ mod.Index ] ); collection.RemoveMod( mod, mod.Index ); } diff --git a/Penumbra/Mods/Editor/Mod.Editor.Meta.cs b/Penumbra/Mods/Editor/Mod.Editor.Meta.cs index 19a48f95..c0908a9c 100644 --- a/Penumbra/Mods/Editor/Mod.Editor.Meta.cs +++ b/Penumbra/Mods/Editor/Mod.Editor.Meta.cs @@ -134,20 +134,19 @@ public partial class Mod Changes = false; } - private HashSet< MetaManipulation > Recombine() + public IEnumerable< MetaManipulation > Recombine() => _imc.Select( m => ( MetaManipulation )m ) .Concat( _eqdp.Select( m => ( MetaManipulation )m ) ) .Concat( _eqp.Select( m => ( MetaManipulation )m ) ) .Concat( _est.Select( m => ( MetaManipulation )m ) ) .Concat( _gmp.Select( m => ( MetaManipulation )m ) ) - .Concat( _rsp.Select( m => ( MetaManipulation )m ) ) - .ToHashSet(); + .Concat( _rsp.Select( m => ( MetaManipulation )m ) ); public void Apply( Mod mod, int groupIdx, int optionIdx ) { if( Changes ) { - Penumbra.ModManager.OptionSetManipulations( mod, groupIdx, optionIdx, Recombine() ); + Penumbra.ModManager.OptionSetManipulations( mod, groupIdx, optionIdx, Recombine().ToHashSet() ); Changes = false; } } diff --git a/Penumbra/Mods/Mod.BasePath.cs b/Penumbra/Mods/Mod.BasePath.cs index 1e37b143..16efdf12 100644 --- a/Penumbra/Mods/Mod.BasePath.cs +++ b/Penumbra/Mods/Mod.BasePath.cs @@ -33,6 +33,7 @@ public partial class Mod { // Can not be base path not existing because that is checked before. PluginLog.Error( $"Mod at {modPath} without name is not supported." ); + return null; } return mod; diff --git a/Penumbra/Mods/Mod.Creation.cs b/Penumbra/Mods/Mod.Creation.cs index 85a5d264..de4f9f88 100644 --- a/Penumbra/Mods/Mod.Creation.cs +++ b/Penumbra/Mods/Mod.Creation.cs @@ -54,7 +54,7 @@ public partial class Mod mod.Description = description ?? mod.Description; mod.Version = version ?? mod.Version; mod.Website = website ?? mod.Website; - mod.SaveMeta(); + mod.SaveMetaFile(); // Not delayed. } // Create a file for an option group from given data. diff --git a/Penumbra/UI/Classes/ModEditWindow.Meta.cs b/Penumbra/UI/Classes/ModEditWindow.Meta.cs index 60ce5b0f..9b20e847 100644 --- a/Penumbra/UI/Classes/ModEditWindow.Meta.cs +++ b/Penumbra/UI/Classes/ModEditWindow.Meta.cs @@ -43,18 +43,25 @@ public partial class ModEditWindow _editor.RevertManipulations(); } + ImGui.SameLine(); + AddFromClipboardButton(); + ImGui.SameLine(); + SetFromClipboardButton(); + ImGui.SameLine(); + CopyToClipboardButton( "Copy all current manipulations to clipboard.", _iconSize, _editor.Meta.Recombine() ); + using var child = ImRaii.Child( "##meta", -Vector2.One, true ); if( !child ) { return; } - DrawEditHeader( _editor.Meta.Eqp, "Equipment Parameter Edits (EQP)###EQP", 4, EqpRow.Draw, EqpRow.DrawNew ); - DrawEditHeader( _editor.Meta.Eqdp, "Racial Model Edits (EQDP)###EQDP", 6, EqdpRow.Draw, EqdpRow.DrawNew ); - DrawEditHeader( _editor.Meta.Imc, "Variant Edits (IMC)###IMC", 8, ImcRow.Draw, ImcRow.DrawNew ); - DrawEditHeader( _editor.Meta.Est, "Extra Skeleton Parameters (EST)###EST", 6, EstRow.Draw, EstRow.DrawNew ); - DrawEditHeader( _editor.Meta.Gmp, "Visor/Gimmick Edits (GMP)###GMP", 6, GmpRow.Draw, GmpRow.DrawNew ); - DrawEditHeader( _editor.Meta.Rsp, "Racial Scaling Edits (RSP)###RSP", 4, RspRow.Draw, RspRow.DrawNew ); + DrawEditHeader( _editor.Meta.Eqp, "Equipment Parameter Edits (EQP)###EQP", 5, EqpRow.Draw, EqpRow.DrawNew ); + DrawEditHeader( _editor.Meta.Eqdp, "Racial Model Edits (EQDP)###EQDP", 7, EqdpRow.Draw, EqdpRow.DrawNew ); + DrawEditHeader( _editor.Meta.Imc, "Variant Edits (IMC)###IMC", 9, ImcRow.Draw, ImcRow.DrawNew ); + DrawEditHeader( _editor.Meta.Est, "Extra Skeleton Parameters (EST)###EST", 7, EstRow.Draw, EstRow.DrawNew ); + DrawEditHeader( _editor.Meta.Gmp, "Visor/Gimmick Edits (GMP)###GMP", 7, GmpRow.Draw, GmpRow.DrawNew ); + DrawEditHeader( _editor.Meta.Rsp, "Racial Scaling Edits (RSP)###RSP", 5, RspRow.Draw, RspRow.DrawNew ); } @@ -67,12 +74,12 @@ public partial class ModEditWindow { return; } - using( var table = ImRaii.Table( label, numColumns, flags ) ) { if( table ) { drawNew( _editor!, _iconSize ); + ImGui.Separator(); foreach( var (item, index) in items.ToArray().WithIndex() ) { using var id = ImRaii.PushId( index ); @@ -93,6 +100,8 @@ public partial class ModEditWindow public static void DrawNew( Mod.Editor editor, Vector2 iconSize ) { + ImGui.TableNextColumn(); + CopyToClipboardButton( "Copy all current EQP manipulations to clipboard.", iconSize, editor.Meta.Eqp.Select( m => (MetaManipulation) m ) ); ImGui.TableNextColumn(); var canAdd = editor.Meta.CanAdd( _new ); var tt = canAdd ? "Stage this edit." : "This entry is already edited."; @@ -125,15 +134,12 @@ public partial class ModEditWindow Checkmark( string.Empty, flag.ToLocalName(), value, value, out _ ); ImGui.SameLine(); } + ImGui.NewLine(); } public static void Draw( EqpManipulation meta, Mod.Editor editor, Vector2 iconSize ) { - ImGui.TableNextColumn(); - if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), iconSize, "Delete this meta edit.", false, true ) ) - { - editor.Meta.Delete( meta ); - } + DrawMetaButtons( meta, editor, iconSize ); // Identifier ImGui.TableNextColumn(); @@ -172,6 +178,8 @@ public partial class ModEditWindow public static void DrawNew( Mod.Editor editor, Vector2 iconSize ) { + ImGui.TableNextColumn(); + CopyToClipboardButton( "Copy all current EQDP manipulations to clipboard.", iconSize, editor.Meta.Eqdp.Select( m => ( MetaManipulation )m ) ); ImGui.TableNextColumn(); var raceCode = Names.CombinedRace( _new.Gender, _new.Race ); var validRaceCode = CharacterUtility.EqdpIdx( raceCode, false ) >= 0; @@ -221,11 +229,7 @@ public partial class ModEditWindow public static void Draw( EqdpManipulation meta, Mod.Editor editor, Vector2 iconSize ) { - ImGui.TableNextColumn(); - if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), iconSize, "Delete this meta edit.", false, true ) ) - { - editor.Meta.Delete( meta ); - } + DrawMetaButtons( meta, editor, iconSize ); // Identifier ImGui.TableNextColumn(); @@ -284,6 +288,8 @@ public partial class ModEditWindow public static void DrawNew( Mod.Editor editor, Vector2 iconSize ) { + ImGui.TableNextColumn(); + CopyToClipboardButton( "Copy all current IMC manipulations to clipboard.", iconSize, editor.Meta.Imc.Select( m => ( MetaManipulation )m ) ); ImGui.TableNextColumn(); var defaultEntry = GetDefault( _new ); var canAdd = defaultEntry != null && editor.Meta.CanAdd( _new ); @@ -354,11 +360,7 @@ public partial class ModEditWindow public static void Draw( ImcManipulation meta, Mod.Editor editor, Vector2 iconSize ) { - ImGui.TableNextColumn(); - if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), iconSize, "Delete this meta edit.", false, true ) ) - { - editor.Meta.Delete( meta ); - } + DrawMetaButtons( meta, editor, iconSize ); // Identifier ImGui.TableNextColumn(); @@ -438,6 +440,8 @@ public partial class ModEditWindow public static void DrawNew( Mod.Editor editor, Vector2 iconSize ) { + ImGui.TableNextColumn(); + CopyToClipboardButton( "Copy all current EST manipulations to clipboard.", iconSize, editor.Meta.Est.Select( m => ( MetaManipulation )m ) ); ImGui.TableNextColumn(); var canAdd = editor.Meta.CanAdd( _new ); var tt = canAdd ? "Stage this edit." : "This entry is already edited."; @@ -479,11 +483,7 @@ public partial class ModEditWindow public static void Draw( EstManipulation meta, Mod.Editor editor, Vector2 iconSize ) { - ImGui.TableNextColumn(); - if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), iconSize, "Delete this meta edit.", false, true ) ) - { - editor.Meta.Delete( meta ); - } + DrawMetaButtons( meta, editor, iconSize ); // Identifier ImGui.TableNextColumn(); @@ -525,6 +525,8 @@ public partial class ModEditWindow public static void DrawNew( Mod.Editor editor, Vector2 iconSize ) { + ImGui.TableNextColumn(); + CopyToClipboardButton( "Copy all current GMP manipulations to clipboard.", iconSize, editor.Meta.Gmp.Select( m => ( MetaManipulation )m ) ); ImGui.TableNextColumn(); var canAdd = editor.Meta.CanAdd( _new ); var tt = canAdd ? "Stage this edit." : "This entry is already edited."; @@ -563,11 +565,7 @@ public partial class ModEditWindow public static void Draw( GmpManipulation meta, Mod.Editor editor, Vector2 iconSize ) { - ImGui.TableNextColumn(); - if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), iconSize, "Delete this meta edit.", false, true ) ) - { - editor.Meta.Delete( meta ); - } + DrawMetaButtons( meta, editor, iconSize ); // Identifier ImGui.TableNextColumn(); @@ -634,6 +632,8 @@ public partial class ModEditWindow public static void DrawNew( Mod.Editor editor, Vector2 iconSize ) { + ImGui.TableNextColumn(); + CopyToClipboardButton( "Copy all current RSP manipulations to clipboard.", iconSize, editor.Meta.Rsp.Select( m => ( MetaManipulation )m ) ); ImGui.TableNextColumn(); var canAdd = editor.Meta.CanAdd( _new ); var tt = canAdd ? "Stage this edit." : "This entry is already edited."; @@ -664,11 +664,7 @@ public partial class ModEditWindow public static void Draw( RspManipulation meta, Mod.Editor editor, Vector2 iconSize ) { - ImGui.TableNextColumn(); - if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), iconSize, "Delete this meta edit.", false, true ) ) - { - editor.Meta.Delete( meta ); - } + DrawMetaButtons( meta, editor, iconSize ); // Identifier ImGui.TableNextColumn(); @@ -770,4 +766,63 @@ public partial class ModEditWindow return newValue != currentValue; } + + private const byte CurrentManipulationVersion = 0; + + private static void CopyToClipboardButton( string tooltip, Vector2 iconSize, IEnumerable< MetaManipulation > manipulations ) + { + if( !ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Clipboard.ToIconString(), iconSize, tooltip, false, true ) ) + { + return; + } + + var text = Functions.ToCompressedBase64( manipulations, CurrentManipulationVersion ); + if( text.Length > 0 ) + { + ImGui.SetClipboardText( text ); + } + } + + private void AddFromClipboardButton( ) + { + if( ImGui.Button( "Add from Clipboard" ) ) + { + var clipboard = ImGui.GetClipboardText(); + var version = Functions.FromCompressedBase64< MetaManipulation[] >( clipboard, out var manips ); + if( version == CurrentManipulationVersion && manips != null) + { + foreach( var manip in manips ) + _editor!.Meta.Set( manip ); + } + } + ImGuiUtil.HoverTooltip( "Try to add meta manipulations currently stored in the clipboard to the current manipulations.\nOverwrites already existing manipulations." ); + } + + private void SetFromClipboardButton() + { + if( ImGui.Button( "Set from Clipboard" ) ) + { + var clipboard = ImGui.GetClipboardText(); + var version = Functions.FromCompressedBase64( clipboard, out var manips ); + if( version == CurrentManipulationVersion && manips != null ) + { + _editor!.Meta.Clear(); + foreach( var manip in manips ) + _editor!.Meta.Set( manip ); + } + } + ImGuiUtil.HoverTooltip( "Try to set the current meta manipulations to the set currently stored in the clipboard.\nRemoves all other manipulations." ); + } + + private static void DrawMetaButtons( MetaManipulation meta, Mod.Editor editor, Vector2 iconSize ) + { + ImGui.TableNextColumn(); + CopyToClipboardButton( "Copy this manipulation to clipboard.", iconSize, Array.Empty().Append( meta ) ); + + ImGui.TableNextColumn(); + if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), iconSize, "Delete this meta manipulation.", false, true ) ) + { + editor.Meta.Delete( meta ); + } + } } \ No newline at end of file diff --git a/Penumbra/UI/Classes/ModEditWindow.cs b/Penumbra/UI/Classes/ModEditWindow.cs index 4d919444..5f9d6be7 100644 --- a/Penumbra/UI/Classes/ModEditWindow.cs +++ b/Penumbra/UI/Classes/ModEditWindow.cs @@ -430,6 +430,12 @@ public partial class ModEditWindow : Window, IDisposable return; } + if( ImGui.Button( "Refresh" ) ) + { + _editor!.Dispose(); + _editor = new Mod.Editor( _mod! ); + } + if( _editor!.UnusedFiles.Count == 0 ) { ImGui.NewLine(); @@ -437,6 +443,7 @@ public partial class ModEditWindow : Window, IDisposable } else { + ImGui.SameLine(); if( ImGui.Button( "Add Unused Files to Default" ) ) { _editor.AddUnusedPathsToDefault();