mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Make interface code exception-resistant due to RAII, and global scale resistant.
This commit is contained in:
parent
69cb329b8f
commit
23ebaf7a0d
21 changed files with 1053 additions and 822 deletions
|
|
@ -8,13 +8,13 @@ namespace Penumbra.UI.Custom
|
|||
public static partial class ImGuiCustom
|
||||
{
|
||||
public static void BeginFramedGroup( string label )
|
||||
=> BeginFramedGroupInternal( ref label, ZeroVector, false );
|
||||
=> BeginFramedGroupInternal( ref label, Vector2.Zero, false );
|
||||
|
||||
public static void BeginFramedGroup( string label, Vector2 minSize )
|
||||
=> BeginFramedGroupInternal( ref label, minSize, false );
|
||||
|
||||
public static bool BeginFramedGroupEdit( ref string label )
|
||||
=> BeginFramedGroupInternal( ref label, ZeroVector, true );
|
||||
=> BeginFramedGroupInternal( ref label, Vector2.Zero, true );
|
||||
|
||||
public static bool BeginFramedGroupEdit( ref string label, Vector2 minSize )
|
||||
=> BeginFramedGroupInternal( ref label, minSize, true );
|
||||
|
|
@ -27,8 +27,8 @@ namespace Penumbra.UI.Custom
|
|||
|
||||
ImGui.BeginGroup(); // First group
|
||||
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.FramePadding, ZeroVector );
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, ZeroVector );
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.FramePadding, Vector2.Zero );
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
|
||||
|
||||
ImGui.BeginGroup(); // Second group
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ namespace Penumbra.UI.Custom
|
|||
}
|
||||
|
||||
// Ensure width.
|
||||
ImGui.Dummy( new Vector2( effectiveSize.X, 0 ) );
|
||||
ImGui.Dummy( Vector2.UnitX * effectiveSize.X );
|
||||
// Ensure left half boundary width/distance.
|
||||
ImGui.Dummy( halfFrameHeight );
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ namespace Penumbra.UI.Custom
|
|||
var labelMax = ImGui.GetItemRectMax();
|
||||
ImGui.SameLine();
|
||||
// Ensure height and distance to label.
|
||||
ImGui.Dummy( new Vector2( 0, frameHeight + itemSpacing.Y ) );
|
||||
ImGui.Dummy( Vector2.UnitX * ( frameHeight + itemSpacing.Y ) );
|
||||
|
||||
ImGui.BeginGroup(); // Fourth Group.
|
||||
|
||||
|
|
@ -96,8 +96,8 @@ namespace Penumbra.UI.Custom
|
|||
|
||||
ImGui.PopItemWidth();
|
||||
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.FramePadding, ZeroVector );
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, ZeroVector );
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.FramePadding, Vector2.Zero );
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
|
||||
|
||||
ImGui.EndGroup(); // Close fourth group
|
||||
ImGui.EndGroup(); // Close third group
|
||||
|
|
@ -106,19 +106,19 @@ namespace Penumbra.UI.Custom
|
|||
// Ensure right distance.
|
||||
ImGui.Dummy( halfFrameHeight );
|
||||
// Ensure bottom distance
|
||||
ImGui.Dummy( new Vector2( 0, frameHeight / 2 - itemSpacing.Y ) );
|
||||
ImGui.Dummy( Vector2.UnitX * ( frameHeight / 2 - itemSpacing.Y ) );
|
||||
ImGui.EndGroup(); // Close second group
|
||||
|
||||
var itemMin = ImGui.GetItemRectMin();
|
||||
var itemMax = ImGui.GetItemRectMax();
|
||||
var (currentLabelMin, currentLabelMax) = LabelStack[ LabelStack.Count - 1 ];
|
||||
var (currentLabelMin, currentLabelMax) = LabelStack[ ^1 ];
|
||||
LabelStack.RemoveAt( LabelStack.Count - 1 );
|
||||
|
||||
var halfFrame = new Vector2( frameHeight / 8, frameHeight / 2 );
|
||||
currentLabelMin.X -= itemSpacing.X;
|
||||
currentLabelMax.X += itemSpacing.X;
|
||||
var frameMin = itemMin + halfFrame;
|
||||
var frameMax = itemMax - new Vector2( halfFrame.X, 0 );
|
||||
var frameMax = itemMax - Vector2.UnitX * halfFrame.X;
|
||||
|
||||
// Left
|
||||
DrawClippedRect( new Vector2( -float.MaxValue, -float.MaxValue ), new Vector2( currentLabelMin.X, float.MaxValue ), frameMin,
|
||||
|
|
@ -136,13 +136,11 @@ namespace Penumbra.UI.Custom
|
|||
ImGui.PopStyleVar( 2 );
|
||||
// This seems wrong?
|
||||
// ImGui.SetWindowSize( new Vector2( ImGui.GetWindowSize().X + frameHeight, ImGui.GetWindowSize().Y ) );
|
||||
ImGui.Dummy( ZeroVector );
|
||||
ImGui.Dummy( Vector2.Zero );
|
||||
|
||||
ImGui.EndGroup(); // Close first group
|
||||
}
|
||||
|
||||
private static readonly Vector2 ZeroVector = new( 0, 0 );
|
||||
|
||||
private static readonly List< (Vector2, Vector2) > LabelStack = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Windows.Forms;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Penumbra.UI.Custom
|
||||
|
|
@ -23,7 +25,7 @@ namespace Penumbra.UI.Custom
|
|||
{
|
||||
public static void VerticalDistance( float distance )
|
||||
{
|
||||
ImGui.SetCursorPosY( ImGui.GetCursorPosY() + distance );
|
||||
ImGui.SetCursorPosY( ImGui.GetCursorPosY() + distance * ImGuiHelpers.GlobalScale );
|
||||
}
|
||||
|
||||
public static void RightJustifiedText( float pos, string text )
|
||||
|
|
@ -39,4 +41,25 @@ namespace Penumbra.UI.Custom
|
|||
ImGui.SameLine( pos );
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class ImGuiCustom
|
||||
{
|
||||
public static void HoverTooltip( string text )
|
||||
{
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( text );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class ImGuiCustom
|
||||
{
|
||||
public static void PrintIcon( FontAwesomeIcon icon )
|
||||
{
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
ImGui.TextUnformatted( icon.ToIconString() );
|
||||
ImGui.PopFont();
|
||||
}
|
||||
}
|
||||
}
|
||||
52
Penumbra/UI/Custom/Raii/Color.cs
Normal file
52
Penumbra/UI/Custom/Raii/Color.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Penumbra.UI.Custom
|
||||
{
|
||||
public static partial class ImGuiRaii
|
||||
{
|
||||
public static Color PushColor( ImGuiCol idx, uint color, bool condition = true )
|
||||
=> new Color().Push( idx, color, condition );
|
||||
|
||||
public static Color PushColor( ImGuiCol idx, Vector4 color, bool condition = true )
|
||||
=> new Color().Push( idx, color, condition );
|
||||
|
||||
public class Color : IDisposable
|
||||
{
|
||||
private int _count;
|
||||
|
||||
public Color Push( ImGuiCol idx, uint color, bool condition = true )
|
||||
{
|
||||
if( condition )
|
||||
{
|
||||
ImGui.PushStyleColor( idx, color );
|
||||
++_count;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Color Push( ImGuiCol idx, Vector4 color, bool condition = true )
|
||||
{
|
||||
if( condition )
|
||||
{
|
||||
ImGui.PushStyleColor( idx, color );
|
||||
++_count;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Pop( int num = 1 )
|
||||
{
|
||||
num = Math.Min( num, _count );
|
||||
_count -= num;
|
||||
ImGui.PopStyleColor( num );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> Pop( _count );
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Penumbra/UI/Custom/Raii/EndStack.cs
Normal file
40
Penumbra/UI/Custom/Raii/EndStack.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Penumbra.UI.Custom
|
||||
{
|
||||
public static partial class ImGuiRaii
|
||||
{
|
||||
public static EndStack DeferredEnd( Action a, bool condition = true )
|
||||
=> new EndStack().Push( a, condition );
|
||||
|
||||
public class EndStack : IDisposable
|
||||
{
|
||||
private readonly Stack< Action > _cleanActions = new();
|
||||
|
||||
public EndStack Push( Action a, bool condition = true )
|
||||
{
|
||||
if( condition )
|
||||
{
|
||||
_cleanActions.Push( a );
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public EndStack Pop( int num = 1 )
|
||||
{
|
||||
while( num-- > 0 && _cleanActions.TryPop( out var action ) )
|
||||
{
|
||||
action.Invoke();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> Pop( _cleanActions.Count );
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Penumbra/UI/Custom/Raii/Font.cs
Normal file
39
Penumbra/UI/Custom/Raii/Font.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Penumbra.UI.Custom
|
||||
{
|
||||
public static partial class ImGuiRaii
|
||||
{
|
||||
public static Font PushFont( ImFontPtr font )
|
||||
=> new( font );
|
||||
|
||||
public class Font : IDisposable
|
||||
{
|
||||
private int _count;
|
||||
|
||||
public Font( ImFontPtr font )
|
||||
=> Push( font );
|
||||
|
||||
public Font Push( ImFontPtr font )
|
||||
{
|
||||
ImGui.PushFont( font );
|
||||
++_count;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Pop( int num = 1 )
|
||||
{
|
||||
num = Math.Min( num, _count );
|
||||
_count -= num;
|
||||
while( num-- > 0 )
|
||||
{
|
||||
ImGui.PopFont();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> Pop( _count );
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Penumbra/UI/Custom/Raii/Indent.cs
Normal file
72
Penumbra/UI/Custom/Raii/Indent.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Penumbra.UI.Custom
|
||||
{
|
||||
public static partial class ImGuiRaii
|
||||
{
|
||||
public static Indent PushIndent( float f, bool scaled = true, bool condition = true )
|
||||
=> new Indent().Push( f, condition );
|
||||
|
||||
public static Indent PushIndent( int i = 1, bool scaled = true, bool condition = true )
|
||||
=> new Indent().Push( i, condition );
|
||||
|
||||
public class Indent : IDisposable
|
||||
{
|
||||
private float _indentation;
|
||||
|
||||
public Indent Push( float indent, bool scaled = true, bool condition = true )
|
||||
{
|
||||
Debug.Assert( indent >= 0f );
|
||||
if( condition )
|
||||
{
|
||||
if( scaled )
|
||||
{
|
||||
indent *= ImGuiHelpers.GlobalScale;
|
||||
}
|
||||
|
||||
ImGui.Indent( indent );
|
||||
_indentation += indent;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Indent Push( uint i = 1, bool scaled = true, bool condition = true )
|
||||
{
|
||||
if( condition )
|
||||
{
|
||||
var spacing = i * ImGui.GetStyle().IndentSpacing * ( scaled ? ImGuiHelpers.GlobalScale : 1f );
|
||||
ImGui.Indent( spacing );
|
||||
_indentation += spacing;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Pop( float indent, bool scaled = true )
|
||||
{
|
||||
if( scaled )
|
||||
{
|
||||
indent *= ImGuiHelpers.GlobalScale;
|
||||
}
|
||||
|
||||
Debug.Assert( indent >= 0f );
|
||||
ImGui.Unindent( indent );
|
||||
_indentation -= indent;
|
||||
}
|
||||
|
||||
public void Pop( uint i, bool scaled = true )
|
||||
{
|
||||
var spacing = i * ImGui.GetStyle().IndentSpacing * ( scaled ? ImGuiHelpers.GlobalScale : 1f );
|
||||
ImGui.Unindent( spacing );
|
||||
_indentation += spacing;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> Pop( _indentation, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
92
Penumbra/UI/Custom/Raii/Style.cs
Normal file
92
Penumbra/UI/Custom/Raii/Style.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Penumbra.UI.Custom
|
||||
{
|
||||
public static partial class ImGuiRaii
|
||||
{
|
||||
public static Style PushStyle( ImGuiStyleVar idx, float value, bool condition = true )
|
||||
=> new Style().Push( idx, value, condition );
|
||||
|
||||
public static Style PushStyle( ImGuiStyleVar idx, Vector2 value, bool condition = true )
|
||||
=> new Style().Push( idx, value, condition );
|
||||
|
||||
public class Style : IDisposable
|
||||
{
|
||||
private int _count;
|
||||
|
||||
[System.Diagnostics.Conditional( "DEBUG" )]
|
||||
private static void CheckStyleIdx( ImGuiStyleVar idx, Type type )
|
||||
{
|
||||
var shouldThrow = idx switch
|
||||
{
|
||||
ImGuiStyleVar.Alpha => type != typeof( float ),
|
||||
ImGuiStyleVar.WindowPadding => type != typeof( Vector2 ),
|
||||
ImGuiStyleVar.WindowRounding => type != typeof( float ),
|
||||
ImGuiStyleVar.WindowBorderSize => type != typeof( float ),
|
||||
ImGuiStyleVar.WindowMinSize => type != typeof( Vector2 ),
|
||||
ImGuiStyleVar.WindowTitleAlign => type != typeof( Vector2 ),
|
||||
ImGuiStyleVar.ChildRounding => type != typeof( float ),
|
||||
ImGuiStyleVar.ChildBorderSize => type != typeof( float ),
|
||||
ImGuiStyleVar.PopupRounding => type != typeof( float ),
|
||||
ImGuiStyleVar.PopupBorderSize => type != typeof( float ),
|
||||
ImGuiStyleVar.FramePadding => type != typeof( Vector2 ),
|
||||
ImGuiStyleVar.FrameRounding => type != typeof( float ),
|
||||
ImGuiStyleVar.FrameBorderSize => type != typeof( float ),
|
||||
ImGuiStyleVar.ItemSpacing => type != typeof( Vector2 ),
|
||||
ImGuiStyleVar.ItemInnerSpacing => type != typeof( Vector2 ),
|
||||
ImGuiStyleVar.IndentSpacing => type != typeof( float ),
|
||||
ImGuiStyleVar.CellPadding => type != typeof( Vector2 ),
|
||||
ImGuiStyleVar.ScrollbarSize => type != typeof( float ),
|
||||
ImGuiStyleVar.ScrollbarRounding => type != typeof( float ),
|
||||
ImGuiStyleVar.GrabMinSize => type != typeof( float ),
|
||||
ImGuiStyleVar.GrabRounding => type != typeof( float ),
|
||||
ImGuiStyleVar.TabRounding => type != typeof( float ),
|
||||
ImGuiStyleVar.ButtonTextAlign => type != typeof( Vector2 ),
|
||||
ImGuiStyleVar.SelectableTextAlign => type != typeof( Vector2 ),
|
||||
_ => throw new ArgumentOutOfRangeException( nameof( idx ), idx, null ),
|
||||
};
|
||||
|
||||
if( shouldThrow )
|
||||
{
|
||||
throw new ArgumentException( $"Unable to push {type} to {idx}." );
|
||||
}
|
||||
}
|
||||
|
||||
public Style Push( ImGuiStyleVar idx, float value, bool condition = true )
|
||||
{
|
||||
if( condition )
|
||||
{
|
||||
CheckStyleIdx( idx, typeof( float ) );
|
||||
ImGui.PushStyleVar( idx, value );
|
||||
++_count;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Style Push( ImGuiStyleVar idx, Vector2 value, bool condition = true )
|
||||
{
|
||||
if( condition )
|
||||
{
|
||||
CheckStyleIdx( idx, typeof( Vector2 ) );
|
||||
ImGui.PushStyleVar( idx, value );
|
||||
++_count;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Pop( int num = 1 )
|
||||
{
|
||||
num = Math.Min( num, _count );
|
||||
_count -= num;
|
||||
ImGui.PopStyleVar( num );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> Pop( _count );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using ImGuiNET;
|
||||
using Penumbra.UI.Custom;
|
||||
|
||||
namespace Penumbra.UI
|
||||
{
|
||||
|
|
@ -30,28 +31,30 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
if( ImGui.BeginMenu( MenuLabel ) )
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndMainMenuBar );
|
||||
|
||||
if( !ImGui.BeginMenu( MenuLabel ) )
|
||||
{
|
||||
if( ImGui.MenuItem( MenuItemToggle, SlashCommand, _base._menu.Visible ) )
|
||||
{
|
||||
_base.FlipVisibility();
|
||||
}
|
||||
|
||||
if( ImGui.MenuItem( MenuItemRediscover ) )
|
||||
{
|
||||
_base.ReloadMods();
|
||||
}
|
||||
#if DEBUG
|
||||
if( ImGui.MenuItem( MenuItemHide ) )
|
||||
{
|
||||
_showDebugBar = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGui.EndMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.EndMainMenuBar();
|
||||
raii.Push( ImGui.EndMenu );
|
||||
|
||||
if( ImGui.MenuItem( MenuItemToggle, SlashCommand, _base._menu.Visible ) )
|
||||
{
|
||||
_base.FlipVisibility();
|
||||
}
|
||||
|
||||
if( ImGui.MenuItem( MenuItemRediscover ) )
|
||||
{
|
||||
_base.ReloadMods();
|
||||
}
|
||||
#if DEBUG
|
||||
if( ImGui.MenuItem( MenuItemHide ) )
|
||||
{
|
||||
_showDebugBar = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Dalamud.Logging;
|
|||
using ImGuiNET;
|
||||
using Penumbra.Mod;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -97,12 +98,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
ImGui.InputTextWithHint( "##New Collection", "New Collection", ref _newCollectionName, 64 );
|
||||
|
||||
var changedStyle = false;
|
||||
if( _newCollectionName.Length == 0 )
|
||||
{
|
||||
changedStyle = true;
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.Alpha, 0.5f );
|
||||
}
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f, _newCollectionName.Length == 0 );
|
||||
|
||||
if( ImGui.Button( "Create New Empty Collection" ) && _newCollectionName.Length > 0 )
|
||||
{
|
||||
|
|
@ -115,10 +111,7 @@ namespace Penumbra.UI
|
|||
CreateNewCollection( _manager.Collections.CurrentCollection.Settings );
|
||||
}
|
||||
|
||||
if( changedStyle )
|
||||
{
|
||||
ImGui.PopStyleVar();
|
||||
}
|
||||
style.Pop();
|
||||
|
||||
if( _manager.Collections.Collections.Count > 1
|
||||
&& _manager.Collections.CurrentCollection.Name != ModCollection.DefaultCollection )
|
||||
|
|
@ -161,11 +154,8 @@ namespace Penumbra.UI
|
|||
{
|
||||
var index = _currentCollectionIndex;
|
||||
var combo = ImGui.Combo( LabelCurrentCollection, ref index, _collectionNames );
|
||||
if( tooltip && ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"This collection will be modified when using the Installed Mods tab and making changes. It does not apply to anything by itself." );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"This collection will be modified when using the Installed Mods tab and making changes. It does not apply to anything by itself." );
|
||||
|
||||
if( combo )
|
||||
{
|
||||
|
|
@ -182,15 +172,12 @@ namespace Penumbra.UI
|
|||
_currentDefaultIndex = index;
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"Mods in the default collection are loaded for any character that is not explicitly named in the character collections below.\n"
|
||||
+ "They also take precedence before the forced collection." );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"Mods in the default collection are loaded for any character that is not explicitly named in the character collections below.\n"
|
||||
+ "They also take precedence before the forced collection." );
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Dummy( new Vector2( 24, 0 ) );
|
||||
ImGuiHelpers.ScaledDummy( 24, 0 );
|
||||
ImGui.SameLine();
|
||||
ImGui.Text( "Default Collection" );
|
||||
}
|
||||
|
|
@ -204,15 +191,12 @@ namespace Penumbra.UI
|
|||
_currentForcedIndex = index;
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"Mods in the forced collection are always loaded if not overwritten by anything in the current or character-based collection.\n"
|
||||
+ "Please avoid mixing meta-manipulating mods in Forced and other collections, as this will probably not work correctly." );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"Mods in the forced collection are always loaded if not overwritten by anything in the current or character-based collection.\n"
|
||||
+ "Please avoid mixing meta-manipulating mods in Forced and other collections, as this will probably not work correctly." );
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Dummy( new Vector2( 24, 0 ) );
|
||||
ImGuiHelpers.ScaledDummy( 24, 0 );
|
||||
ImGui.SameLine();
|
||||
ImGui.Text( "Forced Collection" );
|
||||
}
|
||||
|
|
@ -221,12 +205,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
ImGui.InputTextWithHint( "##New Character", "New Character Name", ref _newCharacterName, 32 );
|
||||
|
||||
var changedStyle = false;
|
||||
if( _newCharacterName.Length == 0 )
|
||||
{
|
||||
changedStyle = true;
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.Alpha, 0.5f );
|
||||
}
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f, _newCharacterName.Length == 0 );
|
||||
|
||||
ImGui.SameLine();
|
||||
if( ImGui.Button( "Create New Character Collection" ) && _newCharacterName.Length > 0 )
|
||||
|
|
@ -236,25 +215,19 @@ namespace Penumbra.UI
|
|||
_newCharacterName = string.Empty;
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"A character collection will be used whenever you manually redraw a character with the Name you have set up.\n"
|
||||
+ "If you enable automatic character redraws in the Settings tab, penumbra will try to use Character collections for corresponding characters automatically.\n" );
|
||||
}
|
||||
style.Pop();
|
||||
|
||||
if( changedStyle )
|
||||
{
|
||||
ImGui.PopStyleVar();
|
||||
}
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"A character collection will be used whenever you manually redraw a character with the Name you have set up.\n"
|
||||
+ "If you enable automatic character redraws in the Settings tab, penumbra will try to use Character collections for corresponding characters automatically.\n" );
|
||||
}
|
||||
|
||||
|
||||
private void DrawCharacterCollectionSelectors()
|
||||
{
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndChild );
|
||||
if( !ImGui.BeginChild( "##CollectionChild", AutoFillSize, true ) )
|
||||
{
|
||||
ImGui.EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -272,21 +245,20 @@ namespace Penumbra.UI
|
|||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
|
||||
using var font = ImGuiRaii.PushFont( UiBuilder.IconFont );
|
||||
if( ImGui.Button( $"{FontAwesomeIcon.Trash.ToIconString()}##{name}" ) )
|
||||
{
|
||||
_manager.Collections.RemoveCharacterCollection( name );
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
font.Pop();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text( name );
|
||||
}
|
||||
|
||||
DrawNewCharacterCollection();
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
|
|
@ -296,19 +268,20 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem )
|
||||
.Push( ImGui.EndChild );
|
||||
|
||||
if( ImGui.BeginChild( "##CollectionHandling", new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 6 ), true ) )
|
||||
{
|
||||
DrawCurrentCollectionSelector( true );
|
||||
|
||||
ImGui.Dummy( new Vector2( 0, 10 ) );
|
||||
ImGuiHelpers.ScaledDummy( 0, 10 );
|
||||
DrawNewCollectionInput();
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
raii.Pop();
|
||||
|
||||
DrawCharacterCollectionSelectors();
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using Penumbra.GameData.Util;
|
|||
using Penumbra.Interop;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -38,6 +39,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
|
||||
var identifier = GameData.GameData.GetIdentifier();
|
||||
|
||||
foreach( var (actor, equip) in players )
|
||||
|
|
@ -109,8 +112,6 @@ namespace Penumbra.UI
|
|||
ImGui.Text( identifier.Identify( equip.RFinger.Set, 0, equip.RFinger.Variant, EquipSlot.LFinger )?.Name.ToString() ?? "Unknown" );
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
private static void PrintValue( string name, string value )
|
||||
|
|
@ -135,6 +136,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
|
||||
var manager = Service< ModManager >.Get();
|
||||
PrintValue( "Active Collection", manager.Collections.ActiveCollection.Name );
|
||||
PrintValue( "Mod Manager BasePath", manager.BasePath.Name );
|
||||
|
|
@ -147,8 +150,6 @@ namespace Penumbra.UI
|
|||
( !Penumbra.Config.TempDirectory.Any() || Path.IsPathRooted( Penumbra.Config.TempDirectory ) ).ToString() );
|
||||
PrintValue( "Mod Manager Temp Path Exists", Directory.Exists( manager.TempPath.FullName ).ToString() );
|
||||
PrintValue( "Mod Manager Temp Path IsWritable", manager.TempWritable.ToString() );
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
private void DrawDebugTabRedraw()
|
||||
|
|
@ -207,9 +208,11 @@ namespace Penumbra.UI
|
|||
.GetField( "_inGPose", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||
?.GetValue( _penumbra.ObjectReloader );
|
||||
|
||||
using var raii = new ImGuiRaii.EndStack();
|
||||
if( ImGui.BeginTable( "##RedrawData", 2, ImGuiTableFlags.SizingFixedFit,
|
||||
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 7 ) ) )
|
||||
{
|
||||
raii.Push( ImGui.EndTable );
|
||||
PrintValue( "Current Wait Frame", waitFrames?.ToString() ?? "null" );
|
||||
PrintValue( "Current Frame", currentFrame?.ToString() ?? "null" );
|
||||
PrintValue( "Currently in GPose", gPose?.ToString() ?? "null" );
|
||||
|
|
@ -222,13 +225,13 @@ namespace Penumbra.UI
|
|||
PrintValue( "Current Object Address", currentObject?.Address.ToString( "X16" ) ?? "null" );
|
||||
PrintValue( "Current Object Index", currentObjectIdx >= 0 ? currentObjectIdx.ToString() : "null" );
|
||||
PrintValue( "Current Object Render Flags", ( ( int? )currentRender )?.ToString( "X8" ) ?? "null" );
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
if( queue.Any()
|
||||
&& ImGui.BeginTable( "##RedrawTable", 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX,
|
||||
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * queue.Count ) ) )
|
||||
{
|
||||
raii.Push( ImGui.EndTable );
|
||||
foreach( var (objectId, objectName, redraw) in queue )
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
|
|
@ -239,8 +242,6 @@ namespace Penumbra.UI
|
|||
ImGui.TableNextColumn();
|
||||
ImGui.Text( redraw.ToString() );
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
if( queue.Any() && ImGui.Button( "Clear" ) )
|
||||
|
|
@ -263,6 +264,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
|
||||
foreach( var collection in Service< ModManager >.Get().Collections.Collections.Values.Where( c => c.Cache != null ) )
|
||||
{
|
||||
var manip = collection.Cache!.MetaManipulations;
|
||||
|
|
@ -285,39 +288,58 @@ namespace Penumbra.UI
|
|||
ImGui.Text( info.Changed ? "Data Changed" : "Unchanged" );
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
private void DrawDebugTabIpc()
|
||||
{
|
||||
|
||||
if( !ImGui.CollapsingHeader( "IPC##Debug" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ipc = _penumbra.Ipc;
|
||||
ImGui.Text($"API Version: {ipc.Api.ApiVersion}" );
|
||||
ImGui.Text("Available subscriptions:" );
|
||||
ImGui.Indent();
|
||||
if (ipc.ProviderApiVersion != null)
|
||||
ImGui.Text( $"API Version: {ipc.Api.ApiVersion}" );
|
||||
ImGui.Text( "Available subscriptions:" );
|
||||
using var indent = ImGuiRaii.PushIndent();
|
||||
if( ipc.ProviderApiVersion != null )
|
||||
{
|
||||
ImGui.Text( PenumbraIpc.LabelProviderApiVersion );
|
||||
}
|
||||
|
||||
if( ipc.ProviderRedrawName != null )
|
||||
{
|
||||
ImGui.Text( PenumbraIpc.LabelProviderRedrawName );
|
||||
}
|
||||
|
||||
if( ipc.ProviderRedrawObject != null )
|
||||
{
|
||||
ImGui.Text( PenumbraIpc.LabelProviderRedrawObject );
|
||||
}
|
||||
|
||||
if( ipc.ProviderRedrawAll != null )
|
||||
{
|
||||
ImGui.Text( PenumbraIpc.LabelProviderRedrawAll );
|
||||
}
|
||||
|
||||
if( ipc.ProviderResolveDefault != null )
|
||||
{
|
||||
ImGui.Text( PenumbraIpc.LabelProviderResolveDefault );
|
||||
}
|
||||
|
||||
if( ipc.ProviderResolveCharacter != null )
|
||||
{
|
||||
ImGui.Text( PenumbraIpc.LabelProviderResolveCharacter );
|
||||
}
|
||||
|
||||
if( ipc.ProviderChangedItemTooltip != null )
|
||||
{
|
||||
ImGui.Text( PenumbraIpc.LabelProviderChangedItemTooltip );
|
||||
}
|
||||
|
||||
if( ipc.ProviderChangedItemClick != null )
|
||||
{
|
||||
ImGui.Text( PenumbraIpc.LabelProviderChangedItemClick );
|
||||
ImGui.Unindent();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawDebugTab()
|
||||
|
|
@ -327,6 +349,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
DrawDebugTabGeneral();
|
||||
ImGui.NewLine();
|
||||
DrawDebugTabRedraw();
|
||||
|
|
@ -337,8 +361,6 @@ namespace Penumbra.UI
|
|||
ImGui.NewLine();
|
||||
DrawDebugTabIpc();
|
||||
ImGui.NewLine();
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using ImGuiNET;
|
|||
using Penumbra.GameData.Util;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -13,9 +14,8 @@ namespace Penumbra.UI
|
|||
{
|
||||
private class TabEffective
|
||||
{
|
||||
private const string LabelTab = "Effective Changes";
|
||||
private static readonly string LongArrowLeft = $"{( char )FontAwesomeIcon.LongArrowAltLeft}";
|
||||
private readonly ModManager _modManager;
|
||||
private const string LabelTab = "Effective Changes";
|
||||
private readonly ModManager _modManager;
|
||||
|
||||
private readonly float _leftTextLength =
|
||||
ImGui.CalcTextSize( "chara/human/c0000/obj/body/b0000/material/v0000/mt_c0000b0000_b.mtrl" ).X + 40;
|
||||
|
|
@ -27,14 +27,12 @@ namespace Penumbra.UI
|
|||
private static void DrawFileLine( FileInfo file, GamePath path )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
Custom.ImGuiCustom.CopyOnClickSelectable( path );
|
||||
ImGuiCustom.CopyOnClickSelectable( path );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
ImGui.TextUnformatted( LongArrowLeft );
|
||||
ImGui.PopFont();
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltLeft );
|
||||
ImGui.SameLine();
|
||||
Custom.ImGuiCustom.CopyOnClickSelectable( file.FullName );
|
||||
ImGuiCustom.CopyOnClickSelectable( file.FullName );
|
||||
}
|
||||
|
||||
private static void DrawManipulationLine( MetaManipulation manip, Mod.Mod mod )
|
||||
|
|
@ -43,9 +41,7 @@ namespace Penumbra.UI
|
|||
ImGui.Selectable( manip.IdentifierString() );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
ImGui.TextUnformatted( LongArrowLeft );
|
||||
ImGui.PopFont();
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltLeft );
|
||||
ImGui.SameLine();
|
||||
ImGui.Selectable( mod.Data.Meta.Name );
|
||||
}
|
||||
|
|
@ -57,17 +53,19 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
const ImGuiTableFlags flags = ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollX;
|
||||
|
||||
var activeCollection = _modManager.Collections.ActiveCollection.Cache;
|
||||
var forcedCollection = _modManager.Collections.ForcedCollection.Cache;
|
||||
var activeCollection = _modManager.Collections.ActiveCollection.Cache;
|
||||
var forcedCollection = _modManager.Collections.ForcedCollection.Cache;
|
||||
|
||||
var (activeResolved, activeMeta) = activeCollection != null
|
||||
? ( activeCollection.ResolvedFiles.Count, activeCollection.MetaManipulations.Count )
|
||||
: ( 0, 0 );
|
||||
var (forcedResolved, forcedMeta) = forcedCollection != null
|
||||
? (forcedCollection.ResolvedFiles.Count, forcedCollection.MetaManipulations.Count)
|
||||
: (0, 0);
|
||||
? ( forcedCollection.ResolvedFiles.Count, forcedCollection.MetaManipulations.Count )
|
||||
: ( 0, 0 );
|
||||
|
||||
var lines = activeResolved + forcedResolved + activeMeta + forcedMeta;
|
||||
ImGuiListClipperPtr clipper;
|
||||
|
|
@ -80,6 +78,7 @@ namespace Penumbra.UI
|
|||
|
||||
if( ImGui.BeginTable( "##effective_changes", 2, flags, AutoFillSize ) )
|
||||
{
|
||||
raii.Push( ImGui.EndTable );
|
||||
ImGui.TableSetupColumn( "##tableGamePathCol", ImGuiTableColumnFlags.None, _leftTextLength );
|
||||
while( clipper.Step() )
|
||||
{
|
||||
|
|
@ -89,32 +88,28 @@ namespace Penumbra.UI
|
|||
ImGui.TableNextRow();
|
||||
if( row < activeResolved )
|
||||
{
|
||||
var file = activeCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawFileLine( file.Value, file.Key );
|
||||
var (gamePath, file) = activeCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawFileLine( file, gamePath );
|
||||
}
|
||||
else if( ( row -= activeResolved ) < forcedResolved )
|
||||
{
|
||||
var file = forcedCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawFileLine( file.Value, file.Key );
|
||||
var (gamePath, file) = forcedCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawFileLine( file, gamePath );
|
||||
}
|
||||
else if( ( row -= forcedResolved ) < activeMeta )
|
||||
{
|
||||
var manip = activeCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawManipulationLine( manip.Item1, manip.Item2 );
|
||||
var (manip, mod) = activeCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawManipulationLine( manip, mod );
|
||||
}
|
||||
else
|
||||
{
|
||||
row -= activeMeta;
|
||||
var manip = forcedCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawManipulationLine( manip.Item1, manip.Item2 );
|
||||
row -= activeMeta;
|
||||
var (manip, mod) = forcedCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawManipulationLine( manip, mod );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Dalamud.Logging;
|
|||
using ImGuiNET;
|
||||
using Penumbra.Importer;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -104,20 +105,20 @@ namespace Penumbra.UI
|
|||
{
|
||||
if( !_manager.Valid )
|
||||
{
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.Alpha, 0.5f );
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f );
|
||||
ImGui.Button( LabelImportButton );
|
||||
ImGui.PopStyleVar();
|
||||
style.Pop();
|
||||
|
||||
ImGui.PushStyleColor( ImGuiCol.Text, ColorRed );
|
||||
using var color = ImGuiRaii.PushColor( ImGuiCol.Text, ColorRed );
|
||||
ImGui.Text( "Can not import since the mod directory path is not valid." );
|
||||
ImGui.Dummy( Vector2.UnitY * ImGui.GetTextLineHeightWithSpacing() );
|
||||
ImGui.PopStyleColor();
|
||||
color.Pop();
|
||||
|
||||
ImGui.Text( "Please set the mod directory in the settings tab." );
|
||||
ImGui.Text( "This folder should preferably be close to the root directory of your (preferably SSD) drive, for example" );
|
||||
ImGui.PushStyleColor( ImGuiCol.Text, ColorYellow );
|
||||
color.Push( ImGuiCol.Text, ColorYellow );
|
||||
ImGui.Text( " D:\\ffxivmods" );
|
||||
ImGui.PopStyleColor();
|
||||
color.Pop();
|
||||
ImGui.Text( "You can return to this tab once you've done that." );
|
||||
}
|
||||
else if( ImGui.Button( LabelImportButton ) )
|
||||
|
|
@ -156,19 +157,19 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawFailedImportMessage()
|
||||
{
|
||||
ImGui.PushStyleColor( ImGuiCol.Text, ColorRed );
|
||||
using var color = ImGuiRaii.PushColor( ImGuiCol.Text, ColorRed );
|
||||
ImGui.Text( $"One or more of your modpacks failed to import:\n\t\t{_errorMessage}" );
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
var ret = ImGui.BeginTabItem( LabelTab );
|
||||
if( !ret )
|
||||
if( !ImGui.BeginTabItem( LabelTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
if( !_isImportRunning )
|
||||
{
|
||||
DrawImportButton();
|
||||
|
|
@ -182,8 +183,6 @@ namespace Penumbra.UI
|
|||
{
|
||||
DrawFailedImportMessage();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using ImGuiNET;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -34,6 +35,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
if( _modManager.Mods.Count > 0 )
|
||||
{
|
||||
Selector.Draw();
|
||||
|
|
@ -44,8 +47,6 @@ namespace Penumbra.UI
|
|||
{
|
||||
DrawNoModsAvailable();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,15 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Util;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Mod;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Structs;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
using ImGui = ImGuiNET.ImGui;
|
||||
|
||||
namespace Penumbra.UI
|
||||
{
|
||||
|
|
@ -140,6 +141,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
var desc = Meta.Description;
|
||||
var flags = _editMode
|
||||
? ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.CtrlEnterForNewLine
|
||||
|
|
@ -154,17 +157,12 @@ namespace Penumbra.UI
|
|||
_selector.SaveCurrentMod();
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipAboutEdit );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipAboutEdit );
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextWrapped( desc );
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
private void DrawChangedItemsTab()
|
||||
|
|
@ -174,31 +172,33 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
if( ImGui.BeginListBox( LabelChangedItemsHeader, AutoFillSize ) )
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
if( !ImGui.BeginListBox( LabelChangedItemsHeader, AutoFillSize ) )
|
||||
{
|
||||
foreach( var item in Mod.Data.ChangedItems )
|
||||
{
|
||||
var ret = ImGui.Selectable( item.Key ) ? MouseButton.Left : MouseButton.None;
|
||||
ret = ImGui.IsItemClicked( ImGuiMouseButton.Right ) ? MouseButton.Right : ret;
|
||||
ret = ImGui.IsItemClicked( ImGuiMouseButton.Middle ) ? MouseButton.Middle : ret;
|
||||
|
||||
if( ret != MouseButton.None )
|
||||
{
|
||||
_base._penumbra.Api.InvokeClick( ret, item.Value );
|
||||
}
|
||||
|
||||
if( _base._penumbra.Api.HasTooltip && ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
_base._penumbra.Api.InvokeTooltip( item.Value );
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndListBox();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
raii.Push( ImGui.EndListBox );
|
||||
foreach( var (name, data) in Mod.Data.ChangedItems )
|
||||
{
|
||||
var ret = ImGui.Selectable( name ) ? MouseButton.Left : MouseButton.None;
|
||||
ret = ImGui.IsItemClicked( ImGuiMouseButton.Right ) ? MouseButton.Right : ret;
|
||||
ret = ImGui.IsItemClicked( ImGuiMouseButton.Middle ) ? MouseButton.Middle : ret;
|
||||
|
||||
if( ret != MouseButton.None )
|
||||
{
|
||||
_base._penumbra.Api.InvokeClick( ret, data );
|
||||
}
|
||||
|
||||
if( _base._penumbra.Api.HasTooltip && ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
raii.Push( ImGui.EndTooltip );
|
||||
_base._penumbra.Api.InvokeTooltip( data );
|
||||
raii.Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawConflictTab()
|
||||
|
|
@ -208,38 +208,39 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.BeginListBox( LabelConflictsHeader, AutoFillSize ) )
|
||||
if( !ImGui.BeginListBox( LabelConflictsHeader, AutoFillSize ) )
|
||||
{
|
||||
foreach( var kv in Mod.Cache.Conflicts )
|
||||
{
|
||||
var mod = kv.Key;
|
||||
if( ImGui.Selectable( mod.Data.Meta.Name ) )
|
||||
{
|
||||
_selector.SelectModByDir( mod.Data.BasePath.Name );
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text( $"(Priority {mod.Settings.Priority})" );
|
||||
|
||||
ImGui.Indent( 15 );
|
||||
foreach( var file in kv.Value.Files )
|
||||
{
|
||||
ImGui.Selectable( file );
|
||||
}
|
||||
|
||||
foreach( var manip in kv.Value.Manipulations )
|
||||
{
|
||||
ImGui.Text( manip.IdentifierString() );
|
||||
}
|
||||
|
||||
ImGui.Unindent( 15 );
|
||||
}
|
||||
|
||||
ImGui.EndListBox();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
raii.Push( ImGui.EndListBox );
|
||||
using var indent = ImGuiRaii.PushIndent( 0 );
|
||||
foreach( var (mod, (files, manipulations)) in Mod.Cache.Conflicts )
|
||||
{
|
||||
if( ImGui.Selectable( mod.Data.Meta.Name ) )
|
||||
{
|
||||
_selector.SelectModByDir( mod.Data.BasePath.Name );
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text( $"(Priority {mod.Settings.Priority})" );
|
||||
|
||||
indent.Push( 15f );
|
||||
foreach( var file in files )
|
||||
{
|
||||
ImGui.Selectable( file );
|
||||
}
|
||||
|
||||
foreach( var manip in manipulations )
|
||||
{
|
||||
ImGui.Text( manip.IdentifierString() );
|
||||
}
|
||||
|
||||
indent.Pop( 15f );
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawFileSwapTab()
|
||||
|
|
@ -255,31 +256,31 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
const ImGuiTableFlags flags = ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollX;
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.BeginTable( LabelFileSwapHeader, 3, flags, AutoFillSize ) )
|
||||
if( !ImGui.BeginTable( LabelFileSwapHeader, 3, flags, AutoFillSize ) )
|
||||
{
|
||||
foreach( var file in Meta.FileSwaps )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
Custom.ImGuiCustom.CopyOnClickSelectable( file.Key );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
ImGui.TextUnformatted( $"{( char )FontAwesomeIcon.LongArrowAltRight}" );
|
||||
ImGui.PopFont();
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
Custom.ImGuiCustom.CopyOnClickSelectable( file.Value );
|
||||
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
raii.Push( ImGui.EndTable );
|
||||
|
||||
foreach( var (source, target) in Meta.FileSwaps )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.CopyOnClickSelectable( source );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltRight );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.CopyOnClickSelectable( target );
|
||||
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateFilenameList()
|
||||
|
|
@ -329,30 +330,26 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipFilesTab );
|
||||
}
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
ImGuiCustom.HoverTooltip( TooltipFilesTab );
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.BeginListBox( LabelFileListHeader, AutoFillSize ) )
|
||||
{
|
||||
raii.Push( ImGui.EndListBox );
|
||||
UpdateFilenameList();
|
||||
using var colorRaii = new ImGuiRaii.Color();
|
||||
foreach( var (name, _, color, _) in _fullFilenameList! )
|
||||
{
|
||||
ImGui.PushStyleColor( ImGuiCol.Text, color );
|
||||
colorRaii.Push( ImGuiCol.Text, color );
|
||||
ImGui.Selectable( name.FullName );
|
||||
ImGui.PopStyleColor();
|
||||
colorRaii.Pop();
|
||||
}
|
||||
|
||||
ImGui.EndListBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
_fullFilenameList = null;
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
private static int HandleDefaultString( GamePath[] gamePaths, out int removeFolders )
|
||||
|
|
@ -469,10 +466,7 @@ namespace Penumbra.UI
|
|||
ImGui.SetNextItemWidth( -1 );
|
||||
ImGui.InputTextWithHint( LabelGamePathsEditBox, "Hover for help...", ref _currentGamePaths,
|
||||
128 );
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipGamePathsEdit );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipGamePathsEdit );
|
||||
}
|
||||
|
||||
private void DrawGroupRow()
|
||||
|
|
@ -516,12 +510,11 @@ namespace Penumbra.UI
|
|||
loc = colorReplace;
|
||||
}
|
||||
|
||||
ImGui.PushStyleColor( ImGuiCol.Text, loc );
|
||||
using var colors = ImGuiRaii.PushColor( ImGuiCol.Text, loc );
|
||||
ImGui.Selectable( _fullFilenameList[ idx ].name.FullName, ref _fullFilenameList[ idx ].selected );
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
|
||||
const float indent = 30f;
|
||||
const float indentWidth = 30f;
|
||||
if( _selectedOption == null )
|
||||
{
|
||||
Selectable( 0, ColorGreen );
|
||||
|
|
@ -534,8 +527,8 @@ namespace Penumbra.UI
|
|||
{
|
||||
Selectable( 0, ColorGreen );
|
||||
|
||||
ImGui.Indent( indent );
|
||||
var tmpPaths = gamePaths.ToArray();
|
||||
using var indent = ImGuiRaii.PushIndent( indentWidth );
|
||||
var tmpPaths = gamePaths.ToArray();
|
||||
foreach( var gamePath in tmpPaths )
|
||||
{
|
||||
string tmp = gamePath;
|
||||
|
|
@ -556,8 +549,6 @@ namespace Penumbra.UI
|
|||
_selector.ReloadCurrentMod();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.Unindent( indent );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -588,14 +579,13 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
Custom.ImGuiCustom.BeginFramedGroup( group.GroupName );
|
||||
ImGuiCustom.BeginFramedGroup( group.GroupName );
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGuiCustom.EndFramedGroup );
|
||||
for( var i = 0; i < group.Options.Count; ++i )
|
||||
{
|
||||
DrawMultiSelectorCheckBox( group, i, Mod.Settings.Settings[ group.GroupName ],
|
||||
$"{group.Options[ i ].OptionName}##{group.GroupName}" );
|
||||
}
|
||||
|
||||
Custom.ImGuiCustom.EndFramedGroup();
|
||||
}
|
||||
|
||||
private void DrawSingleSelector( OptionGroup group )
|
||||
|
|
@ -635,79 +625,76 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawConfigurationTab()
|
||||
{
|
||||
if( !_editMode && !Meta.HasGroupsWithConfig )
|
||||
if( !_editMode && !Meta.HasGroupsWithConfig || !ImGui.BeginTabItem( LabelConfigurationTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( ImGui.BeginTabItem( LabelConfigurationTab ) )
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
if( _editMode )
|
||||
{
|
||||
if( _editMode )
|
||||
{
|
||||
DrawGroupSelectorsEdit();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGroupSelectors();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
DrawGroupSelectorsEdit();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGroupSelectors();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMetaManipulationsTab()
|
||||
{
|
||||
if( !_editMode && Mod.Data.Resources.MetaManipulations.Count == 0 )
|
||||
if( !_editMode && Mod.Data.Resources.MetaManipulations.Count == 0 || !ImGui.BeginTabItem( "Meta Manipulations" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !ImGui.BeginTabItem( "Meta Manipulations" ) )
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
if( !ImGui.BeginListBox( "##MetaManipulations", AutoFillSize ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( ImGui.BeginListBox( "##MetaManipulations", AutoFillSize ) )
|
||||
raii.Push( ImGui.EndListBox );
|
||||
|
||||
var manips = Mod.Data.Resources.MetaManipulations;
|
||||
var changes = false;
|
||||
if( _editMode || manips.DefaultData.Count > 0 )
|
||||
{
|
||||
var manips = Mod.Data.Resources.MetaManipulations;
|
||||
var changes = false;
|
||||
if( _editMode || manips.DefaultData.Count > 0 )
|
||||
if( ImGui.CollapsingHeader( "Default" ) )
|
||||
{
|
||||
if( ImGui.CollapsingHeader( "Default" ) )
|
||||
{
|
||||
changes = DrawMetaManipulationsTable( "##DefaultManips", manips.DefaultData, ref manips.Count );
|
||||
}
|
||||
changes = DrawMetaManipulationsTable( "##DefaultManips", manips.DefaultData, ref manips.Count );
|
||||
}
|
||||
|
||||
foreach( var group in manips.GroupData )
|
||||
{
|
||||
foreach( var option in group.Value )
|
||||
{
|
||||
if( ImGui.CollapsingHeader( $"{group.Key} - {option.Key}" ) )
|
||||
{
|
||||
changes |= DrawMetaManipulationsTable( $"##{group.Key}{option.Key}manips", option.Value, ref manips.Count );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( changes )
|
||||
{
|
||||
Mod.Data.Resources.MetaManipulations.SaveToFile( MetaCollection.FileName( Mod.Data.BasePath ) );
|
||||
Mod.Data.Resources.SetManipulations( Meta, Mod.Data.BasePath, false );
|
||||
_selector.ReloadCurrentMod( true, false );
|
||||
}
|
||||
|
||||
ImGui.EndListBox();
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
foreach( var (groupName, group) in manips.GroupData )
|
||||
{
|
||||
foreach( var (optionName, option) in group )
|
||||
{
|
||||
if( ImGui.CollapsingHeader( $"{groupName} - {optionName}" ) )
|
||||
{
|
||||
changes |= DrawMetaManipulationsTable( $"##{groupName}{optionName}manips", option, ref manips.Count );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( changes )
|
||||
{
|
||||
Mod.Data.Resources.MetaManipulations.SaveToFile( MetaCollection.FileName( Mod.Data.BasePath ) );
|
||||
Mod.Data.Resources.SetManipulations( Meta, Mod.Data.BasePath, false );
|
||||
_selector.ReloadCurrentMod( true, false );
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw( bool editMode )
|
||||
{
|
||||
_editMode = editMode;
|
||||
ImGui.BeginTabBar( LabelPluginDetails );
|
||||
if( !ImGui.BeginTabBar( LabelPluginDetails ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabBar );
|
||||
DrawAboutTab();
|
||||
DrawChangedItemsTab();
|
||||
|
||||
|
|
@ -724,7 +711,6 @@ namespace Penumbra.UI
|
|||
DrawFileSwapTab();
|
||||
DrawMetaManipulationsTab();
|
||||
DrawConflictTab();
|
||||
ImGui.EndTabBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using ImGuiNET;
|
|||
using Penumbra.GameData.Util;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Structs;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -38,7 +39,7 @@ namespace Penumbra.UI
|
|||
|
||||
private bool DrawEditGroupSelector()
|
||||
{
|
||||
ImGui.SetNextItemWidth( OptionSelectionWidth );
|
||||
ImGui.SetNextItemWidth( OptionSelectionWidth * ImGuiHelpers.GlobalScale );
|
||||
if( Meta!.Groups.Count == 0 )
|
||||
{
|
||||
ImGui.Combo( LabelGroupSelect, ref _selectedGroupIndex, TextNoOptionAvailable, 1 );
|
||||
|
|
@ -87,7 +88,7 @@ namespace Penumbra.UI
|
|||
}
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.BeginListBox( LabelFileListHeader, AutoFillSize - new Vector2( 0, 1.5f * ImGui.GetTextLineHeight() ) ) )
|
||||
if( ImGui.BeginListBox( LabelFileListHeader, AutoFillSize - Vector2.UnitY * 1.5f * ImGui.GetTextLineHeight() ) )
|
||||
{
|
||||
for( var i = 0; i < Mod!.Data.Resources.ModFiles.Count; ++i )
|
||||
{
|
||||
|
|
@ -106,23 +107,27 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawMultiSelectorEditBegin( OptionGroup group )
|
||||
private ImGuiRaii.EndStack DrawMultiSelectorEditBegin( OptionGroup group )
|
||||
{
|
||||
var groupName = group.GroupName;
|
||||
if( Custom.ImGuiCustom.BeginFramedGroupEdit( ref groupName ) )
|
||||
if( !ImGuiCustom.BeginFramedGroupEdit( ref groupName ) )
|
||||
{
|
||||
if( _modManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
return new ImGuiRaii.EndStack();
|
||||
}
|
||||
|
||||
if( _modManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
|
||||
return ImGuiRaii.DeferredEnd( ImGuiCustom.EndFramedGroup );
|
||||
}
|
||||
|
||||
private void DrawMultiSelectorEditAdd( OptionGroup group, float nameBoxStart )
|
||||
{
|
||||
var newOption = "";
|
||||
ImGui.SetCursorPosX( nameBoxStart );
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth );
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( $"##new_{group.GroupName}_l", "Add new option...", ref newOption, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue )
|
||||
&& newOption.Length != 0 )
|
||||
|
|
@ -142,7 +147,7 @@ namespace Penumbra.UI
|
|||
var nameBoxStart = CheckMarkSize;
|
||||
var flag = Mod!.Settings.Settings[ group.GroupName ];
|
||||
|
||||
DrawMultiSelectorEditBegin( group );
|
||||
using var raii = DrawMultiSelectorEditBegin( group );
|
||||
for( var i = 0; i < group.Options.Count; ++i )
|
||||
{
|
||||
var opt = group.Options[ i ];
|
||||
|
|
@ -157,7 +162,7 @@ namespace Penumbra.UI
|
|||
nameBoxStart = ImGui.GetCursorPosX();
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth );
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputText( $"{label}_l", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
if( newName.Length == 0 )
|
||||
|
|
@ -179,8 +184,6 @@ namespace Penumbra.UI
|
|||
}
|
||||
|
||||
DrawMultiSelectorEditAdd( group, nameBoxStart );
|
||||
|
||||
Custom.ImGuiCustom.EndFramedGroup();
|
||||
}
|
||||
|
||||
private void DrawSingleSelectorEditGroup( OptionGroup group )
|
||||
|
|
@ -199,7 +202,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
var oldSetting = Mod!.Settings.Settings[ group.GroupName ];
|
||||
var code = oldSetting;
|
||||
if( Custom.ImGuiCustom.RenameableCombo( $"##{group.GroupName}", ref code, out var newName,
|
||||
if( ImGuiCustom.RenameableCombo( $"##{group.GroupName}", ref code, out var newName,
|
||||
group.Options.Select( x => x.OptionName ).ToArray(), group.Options.Count ) )
|
||||
{
|
||||
if( code == group.Options.Count )
|
||||
|
|
@ -260,7 +263,7 @@ namespace Penumbra.UI
|
|||
ImGui.SetCursorPosX( labelEditPos );
|
||||
if( labelEditPos == CheckMarkSize )
|
||||
{
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth );
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
}
|
||||
|
||||
if( ImGui.InputTextWithHint( LabelNewSingleGroupEdit, "Add new Single Group...", ref newGroup, 64,
|
||||
|
|
@ -275,7 +278,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
var newGroup = "";
|
||||
ImGui.SetCursorPosX( CheckMarkSize );
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth );
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( LabelNewMultiGroup, "Add new Multi Group...", ref newGroup, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
|
|
@ -310,74 +313,75 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.BeginListBox( LabelFileSwapHeader, AutoFillSize ) )
|
||||
if( !ImGui.BeginListBox( LabelFileSwapHeader, AutoFillSize ) )
|
||||
{
|
||||
var swaps = Meta.FileSwaps.Keys.ToArray();
|
||||
return;
|
||||
}
|
||||
|
||||
var arrow = $"{( char )FontAwesomeIcon.LongArrowAltRight}";
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
var arrowWidth = ImGui.CalcTextSize( arrow ).X;
|
||||
ImGui.PopFont();
|
||||
raii.Push( ImGui.EndListBox );
|
||||
|
||||
var width = ( ImGui.GetWindowWidth() - arrowWidth - 4 * ImGui.GetStyle().ItemSpacing.X ) / 2;
|
||||
for( var idx = 0; idx < swaps.Length + 1; ++idx )
|
||||
var swaps = Meta.FileSwaps.Keys.ToArray();
|
||||
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
var arrowWidth = ImGui.CalcTextSize( FontAwesomeIcon.LongArrowAltRight.ToIconString() ).X;
|
||||
ImGui.PopFont();
|
||||
|
||||
var width = ( ImGui.GetWindowWidth() - arrowWidth - 4 * ImGui.GetStyle().ItemSpacing.X ) / 2;
|
||||
for( var idx = 0; idx < swaps.Length + 1; ++idx )
|
||||
{
|
||||
var key = idx == swaps.Length ? GamePath.GenerateUnchecked( "" ) : swaps[ idx ];
|
||||
var value = idx == swaps.Length ? GamePath.GenerateUnchecked( "" ) : Meta.FileSwaps[ key ];
|
||||
string keyString = key;
|
||||
string valueString = value;
|
||||
|
||||
ImGui.SetNextItemWidth( width );
|
||||
if( ImGui.InputTextWithHint( $"##swapLhs_{idx}", "Enter new file to be replaced...", ref keyString,
|
||||
GamePath.MaxGamePathLength, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
var key = idx == swaps.Length ? GamePath.GenerateUnchecked( "" ) : swaps[ idx ];
|
||||
var value = idx == swaps.Length ? GamePath.GenerateUnchecked( "" ) : Meta.FileSwaps[ key ];
|
||||
string keyString = key;
|
||||
string valueString = value;
|
||||
|
||||
ImGui.SetNextItemWidth( width );
|
||||
if( ImGui.InputTextWithHint( $"##swapLhs_{idx}", "Enter new file to be replaced...", ref keyString,
|
||||
GamePath.MaxGamePathLength, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
var newKey = new GamePath( keyString );
|
||||
if( newKey.CompareTo( key ) != 0 )
|
||||
{
|
||||
var newKey = new GamePath( keyString );
|
||||
if( newKey.CompareTo( key ) != 0 )
|
||||
if( idx < swaps.Length )
|
||||
{
|
||||
if( idx < swaps.Length )
|
||||
{
|
||||
Meta.FileSwaps.Remove( key );
|
||||
}
|
||||
|
||||
if( newKey != string.Empty )
|
||||
{
|
||||
Meta.FileSwaps[ newKey ] = value;
|
||||
}
|
||||
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.ReloadCurrentMod();
|
||||
Meta.FileSwaps.Remove( key );
|
||||
}
|
||||
}
|
||||
|
||||
if( idx < swaps.Length )
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
ImGui.TextUnformatted( arrow );
|
||||
ImGui.PopFont();
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.SetNextItemWidth( width );
|
||||
if( ImGui.InputTextWithHint( $"##swapRhs_{idx}", "Enter new replacement path...", ref valueString,
|
||||
GamePath.MaxGamePathLength,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
if( newKey != string.Empty )
|
||||
{
|
||||
var newValue = new GamePath( valueString );
|
||||
if( newValue.CompareTo( value ) != 0 )
|
||||
{
|
||||
Meta.FileSwaps[ key ] = newValue;
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.Cache.TriggerListReset();
|
||||
}
|
||||
Meta.FileSwaps[ newKey ] = value;
|
||||
}
|
||||
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.ReloadCurrentMod();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndListBox();
|
||||
}
|
||||
if( idx >= swaps.Length )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
ImGui.SameLine();
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltRight );
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGui.SetNextItemWidth( width );
|
||||
if( ImGui.InputTextWithHint( $"##swapRhs_{idx}", "Enter new replacement path...", ref valueString,
|
||||
GamePath.MaxGamePathLength,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
var newValue = new GamePath( valueString );
|
||||
if( newValue.CompareTo( value ) != 0 )
|
||||
{
|
||||
Meta.FileSwaps[ key ] = newValue;
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.Cache.TriggerListReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Penumbra.GameData.Enums;
|
|||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
using ObjectType = Penumbra.GameData.Enums.ObjectType;
|
||||
|
||||
|
|
@ -157,9 +158,8 @@ namespace Penumbra.UI
|
|||
return ImGui.Checkbox( name, ref value );
|
||||
}
|
||||
|
||||
ImGui.PushStyleColor( ImGuiCol.Text, color );
|
||||
var ret = ImGui.Checkbox( name, ref value );
|
||||
ImGui.PopStyleColor();
|
||||
using var colorRaii = ImGuiRaii.PushColor( ImGuiCol.Text, color );
|
||||
var ret = ImGui.Checkbox( name, ref value );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -184,10 +184,9 @@ namespace Penumbra.UI
|
|||
var color = compare < 0 ? ColorDarkGreen :
|
||||
compare > 0 ? ColorDarkRed : ImGui.ColorConvertFloat4ToU32( ImGui.GetStyle().Colors[ ( int )ImGuiCol.Button ] );
|
||||
|
||||
ImGui.PushStyleColor( ImGuiCol.Button, color );
|
||||
var ret = ImGui.Button( name, Vector2.UnitX * 120 ) && compare != 0;
|
||||
using var colorRaii = ImGuiRaii.PushColor( ImGuiCol.Button, color );
|
||||
var ret = ImGui.Button( name, Vector2.UnitX * 120 ) && compare != 0;
|
||||
ImGui.SameLine();
|
||||
ImGui.PopStyleColor();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -204,18 +203,20 @@ namespace Penumbra.UI
|
|||
return false;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndCombo );
|
||||
|
||||
for( var i = 0; i < namesAndValues.Count; ++i )
|
||||
{
|
||||
if( ImGui.Selectable( $"{namesAndValues[ i ].Item1}##{label}{i}", idx == i ) && idx != i )
|
||||
if( !ImGui.Selectable( $"{namesAndValues[ i ].Item1}##{label}{i}", idx == i ) || idx == i )
|
||||
{
|
||||
idx = i;
|
||||
value = namesAndValues[ i ].Item2;
|
||||
ImGui.EndCombo();
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
idx = i;
|
||||
value = namesAndValues[ i ].Item2;
|
||||
return true;
|
||||
}
|
||||
|
||||
ImGui.EndCombo();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -227,8 +228,9 @@ namespace Penumbra.UI
|
|||
|
||||
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
{
|
||||
var defaults = ( EqpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||
var attributes = Eqp.EqpAttributes[ id.Slot ];
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
var defaults = ( EqpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||
var attributes = Eqp.EqpAttributes[ id.Slot ];
|
||||
|
||||
foreach( var flag in attributes )
|
||||
{
|
||||
|
|
@ -240,8 +242,6 @@ namespace Penumbra.UI
|
|||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.Text( ObjectType.Equipment.ToString() );
|
||||
|
|
@ -261,12 +261,13 @@ namespace Penumbra.UI
|
|||
|
||||
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
{
|
||||
var enabled = val.Enabled;
|
||||
var animated = val.Animated;
|
||||
var rotationA = val.RotationA;
|
||||
var rotationB = val.RotationB;
|
||||
var rotationC = val.RotationC;
|
||||
ushort unk = val.UnknownTotal;
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
var enabled = val.Enabled;
|
||||
var animated = val.Animated;
|
||||
var rotationA = val.RotationA;
|
||||
var rotationB = val.RotationB;
|
||||
var rotationC = val.RotationC;
|
||||
ushort unk = val.UnknownTotal;
|
||||
|
||||
ret |= PrintCheckBox( "Visor Enabled##manip", ref enabled, defaults.Enabled ) && enabled != val.Enabled;
|
||||
ret |= PrintCheckBox( "Visor Animated##manip", ref animated, defaults.Animated );
|
||||
|
|
@ -284,8 +285,6 @@ namespace Penumbra.UI
|
|||
RotationA = rotationA, RotationB = rotationB, RotationC = rotationC,
|
||||
} );
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.Text( ObjectType.Equipment.ToString() );
|
||||
|
|
@ -300,17 +299,17 @@ namespace Penumbra.UI
|
|||
{
|
||||
return slot switch
|
||||
{
|
||||
EquipSlot.Head => ( entry.HasFlag( EqdpEntry.Head1 ), entry.HasFlag( EqdpEntry.Head2 ) ),
|
||||
EquipSlot.Body => ( entry.HasFlag( EqdpEntry.Body1 ), entry.HasFlag( EqdpEntry.Body2 ) ),
|
||||
EquipSlot.Hands => ( entry.HasFlag( EqdpEntry.Hands1 ), entry.HasFlag( EqdpEntry.Hands2 ) ),
|
||||
EquipSlot.Legs => ( entry.HasFlag( EqdpEntry.Legs1 ), entry.HasFlag( EqdpEntry.Legs2 ) ),
|
||||
EquipSlot.Feet => ( entry.HasFlag( EqdpEntry.Feet1 ), entry.HasFlag( EqdpEntry.Feet2 ) ),
|
||||
EquipSlot.Neck => ( entry.HasFlag( EqdpEntry.Neck1 ), entry.HasFlag( EqdpEntry.Neck2 ) ),
|
||||
EquipSlot.Ears => ( entry.HasFlag( EqdpEntry.Ears1 ), entry.HasFlag( EqdpEntry.Ears2 ) ),
|
||||
EquipSlot.Wrists => ( entry.HasFlag( EqdpEntry.Wrists1 ), entry.HasFlag( EqdpEntry.Wrists2 ) ),
|
||||
EquipSlot.RFinger => ( entry.HasFlag( EqdpEntry.RingR1 ), entry.HasFlag( EqdpEntry.RingR2 ) ),
|
||||
EquipSlot.LFinger => ( entry.HasFlag( EqdpEntry.RingL1 ), entry.HasFlag( EqdpEntry.RingL2 ) ),
|
||||
_ => ( false, false ),
|
||||
EquipSlot.Head => ( entry.HasFlag( EqdpEntry.Head1 ), entry.HasFlag( EqdpEntry.Head2 ) ),
|
||||
EquipSlot.Body => ( entry.HasFlag( EqdpEntry.Body1 ), entry.HasFlag( EqdpEntry.Body2 ) ),
|
||||
EquipSlot.Hands => ( entry.HasFlag( EqdpEntry.Hands1 ), entry.HasFlag( EqdpEntry.Hands2 ) ),
|
||||
EquipSlot.Legs => ( entry.HasFlag( EqdpEntry.Legs1 ), entry.HasFlag( EqdpEntry.Legs2 ) ),
|
||||
EquipSlot.Feet => ( entry.HasFlag( EqdpEntry.Feet1 ), entry.HasFlag( EqdpEntry.Feet2 ) ),
|
||||
EquipSlot.Neck => ( entry.HasFlag( EqdpEntry.Neck1 ), entry.HasFlag( EqdpEntry.Neck2 ) ),
|
||||
EquipSlot.Ears => ( entry.HasFlag( EqdpEntry.Ears1 ), entry.HasFlag( EqdpEntry.Ears2 ) ),
|
||||
EquipSlot.Wrists => ( entry.HasFlag( EqdpEntry.Wrists1 ), entry.HasFlag( EqdpEntry.Wrists2 ) ),
|
||||
EquipSlot.RFinger => ( entry.HasFlag( EqdpEntry.RingR1 ), entry.HasFlag( EqdpEntry.RingR2 ) ),
|
||||
EquipSlot.LFinger => ( entry.HasFlag( EqdpEntry.RingL1 ), entry.HasFlag( EqdpEntry.RingL2 ) ),
|
||||
_ => ( false, false ),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -372,6 +371,7 @@ namespace Penumbra.UI
|
|||
|
||||
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
{
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
var (bit1, bit2) = GetEqdpBits( id.Slot, val );
|
||||
var (defBit1, defBit2) = GetEqdpBits( id.Slot, defaults );
|
||||
|
||||
|
|
@ -382,8 +382,6 @@ namespace Penumbra.UI
|
|||
{
|
||||
list[ manipIdx ] = MetaManipulation.Eqdp( id.Slot, id.GenderRace, id.SetId, SetEqdpBits( id.Slot, val, bit1, bit2 ) );
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.Text( id.Slot.IsAccessory()
|
||||
|
|
@ -409,13 +407,12 @@ namespace Penumbra.UI
|
|||
var val = list[ manipIdx ].EstValue;
|
||||
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
{
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
if( DrawInputWithDefault( "No Idea what this does!##manip", ref val, defaults, ushort.MaxValue ) && _editMode )
|
||||
{
|
||||
list[ manipIdx ] = new MetaManipulation( id.Value, val );
|
||||
ret = true;
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.Text( id.ObjectType.ToString() );
|
||||
|
|
@ -443,12 +440,13 @@ namespace Penumbra.UI
|
|||
|
||||
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
{
|
||||
ushort materialId = val.MaterialId;
|
||||
ushort vfxId = val.VfxId;
|
||||
ushort decalId = val.DecalId;
|
||||
var soundId = ( ushort )( val.SoundId >> 10 );
|
||||
var attributeMask = val.AttributeMask;
|
||||
var materialAnimationId = ( ushort )( val.MaterialAnimationId >> 12 );
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
ushort materialId = val.MaterialId;
|
||||
ushort vfxId = val.VfxId;
|
||||
ushort decalId = val.DecalId;
|
||||
var soundId = ( ushort )( val.SoundId >> 10 );
|
||||
var attributeMask = val.AttributeMask;
|
||||
var materialAnimationId = ( ushort )( val.MaterialAnimationId >> 12 );
|
||||
ret |= DrawInputWithDefault( "Material Id", ref materialId, defaults.MaterialId, byte.MaxValue );
|
||||
ret |= DrawInputWithDefault( "Vfx Id", ref vfxId, defaults.VfxId, byte.MaxValue );
|
||||
ret |= DrawInputWithDefault( "Decal Id", ref decalId, defaults.DecalId, byte.MaxValue );
|
||||
|
|
@ -463,8 +461,6 @@ namespace Penumbra.UI
|
|||
( byte )vfxId, ( byte )materialAnimationId );
|
||||
list[ manipIdx ] = new MetaManipulation( id.Value, value.ToInteger() );
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.Text( id.ObjectType.ToString() );
|
||||
|
|
@ -503,6 +499,7 @@ namespace Penumbra.UI
|
|||
|
||||
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
{
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
if( DefaultButton(
|
||||
$"{( _editMode ? "Set to " : "" )}Default: {defaults:F3}##scaleManip", ref val, defaults )
|
||||
&& _editMode )
|
||||
|
|
@ -511,7 +508,7 @@ namespace Penumbra.UI
|
|||
ret = true;
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( 50 );
|
||||
ImGui.SetNextItemWidth( 50 * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputFloat( "Scale###manip", ref val, 0, 0, "%.3f",
|
||||
_editMode ? ImGuiInputTextFlags.EnterReturnsTrue : ImGuiInputTextFlags.ReadOnly )
|
||||
&& val >= 0
|
||||
|
|
@ -521,8 +518,6 @@ namespace Penumbra.UI
|
|||
list[ manipIdx ] = MetaManipulation.Rsp( id.SubRace, id.Attribute, val );
|
||||
ret = true;
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
ImGui.Text( id.Attribute.ToUngenderedString() );
|
||||
|
|
@ -542,18 +537,15 @@ namespace Penumbra.UI
|
|||
if( _editMode )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
using var font = ImGuiRaii.PushFont( UiBuilder.IconFont );
|
||||
if( ImGui.Button( $"{FontAwesomeIcon.Trash.ToIconString()}##manipDelete{manipIdx}" ) )
|
||||
{
|
||||
list.RemoveAt( manipIdx );
|
||||
ImGui.PopFont();
|
||||
ImGui.TableNextRow();
|
||||
--manipIdx;
|
||||
--count;
|
||||
return true;
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
|
@ -613,114 +605,116 @@ namespace Penumbra.UI
|
|||
private bool DrawNewManipulationPopup( string popupName, IList< MetaManipulation > list, ref int count )
|
||||
{
|
||||
var change = false;
|
||||
if( ImGui.BeginPopup( popupName ) )
|
||||
if( !ImGui.BeginPopup( popupName ) )
|
||||
{
|
||||
var manipType = DrawNewTypeSelection();
|
||||
MetaManipulation? newManip = null;
|
||||
switch( manipType )
|
||||
return change;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
var manipType = DrawNewTypeSelection();
|
||||
MetaManipulation? newManip = null;
|
||||
switch( manipType )
|
||||
{
|
||||
case MetaType.Imc:
|
||||
{
|
||||
case MetaType.Imc:
|
||||
RestrictedInputInt( "Set Id##newManipImc", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
RestrictedInputInt( "Variant##newManipImc", ref _newManipVariant, 0, byte.MaxValue );
|
||||
CustomCombo( "Object Type", ImcObjectType, out var objectType, ref _newManipObjectType );
|
||||
EquipSlot equipSlot = default;
|
||||
switch( objectType )
|
||||
{
|
||||
RestrictedInputInt( "Set Id##newManipImc", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
RestrictedInputInt( "Variant##newManipImc", ref _newManipVariant, 0, byte.MaxValue );
|
||||
CustomCombo( "Object Type", ImcObjectType, out var objectType, ref _newManipObjectType );
|
||||
EquipSlot equipSlot = default;
|
||||
switch( objectType )
|
||||
{
|
||||
case ObjectType.Equipment:
|
||||
CustomCombo( "Equipment Slot", EqdpEquipSlots, out equipSlot, ref _newManipEquipSlot );
|
||||
newManip = MetaManipulation.Imc( equipSlot, _newManipSetId, _newManipVariant,
|
||||
new ImcFile.ImageChangeData() );
|
||||
break;
|
||||
case ObjectType.DemiHuman:
|
||||
case ObjectType.Weapon:
|
||||
case ObjectType.Monster:
|
||||
RestrictedInputInt( "Secondary Id##newManipImc", ref _newManipSecondaryId, 0, ushort.MaxValue );
|
||||
CustomCombo( "Body Slot", ImcBodySlots, out var bodySlot, ref _newManipBodySlot );
|
||||
newManip = MetaManipulation.Imc( objectType, bodySlot, _newManipSetId, _newManipSecondaryId,
|
||||
_newManipVariant, new ImcFile.ImageChangeData() );
|
||||
break;
|
||||
}
|
||||
case ObjectType.Equipment:
|
||||
CustomCombo( "Equipment Slot", EqdpEquipSlots, out equipSlot, ref _newManipEquipSlot );
|
||||
newManip = MetaManipulation.Imc( equipSlot, _newManipSetId, _newManipVariant,
|
||||
new ImcFile.ImageChangeData() );
|
||||
break;
|
||||
case ObjectType.DemiHuman:
|
||||
case ObjectType.Weapon:
|
||||
case ObjectType.Monster:
|
||||
RestrictedInputInt( "Secondary Id##newManipImc", ref _newManipSecondaryId, 0, ushort.MaxValue );
|
||||
CustomCombo( "Body Slot", ImcBodySlots, out var bodySlot, ref _newManipBodySlot );
|
||||
newManip = MetaManipulation.Imc( objectType, bodySlot, _newManipSetId, _newManipSecondaryId,
|
||||
_newManipVariant, new ImcFile.ImageChangeData() );
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MetaType.Eqdp:
|
||||
break;
|
||||
}
|
||||
case MetaType.Eqdp:
|
||||
{
|
||||
RestrictedInputInt( "Set Id##newManipEqdp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
|
||||
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
||||
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
||||
newManip = MetaManipulation.Eqdp( equipSlot, Names.CombinedRace( gender, race ), ( ushort )_newManipSetId,
|
||||
new EqdpEntry() );
|
||||
break;
|
||||
}
|
||||
case MetaType.Eqp:
|
||||
{
|
||||
RestrictedInputInt( "Set Id##newManipEqp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
CustomCombo( "Equipment Slot", EqpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
|
||||
newManip = MetaManipulation.Eqp( equipSlot, ( ushort )_newManipSetId, 0 );
|
||||
break;
|
||||
}
|
||||
case MetaType.Est:
|
||||
{
|
||||
RestrictedInputInt( "Set Id##newManipEst", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
CustomCombo( "Object Type", ObjectTypes, out var objectType, ref _newManipObjectType );
|
||||
EquipSlot equipSlot = default;
|
||||
BodySlot bodySlot = default;
|
||||
switch( ( ObjectType )_newManipObjectType )
|
||||
{
|
||||
RestrictedInputInt( "Set Id##newManipEqdp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
|
||||
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
||||
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
||||
newManip = MetaManipulation.Eqdp( equipSlot, Names.CombinedRace( gender, race ), ( ushort )_newManipSetId,
|
||||
new EqdpEntry() );
|
||||
break;
|
||||
case ObjectType.Equipment:
|
||||
CustomCombo( "Equipment Slot", EstEquipSlots, out equipSlot, ref _newManipEquipSlot );
|
||||
break;
|
||||
case ObjectType.Character:
|
||||
CustomCombo( "Body Slot", EstBodySlots, out bodySlot, ref _newManipBodySlot );
|
||||
break;
|
||||
}
|
||||
case MetaType.Eqp:
|
||||
{
|
||||
RestrictedInputInt( "Set Id##newManipEqp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
CustomCombo( "Equipment Slot", EqpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
|
||||
newManip = MetaManipulation.Eqp( equipSlot, ( ushort )_newManipSetId, 0 );
|
||||
break;
|
||||
}
|
||||
case MetaType.Est:
|
||||
{
|
||||
RestrictedInputInt( "Set Id##newManipEst", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
CustomCombo( "Object Type", ObjectTypes, out var objectType, ref _newManipObjectType );
|
||||
EquipSlot equipSlot = default;
|
||||
BodySlot bodySlot = default;
|
||||
switch( ( ObjectType )_newManipObjectType )
|
||||
{
|
||||
case ObjectType.Equipment:
|
||||
CustomCombo( "Equipment Slot", EstEquipSlots, out equipSlot, ref _newManipEquipSlot );
|
||||
break;
|
||||
case ObjectType.Character:
|
||||
CustomCombo( "Body Slot", EstBodySlots, out bodySlot, ref _newManipBodySlot );
|
||||
break;
|
||||
}
|
||||
|
||||
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
||||
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
||||
newManip = MetaManipulation.Est( objectType, equipSlot, Names.CombinedRace( gender, race ), bodySlot,
|
||||
( ushort )_newManipSetId, 0 );
|
||||
break;
|
||||
}
|
||||
case MetaType.Gmp:
|
||||
RestrictedInputInt( "Set Id##newManipGmp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
newManip = MetaManipulation.Gmp( ( ushort )_newManipSetId, new GmpEntry() );
|
||||
break;
|
||||
case MetaType.Rsp:
|
||||
CustomCombo( "Subrace", Subraces, out var subRace, ref _newManipSubrace );
|
||||
CustomCombo( "Attribute", RspAttributes, out var rspAttribute, ref _newManipAttribute );
|
||||
newManip = MetaManipulation.Rsp( subRace, rspAttribute, 1f );
|
||||
break;
|
||||
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
||||
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
||||
newManip = MetaManipulation.Est( objectType, equipSlot, Names.CombinedRace( gender, race ), bodySlot,
|
||||
( ushort )_newManipSetId, 0 );
|
||||
break;
|
||||
}
|
||||
case MetaType.Gmp:
|
||||
RestrictedInputInt( "Set Id##newManipGmp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||
newManip = MetaManipulation.Gmp( ( ushort )_newManipSetId, new GmpEntry() );
|
||||
break;
|
||||
case MetaType.Rsp:
|
||||
CustomCombo( "Subrace", Subraces, out var subRace, ref _newManipSubrace );
|
||||
CustomCombo( "Attribute", RspAttributes, out var rspAttribute, ref _newManipAttribute );
|
||||
newManip = MetaManipulation.Rsp( subRace, rspAttribute, 1f );
|
||||
break;
|
||||
}
|
||||
|
||||
if( ImGui.Button( "Create Manipulation##newManip", Vector2.UnitX * -1 )
|
||||
&& newManip != null
|
||||
&& list.All( m => m.Identifier != newManip.Value.Identifier ) )
|
||||
{
|
||||
var def = Service< MetaDefaults >.Get().GetDefaultValue( newManip.Value );
|
||||
if( def != null )
|
||||
{
|
||||
var manip = newManip.Value.Type switch
|
||||
{
|
||||
MetaType.Est => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||
MetaType.Eqp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||
MetaType.Eqdp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||
MetaType.Gmp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||
MetaType.Imc => new MetaManipulation( newManip.Value.Identifier,
|
||||
( ( ImcFile.ImageChangeData )def ).ToInteger() ),
|
||||
MetaType.Rsp => MetaManipulation.Rsp( newManip.Value.RspIdentifier.SubRace,
|
||||
newManip.Value.RspIdentifier.Attribute, ( float )def ),
|
||||
_ => throw new InvalidEnumArgumentException(),
|
||||
};
|
||||
list.Add( manip );
|
||||
change = true;
|
||||
++count;
|
||||
}
|
||||
|
||||
if( ImGui.Button( "Create Manipulation##newManip", Vector2.UnitX * -1 )
|
||||
&& newManip != null
|
||||
&& list.All( m => m.Identifier != newManip.Value.Identifier ) )
|
||||
{
|
||||
var def = Service< MetaDefaults >.Get().GetDefaultValue( newManip.Value );
|
||||
if( def != null )
|
||||
{
|
||||
var manip = newManip.Value.Type switch
|
||||
{
|
||||
MetaType.Est => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||
MetaType.Eqp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||
MetaType.Eqdp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||
MetaType.Gmp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||
MetaType.Imc => new MetaManipulation( newManip.Value.Identifier,
|
||||
( ( ImcFile.ImageChangeData )def ).ToInteger() ),
|
||||
MetaType.Rsp => MetaManipulation.Rsp( newManip.Value.RspIdentifier.SubRace,
|
||||
newManip.Value.RspIdentifier.Attribute, ( float )def ),
|
||||
_ => throw new InvalidEnumArgumentException(),
|
||||
};
|
||||
list.Add( manip );
|
||||
change = true;
|
||||
++count;
|
||||
}
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
return change;
|
||||
|
|
@ -734,6 +728,7 @@ namespace Penumbra.UI
|
|||
&& ImGui.BeginTable( label, numRows,
|
||||
ImGuiTableFlags.BordersInner | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ) )
|
||||
{
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
if( _editMode )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
|
|
@ -764,8 +759,6 @@ namespace Penumbra.UI
|
|||
{
|
||||
changes |= DrawManipulationRow( ref i, list, ref count );
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
var popupName = $"##newManip{label}";
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ using System;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Logging;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Mod;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -72,7 +74,7 @@ namespace Penumbra.UI
|
|||
private void DrawName()
|
||||
{
|
||||
var name = Meta!.Name;
|
||||
if( Custom.ImGuiCustom.InputOrText( _editMode, LabelEditName, ref name, 64 ) && _modManager.RenameMod( name, Mod!.Data ) )
|
||||
if( ImGuiCustom.InputOrText( _editMode, LabelEditName, ref name, 64 ) && _modManager.RenameMod( name, Mod!.Data ) )
|
||||
{
|
||||
_selector.SelectModOnUpdate( Mod.Data.BasePath.Name );
|
||||
if( !_modManager.Config.ModSortOrder.ContainsKey( Mod!.Data.BasePath.Name ) )
|
||||
|
|
@ -87,12 +89,13 @@ namespace Penumbra.UI
|
|||
if( _editMode )
|
||||
{
|
||||
ImGui.BeginGroup();
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndGroup );
|
||||
ImGui.Text( "(Version " );
|
||||
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, ZeroVector );
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.ItemSpacing, ZeroVector );
|
||||
ImGui.SameLine();
|
||||
var version = Meta!.Version;
|
||||
if( Custom.ImGuiCustom.ResizingTextInput( LabelEditVersion, ref version, 16 )
|
||||
if( ImGuiCustom.ResizingTextInput( LabelEditVersion, ref version, 16 )
|
||||
&& version != Meta.Version )
|
||||
{
|
||||
Meta.Version = version;
|
||||
|
|
@ -101,8 +104,6 @@ namespace Penumbra.UI
|
|||
|
||||
ImGui.SameLine();
|
||||
ImGui.Text( ")" );
|
||||
ImGui.PopStyleVar();
|
||||
ImGui.EndGroup();
|
||||
}
|
||||
else if( Meta!.Version.Length > 0 )
|
||||
{
|
||||
|
|
@ -117,7 +118,7 @@ namespace Penumbra.UI
|
|||
|
||||
ImGui.SameLine();
|
||||
var author = Meta!.Author;
|
||||
if( Custom.ImGuiCustom.InputOrText( _editMode, LabelEditAuthor, ref author, 64 )
|
||||
if( ImGuiCustom.InputOrText( _editMode, LabelEditAuthor, ref author, 64 )
|
||||
&& author != Meta.Author )
|
||||
{
|
||||
Meta.Author = author;
|
||||
|
|
@ -131,12 +132,13 @@ namespace Penumbra.UI
|
|||
private void DrawWebsite()
|
||||
{
|
||||
ImGui.BeginGroup();
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndGroup );
|
||||
if( _editMode )
|
||||
{
|
||||
ImGui.TextColored( GreyColor, "from" );
|
||||
ImGui.SameLine();
|
||||
var website = Meta!.Website;
|
||||
if( Custom.ImGuiCustom.ResizingTextInput( LabelEditWebsite, ref website, 512 )
|
||||
if( ImGuiCustom.ResizingTextInput( LabelEditWebsite, ref website, 512 )
|
||||
&& website != Meta.Website )
|
||||
{
|
||||
Meta.Website = website;
|
||||
|
|
@ -170,10 +172,7 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( Meta.Website );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( Meta.Website );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -182,8 +181,6 @@ namespace Penumbra.UI
|
|||
ImGui.Text( Meta.Website );
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndGroup();
|
||||
}
|
||||
|
||||
private void DrawHeaderLine()
|
||||
|
|
@ -200,7 +197,7 @@ namespace Penumbra.UI
|
|||
private void DrawPriority()
|
||||
{
|
||||
var priority = Mod!.Settings.Priority;
|
||||
ImGui.SetNextItemWidth( 50 );
|
||||
ImGui.SetNextItemWidth( 50 * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputInt( "Priority", ref priority, 0 ) && priority != Mod!.Settings.Priority )
|
||||
{
|
||||
Mod.Settings.Priority = priority;
|
||||
|
|
@ -208,11 +205,9 @@ namespace Penumbra.UI
|
|||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( "Higher priority mods take precedence over other mods in the case of file conflicts.\n"
|
||||
+ "In case of identical priority, the alphabetically first mod takes precedence." );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"Higher priority mods take precedence over other mods in the case of file conflicts.\n"
|
||||
+ "In case of identical priority, the alphabetically first mod takes precedence." );
|
||||
}
|
||||
|
||||
private void DrawEnabledMark()
|
||||
|
|
@ -229,7 +224,7 @@ namespace Penumbra.UI
|
|||
public static bool DrawSortOrder( ModData mod, ModManager manager, Selector selector )
|
||||
{
|
||||
var currentSortOrder = mod.SortOrder.FullPath;
|
||||
ImGui.SetNextItemWidth( 300 );
|
||||
ImGui.SetNextItemWidth( 300 * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputText( "Sort Order", ref currentSortOrder, 256, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
manager.ChangeSortOrder( mod, currentSortOrder );
|
||||
|
|
@ -253,10 +248,7 @@ namespace Penumbra.UI
|
|||
Process.Start( new ProcessStartInfo( Mod!.Data.BasePath.FullName ) { UseShellExecute = true } );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipOpenModFolder );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipOpenModFolder );
|
||||
}
|
||||
|
||||
private string _newName = "";
|
||||
|
|
@ -318,35 +310,37 @@ namespace Penumbra.UI
|
|||
{
|
||||
var closeParent = false;
|
||||
var _ = true;
|
||||
if( ImGui.BeginPopupModal( LabelOverWriteDir, ref _, ImGuiWindowFlags.AlwaysAutoResize ) )
|
||||
if( !ImGui.BeginPopupModal( LabelOverWriteDir, ref _, ImGuiWindowFlags.AlwaysAutoResize ) )
|
||||
{
|
||||
DirectoryInfo dir = Mod!.Data.BasePath;
|
||||
DirectoryInfo newDir = new( Path.Combine( dir.Parent!.FullName, _newName ) );
|
||||
ImGui.Text(
|
||||
$"The mod directory {newDir} already exists.\nDo you want to merge / overwrite both mods?\nThis may corrupt the resulting mod in irrecoverable ways." );
|
||||
var buttonSize = new Vector2( 120, 0 );
|
||||
if( ImGui.Button( "Yes", buttonSize ) )
|
||||
return closeParent;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
|
||||
DirectoryInfo dir = Mod!.Data.BasePath;
|
||||
DirectoryInfo newDir = new( Path.Combine( dir.Parent!.FullName, _newName ) );
|
||||
ImGui.Text(
|
||||
$"The mod directory {newDir} already exists.\nDo you want to merge / overwrite both mods?\nThis may corrupt the resulting mod in irrecoverable ways." );
|
||||
var buttonSize = ImGuiHelpers.ScaledVector2( 120, 0 );
|
||||
if( ImGui.Button( "Yes", buttonSize ) )
|
||||
{
|
||||
if( MergeFolderInto( dir, newDir ) )
|
||||
{
|
||||
if( MergeFolderInto( dir, newDir ) )
|
||||
{
|
||||
Service< ModManager >.Get()!.RenameModFolder( Mod.Data, newDir, false );
|
||||
Service< ModManager >.Get()!.RenameModFolder( Mod.Data, newDir, false );
|
||||
|
||||
_selector.SelectModOnUpdate( _newName );
|
||||
_selector.SelectModOnUpdate( _newName );
|
||||
|
||||
closeParent = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if( ImGui.Button( "Cancel", buttonSize ) )
|
||||
{
|
||||
_keyboardFocus = true;
|
||||
closeParent = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
ImGui.SameLine();
|
||||
|
||||
if( ImGui.Button( "Cancel", buttonSize ) )
|
||||
{
|
||||
_keyboardFocus = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
return closeParent;
|
||||
|
|
@ -358,38 +352,40 @@ namespace Penumbra.UI
|
|||
_keyboardFocus |= !ImGui.IsPopupOpen( PopupRenameFolder );
|
||||
|
||||
ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, new Vector2( 0.5f, 1f ) );
|
||||
if( ImGui.BeginPopupModal( PopupRenameFolder, ref _, ImGuiWindowFlags.AlwaysAutoResize ) )
|
||||
if( !ImGui.BeginPopupModal( PopupRenameFolder, ref _, ImGuiWindowFlags.AlwaysAutoResize ) )
|
||||
{
|
||||
if( ImGui.IsKeyPressed( ImGui.GetKeyIndex( ImGuiKey.Escape ) ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var newName = Mod!.Data.BasePath.Name;
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
|
||||
if( _keyboardFocus )
|
||||
{
|
||||
ImGui.SetKeyboardFocusHere();
|
||||
_keyboardFocus = false;
|
||||
}
|
||||
if( ImGui.IsKeyPressed( ImGui.GetKeyIndex( ImGuiKey.Escape ) ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if( ImGui.InputText( "New Folder Name##RenameFolderInput", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
RenameModFolder( newName );
|
||||
}
|
||||
var newName = Mod!.Data.BasePath.Name;
|
||||
|
||||
ImGui.TextColored( GreyColor,
|
||||
"Please restrict yourself to ascii symbols that are valid in a windows path,\nother symbols will be replaced by underscores." );
|
||||
if( _keyboardFocus )
|
||||
{
|
||||
ImGui.SetKeyboardFocusHere();
|
||||
_keyboardFocus = false;
|
||||
}
|
||||
|
||||
ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, Vector2.One / 2 );
|
||||
if( ImGui.InputText( "New Folder Name##RenameFolderInput", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
RenameModFolder( newName );
|
||||
}
|
||||
|
||||
ImGui.TextColored( GreyColor,
|
||||
"Please restrict yourself to ascii symbols that are valid in a windows path,\nother symbols will be replaced by underscores." );
|
||||
|
||||
ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, Vector2.One / 2 );
|
||||
|
||||
|
||||
if( OverwriteDirPopup() )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
if( OverwriteDirPopup() )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -401,10 +397,7 @@ namespace Penumbra.UI
|
|||
ImGui.OpenPopup( PopupRenameFolder );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipRenameModFolder );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipRenameModFolder );
|
||||
}
|
||||
|
||||
private void DrawEditJsonButton()
|
||||
|
|
@ -415,10 +408,7 @@ namespace Penumbra.UI
|
|||
Process.Start( new ProcessStartInfo( Mod!.Data.MetaFile.FullName ) { UseShellExecute = true } );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipEditJson );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipEditJson );
|
||||
}
|
||||
|
||||
private void DrawReloadJsonButton()
|
||||
|
|
@ -428,10 +418,7 @@ namespace Penumbra.UI
|
|||
_selector.ReloadCurrentMod( true, false );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipReloadJson );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipReloadJson );
|
||||
}
|
||||
|
||||
private void DrawResetMetaButton()
|
||||
|
|
@ -441,13 +428,10 @@ namespace Penumbra.UI
|
|||
_selector.ReloadCurrentMod( true, true );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"Force a recomputation of the metadata_manipulations.json file from all .meta files in the folder.\n"
|
||||
+ "Also reloads the mod.\n"
|
||||
+ "Be aware that this removes all manually added metadata changes." );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"Force a recomputation of the metadata_manipulations.json file from all .meta files in the folder.\n"
|
||||
+ "Also reloads the mod.\n"
|
||||
+ "Be aware that this removes all manually added metadata changes." );
|
||||
}
|
||||
|
||||
private void DrawDeduplicateButton()
|
||||
|
|
@ -459,10 +443,7 @@ namespace Penumbra.UI
|
|||
_selector.ReloadCurrentMod();
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipDeduplicate );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipDeduplicate );
|
||||
}
|
||||
|
||||
private void DrawNormalizeButton()
|
||||
|
|
@ -474,10 +455,7 @@ namespace Penumbra.UI
|
|||
_selector.ReloadCurrentMod();
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipNormalize );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipNormalize );
|
||||
}
|
||||
|
||||
private void DrawSplitButton()
|
||||
|
|
@ -487,13 +465,10 @@ namespace Penumbra.UI
|
|||
ModCleanup.SplitMod( Mod!.Data );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"Split off all options of a mod into single mods that are placed in a collective folder.\n"
|
||||
+ "Does not remove or change the mod itself, just create (potentially inefficient) copies.\n"
|
||||
+ "Experimental - Use at own risk!" );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"Split off all options of a mod into single mods that are placed in a collective folder.\n"
|
||||
+ "Does not remove or change the mod itself, just create (potentially inefficient) copies.\n"
|
||||
+ "Experimental - Use at own risk!" );
|
||||
}
|
||||
|
||||
private void DrawEditLine()
|
||||
|
|
@ -521,18 +496,18 @@ namespace Penumbra.UI
|
|||
{
|
||||
try
|
||||
{
|
||||
var ret = ImGui.BeginChild( LabelModPanel, AutoFillSize, true );
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndChild );
|
||||
var ret = ImGui.BeginChild( LabelModPanel, AutoFillSize, true );
|
||||
|
||||
if( !ret || Mod == null )
|
||||
{
|
||||
ImGui.EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
DrawHeaderLine();
|
||||
|
||||
// Next line with fixed distance.
|
||||
Custom.ImGuiCustom.VerticalDistance( HeaderLineDistance );
|
||||
ImGuiCustom.VerticalDistance( HeaderLineDistance );
|
||||
|
||||
DrawEnabledMark();
|
||||
ImGui.SameLine();
|
||||
|
|
@ -550,12 +525,10 @@ namespace Penumbra.UI
|
|||
}
|
||||
|
||||
Details.Draw( _editMode );
|
||||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
PluginLog.LogError( ex, "fuck" );
|
||||
PluginLog.LogError( ex, "Oh no" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Logging;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Importer;
|
||||
using Penumbra.Mod;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -36,6 +38,8 @@ namespace Penumbra.UI
|
|||
|
||||
private static readonly Vector2 SelectorButtonSizes = new( 100, 0 );
|
||||
private static readonly Vector2 HelpButtonSizes = new( 40, 0 );
|
||||
|
||||
private static readonly Vector4 DeleteModNameColor = new( 0.7f, 0.1f, 0.1f, 1 );
|
||||
}
|
||||
|
||||
// Buttons
|
||||
|
|
@ -46,19 +50,16 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawModTrashButton()
|
||||
{
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
using var raii = ImGuiRaii.PushFont( UiBuilder.IconFont );
|
||||
|
||||
if( ImGui.Button( FontAwesomeIcon.Trash.ToIconString(), SelectorButtonSizes * _selectorScalingFactor ) && _index >= 0 )
|
||||
{
|
||||
_deleteIndex = _index;
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
raii.Pop();
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipDelete );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipDelete );
|
||||
}
|
||||
|
||||
private void DrawDeleteModal()
|
||||
|
|
@ -78,20 +79,22 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
|
||||
if( Mod == null )
|
||||
{
|
||||
_deleteIndex = null;
|
||||
ImGui.CloseCurrentPopup();
|
||||
ImGui.EndPopup();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.Text( "Are you sure you want to delete the following mod:" );
|
||||
ImGui.Dummy( new Vector2( ImGui.GetTextLineHeight() / 2 ) );
|
||||
ImGui.TextColored( new Vector4( 0.7f, 0.1f, 0.1f, 1 ), Mod.Data.Meta.Name );
|
||||
ImGui.Dummy( new Vector2( ImGui.GetTextLineHeight() ) / 2 );
|
||||
var halfLine = new Vector2( ImGui.GetTextLineHeight() / 2 );
|
||||
ImGui.Dummy( halfLine );
|
||||
ImGui.TextColored( DeleteModNameColor, Mod.Data.Meta.Name );
|
||||
ImGui.Dummy( halfLine );
|
||||
|
||||
var buttonSize = new Vector2( 120, 0 );
|
||||
var buttonSize = ImGuiHelpers.ScaledVector2( 120, 0 );
|
||||
if( ImGui.Button( ButtonYesDelete, buttonSize ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
|
|
@ -109,8 +112,6 @@ namespace Penumbra.UI
|
|||
ImGui.CloseCurrentPopup();
|
||||
_deleteIndex = null;
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
// === Add ===
|
||||
|
|
@ -118,7 +119,7 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawModAddButton()
|
||||
{
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
using var raii = ImGuiRaii.PushFont( UiBuilder.IconFont );
|
||||
|
||||
if( ImGui.Button( FontAwesomeIcon.Plus.ToIconString(), SelectorButtonSizes * _selectorScalingFactor ) )
|
||||
{
|
||||
|
|
@ -126,12 +127,9 @@ namespace Penumbra.UI
|
|||
ImGui.OpenPopup( LabelAddModPopup );
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
raii.Pop();
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipAdd );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipAdd );
|
||||
|
||||
DrawModAddPopup();
|
||||
}
|
||||
|
|
@ -143,6 +141,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
|
||||
if( _modAddKeyboardFocus )
|
||||
{
|
||||
ImGui.SetKeyboardFocusHere();
|
||||
|
|
@ -181,20 +181,16 @@ namespace Penumbra.UI
|
|||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
// === Help ===
|
||||
private void DrawModHelpButton()
|
||||
{
|
||||
ImGui.PushFont( UiBuilder.IconFont );
|
||||
using var raii = ImGuiRaii.PushFont( UiBuilder.IconFont );
|
||||
if( ImGui.Button( FontAwesomeIcon.QuestionCircle.ToIconString(), HelpButtonSizes * _selectorScalingFactor ) )
|
||||
{
|
||||
ImGui.OpenPopup( LabelModHelpPopup );
|
||||
}
|
||||
|
||||
ImGui.PopFont();
|
||||
}
|
||||
|
||||
private static void DrawModHelpPopup()
|
||||
|
|
@ -208,6 +204,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
|
||||
ImGui.Dummy( Vector2.UnitY * ImGui.GetTextLineHeight() );
|
||||
ImGui.Text( "Mod Selector" );
|
||||
ImGui.BulletText( "Select a mod to obtain more information." );
|
||||
|
|
@ -268,24 +266,20 @@ namespace Penumbra.UI
|
|||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
// === Main ===
|
||||
private void DrawModsSelectorButtons()
|
||||
{
|
||||
// Selector controls
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.WindowPadding, ZeroVector );
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.FrameRounding, 0 );
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.WindowPadding, ZeroVector )
|
||||
.Push( ImGuiStyleVar.FrameRounding, 0 );
|
||||
|
||||
DrawModAddButton();
|
||||
ImGui.SameLine();
|
||||
DrawModHelpButton();
|
||||
ImGui.SameLine();
|
||||
DrawModTrashButton();
|
||||
|
||||
ImGui.PopStyleVar( 2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -296,7 +290,7 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawTextFilter()
|
||||
{
|
||||
ImGui.SetNextItemWidth( SelectorPanelWidth * _selectorScalingFactor - 22 );
|
||||
ImGui.SetNextItemWidth( SelectorPanelWidth * _selectorScalingFactor - 22 * ImGuiHelpers.GlobalScale );
|
||||
var tmp = _modFilterInput;
|
||||
if( ImGui.InputTextWithHint( LabelModFilter, "Filter Mods...", ref tmp, 256 ) && _modFilterInput != tmp )
|
||||
{
|
||||
|
|
@ -304,10 +298,7 @@ namespace Penumbra.UI
|
|||
_modFilterInput = tmp;
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( TooltipModFilter );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( TooltipModFilter );
|
||||
}
|
||||
|
||||
private void DrawToggleFilter()
|
||||
|
|
@ -315,30 +306,25 @@ namespace Penumbra.UI
|
|||
if( ImGui.BeginCombo( "##ModStateFilter", "",
|
||||
ImGuiComboFlags.NoPreview | ImGuiComboFlags.PopupAlignLeft | ImGuiComboFlags.HeightLargest ) )
|
||||
{
|
||||
var flags = ( int )Cache.StateFilter;
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndCombo );
|
||||
var flags = ( int )Cache.StateFilter;
|
||||
foreach( ModFilter flag in Enum.GetValues( typeof( ModFilter ) ) )
|
||||
{
|
||||
ImGui.CheckboxFlags( flag.ToName(), ref flags, ( int )flag );
|
||||
}
|
||||
|
||||
Cache.StateFilter = ( ModFilter )flags;
|
||||
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( "Filter mods for their activation status." );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( "Filter mods for their activation status." );
|
||||
}
|
||||
|
||||
private void DrawModsSelectorFilter()
|
||||
{
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, ZeroVector );
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.ItemSpacing, ZeroVector );
|
||||
DrawTextFilter();
|
||||
ImGui.SameLine();
|
||||
DrawToggleFilter();
|
||||
ImGui.PopStyleVar();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -360,15 +346,14 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndDragDropTarget );
|
||||
|
||||
if( IsDropping( DraggedModLabel ) )
|
||||
{
|
||||
var payload = ImGui.GetDragDropPayload();
|
||||
var modIndex = Marshal.ReadInt32( payload.Data );
|
||||
var mod = Cache.GetMod( modIndex ).Item1;
|
||||
if( mod != null )
|
||||
{
|
||||
mod.Data.Move( folder );
|
||||
}
|
||||
mod?.Data.Move( folder );
|
||||
}
|
||||
else if( IsDropping( DraggedFolderLabel ) )
|
||||
{
|
||||
|
|
@ -381,8 +366,6 @@ namespace Penumbra.UI
|
|||
droppedFolder.Move( folder );
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndDragDropTarget();
|
||||
}
|
||||
|
||||
private void DragDropSourceFolder( ModFolder folder )
|
||||
|
|
@ -392,11 +375,12 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndDragDropSource );
|
||||
|
||||
var folderName = folder.FullName;
|
||||
var ptr = Marshal.StringToHGlobalUni( folderName );
|
||||
ImGui.SetDragDropPayload( DraggedFolderLabel, ptr, ( uint )( folderName.Length + 1 ) * 2 );
|
||||
ImGui.Text( $"Moving {folderName}..." );
|
||||
ImGui.EndDragDropSource();
|
||||
}
|
||||
|
||||
private void DragDropSourceMod( int modIndex, string modName )
|
||||
|
|
@ -406,10 +390,11 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndDragDropSource );
|
||||
|
||||
Marshal.WriteInt32( _dragDropPayload, modIndex );
|
||||
ImGui.SetDragDropPayload( "ModIndex", _dragDropPayload, 4 );
|
||||
ImGui.Text( $"Moving {modName}..." );
|
||||
ImGui.EndDragDropSource();
|
||||
}
|
||||
|
||||
~Selector()
|
||||
|
|
@ -496,6 +481,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
|
||||
if( ModPanel.DrawSortOrder( mod.Data, _modManager, this ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
|
|
@ -505,8 +492,6 @@ namespace Penumbra.UI
|
|||
{
|
||||
ImGui.SetKeyboardFocusHere( mod.Data.SortOrder.FullPath.Length - 1 );
|
||||
}
|
||||
|
||||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
// === Folder ===
|
||||
|
|
@ -545,7 +530,7 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawRenameFolderInput( ModFolder folder )
|
||||
{
|
||||
ImGui.SetNextItemWidth( 150 );
|
||||
ImGui.SetNextItemWidth( 150 * ImGuiHelpers.GlobalScale );
|
||||
if( !ImGui.InputTextWithHint( "##NewFolderName", "Rename Folder...", ref _newFolderName, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
|
|
@ -566,23 +551,25 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawFolderContextMenu( ModFolder folder, int currentIdx, string treeName )
|
||||
{
|
||||
if( ImGui.BeginPopup( treeName ) )
|
||||
if( !ImGui.BeginPopup( treeName ) )
|
||||
{
|
||||
if( ImGui.MenuItem( "Enable All Descendants" ) )
|
||||
{
|
||||
ChangeStatusOfChildren( folder, currentIdx, true );
|
||||
}
|
||||
|
||||
if( ImGui.MenuItem( "Disable All Descendants" ) )
|
||||
{
|
||||
ChangeStatusOfChildren( folder, currentIdx, false );
|
||||
}
|
||||
|
||||
ImGui.Dummy( Vector2.UnitY * 10 );
|
||||
DrawRenameFolderInput( folder );
|
||||
|
||||
ImGui.EndPopup();
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
|
||||
if( ImGui.MenuItem( "Enable All Descendants" ) )
|
||||
{
|
||||
ChangeStatusOfChildren( folder, currentIdx, true );
|
||||
}
|
||||
|
||||
if( ImGui.MenuItem( "Disable All Descendants" ) )
|
||||
{
|
||||
ChangeStatusOfChildren( folder, currentIdx, false );
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy( 0, 10 );
|
||||
DrawRenameFolderInput( folder );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -607,35 +594,32 @@ namespace Penumbra.UI
|
|||
if( collection == ModCollection.Empty
|
||||
|| collection == _modManager.Collections.CurrentCollection )
|
||||
{
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.Alpha, 0.5f );
|
||||
using var _ = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f );
|
||||
ImGui.Button( label, Vector2.UnitX * size );
|
||||
ImGui.PopStyleVar();
|
||||
}
|
||||
else if( ImGui.Button( label, Vector2.UnitX * size ) )
|
||||
{
|
||||
_base._menu.CollectionsTab.SetCurrentCollection( collection );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
$"Switches to the currently set {tooltipLabel} collection, if it is not set to None and it is not the current collection already." );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip(
|
||||
$"Switches to the currently set {tooltipLabel} collection, if it is not set to None and it is not the current collection already." );
|
||||
}
|
||||
|
||||
private void DrawHeaderBar()
|
||||
{
|
||||
const float size = 200;
|
||||
|
||||
DrawModsSelectorFilter();
|
||||
var textSize = ImGui.CalcTextSize( TabCollections.LabelCurrentCollection ).X + ImGui.GetStyle().ItemInnerSpacing.X;
|
||||
var comboSize = size * ImGui.GetIO().FontGlobalScale;
|
||||
var offset = comboSize + textSize;
|
||||
|
||||
var buttonSize = ( ImGui.GetWindowContentRegionWidth()
|
||||
var buttonSize = Math.Max( ( ImGui.GetWindowContentRegionWidth()
|
||||
- offset
|
||||
- SelectorPanelWidth * _selectorScalingFactor
|
||||
- 4 * ImGui.GetStyle().ItemSpacing.X )
|
||||
/ 2;
|
||||
/ 2, 5f );
|
||||
ImGui.SameLine();
|
||||
DrawCollectionButton( "Default", "default", buttonSize, _modManager.Collections.DefaultCollection );
|
||||
|
||||
|
|
@ -644,9 +628,8 @@ namespace Penumbra.UI
|
|||
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth( comboSize );
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
|
||||
_base._menu.CollectionsTab.DrawCurrentCollectionSelector( false );
|
||||
ImGui.PopStyleVar();
|
||||
}
|
||||
|
||||
private void DrawFolderContent( ModFolder folder, ref int idx )
|
||||
|
|
@ -683,8 +666,9 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawModFolder( ModFolder folder, ref int idx )
|
||||
{
|
||||
var treeName = $"{folder.Name}##{folder.FullName}";
|
||||
var open = ImGui.TreeNodeEx( treeName );
|
||||
var treeName = $"{folder.Name}##{folder.FullName}";
|
||||
var open = ImGui.TreeNodeEx( treeName );
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.TreePop, open );
|
||||
if( ImGui.IsItemClicked( ImGuiMouseButton.Right ) )
|
||||
{
|
||||
_newFolderName = string.Empty;
|
||||
|
|
@ -698,7 +682,6 @@ namespace Penumbra.UI
|
|||
if( open )
|
||||
{
|
||||
DrawFolderContent( folder, ref idx );
|
||||
ImGui.TreePop();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -708,17 +691,10 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawMod( Mod.Mod mod, int modIndex, uint color )
|
||||
{
|
||||
if( color != 0 )
|
||||
{
|
||||
ImGui.PushStyleColor( ImGuiCol.Text, color );
|
||||
}
|
||||
using var colorRaii = ImGuiRaii.PushColor( ImGuiCol.Text, color, color != 0 );
|
||||
|
||||
var selected = ImGui.Selectable( $"{mod.Data.Meta.Name}##{modIndex}", modIndex == _index );
|
||||
|
||||
if( color != 0 )
|
||||
{
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
colorRaii.Pop();
|
||||
|
||||
var popupName = $"##SortOrderPopup{modIndex}";
|
||||
var firstOpen = false;
|
||||
|
|
@ -754,37 +730,33 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_selectorScalingFactor = Penumbra.Config.ScaleModSelector
|
||||
_selectorScalingFactor = ImGuiHelpers.GlobalScale
|
||||
* ( Penumbra.Config.ScaleModSelector
|
||||
? ImGui.GetWindowWidth() / SettingsMenu.MinSettingsSize.X
|
||||
: 1f;
|
||||
// Selector pane
|
||||
DrawHeaderBar();
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
|
||||
ImGui.BeginGroup();
|
||||
// Inlay selector list
|
||||
if( ImGui.BeginChild( LabelSelectorList,
|
||||
new Vector2( SelectorPanelWidth * _selectorScalingFactor, -ImGui.GetFrameHeightWithSpacing() ),
|
||||
true, ImGuiWindowFlags.HorizontalScrollbar ) )
|
||||
{
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.IndentSpacing, 12.5f );
|
||||
|
||||
var modIndex = 0;
|
||||
DrawFolderContent( _modManager.StructuredMods, ref modIndex );
|
||||
ImGui.PopStyleVar();
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
DrawModsSelectorButtons();
|
||||
ImGui.EndGroup();
|
||||
}
|
||||
finally
|
||||
: 1f );
|
||||
// Selector pane
|
||||
DrawHeaderBar();
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
|
||||
ImGui.BeginGroup();
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndGroup )
|
||||
.Push( ImGui.EndChild );
|
||||
// Inlay selector list
|
||||
if( ImGui.BeginChild( LabelSelectorList,
|
||||
new Vector2( SelectorPanelWidth * _selectorScalingFactor, -ImGui.GetFrameHeightWithSpacing() ),
|
||||
true, ImGuiWindowFlags.HorizontalScrollbar ) )
|
||||
{
|
||||
ImGui.PopStyleVar();
|
||||
style.Push( ImGuiStyleVar.IndentSpacing, 12.5f );
|
||||
|
||||
var modIndex = 0;
|
||||
DrawFolderContent( _modManager.StructuredMods, ref modIndex );
|
||||
style.Pop();
|
||||
}
|
||||
|
||||
raii.Pop();
|
||||
|
||||
DrawModsSelectorButtons();
|
||||
|
||||
style.Pop();
|
||||
DrawModHelpPopup();
|
||||
|
||||
DrawDeleteModal();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using FFXIVClientStructs.STD;
|
||||
using ImGuiNET;
|
||||
using Penumbra.UI.Custom;
|
||||
|
||||
namespace Penumbra.UI
|
||||
{
|
||||
|
|
@ -26,17 +28,19 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.TreePop );
|
||||
|
||||
if( typeMap->Count == 0 || !ImGui.BeginTable( $"##{label}_table", 4, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg ) )
|
||||
{
|
||||
ImGui.TreePop();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.TableSetupColumn( "Hash", ImGuiTableColumnFlags.WidthFixed, 100 );
|
||||
ImGui.TableSetupColumn( "Ptr", ImGuiTableColumnFlags.WidthFixed, 100 );
|
||||
ImGui.TableSetupColumn( "Path", ImGuiTableColumnFlags.WidthFixed, ImGui.GetWindowContentRegionWidth() - 300 );
|
||||
ImGui.TableSetupColumn( "Refs", ImGuiTableColumnFlags.WidthFixed, 30 );
|
||||
raii.Push( ImGui.EndTable );
|
||||
|
||||
ImGui.TableSetupColumn( "Hash", ImGuiTableColumnFlags.WidthFixed, 100 * ImGuiHelpers.GlobalScale );
|
||||
ImGui.TableSetupColumn( "Ptr", ImGuiTableColumnFlags.WidthFixed, 100 * ImGuiHelpers.GlobalScale );
|
||||
ImGui.TableSetupColumn( "Path", ImGuiTableColumnFlags.WidthFixed, ImGui.GetWindowContentRegionWidth() - 300 * ImGuiHelpers.GlobalScale );
|
||||
ImGui.TableSetupColumn( "Refs", ImGuiTableColumnFlags.WidthFixed, 30 * ImGuiHelpers.GlobalScale );
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
var node = typeMap->SmallestValue;
|
||||
|
|
@ -59,9 +63,6 @@ namespace Penumbra.UI
|
|||
ImGui.Text( node->KeyValuePair.Item2.Value->RefCount.ToString() );
|
||||
node = node->Next();
|
||||
}
|
||||
|
||||
ImGui.EndTable();
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
private unsafe void DrawCategoryContainer( string label, ResourceGraph.CategoryContainer container )
|
||||
|
|
@ -72,6 +73,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.TreePop );
|
||||
|
||||
var node = map->SmallestValue;
|
||||
while( !node->IsNil )
|
||||
{
|
||||
|
|
@ -79,8 +82,6 @@ namespace Penumbra.UI
|
|||
node->KeyValuePair.Item2.Value );
|
||||
node = node->Next();
|
||||
}
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
private unsafe void DrawResourceManagerTab()
|
||||
|
|
@ -90,6 +91,8 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
var resourceHandler = *( ResourceManager** )( Dalamud.SigScanner.Module.BaseAddress + 0x1D93AC0 );
|
||||
|
||||
if( resourceHandler == null )
|
||||
|
|
@ -97,28 +100,27 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
if( ImGui.BeginChild( "##ResourceManagerChild", -Vector2.One, true ) )
|
||||
raii.Push( ImGui.EndChild );
|
||||
if( !ImGui.BeginChild( "##ResourceManagerChild", -Vector2.One, true ) )
|
||||
{
|
||||
DrawCategoryContainer( "Common", resourceHandler->ResourceGraph->CommonContainer );
|
||||
DrawCategoryContainer( "BgCommon", resourceHandler->ResourceGraph->BgCommonContainer );
|
||||
DrawCategoryContainer( "Bg", resourceHandler->ResourceGraph->BgContainer );
|
||||
DrawCategoryContainer( "Cut", resourceHandler->ResourceGraph->CutContainer );
|
||||
DrawCategoryContainer( "Chara", resourceHandler->ResourceGraph->CharaContainer );
|
||||
DrawCategoryContainer( "Shader", resourceHandler->ResourceGraph->ShaderContainer );
|
||||
DrawCategoryContainer( "Ui", resourceHandler->ResourceGraph->UiContainer );
|
||||
DrawCategoryContainer( "Sound", resourceHandler->ResourceGraph->SoundContainer );
|
||||
DrawCategoryContainer( "Vfx", resourceHandler->ResourceGraph->VfxContainer );
|
||||
DrawCategoryContainer( "UiScript", resourceHandler->ResourceGraph->UiScriptContainer );
|
||||
DrawCategoryContainer( "Exd", resourceHandler->ResourceGraph->ExdContainer );
|
||||
DrawCategoryContainer( "GameScript", resourceHandler->ResourceGraph->GameScriptContainer );
|
||||
DrawCategoryContainer( "Music", resourceHandler->ResourceGraph->MusicContainer );
|
||||
DrawCategoryContainer( "SqpackTest", resourceHandler->ResourceGraph->SqpackTestContainer );
|
||||
DrawCategoryContainer( "Debug", resourceHandler->ResourceGraph->DebugContainer );
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
ImGui.EndTabItem();
|
||||
DrawCategoryContainer( "Common", resourceHandler->ResourceGraph->CommonContainer );
|
||||
DrawCategoryContainer( "BgCommon", resourceHandler->ResourceGraph->BgCommonContainer );
|
||||
DrawCategoryContainer( "Bg", resourceHandler->ResourceGraph->BgContainer );
|
||||
DrawCategoryContainer( "Cut", resourceHandler->ResourceGraph->CutContainer );
|
||||
DrawCategoryContainer( "Chara", resourceHandler->ResourceGraph->CharaContainer );
|
||||
DrawCategoryContainer( "Shader", resourceHandler->ResourceGraph->ShaderContainer );
|
||||
DrawCategoryContainer( "Ui", resourceHandler->ResourceGraph->UiContainer );
|
||||
DrawCategoryContainer( "Sound", resourceHandler->ResourceGraph->SoundContainer );
|
||||
DrawCategoryContainer( "Vfx", resourceHandler->ResourceGraph->VfxContainer );
|
||||
DrawCategoryContainer( "UiScript", resourceHandler->ResourceGraph->UiScriptContainer );
|
||||
DrawCategoryContainer( "Exd", resourceHandler->ResourceGraph->ExdContainer );
|
||||
DrawCategoryContainer( "GameScript", resourceHandler->ResourceGraph->GameScriptContainer );
|
||||
DrawCategoryContainer( "Music", resourceHandler->ResourceGraph->MusicContainer );
|
||||
DrawCategoryContainer( "SqpackTest", resourceHandler->ResourceGraph->SqpackTestContainer );
|
||||
DrawCategoryContainer( "Debug", resourceHandler->ResourceGraph->DebugContainer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ using ImGuiNET;
|
|||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -65,13 +66,10 @@ namespace Penumbra.UI
|
|||
_base._modManager.SetTempDirectory( tempPath );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( "The folder used to store temporary meta manipulation files.\n"
|
||||
+ "Leave this blank if you have no reason not to.\n"
|
||||
+ "A folder 'penumbrametatmp' will be created as a subdirectory to the specified directory.\n"
|
||||
+ "If none is specified (i.e. this is blank) this folder will be created in the root folder instead." );
|
||||
}
|
||||
ImGuiCustom.HoverTooltip( "The folder used to store temporary meta manipulation files.\n"
|
||||
+ "Leave this blank if you have no reason not to.\n"
|
||||
+ "A folder 'penumbrametatmp' will be created as a subdirectory to the specified directory.\n"
|
||||
+ "If none is specified (i.e. this is blank) this folder will be created in the root folder instead." );
|
||||
|
||||
ImGui.SameLine();
|
||||
if( ImGui.Button( LabelOpenTempFolder ) )
|
||||
|
|
@ -115,7 +113,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
_config.IsEnabled = enabled;
|
||||
_configChanged = true;
|
||||
Service<ResidentResources>.Get().ReloadPlayerResources();
|
||||
Service< ResidentResources >.Get().ReloadPlayerResources();
|
||||
_base._penumbra.ObjectReloader.RedrawAll( enabled ? RedrawType.WithSettings : RedrawType.WithoutSettings );
|
||||
if( _config.EnablePlayerWatch )
|
||||
{
|
||||
|
|
@ -177,10 +175,10 @@ namespace Penumbra.UI
|
|||
|
||||
private void DrawDisableNotificationsBox()
|
||||
{
|
||||
var fswatch = _config.DisableFileSystemNotifications;
|
||||
if( ImGui.Checkbox( LabelDisableNotifications, ref fswatch ) )
|
||||
var fsWatch = _config.DisableFileSystemNotifications;
|
||||
if( ImGui.Checkbox( LabelDisableNotifications, ref fsWatch ) )
|
||||
{
|
||||
_config.DisableFileSystemNotifications = fswatch;
|
||||
_config.DisableFileSystemNotifications = fsWatch;
|
||||
_configChanged = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -210,39 +208,35 @@ namespace Penumbra.UI
|
|||
if( ImGui.Checkbox( LabelEnabledPlayerWatch, ref enabled ) )
|
||||
{
|
||||
_config.EnablePlayerWatch = enabled;
|
||||
_configChanged = true;
|
||||
_configChanged = true;
|
||||
Penumbra.PlayerWatcher.SetStatus( enabled );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"If this setting is enabled, penumbra will keep tabs on characters that have a corresponding collection setup in the Collections tab.\n"
|
||||
+ "Penumbra will try to automatically redraw those characters using their collection when they first appear in an instance, or when they change their current equip." );
|
||||
|
||||
if( !_config.EnablePlayerWatch || !_config.ShowAdvanced )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"If this setting is enabled, penumbra will keep tabs on characters that have a corresponding collection setup in the Collections tab.\n"
|
||||
+ "Penumbra will try to automatically redraw those characters using their collection when they first appear in an instance, or when they change their current equip." );
|
||||
return;
|
||||
}
|
||||
|
||||
if( _config.EnablePlayerWatch && _config.ShowAdvanced )
|
||||
var waitFrames = _config.WaitFrames;
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth( 50 );
|
||||
if( ImGui.InputInt( LabelWaitFrames, ref waitFrames, 0, 0 )
|
||||
&& waitFrames != _config.WaitFrames
|
||||
&& waitFrames > 0
|
||||
&& waitFrames < 3000 )
|
||||
{
|
||||
var waitFrames = _config.WaitFrames;
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth( 50 );
|
||||
if( ImGui.InputInt( LabelWaitFrames, ref waitFrames, 0, 0 )
|
||||
&& waitFrames != _config.WaitFrames
|
||||
&& waitFrames > 0
|
||||
&& waitFrames < 3000 )
|
||||
{
|
||||
_base._penumbra.ObjectReloader.DefaultWaitFrames = waitFrames;
|
||||
_config.WaitFrames = waitFrames;
|
||||
_configChanged = true;
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"The number of frames penumbra waits after some events (like zone changes) until it starts trying to redraw actors again, in a range of [1, 3001].\n"
|
||||
+ "Keep this as low as possible while producing stable results." );
|
||||
}
|
||||
_base._penumbra.ObjectReloader.DefaultWaitFrames = waitFrames;
|
||||
_config.WaitFrames = waitFrames;
|
||||
_configChanged = true;
|
||||
}
|
||||
|
||||
ImGuiCustom.HoverTooltip(
|
||||
"The number of frames penumbra waits after some events (like zone changes) until it starts trying to redraw actors again, in a range of [1, 3001].\n"
|
||||
+ "Keep this as low as possible while producing stable results." );
|
||||
}
|
||||
|
||||
private static void DrawReloadResourceButton()
|
||||
|
|
@ -264,23 +258,24 @@ namespace Penumbra.UI
|
|||
|
||||
public void Draw()
|
||||
{
|
||||
var ret = ImGui.BeginTabItem( LabelTab );
|
||||
if( !ret )
|
||||
if( !ImGui.BeginTabItem( LabelTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
DrawRootFolder();
|
||||
|
||||
DrawRediscoverButton();
|
||||
ImGui.SameLine();
|
||||
DrawOpenModsButton();
|
||||
|
||||
Custom.ImGuiCustom.VerticalDistance( DefaultVerticalSpace );
|
||||
ImGuiCustom.VerticalDistance( DefaultVerticalSpace );
|
||||
DrawEnabledBox();
|
||||
DrawEnabledPlayerWatcher();
|
||||
|
||||
Custom.ImGuiCustom.VerticalDistance( DefaultVerticalSpace );
|
||||
ImGuiCustom.VerticalDistance( DefaultVerticalSpace );
|
||||
DrawScaleModSelectorBox();
|
||||
DrawSortFoldersFirstBox();
|
||||
DrawShowAdvancedBox();
|
||||
|
|
@ -295,8 +290,6 @@ namespace Penumbra.UI
|
|||
_config.Save();
|
||||
_configChanged = false;
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Numerics;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
|
|
@ -54,13 +55,14 @@ namespace Penumbra.UI
|
|||
#else
|
||||
var ret = ImGui.Begin( _base._penumbra.Name, ref Visible );
|
||||
#endif
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.End );
|
||||
if( !ret )
|
||||
{
|
||||
ImGui.End();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.BeginTabBar( PenumbraSettingsLabel );
|
||||
raii.Push( ImGui.EndTabBar );
|
||||
|
||||
_settingsTab.Draw();
|
||||
CollectionsTab.Draw();
|
||||
|
|
@ -82,9 +84,6 @@ namespace Penumbra.UI
|
|||
_base.DrawDebugTab();
|
||||
_base.DrawResourceManagerTab();
|
||||
}
|
||||
|
||||
ImGui.EndTabBar();
|
||||
ImGui.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue