mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-30 12:23:41 +01:00
Change most things to new byte strings, introduce new ResourceLoader and Logger fully.
This commit is contained in:
parent
5d77cd5514
commit
f5fccb0235
55 changed files with 2681 additions and 2730 deletions
|
|
@ -1,8 +1,8 @@
|
|||
using System.Numerics;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Windows.Forms;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using Penumbra.GameData.ByteString;
|
||||
|
||||
namespace Penumbra.UI.Custom
|
||||
{
|
||||
|
|
@ -20,6 +20,19 @@ namespace Penumbra.UI.Custom
|
|||
ImGui.SetTooltip( "Click to copy to clipboard." );
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void CopyOnClickSelectable( Utf8String text )
|
||||
{
|
||||
if( ImGuiNative.igSelectable_Bool( text.Path, 0, ImGuiSelectableFlags.None, Vector2.Zero ) != 0 )
|
||||
{
|
||||
ImGuiNative.igSetClipboardText( text.Path );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( "Click to copy to clipboard." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class ImGuiCustom
|
||||
|
|
|
|||
|
|
@ -21,11 +21,21 @@ public partial class SettingsInterface
|
|||
private string _filePathFilter = string.Empty;
|
||||
private string _filePathFilterLower = string.Empty;
|
||||
|
||||
private readonly float _leftTextLength =
|
||||
ImGui.CalcTextSize( "chara/human/c0000/obj/body/b0000/material/v0000/mt_c0000b0000_b.mtrl" ).X / ImGuiHelpers.GlobalScale + 40;
|
||||
private const float LeftTextLength = 600;
|
||||
|
||||
private float _arrowLength = 0;
|
||||
|
||||
private static void DrawLine( Utf8GamePath path, FullPath name )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.CopyOnClickSelectable( path.Path );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltLeft );
|
||||
ImGui.SameLine();
|
||||
ImGuiCustom.CopyOnClickSelectable( name.InternalName );
|
||||
}
|
||||
|
||||
private static void DrawLine( string path, string name )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
|
|
@ -45,13 +55,13 @@ public partial class SettingsInterface
|
|||
_arrowLength = ImGui.CalcTextSize( FontAwesomeIcon.LongArrowAltLeft.ToIconString() ).X / ImGuiHelpers.GlobalScale;
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( _leftTextLength * ImGuiHelpers.GlobalScale );
|
||||
ImGui.SetNextItemWidth( LeftTextLength * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( "##effective_changes_gfilter", "Filter game path...", ref _gamePathFilter, 256 ) )
|
||||
{
|
||||
_gamePathFilterLower = _gamePathFilter.ToLowerInvariant();
|
||||
}
|
||||
|
||||
ImGui.SameLine( ( _leftTextLength + _arrowLength ) * ImGuiHelpers.GlobalScale + 3 * ImGui.GetStyle().ItemSpacing.X );
|
||||
ImGui.SameLine( ( LeftTextLength + _arrowLength ) * ImGuiHelpers.GlobalScale + 3 * ImGui.GetStyle().ItemSpacing.X );
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.InputTextWithHint( "##effective_changes_ffilter", "Filter file path...", ref _filePathFilter, 256 ) )
|
||||
{
|
||||
|
|
@ -59,7 +69,7 @@ public partial class SettingsInterface
|
|||
}
|
||||
}
|
||||
|
||||
private bool CheckFilters( KeyValuePair< GamePath, FullPath > kvp )
|
||||
private bool CheckFilters( KeyValuePair< Utf8GamePath, FullPath > kvp )
|
||||
{
|
||||
if( _gamePathFilter.Any() && !kvp.Key.ToString().Contains( _gamePathFilterLower ) )
|
||||
{
|
||||
|
|
@ -69,7 +79,7 @@ public partial class SettingsInterface
|
|||
return !_filePathFilter.Any() || kvp.Value.FullName.ToLowerInvariant().Contains( _filePathFilterLower );
|
||||
}
|
||||
|
||||
private bool CheckFilters( KeyValuePair< GamePath, GamePath > kvp )
|
||||
private bool CheckFilters( KeyValuePair< Utf8GamePath, Utf8GamePath > kvp )
|
||||
{
|
||||
if( _gamePathFilter.Any() && !kvp.Key.ToString().Contains( _gamePathFilterLower ) )
|
||||
{
|
||||
|
|
@ -94,11 +104,6 @@ public partial class SettingsInterface
|
|||
void DrawFileLines( ModCollectionCache cache )
|
||||
{
|
||||
foreach( var (gp, fp) in cache.ResolvedFiles.Where( CheckFilters ) )
|
||||
{
|
||||
DrawLine( gp, fp.FullName );
|
||||
}
|
||||
|
||||
foreach( var (gp, fp) in cache.SwappedFiles.Where( CheckFilters ) )
|
||||
{
|
||||
DrawLine( gp, fp );
|
||||
}
|
||||
|
|
@ -139,75 +144,67 @@ public partial class SettingsInterface
|
|||
var activeCollection = modManager.Collections.ActiveCollection.Cache;
|
||||
var forcedCollection = modManager.Collections.ForcedCollection.Cache;
|
||||
|
||||
var (activeResolved, activeSwap, activeMeta) = activeCollection != null
|
||||
? ( activeCollection.ResolvedFiles.Count, activeCollection.SwappedFiles.Count, activeCollection.MetaManipulations.Count )
|
||||
: ( 0, 0, 0 );
|
||||
var (forcedResolved, forcedSwap, forcedMeta) = forcedCollection != null
|
||||
? ( forcedCollection.ResolvedFiles.Count, forcedCollection.SwappedFiles.Count, forcedCollection.MetaManipulations.Count )
|
||||
: ( 0, 0, 0 );
|
||||
var totalLines = activeResolved + forcedResolved + activeSwap + forcedSwap + activeMeta + forcedMeta;
|
||||
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 );
|
||||
var totalLines = activeResolved + forcedResolved + activeMeta + forcedMeta;
|
||||
if( totalLines == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( ImGui.BeginTable( "##effective_changes", 2, flags, AutoFillSize ) )
|
||||
if( !ImGui.BeginTable( "##effective_changes", 2, flags, AutoFillSize ) )
|
||||
{
|
||||
raii.Push( ImGui.EndTable );
|
||||
ImGui.TableSetupColumn( "##tableGamePathCol", ImGuiTableColumnFlags.None, _leftTextLength * ImGuiHelpers.GlobalScale );
|
||||
return;
|
||||
}
|
||||
|
||||
if( _filePathFilter.Any() || _gamePathFilter.Any() )
|
||||
raii.Push( ImGui.EndTable );
|
||||
ImGui.TableSetupColumn( "##tableGamePathCol", ImGuiTableColumnFlags.None, LeftTextLength * ImGuiHelpers.GlobalScale );
|
||||
|
||||
if( _filePathFilter.Length > 0 || _gamePathFilter.Length > 0 )
|
||||
{
|
||||
DrawFilteredRows( activeCollection, forcedCollection );
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiListClipperPtr clipper;
|
||||
unsafe
|
||||
{
|
||||
DrawFilteredRows( activeCollection, forcedCollection );
|
||||
clipper = new ImGuiListClipperPtr( ImGuiNative.ImGuiListClipper_ImGuiListClipper() );
|
||||
}
|
||||
else
|
||||
|
||||
clipper.Begin( totalLines );
|
||||
|
||||
|
||||
while( clipper.Step() )
|
||||
{
|
||||
ImGuiListClipperPtr clipper;
|
||||
unsafe
|
||||
for( var actualRow = clipper.DisplayStart; actualRow < clipper.DisplayEnd; actualRow++ )
|
||||
{
|
||||
clipper = new ImGuiListClipperPtr( ImGuiNative.ImGuiListClipper_ImGuiListClipper() );
|
||||
}
|
||||
|
||||
clipper.Begin( totalLines );
|
||||
|
||||
|
||||
while( clipper.Step() )
|
||||
{
|
||||
for( var actualRow = clipper.DisplayStart; actualRow < clipper.DisplayEnd; actualRow++ )
|
||||
var row = actualRow;
|
||||
ImGui.TableNextRow();
|
||||
if( row < activeResolved )
|
||||
{
|
||||
var row = actualRow;
|
||||
ImGui.TableNextRow();
|
||||
if( row < activeResolved )
|
||||
{
|
||||
var (gamePath, file) = activeCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, file.FullName );
|
||||
}
|
||||
else if( ( row -= activeResolved ) < activeSwap )
|
||||
{
|
||||
var (gamePath, swap) = activeCollection!.SwappedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, swap );
|
||||
}
|
||||
else if( ( row -= activeSwap ) < activeMeta )
|
||||
{
|
||||
var (manip, mod) = activeCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawLine( manip.IdentifierString(), mod.Data.Meta.Name );
|
||||
}
|
||||
else if( ( row -= activeMeta ) < forcedResolved )
|
||||
{
|
||||
var (gamePath, file) = forcedCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, file.FullName );
|
||||
}
|
||||
else if( ( row -= forcedResolved ) < forcedSwap )
|
||||
{
|
||||
var (gamePath, swap) = forcedCollection!.SwappedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, swap );
|
||||
}
|
||||
else
|
||||
{
|
||||
row -= forcedSwap;
|
||||
var (manip, mod) = forcedCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawLine( manip.IdentifierString(), mod.Data.Meta.Name );
|
||||
}
|
||||
var (gamePath, file) = activeCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, file );
|
||||
}
|
||||
else if( ( row -= activeResolved ) < activeMeta )
|
||||
{
|
||||
var (manip, mod) = activeCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawLine( manip.IdentifierString(), mod.Data.Meta.Name );
|
||||
}
|
||||
else if( ( row -= activeMeta ) < forcedResolved )
|
||||
{
|
||||
var (gamePath, file) = forcedCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, file );
|
||||
}
|
||||
else
|
||||
{
|
||||
row -= forcedResolved;
|
||||
var (manip, mod) = forcedCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawLine( manip.IdentifierString(), mod.Data.Meta.Name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ 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;
|
||||
|
|
@ -56,7 +55,7 @@ public partial class SettingsInterface
|
|||
private Option? _selectedOption;
|
||||
private string _currentGamePaths = "";
|
||||
|
||||
private (FullPath name, bool selected, uint color, RelPath relName)[]? _fullFilenameList;
|
||||
private (FullPath name, bool selected, uint color, Utf8RelPath relName)[]? _fullFilenameList;
|
||||
|
||||
private readonly Selector _selector;
|
||||
private readonly SettingsInterface _base;
|
||||
|
|
@ -218,7 +217,10 @@ public partial class SettingsInterface
|
|||
indent.Push( 15f );
|
||||
foreach( var file in files )
|
||||
{
|
||||
ImGui.Selectable( file );
|
||||
unsafe
|
||||
{
|
||||
ImGuiNative.igSelectable_Bool( file.Path.Path, 0, ImGuiSelectableFlags.None, Vector2.Zero );
|
||||
}
|
||||
}
|
||||
|
||||
foreach( var manip in manipulations )
|
||||
|
|
@ -258,13 +260,13 @@ public partial class SettingsInterface
|
|||
foreach( var (source, target) in Meta.FileSwaps )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.CopyOnClickSelectable( source );
|
||||
ImGuiCustom.CopyOnClickSelectable( source.Path );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltRight );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.CopyOnClickSelectable( target );
|
||||
ImGuiCustom.CopyOnClickSelectable( target.InternalName );
|
||||
|
||||
ImGui.TableNextRow();
|
||||
}
|
||||
|
|
@ -278,7 +280,8 @@ public partial class SettingsInterface
|
|||
}
|
||||
|
||||
_fullFilenameList = Mod.Data.Resources.ModFiles
|
||||
.Select( f => ( f, false, ColorGreen, new RelPath( f, Mod.Data.BasePath ) ) ).ToArray();
|
||||
.Select( f => ( f, false, ColorGreen, Utf8RelPath.FromFile( f, Mod.Data.BasePath, out var p ) ? p : Utf8RelPath.Empty ) )
|
||||
.ToArray();
|
||||
|
||||
if( Meta.Groups.Count == 0 )
|
||||
{
|
||||
|
|
@ -339,24 +342,23 @@ public partial class SettingsInterface
|
|||
}
|
||||
}
|
||||
|
||||
private static int HandleDefaultString( GamePath[] gamePaths, out int removeFolders )
|
||||
private static int HandleDefaultString( Utf8GamePath[] gamePaths, out int removeFolders )
|
||||
{
|
||||
removeFolders = 0;
|
||||
var defaultIndex =
|
||||
gamePaths.IndexOf( p => ( ( string )p ).StartsWith( TextDefaultGamePath ) );
|
||||
var defaultIndex = gamePaths.IndexOf( p => p.Path.StartsWith( DefaultUtf8GamePath ) );
|
||||
if( defaultIndex < 0 )
|
||||
{
|
||||
return defaultIndex;
|
||||
}
|
||||
|
||||
string path = gamePaths[ defaultIndex ];
|
||||
var path = gamePaths[ defaultIndex ].Path;
|
||||
if( path.Length == TextDefaultGamePath.Length )
|
||||
{
|
||||
return defaultIndex;
|
||||
}
|
||||
|
||||
if( path[ TextDefaultGamePath.Length ] != '-'
|
||||
|| !int.TryParse( path.Substring( TextDefaultGamePath.Length + 1 ), out removeFolders ) )
|
||||
if( path[ TextDefaultGamePath.Length ] != ( byte )'-'
|
||||
|| !int.TryParse( path.Substring( TextDefaultGamePath.Length + 1 ).ToString(), out removeFolders ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -373,8 +375,9 @@ public partial class SettingsInterface
|
|||
|
||||
var option = ( Option )_selectedOption;
|
||||
|
||||
var gamePaths = _currentGamePaths.Split( ';' ).Select( p => new GamePath( p ) ).ToArray();
|
||||
if( gamePaths.Length == 0 || ( ( string )gamePaths[ 0 ] ).Length == 0 )
|
||||
var gamePaths = _currentGamePaths.Split( ';' )
|
||||
.Select( p => Utf8GamePath.FromString( p, out var path, false ) ? path : Utf8GamePath.Empty ).Where( p => !p.IsEmpty ).ToArray();
|
||||
if( gamePaths.Length == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -517,18 +520,18 @@ public partial class SettingsInterface
|
|||
{
|
||||
Selectable( 0, ColorGreen );
|
||||
|
||||
using var indent = ImGuiRaii.PushIndent( indentWidth );
|
||||
var tmpPaths = gamePaths.ToArray();
|
||||
foreach( var gamePath in tmpPaths )
|
||||
using var indent = ImGuiRaii.PushIndent( indentWidth );
|
||||
foreach( var gamePath in gamePaths.ToArray() )
|
||||
{
|
||||
string tmp = gamePath;
|
||||
var tmp = gamePath.ToString();
|
||||
var old = tmp;
|
||||
if( ImGui.InputText( $"##{fileName}_{gamePath}", ref tmp, 128, ImGuiInputTextFlags.EnterReturnsTrue )
|
||||
&& tmp != gamePath )
|
||||
&& tmp != old )
|
||||
{
|
||||
gamePaths.Remove( gamePath );
|
||||
if( tmp.Length > 0 )
|
||||
if( tmp.Length > 0 && Utf8GamePath.FromString( tmp, out var p, true ) )
|
||||
{
|
||||
gamePaths.Add( new GamePath( tmp ) );
|
||||
gamePaths.Add( p );
|
||||
}
|
||||
else if( gamePaths.Count == 0 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,136 +3,179 @@ using System.Linq;
|
|||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Util;
|
||||
using Penumbra.Mod;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Structs;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
namespace Penumbra.UI;
|
||||
|
||||
public partial class SettingsInterface
|
||||
{
|
||||
public partial class SettingsInterface
|
||||
private partial class PluginDetails
|
||||
{
|
||||
private partial class PluginDetails
|
||||
private const string LabelDescEdit = "##descedit";
|
||||
private const string LabelNewSingleGroupEdit = "##newSingleGroup";
|
||||
private const string LabelNewMultiGroup = "##newMultiGroup";
|
||||
private const string LabelGamePathsEditBox = "##gamePathsEdit";
|
||||
private const string ButtonAddToGroup = "Add to Group";
|
||||
private const string ButtonRemoveFromGroup = "Remove from Group";
|
||||
private const string TooltipAboutEdit = "Use Ctrl+Enter for newlines.";
|
||||
private const string TextNoOptionAvailable = "[Not Available]";
|
||||
private const string TextDefaultGamePath = "default";
|
||||
private static readonly Utf8String DefaultUtf8GamePath = Utf8String.FromStringUnsafe( TextDefaultGamePath, true );
|
||||
private const char GamePathsSeparator = ';';
|
||||
|
||||
private static readonly string TooltipFilesTabEdit =
|
||||
$"{TooltipFilesTab}\n"
|
||||
+ $"Red Files are replaced in another group or a different option in this group, but not contained in the current option.";
|
||||
|
||||
private static readonly string TooltipGamePathsEdit =
|
||||
$"Enter all game paths to add or remove, separated by '{GamePathsSeparator}'.\n"
|
||||
+ $"Use '{TextDefaultGamePath}' to add the original file path."
|
||||
+ $"Use '{TextDefaultGamePath}-#' to skip the first # relative directories.";
|
||||
|
||||
private const float MultiEditBoxWidth = 300f;
|
||||
|
||||
private bool DrawEditGroupSelector()
|
||||
{
|
||||
private const string LabelDescEdit = "##descedit";
|
||||
private const string LabelNewSingleGroupEdit = "##newSingleGroup";
|
||||
private const string LabelNewMultiGroup = "##newMultiGroup";
|
||||
private const string LabelGamePathsEditBox = "##gamePathsEdit";
|
||||
private const string ButtonAddToGroup = "Add to Group";
|
||||
private const string ButtonRemoveFromGroup = "Remove from Group";
|
||||
private const string TooltipAboutEdit = "Use Ctrl+Enter for newlines.";
|
||||
private const string TextNoOptionAvailable = "[Not Available]";
|
||||
private const string TextDefaultGamePath = "default";
|
||||
private const char GamePathsSeparator = ';';
|
||||
|
||||
private static readonly string TooltipFilesTabEdit =
|
||||
$"{TooltipFilesTab}\n"
|
||||
+ $"Red Files are replaced in another group or a different option in this group, but not contained in the current option.";
|
||||
|
||||
private static readonly string TooltipGamePathsEdit =
|
||||
$"Enter all game paths to add or remove, separated by '{GamePathsSeparator}'.\n"
|
||||
+ $"Use '{TextDefaultGamePath}' to add the original file path."
|
||||
+ $"Use '{TextDefaultGamePath}-#' to skip the first # relative directories.";
|
||||
|
||||
private const float MultiEditBoxWidth = 300f;
|
||||
|
||||
private bool DrawEditGroupSelector()
|
||||
ImGui.SetNextItemWidth( OptionSelectionWidth * ImGuiHelpers.GlobalScale );
|
||||
if( Meta!.Groups.Count == 0 )
|
||||
{
|
||||
ImGui.SetNextItemWidth( OptionSelectionWidth * ImGuiHelpers.GlobalScale );
|
||||
if( Meta!.Groups.Count == 0 )
|
||||
{
|
||||
ImGui.Combo( LabelGroupSelect, ref _selectedGroupIndex, TextNoOptionAvailable, 1 );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ImGui.Combo( LabelGroupSelect, ref _selectedGroupIndex
|
||||
, Meta.Groups.Values.Select( g => g.GroupName ).ToArray()
|
||||
, Meta.Groups.Count ) )
|
||||
{
|
||||
SelectGroup();
|
||||
SelectOption( 0 );
|
||||
}
|
||||
|
||||
return true;
|
||||
ImGui.Combo( LabelGroupSelect, ref _selectedGroupIndex, TextNoOptionAvailable, 1 );
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool DrawEditOptionSelector()
|
||||
if( ImGui.Combo( LabelGroupSelect, ref _selectedGroupIndex
|
||||
, Meta.Groups.Values.Select( g => g.GroupName ).ToArray()
|
||||
, Meta.Groups.Count ) )
|
||||
{
|
||||
SelectGroup();
|
||||
SelectOption( 0 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DrawEditOptionSelector()
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth( OptionSelectionWidth );
|
||||
if( ( _selectedGroup?.Options.Count ?? 0 ) == 0 )
|
||||
{
|
||||
ImGui.Combo( LabelOptionSelect, ref _selectedOptionIndex, TextNoOptionAvailable, 1 );
|
||||
return false;
|
||||
}
|
||||
|
||||
var group = ( OptionGroup )_selectedGroup!;
|
||||
if( ImGui.Combo( LabelOptionSelect, ref _selectedOptionIndex, group.Options.Select( o => o.OptionName ).ToArray(),
|
||||
group.Options.Count ) )
|
||||
{
|
||||
SelectOption();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void DrawFileListTabEdit()
|
||||
{
|
||||
if( ImGui.BeginTabItem( LabelFileListTab ) )
|
||||
{
|
||||
UpdateFilenameList();
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( _editMode ? TooltipFilesTabEdit : TooltipFilesTab );
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.BeginListBox( LabelFileListHeader, AutoFillSize - Vector2.UnitY * 1.5f * ImGui.GetTextLineHeight() ) )
|
||||
{
|
||||
for( var i = 0; i < Mod!.Data.Resources.ModFiles.Count; ++i )
|
||||
{
|
||||
DrawFileAndGamePaths( i );
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndListBox();
|
||||
|
||||
DrawGroupRow();
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
_fullFilenameList = null;
|
||||
}
|
||||
}
|
||||
|
||||
private ImGuiRaii.EndStack DrawMultiSelectorEditBegin( OptionGroup group )
|
||||
{
|
||||
var groupName = group.GroupName;
|
||||
if( ImGuiCustom.BeginFramedGroupEdit( ref groupName ) )
|
||||
{
|
||||
if( Penumbra.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 * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( $"##new_{group.GroupName}_l", "Add new option...", ref newOption, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue )
|
||||
&& newOption.Length != 0 )
|
||||
{
|
||||
group.Options.Add( new Option()
|
||||
{ OptionName = newOption, OptionDesc = "", OptionFiles = new Dictionary< Utf8RelPath, HashSet< Utf8GamePath > >() } );
|
||||
_selector.SaveCurrentMod();
|
||||
if( Mod!.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMultiSelectorEdit( OptionGroup group )
|
||||
{
|
||||
var nameBoxStart = CheckMarkSize;
|
||||
var flag = Mod!.Settings.Settings[ group.GroupName ];
|
||||
|
||||
using var raii = DrawMultiSelectorEditBegin( group );
|
||||
for( var i = 0; i < group.Options.Count; ++i )
|
||||
{
|
||||
var opt = group.Options[ i ];
|
||||
var label = $"##{group.GroupName}_{i}";
|
||||
DrawMultiSelectorCheckBox( group, i, flag, label );
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth( OptionSelectionWidth );
|
||||
if( ( _selectedGroup?.Options.Count ?? 0 ) == 0 )
|
||||
var newName = opt.OptionName;
|
||||
|
||||
if( nameBoxStart == CheckMarkSize )
|
||||
{
|
||||
ImGui.Combo( LabelOptionSelect, ref _selectedOptionIndex, TextNoOptionAvailable, 1 );
|
||||
return false;
|
||||
nameBoxStart = ImGui.GetCursorPosX();
|
||||
}
|
||||
|
||||
var group = ( OptionGroup )_selectedGroup!;
|
||||
if( ImGui.Combo( LabelOptionSelect, ref _selectedOptionIndex, group.Options.Select( o => o.OptionName ).ToArray(),
|
||||
group.Options.Count ) )
|
||||
{
|
||||
SelectOption();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void DrawFileListTabEdit()
|
||||
{
|
||||
if( ImGui.BeginTabItem( LabelFileListTab ) )
|
||||
{
|
||||
UpdateFilenameList();
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( _editMode ? TooltipFilesTabEdit : TooltipFilesTab );
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.BeginListBox( LabelFileListHeader, AutoFillSize - Vector2.UnitY * 1.5f * ImGui.GetTextLineHeight() ) )
|
||||
{
|
||||
for( var i = 0; i < Mod!.Data.Resources.ModFiles.Count; ++i )
|
||||
{
|
||||
DrawFileAndGamePaths( i );
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndListBox();
|
||||
|
||||
DrawGroupRow();
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
_fullFilenameList = null;
|
||||
}
|
||||
}
|
||||
|
||||
private ImGuiRaii.EndStack DrawMultiSelectorEditBegin( OptionGroup group )
|
||||
{
|
||||
var groupName = group.GroupName;
|
||||
if( ImGuiCustom.BeginFramedGroupEdit( ref groupName ) )
|
||||
{
|
||||
if( Penumbra.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 * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( $"##new_{group.GroupName}_l", "Add new option...", ref newOption, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue )
|
||||
&& newOption.Length != 0 )
|
||||
if( ImGui.InputText( $"{label}_l", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
group.Options.Add( new Option()
|
||||
{ OptionName = newOption, OptionDesc = "", OptionFiles = new Dictionary< RelPath, HashSet< GamePath > >() } );
|
||||
_selector.SaveCurrentMod();
|
||||
if( newName.Length == 0 )
|
||||
{
|
||||
Penumbra.ModManager.RemoveModOption( i, group, Mod.Data );
|
||||
}
|
||||
else if( newName != opt.OptionName )
|
||||
{
|
||||
group.Options[ i ] = new Option()
|
||||
{ OptionName = newName, OptionDesc = opt.OptionDesc, OptionFiles = opt.OptionFiles };
|
||||
_selector.SaveCurrentMod();
|
||||
}
|
||||
|
||||
if( Mod!.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
|
|
@ -140,244 +183,201 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawMultiSelectorEdit( OptionGroup group )
|
||||
DrawMultiSelectorEditAdd( group, nameBoxStart );
|
||||
}
|
||||
|
||||
private void DrawSingleSelectorEditGroup( OptionGroup group )
|
||||
{
|
||||
var groupName = group.GroupName;
|
||||
if( ImGui.InputText( $"##{groupName}_add", ref groupName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
var nameBoxStart = CheckMarkSize;
|
||||
var flag = Mod!.Settings.Settings[ group.GroupName ];
|
||||
|
||||
using var raii = DrawMultiSelectorEditBegin( group );
|
||||
for( var i = 0; i < group.Options.Count; ++i )
|
||||
if( Penumbra.ModManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
var opt = group.Options[ i ];
|
||||
var label = $"##{group.GroupName}_{i}";
|
||||
DrawMultiSelectorCheckBox( group, i, flag, label );
|
||||
|
||||
ImGui.SameLine();
|
||||
var newName = opt.OptionName;
|
||||
|
||||
if( nameBoxStart == CheckMarkSize )
|
||||
{
|
||||
nameBoxStart = ImGui.GetCursorPosX();
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputText( $"{label}_l", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
if( newName.Length == 0 )
|
||||
{
|
||||
Penumbra.ModManager.RemoveModOption( i, group, Mod.Data );
|
||||
}
|
||||
else if( newName != opt.OptionName )
|
||||
{
|
||||
group.Options[ i ] = new Option()
|
||||
{ OptionName = newName, OptionDesc = opt.OptionDesc, OptionFiles = opt.OptionFiles };
|
||||
_selector.SaveCurrentMod();
|
||||
}
|
||||
|
||||
if( Mod!.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DrawMultiSelectorEditAdd( group, nameBoxStart );
|
||||
}
|
||||
|
||||
private void DrawSingleSelectorEditGroup( OptionGroup group )
|
||||
{
|
||||
var groupName = group.GroupName;
|
||||
if( ImGui.InputText( $"##{groupName}_add", ref groupName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
if( Penumbra.ModManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float DrawSingleSelectorEdit( OptionGroup group )
|
||||
private float DrawSingleSelectorEdit( OptionGroup group )
|
||||
{
|
||||
var oldSetting = Mod!.Settings.Settings[ group.GroupName ];
|
||||
var code = oldSetting;
|
||||
if( ImGuiCustom.RenameableCombo( $"##{group.GroupName}", ref code, out var newName,
|
||||
group.Options.Select( x => x.OptionName ).ToArray(), group.Options.Count ) )
|
||||
{
|
||||
var oldSetting = Mod!.Settings.Settings[ group.GroupName ];
|
||||
var code = oldSetting;
|
||||
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 )
|
||||
{
|
||||
if( code == group.Options.Count )
|
||||
if( newName.Length > 0 )
|
||||
{
|
||||
if( newName.Length > 0 )
|
||||
Mod.Settings.Settings[ group.GroupName ] = code;
|
||||
group.Options.Add( new Option()
|
||||
{
|
||||
Mod.Settings.Settings[ group.GroupName ] = code;
|
||||
group.Options.Add( new Option()
|
||||
{
|
||||
OptionName = newName,
|
||||
OptionDesc = "",
|
||||
OptionFiles = new Dictionary< RelPath, HashSet< GamePath > >(),
|
||||
} );
|
||||
_selector.SaveCurrentMod();
|
||||
}
|
||||
OptionName = newName,
|
||||
OptionDesc = "",
|
||||
OptionFiles = new Dictionary< Utf8RelPath, HashSet< Utf8GamePath > >(),
|
||||
} );
|
||||
_selector.SaveCurrentMod();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( newName.Length == 0 )
|
||||
{
|
||||
Penumbra.ModManager.RemoveModOption( code, group, Mod.Data );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( newName.Length == 0 )
|
||||
if( newName != group.Options[ code ].OptionName )
|
||||
{
|
||||
Penumbra.ModManager.RemoveModOption( code, group, Mod.Data );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( newName != group.Options[ code ].OptionName )
|
||||
group.Options[ code ] = new Option()
|
||||
{
|
||||
group.Options[ code ] = new Option()
|
||||
{
|
||||
OptionName = newName, OptionDesc = group.Options[ code ].OptionDesc,
|
||||
OptionFiles = group.Options[ code ].OptionFiles,
|
||||
};
|
||||
_selector.SaveCurrentMod();
|
||||
}
|
||||
OptionName = newName, OptionDesc = group.Options[ code ].OptionDesc,
|
||||
OptionFiles = group.Options[ code ].OptionFiles,
|
||||
};
|
||||
_selector.SaveCurrentMod();
|
||||
}
|
||||
}
|
||||
|
||||
if( Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
|
||||
if( code != oldSetting )
|
||||
if( Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
Save();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
|
||||
if( code != oldSetting )
|
||||
{
|
||||
Save();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
var labelEditPos = ImGui.GetCursorPosX();
|
||||
DrawSingleSelectorEditGroup( group );
|
||||
|
||||
return labelEditPos;
|
||||
}
|
||||
|
||||
private void DrawAddSingleGroupField( float labelEditPos )
|
||||
{
|
||||
var newGroup = "";
|
||||
ImGui.SetCursorPosX( labelEditPos );
|
||||
if( labelEditPos == CheckMarkSize )
|
||||
{
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
}
|
||||
|
||||
if( ImGui.InputTextWithHint( LabelNewSingleGroupEdit, "Add new Single Group...", ref newGroup, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
Penumbra.ModManager.ChangeModGroup( "", newGroup, Mod.Data, SelectType.Single );
|
||||
// Adds empty group, so can not change filters.
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAddMultiGroupField()
|
||||
{
|
||||
var newGroup = "";
|
||||
ImGui.SetCursorPosX( CheckMarkSize );
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( LabelNewMultiGroup, "Add new Multi Group...", ref newGroup, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
Penumbra.ModManager.ChangeModGroup( "", newGroup, Mod.Data, SelectType.Multi );
|
||||
// Adds empty group, so can not change filters.
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGroupSelectorsEdit()
|
||||
{
|
||||
var labelEditPos = CheckMarkSize;
|
||||
var groups = Meta.Groups.Values.ToArray();
|
||||
foreach( var g in groups.Where( g => g.SelectionType == SelectType.Single ) )
|
||||
{
|
||||
labelEditPos = DrawSingleSelectorEdit( g );
|
||||
}
|
||||
|
||||
DrawAddSingleGroupField( labelEditPos );
|
||||
|
||||
foreach( var g in groups.Where( g => g.SelectionType == SelectType.Multi ) )
|
||||
{
|
||||
DrawMultiSelectorEdit( g );
|
||||
}
|
||||
|
||||
DrawAddMultiGroupField();
|
||||
}
|
||||
|
||||
private void DrawFileSwapTabEdit()
|
||||
{
|
||||
if( !ImGui.BeginTabItem( LabelFileSwapTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( !ImGui.BeginListBox( LabelFileSwapHeader, AutoFillSize ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
raii.Push( ImGui.EndListBox );
|
||||
|
||||
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 ? Utf8GamePath.Empty : swaps[ idx ];
|
||||
var value = idx == swaps.Length ? FullPath.Empty : Meta.FileSwaps[ key ];
|
||||
var keyString = key.ToString();
|
||||
var valueString = value.ToString();
|
||||
|
||||
ImGui.SetNextItemWidth( width );
|
||||
if( ImGui.InputTextWithHint( $"##swapLhs_{idx}", "Enter new file to be replaced...", ref keyString,
|
||||
GamePath.MaxGamePathLength, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
if( Utf8GamePath.FromString( keyString, out var newKey, true ) && newKey.CompareTo( key ) != 0 )
|
||||
{
|
||||
if( idx < swaps.Length )
|
||||
{
|
||||
Meta.FileSwaps.Remove( key );
|
||||
}
|
||||
|
||||
if( !newKey.IsEmpty )
|
||||
{
|
||||
Meta.FileSwaps[ newKey ] = value;
|
||||
}
|
||||
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.ReloadCurrentMod();
|
||||
}
|
||||
}
|
||||
|
||||
if( idx >= swaps.Length )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
var labelEditPos = ImGui.GetCursorPosX();
|
||||
DrawSingleSelectorEditGroup( group );
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltRight );
|
||||
ImGui.SameLine();
|
||||
|
||||
return labelEditPos;
|
||||
}
|
||||
|
||||
private void DrawAddSingleGroupField( float labelEditPos )
|
||||
{
|
||||
var newGroup = "";
|
||||
ImGui.SetCursorPosX( labelEditPos );
|
||||
if( labelEditPos == CheckMarkSize )
|
||||
ImGui.SetNextItemWidth( width );
|
||||
if( ImGui.InputTextWithHint( $"##swapRhs_{idx}", "Enter new replacement path...", ref valueString,
|
||||
GamePath.MaxGamePathLength,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
}
|
||||
|
||||
if( ImGui.InputTextWithHint( LabelNewSingleGroupEdit, "Add new Single Group...", ref newGroup, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
Penumbra.ModManager.ChangeModGroup( "", newGroup, Mod.Data, SelectType.Single );
|
||||
// Adds empty group, so can not change filters.
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAddMultiGroupField()
|
||||
{
|
||||
var newGroup = "";
|
||||
ImGui.SetCursorPosX( CheckMarkSize );
|
||||
ImGui.SetNextItemWidth( MultiEditBoxWidth * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( LabelNewMultiGroup, "Add new Multi Group...", ref newGroup, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
Penumbra.ModManager.ChangeModGroup( "", newGroup, Mod.Data, SelectType.Multi );
|
||||
// Adds empty group, so can not change filters.
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGroupSelectorsEdit()
|
||||
{
|
||||
var labelEditPos = CheckMarkSize;
|
||||
var groups = Meta.Groups.Values.ToArray();
|
||||
foreach( var g in groups.Where( g => g.SelectionType == SelectType.Single ) )
|
||||
{
|
||||
labelEditPos = DrawSingleSelectorEdit( g );
|
||||
}
|
||||
|
||||
DrawAddSingleGroupField( labelEditPos );
|
||||
|
||||
foreach( var g in groups.Where( g => g.SelectionType == SelectType.Multi ) )
|
||||
{
|
||||
DrawMultiSelectorEdit( g );
|
||||
}
|
||||
|
||||
DrawAddMultiGroupField();
|
||||
}
|
||||
|
||||
private void DrawFileSwapTabEdit()
|
||||
{
|
||||
if( !ImGui.BeginTabItem( LabelFileSwapTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( !ImGui.BeginListBox( LabelFileSwapHeader, AutoFillSize ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
raii.Push( ImGui.EndListBox );
|
||||
|
||||
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 newValue = new FullPath( valueString.ToLowerInvariant() );
|
||||
if( newValue.CompareTo( value ) != 0 )
|
||||
{
|
||||
var newKey = new GamePath( keyString );
|
||||
if( newKey.CompareTo( key ) != 0 )
|
||||
{
|
||||
if( idx < swaps.Length )
|
||||
{
|
||||
Meta.FileSwaps.Remove( key );
|
||||
}
|
||||
|
||||
if( newKey != string.Empty )
|
||||
{
|
||||
Meta.FileSwaps[ newKey ] = value;
|
||||
}
|
||||
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.ReloadCurrentMod();
|
||||
}
|
||||
}
|
||||
|
||||
if( idx >= swaps.Length )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
Meta.FileSwaps[ key ] = newValue;
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.Cache.TriggerListReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ public partial class SettingsInterface
|
|||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
|
||||
if( ModPanel.DrawSortOrder( mod.Data, _modManager, this ) )
|
||||
if( ModPanel.DrawSortOrder( mod.Data, Penumbra.ModManager, this ) )
|
||||
{
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
|
@ -509,7 +509,7 @@ public partial class SettingsInterface
|
|||
{
|
||||
var change = false;
|
||||
var metaManips = false;
|
||||
foreach( var _ in folder.AllMods( _modManager.Config.SortFoldersFirst ) )
|
||||
foreach( var _ in folder.AllMods( Penumbra.ModManager.Config.SortFoldersFirst ) )
|
||||
{
|
||||
var (mod, _, _) = Cache.GetMod( currentIdx++ );
|
||||
if( mod != null )
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text.RegularExpressions;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Logging;
|
||||
using ImGuiNET;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Interop;
|
||||
|
|
@ -131,7 +133,7 @@ public partial class SettingsInterface
|
|||
|
||||
private void DrawEnabledBox()
|
||||
{
|
||||
var enabled = _config.IsEnabled;
|
||||
var enabled = _config.EnableMods;
|
||||
if( ImGui.Checkbox( "Enable Mods", ref enabled ) )
|
||||
{
|
||||
_base._penumbra.SetEnabled( enabled );
|
||||
|
|
@ -317,14 +319,84 @@ public partial class SettingsInterface
|
|||
+ "You usually should not need to do this." );
|
||||
}
|
||||
|
||||
private void DrawEnableFullResourceLoggingBox()
|
||||
{
|
||||
var tmp = _config.EnableFullResourceLogging;
|
||||
if( ImGui.Checkbox( "Enable Full Resource Logging", ref tmp ) && tmp != _config.EnableFullResourceLogging )
|
||||
{
|
||||
if( tmp )
|
||||
{
|
||||
_base._penumbra.ResourceLoader.EnableFullLogging();
|
||||
}
|
||||
else
|
||||
{
|
||||
_base._penumbra.ResourceLoader.DisableFullLogging();
|
||||
}
|
||||
|
||||
_config.EnableFullResourceLogging = tmp;
|
||||
_configChanged = true;
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker( "[DEBUG] Enable the logging of all ResourceLoader events indiscriminately." );
|
||||
}
|
||||
|
||||
private void DrawEnableDebugModeBox()
|
||||
{
|
||||
var tmp = _config.DebugMode;
|
||||
if( ImGui.Checkbox( "Enable Debug Mode", ref tmp ) && tmp != _config.DebugMode )
|
||||
{
|
||||
if( tmp )
|
||||
{
|
||||
_base._penumbra.ResourceLoader.EnableDebug();
|
||||
}
|
||||
else
|
||||
{
|
||||
_base._penumbra.ResourceLoader.DisableDebug();
|
||||
}
|
||||
|
||||
_config.DebugMode = tmp;
|
||||
_configChanged = true;
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker( "[DEBUG] Enable the Debug Tab and Resource Manager Tab as well as some additional data collection." );
|
||||
}
|
||||
|
||||
private void DrawRequestedResourceLogging()
|
||||
{
|
||||
var tmp = _config.EnableResourceLogging;
|
||||
if( ImGui.Checkbox( "Enable Requested Resource Logging", ref tmp ) )
|
||||
{
|
||||
_base._penumbra.ResourceLogger.SetState( tmp );
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker( "Log all game paths FFXIV requests to the plugin log.\n"
|
||||
+ "You can filter the logged paths for those containing the entered string or matching the regex, if the entered string compiles to a valid regex.\n"
|
||||
+ "Red boundary indicates invalid regex." );
|
||||
ImGui.SameLine();
|
||||
var tmpString = Penumbra.Config.ResourceLoggingFilter;
|
||||
using var color = ImGuiRaii.PushColor( ImGuiCol.Border, 0xFF0000B0, !_base._penumbra.ResourceLogger.ValidRegex );
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale,
|
||||
!_base._penumbra.ResourceLogger.ValidRegex );
|
||||
if( ImGui.InputTextWithHint( "##ResourceLogFilter", "Filter...", ref tmpString, Utf8GamePath.MaxGamePathLength ) )
|
||||
{
|
||||
_base._penumbra.ResourceLogger.SetFilter( tmpString );
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAdvancedSettings()
|
||||
{
|
||||
DrawTempFolder();
|
||||
DrawRequestedResourceLogging();
|
||||
DrawDisableSoundStreamingBox();
|
||||
DrawLogLoadedFilesBox();
|
||||
DrawDisableNotificationsBox();
|
||||
DrawEnableHttpApiBox();
|
||||
DrawReloadResourceButton();
|
||||
DrawEnableDebugModeBox();
|
||||
DrawEnableFullResourceLoggingBox();
|
||||
}
|
||||
|
||||
public static unsafe void Text( Utf8String s )
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,36 +5,35 @@ using Lumina.Excel.GeneratedSheets;
|
|||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.UI.Custom;
|
||||
|
||||
namespace Penumbra.UI
|
||||
namespace Penumbra.UI;
|
||||
|
||||
public partial class SettingsInterface
|
||||
{
|
||||
public partial class SettingsInterface
|
||||
internal void DrawChangedItem( string name, object? data, float itemIdOffset = 0 )
|
||||
{
|
||||
internal void DrawChangedItem( string name, object? data, float itemIdOffset = 0)
|
||||
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 )
|
||||
{
|
||||
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;
|
||||
_penumbra.Api.InvokeClick( ret, data );
|
||||
}
|
||||
|
||||
if( ret != MouseButton.None )
|
||||
{
|
||||
_penumbra.Api.InvokeClick( ret, data );
|
||||
}
|
||||
if( _penumbra.Api.HasTooltip && ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
using var tooltip = ImGuiRaii.DeferredEnd( ImGui.EndTooltip );
|
||||
_penumbra.Api.InvokeTooltip( data );
|
||||
}
|
||||
|
||||
if( _penumbra.Api.HasTooltip && ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.BeginTooltip();
|
||||
using var tooltip = ImGuiRaii.DeferredEnd( ImGui.EndTooltip );
|
||||
_penumbra.Api.InvokeTooltip( data );
|
||||
}
|
||||
if( data is Item it )
|
||||
{
|
||||
var modelId = $"({( ( Quad )it.ModelMain ).A})";
|
||||
var offset = ImGui.CalcTextSize( modelId ).X - ImGui.GetStyle().ItemInnerSpacing.X + itemIdOffset;
|
||||
|
||||
if( data is Item it )
|
||||
{
|
||||
var modelId = $"({( ( Quad )it.ModelMain ).A})";
|
||||
var offset = ImGui.CalcTextSize( modelId ).X - ImGui.GetStyle().ItemInnerSpacing.X + itemIdOffset;
|
||||
|
||||
ImGui.SameLine( ImGui.GetWindowContentRegionWidth() - offset );
|
||||
ImGui.TextColored( new Vector4( 0.5f, 0.5f, 0.5f, 1 ), modelId );
|
||||
}
|
||||
ImGui.SameLine( ImGui.GetWindowContentRegionWidth() - offset );
|
||||
ImGui.TextColored( new Vector4( 0.5f, 0.5f, 0.5f, 1 ), modelId );
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue