A few comments, further cleanup. A few TODOs handled.

This commit is contained in:
Ottermandias 2022-04-27 17:19:33 +02:00
parent dbb9931189
commit c78725d7d5
47 changed files with 347 additions and 3664 deletions

View file

@ -16,17 +16,15 @@ public class ModsController : WebApiController
[Route( HttpVerbs.Get, "/mods" )]
public object? GetMods()
{
// TODO
return null;
//return Penumbra.ModManager.Mods.Zip( Penumbra.CollectionManager.Current.ActualSettings ).Select( x => new
//{
// x.Second?.Enabled,
// x.Second?.Priority,
// x.First.BasePath.Name,
// x.First.Name,
// BasePath = x.First.BasePath.FullName,
// Files = x.First.Resources.ModFiles.Select( fi => fi.FullName ),
//} );
return Penumbra.ModManager.Zip( Penumbra.CollectionManager.Current.ActualSettings ).Select( x => new
{
x.Second?.Enabled,
x.Second?.Priority,
FolderName = x.First.BasePath.Name,
x.First.Name,
BasePath = x.First.BasePath.FullName,
Files = x.First.AllFiles,
} );
}
[Route( HttpVerbs.Post, "/mods" )]

View file

@ -251,7 +251,7 @@ public partial class ModCollection
return;
}
var mod = Penumbra.ModManager.Mods[ modIdx ];
var mod = Penumbra.ModManager[ modIdx ];
AddSubMod( mod.Default, new FileRegister( modIdx, settings.Priority, 0, 0 ), withManipulations );
for( var idx = 0; idx < mod.Groups.Count; ++idx )
{

View file

@ -98,7 +98,7 @@ public partial class ModCollection
if( oldValue != newValue )
{
var inheritance = FixInheritance( idx, false );
_settings[ idx ]!.SetValue( Penumbra.ModManager.Mods[ idx ], groupIdx, newValue );
_settings[ idx ]!.SetValue( Penumbra.ModManager[ idx ], groupIdx, newValue );
ModSettingChanged.Invoke( ModSettingChange.Setting, idx, inheritance ? -1 : ( int )oldValue, groupIdx, false );
}
}
@ -137,7 +137,7 @@ public partial class ModCollection
return false;
}
_settings[ idx ] = inherit ? null : this[ idx ].Settings?.DeepCopy() ?? ModSettings.DefaultSettings( Penumbra.ModManager.Mods[ idx ] );
_settings[ idx ] = inherit ? null : this[ idx ].Settings?.DeepCopy() ?? ModSettings.DefaultSettings( Penumbra.ModManager[ idx ] );
return true;
}

View file

@ -32,6 +32,10 @@ public partial class ModCollection
public IReadOnlyList< ModSettings? > Settings
=> _settings;
// Returns whether there are settings not in use by any current mod.
public bool HasUnusedSettings
=> _unusedSettings.Count > 0;
// Evaluates the settings along the whole inheritance tree.
public IEnumerable< ModSettings? > ActualSettings
=> Enumerable.Range( 0, _settings.Count ).Select( i => this[ i ].Settings );

View file

@ -1,16 +0,0 @@
namespace Penumbra;
public partial class Configuration
{
// Contains some default values or boundaries for config values.
public static class Constants
{
public const int CurrentVersion = 3;
public const float MaxAbsoluteSize = 600;
public const int DefaultAbsoluteSize = 250;
public const float MinAbsoluteSize = 50;
public const int MaxScaledSize = 80;
public const int DefaultScaledSize = 20;
public const int MinScaledSize = 5;
}
}

View file

@ -86,4 +86,16 @@ public partial class Configuration : IPluginConfiguration
Save();
}
}
// Contains some default values or boundaries for config values.
public static class Constants
{
public const int CurrentVersion = 3;
public const float MaxAbsoluteSize = 600;
public const int DefaultAbsoluteSize = 250;
public const float MinAbsoluteSize = 50;
public const int MaxScaledSize = 80;
public const int DefaultScaledSize = 20;
public const int MinScaledSize = 5;
}
}

View file

@ -12,14 +12,19 @@ public partial class Mod
public delegate void ModPathChangeDelegate( ModPathChangeType type, Mod mod, DirectoryInfo? oldDirectory,
DirectoryInfo? newDirectory );
public event ModPathChangeDelegate? ModPathChanged;
public event ModPathChangeDelegate ModPathChanged;
// Rename/Move a mod directory.
// Updates all collection settings and sort order settings.
public void MoveModDirectory( Index idx, DirectoryInfo newDirectory )
{
var mod = this[ idx ];
// TODO
}
// Delete a mod by its index.
// Deletes from filesystem as well as from internal data.
// Updates indices of later mods.
public void DeleteMod( int idx )
{
var mod = this[ idx ];
@ -41,9 +46,10 @@ public partial class Mod
--remainingMod.Index;
}
ModPathChanged?.Invoke( ModPathChangeType.Deleted, mod, mod.BasePath, null );
ModPathChanged.Invoke( ModPathChangeType.Deleted, mod, mod.BasePath, null );
}
// Load a new mod and add it to the manager if successful.
public void AddMod( DirectoryInfo modFolder )
{
if( _mods.Any( m => m.BasePath.Name == modFolder.Name ) )
@ -59,7 +65,22 @@ public partial class Mod
mod.Index = _mods.Count;
_mods.Add( mod );
ModPathChanged?.Invoke( ModPathChangeType.Added, mod, null, mod.BasePath );
ModPathChanged.Invoke( ModPathChangeType.Added, mod, null, mod.BasePath );
}
// Add new mods to NewMods and remove deleted mods from NewMods.
private void OnModPathChange( ModPathChangeType type, Mod mod, DirectoryInfo? oldDirectory,
DirectoryInfo? newDirectory )
{
switch( type )
{
case ModPathChangeType.Added:
NewMods.Add( mod );
break;
case ModPathChangeType.Deleted:
NewMods.Remove( mod );
break;
}
}
}
}

View file

@ -197,6 +197,14 @@ public sealed partial class Mod
return;
}
if( mod._groups[ groupIdx ].Count > 63 )
{
PluginLog.Error(
$"Could not add option {option.Name} to {mod._groups[ groupIdx ].Name} for mod {mod.Name}, "
+ "since only up to 64 options are supported in one group." );
return;
}
switch( mod._groups[ groupIdx ] )
{
case SingleModGroup s:

View file

@ -11,16 +11,19 @@ public sealed partial class Mod
public DirectoryInfo BasePath { get; private set; } = null!;
public bool Valid { get; private set; }
public event Action? ModDiscoveryStarted;
public event Action? ModDiscoveryFinished;
// Change the mod base directory and discover available mods.
public void DiscoverMods( string newDir )
{
SetBaseDirectory( newDir, false );
DiscoverMods();
}
// Set the mod base directory.
// If its not the first time, check if it is the same directory as before.
// Also checks if the directory is available and tries to create it if it is not.
private void SetBaseDirectory( string newPath, bool firstTime )
{
if( !firstTime && string.Equals( newPath, Penumbra.Config.ModDirectory, StringComparison.InvariantCultureIgnoreCase ) )
@ -59,8 +62,10 @@ public sealed partial class Mod
}
}
// Discover new mods.
public void DiscoverMods()
{
NewMods.Clear();
ModDiscoveryStarted?.Invoke();
_mods.Clear();
BasePath.Refresh();

View file

@ -6,16 +6,22 @@ namespace Penumbra.Mods;
public sealed partial class Mod
{
public sealed partial class Manager : IEnumerable< Mod >
public sealed partial class Manager : IReadOnlyList< Mod >
{
// An easily accessible set of new mods.
// Mods are added when they are created or imported.
// Mods are removed when they are deleted or when they are toggled in any collection.
// Also gets cleared on mod rediscovery.
public readonly HashSet< Mod > NewMods = new();
private readonly List< Mod > _mods = new();
public Mod this[ int idx ]
=> _mods[ idx ];
public Mod this[ Index idx ]
=> _mods[ idx ];
public IReadOnlyList< Mod > Mods
=> _mods;
public int Count
=> _mods.Count;
@ -29,6 +35,7 @@ public sealed partial class Mod
{
SetBaseDirectory( modDirectory, true );
ModOptionChanged += OnModOptionChange;
ModPathChanged += OnModPathChange;
}
}
}

View file

@ -18,7 +18,7 @@ public partial class Mod
private Mod( DirectoryInfo basePath )
=> BasePath = basePath;
public static Mod? LoadMod( DirectoryInfo basePath )
private static Mod? LoadMod( DirectoryInfo basePath )
{
basePath.Refresh();
if( !basePath.Exists )

View file

@ -8,7 +8,7 @@ public sealed partial class Mod
public SortedList< string, object? > ChangedItems { get; } = new();
public string LowerChangedItemsString { get; private set; } = string.Empty;
public void ComputeChangedItems()
private void ComputeChangedItems()
{
var identifier = GameData.GameData.GetIdentifier();
ChangedItems.Clear();

View file

@ -78,7 +78,7 @@ public partial class Mod
public List< FullPath > FindMissingFiles()
=> AllFiles.Where( f => !f.Exists ).ToList();
public static IModGroup? LoadModGroup( FileInfo file, DirectoryInfo basePath )
private static IModGroup? LoadModGroup( FileInfo file, DirectoryInfo basePath )
{
if( !File.Exists( file.FullName ) )
{

View file

@ -25,13 +25,13 @@ public sealed partial class Mod
{
public const uint CurrentFileVersion = 1;
public uint FileVersion { get; private set; } = CurrentFileVersion;
public LowerString Name { get; private set; } = "Mod";
public LowerString Name { get; private set; } = "New Mod";
public LowerString Author { get; private set; } = LowerString.Empty;
public string Description { get; private set; } = string.Empty;
public string Version { get; private set; } = string.Empty;
public string Website { get; private set; } = string.Empty;
private FileInfo MetaFile
internal FileInfo MetaFile
=> new(Path.Combine( BasePath.FullName, "meta.json" ));
private MetaChangeType LoadMeta()

View file

@ -12,6 +12,7 @@ using Penumbra.Util;
namespace Penumbra.Mods;
// TODO Everything
//ublic class ModCleanup
//
// private const string Duplicates = "Duplicates";
@ -521,7 +522,6 @@ namespace Penumbra.Mods;
// }
// }
//
// // TODO
// var idx = Penumbra.ModManager.Mods.IndexOf( m => m.Meta == meta );
// foreach( var collection in Penumbra.CollectionManager )
// {

View file

@ -42,7 +42,7 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
// Used on construction and on mod rediscoveries.
private void Reload()
{
if( Load( new FileInfo( ModFileSystemFile ), Penumbra.ModManager.Mods, ModToIdentifier, ModToName ) )
if( Load( new FileInfo( ModFileSystemFile ), Penumbra.ModManager, ModToIdentifier, ModToName ) )
{
Save();
}

View file

@ -4,10 +4,15 @@ using System.IO;
using Dalamud.Logging;
using Newtonsoft.Json;
using OtterGui.Filesystem;
using Penumbra.Util;
namespace Penumbra.Mods;
public enum SelectType
{
Single,
Multi,
}
public interface IModGroup : IEnumerable< ISubMod >
{
public string Name { get; }

View file

@ -11,6 +11,7 @@ namespace Penumbra.Mods;
public partial class Mod
{
// Groups that allow all available options to be selected at once.
private sealed class MultiModGroup : IModGroup
{
public SelectType Type

View file

@ -11,6 +11,7 @@ namespace Penumbra.Mods;
public partial class Mod
{
// Groups that allow only one of their available options to be selected.
private sealed class SingleModGroup : IModGroup
{
public SelectType Type

View file

@ -13,9 +13,11 @@ namespace Penumbra.Mods;
public partial class Mod
{
private string DefaultFile
internal string DefaultFile
=> Path.Combine( BasePath.FullName, "default_mod.json" );
// The default mod contains setting-independent sets of file replacements, file swaps and meta changes.
// Every mod has an default mod, though it may be empty.
private void SaveDefaultMod()
{
var defaultFile = DefaultFile;
@ -55,6 +57,14 @@ public partial class Mod
}
// A sub mod is a collection of
// - file replacements
// - file swaps
// - meta manipulations
// that can be used either as an option or as the default data for a mod.
// It can be loaded and reloaded from Json.
// Nothing is checked for existence or validity when loading.
// Objects are also not checked for uniqueness, the first appearance of a game path or meta path decides.
private sealed class SubMod : ISubMod
{
public string Name { get; set; } = "Default";
@ -78,6 +88,7 @@ public partial class Mod
FileSwapData.Clear();
ManipulationData.Clear();
// Every option has a name, but priorities are only relevant for multi group options.
Name = json[ nameof( ISubMod.Name ) ]?.ToObject< string >() ?? string.Empty;
priority = json[ nameof( IModGroup.Priority ) ]?.ToObject< int >() ?? 0;
@ -115,6 +126,8 @@ public partial class Mod
}
}
// If .meta or .rgsp files are encountered, parse them and incorporate their meta changes into the mod.
// If delete is true, the files are deleted afterwards.
public void IncorporateMetaChanges( DirectoryInfo basePath, bool delete )
{
foreach( var (key, file) in Files.ToList() )

View file

@ -14,6 +14,7 @@ public class ModSettings
public int Priority { get; set; }
public bool Enabled { get; set; }
// Create an independent copy of the current settings.
public ModSettings DeepCopy()
=> new()
{
@ -22,6 +23,7 @@ public class ModSettings
Settings = Settings.ToList(),
};
// Create default settings for a given mod.
public static ModSettings DefaultSettings( Mod mod )
=> new()
{
@ -30,24 +32,30 @@ public class ModSettings
Settings = Enumerable.Repeat( 0u, mod.Groups.Count ).ToList(),
};
// Automatically react to changes in a mods available options.
public bool HandleChanges( ModOptionChangeType type, Mod mod, int groupIdx, int optionIdx, int movedToIdx )
{
switch( type )
{
case ModOptionChangeType.GroupRenamed: return true;
case ModOptionChangeType.GroupAdded:
// Add new empty setting for new mod.
Settings.Insert( groupIdx, 0 );
return true;
case ModOptionChangeType.GroupDeleted:
// Remove setting for deleted mod.
Settings.RemoveAt( groupIdx );
return true;
case ModOptionChangeType.GroupTypeChanged:
{
// Fix settings for a changed group type.
// Single -> Multi: set single as enabled, rest as disabled
// Multi -> Single: set the first enabled option or 0.
var group = mod.Groups[ groupIdx ];
var config = Settings[ groupIdx ];
Settings[ groupIdx ] = group.Type switch
{
SelectType.Single => ( uint )Math.Min( group.Count - 1, BitOperations.TrailingZeroCount( config ) ),
SelectType.Single => ( uint )Math.Max( Math.Min( group.Count - 1, BitOperations.TrailingZeroCount( config ) ), 0 ),
SelectType.Multi => 1u << ( int )config,
_ => config,
};
@ -55,6 +63,8 @@ public class ModSettings
}
case ModOptionChangeType.OptionDeleted:
{
// Single -> select the previous option if any.
// Multi -> excise the corresponding bit.
var group = mod.Groups[ groupIdx ];
var config = Settings[ groupIdx ];
Settings[ groupIdx ] = group.Type switch
@ -65,9 +75,13 @@ public class ModSettings
};
return config != Settings[ groupIdx ];
}
case ModOptionChangeType.GroupMoved: return Settings.Move( groupIdx, movedToIdx );
case ModOptionChangeType.GroupMoved:
// Move the group the same way.
return Settings.Move( groupIdx, movedToIdx );
case ModOptionChangeType.OptionMoved:
{
// Single -> select the moved option if it was currently selected
// Multi -> move the corresponding bit
var group = mod.Groups[ groupIdx ];
var config = Settings[ groupIdx ];
Settings[ groupIdx ] = group.Type switch
@ -82,6 +96,7 @@ public class ModSettings
}
}
// Ensure that a value is valid for a group.
private static uint FixSetting( IModGroup group, uint value )
=> group.Type switch
{
@ -90,6 +105,7 @@ public class ModSettings
_ => value,
};
// Set a setting. Ensures that there are enough settings and fixes the setting beforehand.
public void SetValue( Mod mod, int groupIdx, uint newValue )
{
AddMissingSettings( groupIdx + 1 );
@ -97,6 +113,7 @@ public class ModSettings
Settings[ groupIdx ] = FixSetting( group, newValue );
}
// Remove a single bit, moving all further bits one down.
private static uint RemoveBit( uint config, int bit )
{
var lowMask = ( 1u << bit ) - 1u;
@ -106,6 +123,7 @@ public class ModSettings
return low | high;
}
// Move a bit in an uint from its position to another, shifting other bits accordingly.
private static uint MoveBit( uint config, int bit1, int bit2 )
{
var enabled = ( config & ( 1 << bit1 ) ) != 0 ? 1u << bit2 : 0u;
@ -116,7 +134,8 @@ public class ModSettings
return low | enabled | high;
}
internal bool AddMissingSettings( int totalCount )
// Add defaulted settings up to the required count.
private bool AddMissingSettings( int totalCount )
{
if( totalCount <= Settings.Count )
{
@ -127,6 +146,7 @@ public class ModSettings
return true;
}
// A simple struct conversion to easily save settings by name instead of value.
public struct SavedSettings
{
public Dictionary< string, uint > Settings;
@ -154,6 +174,7 @@ public class ModSettings
}
}
// Convert and fix.
public bool ToSettings( Mod mod, out ModSettings settings )
{
var list = new List< uint >( mod.Groups.Count );

View file

@ -1,7 +0,0 @@
namespace Penumbra.Mods;
public enum SelectType
{
Single,
Multi,
}

View file

@ -30,9 +30,9 @@ public class Penumbra : IDalamudPlugin
private const string CommandName = "/penumbra";
public static string Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty;
public static readonly string Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty;
public static string CommitHash =
public static readonly string CommitHash =
Assembly.GetExecutingAssembly().GetCustomAttribute< AssemblyInformationalVersionAttribute >()?.InformationalVersion ?? "Unknown";
public static Configuration Config { get; private set; } = null!;
@ -295,7 +295,7 @@ public class Penumbra : IDalamudPlugin
case "reload":
{
ModManager.DiscoverMods();
Dalamud.Chat.Print( $"Reloaded Penumbra mods. You have {ModManager.Mods.Count} mods."
Dalamud.Chat.Print( $"Reloaded Penumbra mods. You have {ModManager.Count} mods."
);
break;
}

View file

@ -21,11 +21,10 @@ public partial class ModFileSystemSelector
public uint Color;
}
private const StringComparison IgnoreCase = StringComparison.InvariantCultureIgnoreCase;
private readonly IReadOnlySet< Mod > _newMods = new HashSet< Mod >();
private LowerString _modFilter = LowerString.Empty;
private int _filterType = -1;
private ModFilter _stateFilter = ModFilterExtensions.UnfilteredStateMods;
private const StringComparison IgnoreCase = StringComparison.InvariantCultureIgnoreCase;
private LowerString _modFilter = LowerString.Empty;
private int _filterType = -1;
private ModFilter _stateFilter = ModFilterExtensions.UnfilteredStateMods;
private void SetFilterTooltip()
{
@ -105,7 +104,7 @@ public partial class ModFileSystemSelector
// Only get the text color for a mod if no filters are set.
private uint GetTextColor( Mod mod, ModSettings? settings, ModCollection collection )
{
if( _newMods.Contains( mod ) )
if( Penumbra.ModManager.NewMods.Contains( mod ) )
{
return ColorId.NewMod.Value();
}
@ -133,7 +132,7 @@ public partial class ModFileSystemSelector
private bool CheckStateFilters( Mod mod, ModSettings? settings, ModCollection collection, ref ModState state )
{
var isNew = _newMods.Contains( mod );
var isNew = Penumbra.ModManager.NewMods.Contains( mod );
// Handle mod details.
if( CheckFlags( mod.TotalFileCount, ModFilter.HasNoFiles, ModFilter.HasFiles )
|| CheckFlags( mod.TotalSwapCount, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps )

View file

@ -24,10 +24,9 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
public ModSettings SelectedSettings { get; private set; } = ModSettings.Empty;
public ModCollection SelectedSettingCollection { get; private set; } = ModCollection.Empty;
public ModFileSystemSelector( ModFileSystem fileSystem, IReadOnlySet< Mod > newMods )
public ModFileSystemSelector( ModFileSystem fileSystem )
: base( fileSystem )
{
_newMods = newMods;
SubscribeRightClickFolder( EnableDescendants, 10 );
SubscribeRightClickFolder( DisableDescendants, 10 );
SubscribeRightClickFolder( InheritDescendants, 15 );
@ -122,7 +121,8 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
private void AddNewModButton( Vector2 size )
{
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), size, "Create a new, empty mod of a given name.", !Penumbra.ModManager.Valid, true ) )
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), size, "Create a new, empty mod of a given name.",
!Penumbra.ModManager.Valid, true ) )
{
ImGui.OpenPopup( "Create New Mod" );
}
@ -167,17 +167,18 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
private void DrawInfoPopup()
{
var display = ImGui.GetIO().DisplaySize;
ImGui.SetNextWindowSize( display / 4 );
ImGui.SetNextWindowSize( display / 4 );
ImGui.SetNextWindowPos( 3 * display / 8 );
using var popup = ImRaii.Popup( "Import Status", ImGuiWindowFlags.Modal );
if( _import != null && popup.Success )
{
_import.DrawProgressInfo( ImGuiHelpers.ScaledVector2( -1, ImGui.GetFrameHeight() ) );
_import.DrawProgressInfo( new Vector2( -1, ImGui.GetFrameHeight() ) );
if( _import.State == ImporterState.Done )
{
ImGui.SetCursorPosY( ImGui.GetWindowHeight() - ImGui.GetFrameHeight() * 2 );
if( ImGui.Button( "Close", -Vector2.UnitX ) )
{
AddNewMods( _import.ExtractedMods );
_import = null;
ImGui.CloseCurrentPopup();
}
@ -185,6 +186,37 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
}
}
// Clean up invalid directories if necessary.
// Add all successfully extracted mods.
private static void AddNewMods( IEnumerable< (FileInfo File, DirectoryInfo? Mod, Exception? Error) > list )
{
foreach( var (file, dir, error) in list )
{
if( error != null )
{
if( dir != null && Directory.Exists( dir.FullName ) )
{
try
{
Directory.Delete( dir.FullName );
}
catch( Exception e )
{
PluginLog.Error($"Error cleaning up failed mod extraction of {file.FullName} to {dir.FullName}:\n{e}" );
}
}
PluginLog.Error( $"Error extracting {file.FullName}, mod skipped:\n{error}" );
continue;
}
if( dir != null )
{
Penumbra.ModManager.AddMod( dir );
}
}
}
private void DeleteModButton( Vector2 size )
{
var keys = ImGui.GetIO().KeyCtrl && ImGui.GetIO().KeyShift;

View file

@ -31,6 +31,7 @@ public partial class ConfigWindow
return;
}
// Draw filters.
ImGui.SetNextItemWidth( -1 );
LowerString.InputWithHint( "##changedItemsFilter", "Filter...", ref _changedItemFilter, 64 );
@ -40,6 +41,7 @@ public partial class ConfigWindow
return;
}
// Draw table of changed items.
var height = ImGui.GetTextLineHeightWithSpacing() + 2 * ImGui.GetStyle().CellPadding.Y;
var skips = ImGuiClip.GetNecessarySkips( height );
using var list = ImRaii.Table( "##changedItems", 1, ImGuiTableFlags.RowBg, -Vector2.One );

View file

@ -112,7 +112,7 @@ public partial class ConfigWindow
private void DrawCurrentCollectionInheritance()
{
using var list = ImRaii.ListBox( "##inheritanceList",
new Vector2( _window._inputTextWidth.X - ImGui.GetFrameHeight() - ImGui.GetStyle().ItemSpacing.X,
new Vector2( _window._inputTextWidth.X - _window._iconButtonSize.X - ImGui.GetStyle().ItemSpacing.X,
ImGui.GetTextLineHeightWithSpacing() * InheritedCollectionHeight ) );
if( !list )
{
@ -131,7 +131,7 @@ public partial class ConfigWindow
private void DrawInheritanceTrashButton()
{
ImGui.SameLine();
var size = new Vector2( ImGui.GetFrameHeight(), ImGui.GetTextLineHeightWithSpacing() * InheritedCollectionHeight );
var size = new Vector2( _window._iconButtonSize.X, ImGui.GetTextLineHeightWithSpacing() * InheritedCollectionHeight );
var buttonColor = ImGui.GetColorU32( ImGuiCol.Button );
// Prevent hovering from highlighting the button.
using var color = ImRaii.PushColor( ImGuiCol.ButtonActive, buttonColor )
@ -142,7 +142,7 @@ public partial class ConfigWindow
using var target = ImRaii.DragDropTarget();
if( target.Success && ImGuiUtil.IsDropping( InheritanceDragDropLabel ) )
{
_inheritanceAction = ( Penumbra.CollectionManager.Current.Inheritance.IndexOf( _movedInheritance ), -1 );
_inheritanceAction = ( Penumbra.CollectionManager.Current.Inheritance.IndexOf( _movedInheritance! ), -1 );
}
}
@ -192,7 +192,7 @@ public partial class ConfigWindow
ModCollection.ValidInheritance.Circle => "Inheriting from selected collection would lead to cyclic inheritance.",
_ => string.Empty,
};
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), ImGui.GetFrameHeight() * Vector2.One, tt,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), _window._iconButtonSize, tt,
inheritance != ModCollection.ValidInheritance.Valid, true )
&& Penumbra.CollectionManager.Current.AddInheritance( _newInheritance! ) )
{
@ -211,7 +211,7 @@ public partial class ConfigWindow
// Only valid inheritances are drawn in the preview, or nothing if no inheritance is available.
private void DrawNewInheritanceCombo()
{
ImGui.SetNextItemWidth( _window._inputTextWidth.X - ImGui.GetFrameHeight() - ImGui.GetStyle().ItemSpacing.X );
ImGui.SetNextItemWidth( _window._inputTextWidth.X - _window._iconButtonSize.X - ImGui.GetStyle().ItemSpacing.X );
_newInheritance ??= Penumbra.CollectionManager.FirstOrDefault( c
=> c != Penumbra.CollectionManager.Current && !Penumbra.CollectionManager.Current.Inheritance.Contains( c ) )
?? ModCollection.Empty;

View file

@ -47,14 +47,19 @@ public partial class ConfigWindow
}
}
// Only gets drawn when actually relevant.
private static void DrawCleanCollectionButton()
{
if( ImGui.Button( "Clean Settings" ) )
if( Penumbra.Config.ShowAdvanced && Penumbra.CollectionManager.Current.HasUnusedSettings )
{
Penumbra.CollectionManager.Current.CleanUnavailableSettings();
ImGui.SameLine();
if( ImGuiUtil.DrawDisabledButton( "Clean Settings", Vector2.Zero
, "Remove all stored settings for mods not currently available and fix invalid settings.\nUse at own risk."
, false ) )
{
Penumbra.CollectionManager.Current.CleanUnavailableSettings();
}
}
ImGuiUtil.HoverTooltip( "Remove all stored settings for mods not currently available and fix invalid settings.\nUse at own risk." );
}
// Draw the new collection input as well as its buttons.
@ -94,11 +99,7 @@ public partial class ConfigWindow
Penumbra.CollectionManager.RemoveCollection( Penumbra.CollectionManager.Current );
}
if( Penumbra.Config.ShowAdvanced )
{
ImGui.SameLine();
DrawCleanCollectionButton();
}
DrawCleanCollectionButton();
}
private void DrawCurrentCollectionSelector()
@ -152,7 +153,7 @@ public partial class ConfigWindow
using var id = ImRaii.PushId( name );
DrawCollectionSelector( string.Empty, _window._inputTextWidth.X, ModCollection.Type.Character, true, name );
ImGui.SameLine();
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), Vector2.One * ImGui.GetFrameHeight(), string.Empty,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), _window._iconButtonSize, string.Empty,
false,
true ) )
{

View file

@ -124,7 +124,7 @@ public partial class ConfigWindow
// Filters mean we can not use the known counts.
if( hasFilters )
{
var it2 = it.Select( p => ( p.Item1.ToString() ?? string.Empty, Penumbra.ModManager.Mods[ p.Item2 ].Name ) );
var it2 = it.Select( p => ( p.Item1.ToString() ?? string.Empty, Penumbra.ModManager[ p.Item2 ].Name ) );
if( stop >= 0 )
{
ImGuiClip.DrawEndDummy( stop + it2.Count( CheckFilters ), height );
@ -190,7 +190,7 @@ public partial class ConfigWindow
ImGui.TableNextColumn();
ImGuiUtil.PrintIcon( FontAwesomeIcon.LongArrowAltLeft );
ImGui.TableNextColumn();
ImGuiUtil.CopyOnClickSelectable( Penumbra.ModManager.Mods[ modIdx ].Name );
ImGuiUtil.CopyOnClickSelectable( Penumbra.ModManager[ modIdx ].Name );
}
// Check filters for file replacements.

View file

@ -21,16 +21,16 @@ public partial class ConfigWindow
=> ImGuiNative.igTextUnformatted( s.Path, s.Path + s.Length );
// Draw text given by a byte pointer.
internal static unsafe void Text( byte* s, int length )
private static unsafe void Text( byte* s, int length )
=> ImGuiNative.igTextUnformatted( s, s + length );
// Draw the name of a resource file.
internal static unsafe void Text( ResourceHandle* resource )
private static unsafe void Text( ResourceHandle* resource )
=> Text( resource->FileName(), resource->FileNameLength );
// Draw a changed item, invoking the Api-Events for clicks and tooltips.
// Also draw the item Id in grey
internal void DrawChangedItem( string name, object? data, float itemIdOffset = 0 )
private 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;
@ -64,7 +64,7 @@ public partial class ConfigWindow
// A selectable that copies its text to clipboard on selection and provides a on-hover tooltip about that,
// using an Utf8String.
internal static unsafe void CopyOnClickSelectable( Utf8String text )
private static unsafe void CopyOnClickSelectable( Utf8String text )
{
if( ImGuiNative.igSelectable_Bool( text.Path, 0, ImGuiSelectableFlags.None, Vector2.Zero ) != 0 )
{

View file

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Numerics;
using Dalamud.Interface;
using ImGuiNET;
@ -14,7 +15,7 @@ public partial class ConfigWindow
{
private partial class ModPanel
{
public readonly Queue< Action > _delayedActions = new();
private readonly Queue< Action > _delayedActions = new();
private void DrawAddOptionGroupInput()
{
@ -24,7 +25,7 @@ public partial class ConfigWindow
var nameValid = Mod.Manager.VerifyFileName( _mod, null, _newGroupName, false );
var tt = nameValid ? "Add new option group to the mod." : "Can not add a group of this name.";
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), _window._iconButtonSize,
tt, !nameValid, true ) )
{
Penumbra.ModManager.AddModGroup( _mod, SelectType.Single, _newGroupName );
@ -73,6 +74,33 @@ public partial class ConfigWindow
EditDescriptionPopup();
}
private void EditButtons()
{
var folderExists = Directory.Exists( _mod.BasePath.FullName );
var tt = folderExists
? $"Open {_mod.BasePath.FullName} in the file explorer of your choice."
: $"Mod directory {_mod.BasePath.FullName} does not exist.";
if( ImGuiUtil.DrawDisabledButton( "Open Mod Directory", Vector2.Zero, tt, !folderExists ) )
{
Process.Start( new ProcessStartInfo( _mod.BasePath.FullName ) { UseShellExecute = true } );
}
ImGui.SameLine();
ImGuiUtil.DrawDisabledButton( "Rename Mod Directory", Vector2.Zero, "Not implemented yet", true );
ImGui.SameLine();
ImGuiUtil.DrawDisabledButton( "Reload Mod", Vector2.Zero, "Not implemented yet", true );
ImGuiUtil.DrawDisabledButton( "Deduplicate", Vector2.Zero, "Not implemented yet", true );
ImGui.SameLine();
ImGuiUtil.DrawDisabledButton( "Normalize", Vector2.Zero, "Not implemented yet", true );
ImGui.SameLine();
ImGuiUtil.DrawDisabledButton( "Auto-Create Groups", Vector2.Zero, "Not implemented yet", true );
ImGuiUtil.DrawDisabledButton( "Change Material Suffix", Vector2.Zero, "Not implemented yet", true );
ImGui.Dummy( _window._defaultSpace );
}
// Special field indices to reuse the same string buffer.
private const int NoFieldIdx = -1;
@ -105,15 +133,37 @@ public partial class ConfigWindow
Penumbra.ModManager.ChangeModWebsite( _mod.Index, newWebsite );
}
if( ImGui.Button( "Edit Description", _window._inputTextWidth ) )
var reducedSize = new Vector2( _window._inputTextWidth.X - _window._iconButtonSize.X - ImGui.GetStyle().ItemSpacing.X, 0 );
if( ImGui.Button( "Edit Description", reducedSize ) )
{
_delayedActions.Enqueue( () => OpenEditDescriptionPopup( DescriptionFieldIdx ) );
}
if( ImGui.Button( "Edit Default Mod", _window._inputTextWidth ) )
ImGui.SameLine();
var fileExists = File.Exists( _mod.MetaFile.FullName );
var tt = fileExists
? "Open the metadata json file in the text editor of your choice."
: "The metadata json file does not exist.";
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.FileExport.ToIconString(), _window._iconButtonSize, tt, !fileExists, true ) )
{
Process.Start( new ProcessStartInfo( _mod.MetaFile.FullName ) { UseShellExecute = true } );
}
if( ImGui.Button( "Edit Default Mod", reducedSize ) )
{
_window.SubModPopup.Activate( _mod, -1, 0 );
}
ImGui.SameLine();
fileExists = File.Exists( _mod.DefaultFile );
tt = fileExists
? "Open the default option json file in the text editor of your choice."
: "The default option json file does not exist.";
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.FileExport.ToIconString(), _window._iconButtonSize, tt, !fileExists, true ) )
{
Process.Start( new ProcessStartInfo( _mod.DefaultFile ) { UseShellExecute = true } );
}
}
@ -144,7 +194,7 @@ public partial class ConfigWindow
ImGuiUtil.HoverTooltip( "Group Name" );
ImGui.SameLine();
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), _window._iconButtonSize,
"Delete this option group.\nHold Control while clicking to delete.", !ImGui.GetIO().KeyCtrl, true ) )
{
_delayedActions.Enqueue( () => Penumbra.ModManager.DeleteModGroup( _mod, groupIdx ) );
@ -152,7 +202,7 @@ public partial class ConfigWindow
ImGui.SameLine();
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Edit.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Edit.ToIconString(), _window._iconButtonSize,
"Edit group description.", false, true ) )
{
_delayedActions.Enqueue( () => OpenEditDescriptionPopup( groupIdx ) );
@ -167,7 +217,7 @@ public partial class ConfigWindow
ImGuiUtil.HoverTooltip( "Group Priority" );
ImGui.SetNextItemWidth( _window._inputTextWidth.X - 2 * ImGui.GetFrameHeight() - 8 * ImGuiHelpers.GlobalScale );
ImGui.SetNextItemWidth( _window._inputTextWidth.X - 3 * _window._iconButtonSize.X - 12 * ImGuiHelpers.GlobalScale );
using( var combo = ImRaii.Combo( "##GroupType", GroupTypeName( group.Type ) ) )
{
if( combo )
@ -185,7 +235,7 @@ public partial class ConfigWindow
ImGui.SameLine();
var tt = groupIdx == 0 ? "Can not move this group further upwards." : $"Move this group up to group {groupIdx}.";
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.ArrowUp.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.ArrowUp.ToIconString(), _window._iconButtonSize,
tt, groupIdx == 0, true ) )
{
_delayedActions.Enqueue( () => Penumbra.ModManager.MoveModGroup( _mod, groupIdx, groupIdx - 1 ) );
@ -195,19 +245,30 @@ public partial class ConfigWindow
tt = groupIdx == _mod.Groups.Count - 1
? "Can not move this group further downwards."
: $"Move this group down to group {groupIdx + 2}.";
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.ArrowDown.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.ArrowDown.ToIconString(), _window._iconButtonSize,
tt, groupIdx == _mod.Groups.Count - 1, true ) )
{
_delayedActions.Enqueue( () => Penumbra.ModManager.MoveModGroup( _mod, groupIdx, groupIdx + 1 ) );
}
ImGui.SameLine();
var fileName = group.FileName( _mod.BasePath );
var fileExists = File.Exists( fileName );
tt = fileExists
? $"Open the {group.Name} json file in the text editor of your choice."
: $"The {group.Name} json file does not exist.";
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.FileExport.ToIconString(), _window._iconButtonSize, tt, !fileExists, true ) )
{
Process.Start( new ProcessStartInfo( fileName ) { UseShellExecute = true } );
}
ImGui.Dummy( _window._defaultSpace );
using var table = ImRaii.Table( string.Empty, 5, ImGuiTableFlags.SizingFixedFit );
ImGui.TableSetupColumn( "idx", ImGuiTableColumnFlags.WidthFixed, 60 * ImGuiHelpers.GlobalScale );
ImGui.TableSetupColumn( "name", ImGuiTableColumnFlags.WidthFixed, _window._inputTextWidth.X - 62 * ImGuiHelpers.GlobalScale );
ImGui.TableSetupColumn( "delete", ImGuiTableColumnFlags.WidthFixed, ImGui.GetFrameHeight() );
ImGui.TableSetupColumn( "edit", ImGuiTableColumnFlags.WidthFixed, ImGui.GetFrameHeight() );
ImGui.TableSetupColumn( "delete", ImGuiTableColumnFlags.WidthFixed, _window._iconButtonSize.X );
ImGui.TableSetupColumn( "edit", ImGuiTableColumnFlags.WidthFixed, _window._iconButtonSize.X );
ImGui.TableSetupColumn( "priority", ImGuiTableColumnFlags.WidthFixed, 50 * ImGuiHelpers.GlobalScale );
if( table )
{
@ -221,7 +282,7 @@ public partial class ConfigWindow
ImGui.SetNextItemWidth( -1 );
ImGui.InputTextWithHint( "##newOption", "Add new option...", ref _newOptionName, 256 );
ImGui.TableNextColumn();
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), _window._iconButtonSize,
"Add a new option to this group.", _newOptionName.Length == 0, true ) )
{
Penumbra.ModManager.AddOption( _mod, groupIdx, _newOptionName );
@ -258,6 +319,7 @@ public partial class ConfigWindow
}
}
// TODO drag options to other groups without options.
using( var target = ImRaii.DragDropTarget() )
{
if( target.Success && ImGuiUtil.IsDropping( label ) )
@ -266,14 +328,21 @@ public partial class ConfigWindow
{
if( _dragDropGroupIdx == groupIdx )
{
// TODO
Dalamud.Chat.Print(
$"Dropped {_mod.Groups[ _dragDropGroupIdx ][ _dragDropOptionIdx ].Name} onto {_mod.Groups[ groupIdx ][ optionIdx ].Name}" );
var sourceOption = _dragDropOptionIdx;
_delayedActions.Enqueue( () => Penumbra.ModManager.MoveOption( _mod, groupIdx, sourceOption, optionIdx ) );
}
else
{
Dalamud.Chat.Print(
$"Dropped {_mod.Groups[ _dragDropGroupIdx ][ _dragDropOptionIdx ].Name} onto {_mod.Groups[ groupIdx ][ optionIdx ].Name}" );
// Move from one group to another by deleting, then adding the option.
var sourceGroup = _dragDropGroupIdx;
var sourceOption = _dragDropOptionIdx;
var option = group[ _dragDropOptionIdx ];
var priority = group.OptionPriority( _dragDropGroupIdx );
_delayedActions.Enqueue( () =>
{
Penumbra.ModManager.DeleteOption( _mod, sourceGroup, sourceOption );
Penumbra.ModManager.AddOption( _mod, groupIdx, option, priority );
} );
}
}
@ -299,14 +368,14 @@ public partial class ConfigWindow
}
ImGui.TableNextColumn();
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Trash.ToIconString(), _window._iconButtonSize,
"Delete this option.\nHold Control while clicking to delete.", !ImGui.GetIO().KeyCtrl, true ) )
{
_delayedActions.Enqueue( () => Penumbra.ModManager.DeleteOption( _mod, groupIdx, optionIdx ) );
}
ImGui.TableNextColumn();
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Edit.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Edit.ToIconString(), _window._iconButtonSize,
"Edit this option.", false, true ) )
{
_window.SubModPopup.Activate( _mod, groupIdx, optionIdx );

View file

@ -1,4 +1,3 @@
using System.Linq;
using System.Numerics;
using Dalamud.Interface;
using ImGuiNET;
@ -16,7 +15,7 @@ public partial class ConfigWindow
{
private partial class ModPanel
{
private ModSettings _settings = null!;
private ModSettings _settings = null!;
private ModCollection _collection = null!;
private bool _emptySetting;
private bool _inherited;
@ -92,6 +91,7 @@ public partial class ConfigWindow
var enabled = _settings.Enabled;
if( ImGui.Checkbox( "Enabled", ref enabled ) )
{
Penumbra.ModManager.NewMods.Remove( _mod );
Penumbra.CollectionManager.Current.SetModState( _mod.Index, enabled );
}
}
@ -132,7 +132,7 @@ public partial class ConfigWindow
}
var scroll = ImGui.GetScrollMaxY() > 0 ? ImGui.GetStyle().ScrollbarSize : 0;
ImGui.SameLine( ImGui.GetWindowWidth() - ImGui.CalcTextSize( text ).X - ImGui.GetStyle().FramePadding.X * 2 - scroll);
ImGui.SameLine( ImGui.GetWindowWidth() - ImGui.CalcTextSize( text ).X - ImGui.GetStyle().FramePadding.X * 2 - scroll );
if( ImGui.Button( text ) )
{
Penumbra.CollectionManager.Current.SetModInheritance( _mod.Index, true );

View file

@ -1,6 +1,4 @@
using System;
using System.ComponentModel.Design;
using System.Linq;
using System.Numerics;
using ImGuiNET;
using OtterGui;
@ -112,6 +110,7 @@ public partial class ConfigWindow
{
return;
}
var conflicts = Penumbra.CollectionManager.Current.ModConflicts( _mod.Index );
Mod? oldBadMod = null;
using var indent = ImRaii.PushIndent( 0f );
@ -124,19 +123,20 @@ public partial class ConfigWindow
{
indent.Pop( 30f );
}
if( ImGui.Selectable( badMod.Name ) )
{
_window._selector.SelectByValue( badMod );
}
ImGui.SameLine();
using var color = ImRaii.PushColor( ImGuiCol.Text, conflict.Mod1Priority ? ColorId.HandledConflictMod.Value() : ColorId.ConflictingMod.Value() );
using var color = ImRaii.PushColor( ImGuiCol.Text,
conflict.Mod1Priority ? ColorId.HandledConflictMod.Value() : ColorId.ConflictingMod.Value() );
ImGui.Text( $"(Priority {Penumbra.CollectionManager.Current[ conflict.Mod2 ].Settings!.Priority})" );
indent.Push( 30f );
}
if( conflict.Data is Utf8GamePath p )
{
unsafe
@ -148,7 +148,7 @@ public partial class ConfigWindow
{
ImGui.Selectable( m.Manipulation?.ToString() ?? string.Empty );
}
oldBadMod = badMod;
}
}

View file

@ -1,714 +0,0 @@
//using System.IO;
//using System.Linq;
//using System.Numerics;
//using Dalamud.Interface;
//using FFXIVClientStructs.FFXIV.Client.UI.Misc;
//using ImGuiNET;
//using Lumina.Data.Parsing;
//using Lumina.Excel.GeneratedSheets;
//using Penumbra.GameData.ByteString;
//using Penumbra.GameData.Enums;
//using Penumbra.GameData.Util;
//using Penumbra.Meta;
//using Penumbra.Meta.Manipulations;
//using Penumbra.Mods;
//using Penumbra.UI.Custom;
//using Penumbra.Util;
//using ImGui = ImGuiNET.ImGui;
//
//namespace Penumbra.UI;
//
//public partial class SettingsInterface
//{
// private partial class PluginDetails
// {
// private const string LabelPluginDetails = "PenumbraPluginDetails";
// private const string LabelAboutTab = "About";
// private const string LabelChangedItemsTab = "Changed Items";
// private const string LabelChangedItemsHeader = "##changedItems";
// private const string LabelConflictsTab = "Mod Conflicts";
// private const string LabelConflictsHeader = "##conflicts";
// private const string LabelFileSwapTab = "File Swaps";
// private const string LabelFileSwapHeader = "##fileSwaps";
// private const string LabelFileListTab = "Files";
// private const string LabelFileListHeader = "##fileList";
// private const string LabelGroupSelect = "##groupSelect";
// private const string LabelOptionSelect = "##optionSelect";
// private const string LabelConfigurationTab = "Configuration";
//
// private const string TooltipFilesTab =
// "Green files replace their standard game path counterpart (not in any option) or are in all options of a Single-Select option.\n"
// + "Yellow files are restricted to some options.";
//
// private const float OptionSelectionWidth = 140f;
// private const float CheckMarkSize = 50f;
// private const uint ColorDarkGreen = 0xFF00A000;
// private const uint ColorGreen = 0xFF00C800;
// private const uint ColorYellow = 0xFF00C8C8;
// private const uint ColorDarkRed = 0xFF0000A0;
// private const uint ColorRed = 0xFF0000C8;
//
//
// private bool _editMode;
// private int _selectedGroupIndex;
// private OptionGroup? _selectedGroup;
// private int _selectedOptionIndex;
// private ConfigModule.Option? _selectedOption;
// private string _currentGamePaths = "";
//
// private (FullPath name, bool selected, uint color, Utf8RelPath relName)[]? _fullFilenameList;
//
// private readonly Selector _selector;
// private readonly SettingsInterface _base;
//
// private void SelectGroup( int idx )
// {
// // Not using the properties here because we need it to be not null forgiving in this case.
// var numGroups = _selector.Mod?.Data.Meta.Groups.Count ?? 0;
// _selectedGroupIndex = idx;
// if( _selectedGroupIndex >= numGroups )
// {
// _selectedGroupIndex = 0;
// }
//
// if( numGroups > 0 )
// {
// _selectedGroup = Meta.Groups.ElementAt( _selectedGroupIndex ).Value;
// }
// else
// {
// _selectedGroup = null;
// }
// }
//
// private void SelectGroup()
// => SelectGroup( _selectedGroupIndex );
//
// private void SelectOption( int idx )
// {
// _selectedOptionIndex = idx;
// if( _selectedOptionIndex >= _selectedGroup?.Options.Count )
// {
// _selectedOptionIndex = 0;
// }
//
// if( _selectedGroup?.Options.Count > 0 )
// {
// _selectedOption = ( ( OptionGroup )_selectedGroup ).Options[ _selectedOptionIndex ];
// }
// else
// {
// _selectedOption = null;
// }
// }
//
// private void SelectOption()
// => SelectOption( _selectedOptionIndex );
//
// public void ResetState()
// {
// _fullFilenameList = null;
// SelectGroup();
// SelectOption();
// }
//
// public PluginDetails( SettingsInterface ui, Selector s )
// {
// _base = ui;
// _selector = s;
// ResetState();
// }
//
// // This is only drawn when we have a mod selected, so we can forgive nulls.
// private FullMod Mod
// => _selector.Mod!;
//
// private ModMeta Meta
// => Mod.Data.Meta;
//
// private void DrawAboutTab()
// {
// if( !_editMode && Meta.Description.Length == 0 )
// {
// return;
// }
//
// if( !ImGui.BeginTabItem( LabelAboutTab ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
//
// var desc = Meta.Description;
// var flags = _editMode
// ? ImGuiInputTextFlags.EnterReturnsTrue | ImGuiInputTextFlags.CtrlEnterForNewLine
// : ImGuiInputTextFlags.ReadOnly;
//
// if( _editMode )
// {
// if( ImGui.InputTextMultiline( LabelDescEdit, ref desc, 1 << 16,
// AutoFillSize, flags ) )
// {
// Meta.Description = desc;
// _selector.SaveCurrentMod();
// }
//
// ImGuiCustom.HoverTooltip( TooltipAboutEdit );
// }
// else
// {
// ImGui.TextWrapped( desc );
// }
// }
//
// private void DrawChangedItemsTab()
// {
// if( Mod.Data.ChangedItems.Count == 0 || !ImGui.BeginTabItem( LabelChangedItemsTab ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
//
// if( !ImGui.BeginListBox( LabelChangedItemsHeader, AutoFillSize ) )
// {
// return;
// }
//
// raii.Push( ImGui.EndListBox );
// foreach( var (name, data) in Mod.Data.ChangedItems )
// {
// _base.DrawChangedItem( name, data );
// }
// }
//
// private void DrawConflictTab()
// {
// var conflicts = Penumbra.CollectionManager.Current.ModConflicts( Mod.Data.Index ).ToList();
// if( conflicts.Count == 0 || !ImGui.BeginTabItem( LabelConflictsTab ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
//
// ImGui.SetNextItemWidth( -1 );
// if( !ImGui.BeginListBox( LabelConflictsHeader, AutoFillSize ) )
// {
// return;
// }
//
// raii.Push( ImGui.EndListBox );
// using var indent = ImGuiRaii.PushIndent( 0 );
// Mods.Mod? oldBadMod = null;
// foreach( var conflict in conflicts )
// {
// var badMod = Penumbra.ModManager[ conflict.Mod2 ];
// if( badMod != oldBadMod )
// {
// if( oldBadMod != null )
// {
// indent.Pop( 30f );
// }
//
// if( ImGui.Selectable( badMod.Meta.Name ) )
// {
// _selector.SelectModByDir( badMod.BasePath.Name );
// }
//
// ImGui.SameLine();
// using var color = ImGuiRaii.PushColor( ImGuiCol.Text, conflict.Mod1Priority ? ColorGreen : ColorRed );
// ImGui.Text( $"(Priority {Penumbra.CollectionManager.Current[ conflict.Mod2 ].Settings!.Priority})" );
//
// indent.Push( 30f );
// }
//
// if( conflict.Data is Utf8GamePath p )
// {
// unsafe
// {
// ImGuiNative.igSelectable_Bool( p.Path.Path, 0, ImGuiSelectableFlags.None, Vector2.Zero );
// }
// }
// else if( conflict.Data is MetaManipulation m )
// {
// ImGui.Selectable( m.Manipulation?.ToString() ?? string.Empty );
// }
//
// oldBadMod = badMod;
// }
// }
//
// private void DrawFileSwapTab()
// {
// if( _editMode )
// {
// DrawFileSwapTabEdit();
// return;
// }
//
// if( !Meta.FileSwaps.Any() || !ImGui.BeginTabItem( LabelFileSwapTab ) )
// {
// 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 ) )
// {
// return;
// }
//
// raii.Push( ImGui.EndTable );
//
// foreach( var (source, target) in Meta.FileSwaps )
// {
// ImGui.TableNextColumn();
// ImGuiCustom.CopyOnClickSelectable( source.Path );
//
// ImGui.TableNextColumn();
// ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltRight );
//
// ImGui.TableNextColumn();
// ImGuiCustom.CopyOnClickSelectable( target.InternalName );
//
// ImGui.TableNextRow();
// }
// }
//
// private void UpdateFilenameList()
// {
// if( _fullFilenameList != null )
// {
// return;
// }
//
// _fullFilenameList = Mod.Data.Resources.ModFiles
// .Select( f => ( f, false, ColorGreen, Utf8RelPath.FromFile( f, Mod.Data.BasePath, out var p ) ? p : Utf8RelPath.Empty ) )
// .ToArray();
//
// if( Meta.Groups.Count == 0 )
// {
// return;
// }
//
// for( var i = 0; i < Mod.Data.Resources.ModFiles.Count; ++i )
// {
// foreach( var group in Meta.Groups.Values )
// {
// var inAll = true;
// foreach( var option in group.Options )
// {
// if( option.OptionFiles.ContainsKey( _fullFilenameList[ i ].relName ) )
// {
// _fullFilenameList[ i ].color = ColorYellow;
// }
// else
// {
// inAll = false;
// }
// }
//
// if( inAll && group.SelectionType == SelectType.Single )
// {
// _fullFilenameList[ i ].color = ColorGreen;
// }
// }
// }
// }
//
// private void DrawFileListTab()
// {
// if( !ImGui.BeginTabItem( LabelFileListTab ) )
// {
// return;
// }
//
// 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! )
// {
// colorRaii.Push( ImGuiCol.Text, color );
// ImGui.Selectable( name.FullName );
// colorRaii.Pop();
// }
// }
// else
// {
// _fullFilenameList = null;
// }
// }
//
// private static int HandleDefaultString( Utf8GamePath[] gamePaths, out int removeFolders )
// {
// removeFolders = 0;
// var defaultIndex = gamePaths.IndexOf( p => p.Path.StartsWith( DefaultUtf8GamePath ) );
// if( defaultIndex < 0 )
// {
// return defaultIndex;
// }
//
// var path = gamePaths[ defaultIndex ].Path;
// if( path.Length == TextDefaultGamePath.Length )
// {
// return defaultIndex;
// }
//
// if( path[ TextDefaultGamePath.Length ] != ( byte )'-'
// || !int.TryParse( path.Substring( TextDefaultGamePath.Length + 1 ).ToString(), out removeFolders ) )
// {
// return -1;
// }
//
// return defaultIndex;
// }
//
// private void HandleSelectedFilesButton( bool remove )
// {
// if( _selectedOption == null )
// {
// return;
// }
//
// var option = ( ConfigModule.Option )_selectedOption;
//
// 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;
// }
//
// var defaultIndex = HandleDefaultString( gamePaths, out var removeFolders );
// var changed = false;
// for( var i = 0; i < Mod.Data.Resources.ModFiles.Count; ++i )
// {
// if( !_fullFilenameList![ i ].selected )
// {
// continue;
// }
//
// _fullFilenameList![ i ].selected = false;
// var relName = _fullFilenameList[ i ].relName;
// if( defaultIndex >= 0 )
// {
// gamePaths[ defaultIndex ] = relName.ToGamePath( removeFolders );
// }
//
// if( remove && option.OptionFiles.TryGetValue( relName, out var setPaths ) )
// {
// if( setPaths.RemoveWhere( p => gamePaths.Contains( p ) ) > 0 )
// {
// changed = true;
// }
//
// if( setPaths.Count == 0 && option.OptionFiles.Remove( relName ) )
// {
// changed = true;
// }
// }
// else
// {
// changed = gamePaths
// .Aggregate( changed, ( current, gamePath ) => current | option.AddFile( relName, gamePath ) );
// }
// }
//
// if( changed )
// {
// _fullFilenameList = null;
// _selector.SaveCurrentMod();
// var idx = Penumbra.ModManager.Mods.IndexOf( Mod.Data );
// // Since files may have changed, we need to recompute effective files.
// foreach( var collection in Penumbra.CollectionManager
// .Where( c => c.HasCache && c[ idx ].Settings?.Enabled == true ) )
// {
// collection.CalculateEffectiveFileList( false, collection == Penumbra.CollectionManager.Default );
// }
//
// // If the mod is enabled in the current collection, its conflicts may have changed.
// if( Mod.Settings.Enabled )
// {
// _selector.Cache.TriggerFilterReset();
// }
// }
// }
//
// private void DrawAddToGroupButton()
// {
// if( ImGui.Button( ButtonAddToGroup ) )
// {
// HandleSelectedFilesButton( false );
// }
// }
//
// private void DrawRemoveFromGroupButton()
// {
// if( ImGui.Button( ButtonRemoveFromGroup ) )
// {
// HandleSelectedFilesButton( true );
// }
// }
//
// private void DrawGamePathInput()
// {
// ImGui.SetNextItemWidth( -1 );
// ImGui.InputTextWithHint( LabelGamePathsEditBox, "Hover for help...", ref _currentGamePaths,
// 128 );
// ImGuiCustom.HoverTooltip( TooltipGamePathsEdit );
// }
//
// private void DrawGroupRow()
// {
// if( _selectedGroup == null )
// {
// SelectGroup();
// }
//
// if( _selectedOption == null )
// {
// SelectOption();
// }
//
// if( !DrawEditGroupSelector() )
// {
// return;
// }
//
// ImGui.SameLine();
// if( !DrawEditOptionSelector() )
// {
// return;
// }
//
// ImGui.SameLine();
// DrawAddToGroupButton();
// ImGui.SameLine();
// DrawRemoveFromGroupButton();
// ImGui.SameLine();
// DrawGamePathInput();
// }
//
// private void DrawFileAndGamePaths( int idx )
// {
// void Selectable( uint colorNormal, uint colorReplace )
// {
// var loc = _fullFilenameList![ idx ].color;
// if( loc == colorNormal )
// {
// loc = colorReplace;
// }
//
// using var colors = ImGuiRaii.PushColor( ImGuiCol.Text, loc );
// ImGui.Selectable( _fullFilenameList[ idx ].name.FullName, ref _fullFilenameList[ idx ].selected );
// }
//
// const float indentWidth = 30f;
// if( _selectedOption == null )
// {
// Selectable( 0, ColorGreen );
// return;
// }
//
// var fileName = _fullFilenameList![ idx ].relName;
// var optionFiles = ( ( ConfigModule.Option )_selectedOption ).OptionFiles;
// if( optionFiles.TryGetValue( fileName, out var gamePaths ) )
// {
// Selectable( 0, ColorGreen );
//
// using var indent = ImGuiRaii.PushIndent( indentWidth );
// foreach( var gamePath in gamePaths.ToArray() )
// {
// var tmp = gamePath.ToString();
// var old = tmp;
// if( ImGui.InputText( $"##{fileName}_{gamePath}", ref tmp, 128, ImGuiInputTextFlags.EnterReturnsTrue )
// && tmp != old )
// {
// gamePaths.Remove( gamePath );
// if( tmp.Length > 0 && Utf8GamePath.FromString( tmp, out var p, true ) )
// {
// gamePaths.Add( p );
// }
// else if( gamePaths.Count == 0 )
// {
// optionFiles.Remove( fileName );
// }
//
// _selector.SaveCurrentMod();
// _selector.ReloadCurrentMod();
// }
// }
// }
// else
// {
// Selectable( ColorYellow, ColorRed );
// }
// }
//
// private void DrawMultiSelectorCheckBox( OptionGroup group, int idx, int flag, string label )
// {
// var enabled = ( flag & ( 1 << idx ) ) != 0;
// var oldEnabled = enabled;
// if( ImGui.Checkbox( label, ref enabled ) && oldEnabled != enabled )
// {
// Penumbra.CollectionManager.Current.SetModSetting( Mod.Data.Index, group.GroupName,
// Mod.Settings.Settings[ group.GroupName ] ^ ( 1 << idx ) );
// // If the mod is enabled, recalculate files and filters.
// if( Mod.Settings.Enabled )
// {
// _selector.Cache.TriggerFilterReset();
// }
// }
// }
//
// private void DrawMultiSelector( OptionGroup group )
// {
// if( group.Options.Count == 0 )
// {
// return;
// }
//
// 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}" );
// }
// }
//
// private void DrawSingleSelector( OptionGroup group )
// {
// if( group.Options.Count < 2 )
// {
// return;
// }
//
// var code = Mod.Settings.Settings[ group.GroupName ];
// if( ImGui.Combo( group.GroupName, ref code
// , group.Options.Select( x => x.OptionName ).ToArray(), group.Options.Count )
// && code != Mod.Settings.Settings[ group.GroupName ] )
// {
// Penumbra.CollectionManager.Current.SetModSetting( Mod.Data.Index, group.GroupName, code );
// if( Mod.Settings.Enabled )
// {
// _selector.Cache.TriggerFilterReset();
// }
// }
// }
//
// private void DrawGroupSelectors()
// {
// foreach( var g in Meta.Groups.Values.Where( g => g.SelectionType == SelectType.Single ) )
// {
// DrawSingleSelector( g );
// }
//
// foreach( var g in Meta.Groups.Values.Where( g => g.SelectionType == SelectType.Multi ) )
// {
// DrawMultiSelector( g );
// }
// }
//
// private void DrawConfigurationTab()
// {
// if( !_editMode && !Meta.HasGroupsWithConfig || !ImGui.BeginTabItem( LabelConfigurationTab ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
// if( _editMode )
// {
// DrawGroupSelectorsEdit();
// }
// else
// {
// DrawGroupSelectors();
// }
// }
//
// private void DrawMetaManipulationsTab()
// {
// if( !_editMode && Mod.Data.Resources.MetaManipulations.Count == 0 || !ImGui.BeginTabItem( "Meta Manipulations" ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
//
// if( !ImGui.BeginListBox( "##MetaManipulations", AutoFillSize ) )
// {
// return;
// }
//
// raii.Push( ImGui.EndListBox );
//
// var manips = Mod.Data.Resources.MetaManipulations;
// var changes = false;
// if( _editMode || manips.DefaultData.Count > 0 )
// {
// if( ImGui.CollapsingHeader( "Default" ) )
// {
// changes = DrawMetaManipulationsTable( "##DefaultManips", manips.DefaultData, ref manips.Count );
// }
// }
//
// 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;
// if( !ImGui.BeginTabBar( LabelPluginDetails ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabBar );
// DrawAboutTab();
// DrawChangedItemsTab();
//
// DrawConfigurationTab();
// if( _editMode )
// {
// DrawFileListTabEdit();
// }
// else
// {
// DrawFileListTab();
// }
//
// DrawFileSwapTab();
// DrawMetaManipulationsTab();
// DrawConflictTab();
// }
// }
//}

View file

@ -1,381 +0,0 @@
//using System.Collections.Generic;
//using System.Linq;
//using System.Numerics;
//using Dalamud.Interface;
//using FFXIVClientStructs.FFXIV.Client.UI.Misc;
//using ImGuiNET;
//using Penumbra.GameData.ByteString;
//using Penumbra.GameData.Util;
//using Penumbra.Mods;
//using Penumbra.UI.Custom;
//using Penumbra.Util;
//
//namespace Penumbra.UI;
//
//public partial class SettingsInterface
//{
// 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()
// {
// 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;
// }
//
// 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 ConfigModule.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();
// 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 ConfigModule.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();
// }
// }
// }
//
// 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 ) )
// {
// if( code == group.Options.Count )
// {
// if( newName.Length > 0 )
// {
// Penumbra.CollectionManager.Current.SetModSetting(Mod.Data.Index, group.GroupName, code);
// group.Options.Add( new ConfigModule.Option()
// {
// 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 != group.Options[ code ].OptionName )
// {
// group.Options[ code ] = new ConfigModule.Option()
// {
// OptionName = newName, OptionDesc = group.Options[ code ].OptionDesc,
// OptionFiles = group.Options[ code ].OptionFiles,
// };
// _selector.SaveCurrentMod();
// }
// }
// }
//
// if( Mod.Data.Meta.RefreshHasGroupsWithConfig() )
// {
// _selector.Cache.TriggerFilterReset();
// }
// }
//
// 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();
// 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 FullPath( valueString.ToLowerInvariant() );
// if( newValue.CompareTo( value ) != 0 )
// {
// Meta.FileSwaps[ key ] = newValue;
// _selector.SaveCurrentMod();
// _selector.Cache.TriggerListReset();
// }
// }
// }
// }
// }
//}

View file

@ -1,773 +0,0 @@
//using System;
//using System.Collections.Generic;
//using System.ComponentModel;
//using System.Linq;
//using System.Numerics;
//using Dalamud.Interface;
//using ImGuiNET;
//using Penumbra.GameData.Enums;
//using Penumbra.GameData.Structs;
//using Penumbra.Meta.Files;
//using Penumbra.Meta.Manipulations;
//using Penumbra.UI.Custom;
//using ObjectType = Penumbra.GameData.Enums.ObjectType;
//
//namespace Penumbra.UI;
//
//public partial class SettingsInterface
//{
// private partial class PluginDetails
// {
// private int _newManipTypeIdx = 0;
// private ushort _newManipSetId = 0;
// private ushort _newManipSecondaryId = 0;
// private int _newManipSubrace = 0;
// private int _newManipRace = 0;
// private int _newManipAttribute = 0;
// private int _newManipEquipSlot = 0;
// private int _newManipObjectType = 0;
// private int _newManipGender = 0;
// private int _newManipBodySlot = 0;
// private ushort _newManipVariant = 0;
//
//
// private static readonly (string, EquipSlot)[] EqpEquipSlots =
// {
// ( "Head", EquipSlot.Head ),
// ( "Body", EquipSlot.Body ),
// ( "Hands", EquipSlot.Hands ),
// ( "Legs", EquipSlot.Legs ),
// ( "Feet", EquipSlot.Feet ),
// };
//
// private static readonly (string, EquipSlot)[] EqdpEquipSlots =
// {
// EqpEquipSlots[ 0 ],
// EqpEquipSlots[ 1 ],
// EqpEquipSlots[ 2 ],
// EqpEquipSlots[ 3 ],
// EqpEquipSlots[ 4 ],
// ( "Ears", EquipSlot.Ears ),
// ( "Neck", EquipSlot.Neck ),
// ( "Wrist", EquipSlot.Wrists ),
// ( "Left Finger", EquipSlot.LFinger ),
// ( "Right Finger", EquipSlot.RFinger ),
// };
//
// private static readonly (string, ModelRace)[] Races =
// {
// ( ModelRace.Midlander.ToName(), ModelRace.Midlander ),
// ( ModelRace.Highlander.ToName(), ModelRace.Highlander ),
// ( ModelRace.Elezen.ToName(), ModelRace.Elezen ),
// ( ModelRace.Miqote.ToName(), ModelRace.Miqote ),
// ( ModelRace.Roegadyn.ToName(), ModelRace.Roegadyn ),
// ( ModelRace.Lalafell.ToName(), ModelRace.Lalafell ),
// ( ModelRace.AuRa.ToName(), ModelRace.AuRa ),
// ( ModelRace.Viera.ToName(), ModelRace.Viera ),
// ( ModelRace.Hrothgar.ToName(), ModelRace.Hrothgar ),
// };
//
// private static readonly (string, Gender)[] Genders =
// {
// ( Gender.Male.ToName(), Gender.Male ),
// ( Gender.Female.ToName(), Gender.Female ),
// ( Gender.MaleNpc.ToName(), Gender.MaleNpc ),
// ( Gender.FemaleNpc.ToName(), Gender.FemaleNpc ),
// };
//
// private static readonly (string, EstManipulation.EstType)[] EstTypes =
// {
// ( "Hair", EstManipulation.EstType.Hair ),
// ( "Face", EstManipulation.EstType.Face ),
// ( "Body", EstManipulation.EstType.Body ),
// ( "Head", EstManipulation.EstType.Head ),
// };
//
// private static readonly (string, SubRace)[] Subraces =
// {
// ( SubRace.Midlander.ToName(), SubRace.Midlander ),
// ( SubRace.Highlander.ToName(), SubRace.Highlander ),
// ( SubRace.Wildwood.ToName(), SubRace.Wildwood ),
// ( SubRace.Duskwight.ToName(), SubRace.Duskwight ),
// ( SubRace.SeekerOfTheSun.ToName(), SubRace.SeekerOfTheSun ),
// ( SubRace.KeeperOfTheMoon.ToName(), SubRace.KeeperOfTheMoon ),
// ( SubRace.Seawolf.ToName(), SubRace.Seawolf ),
// ( SubRace.Hellsguard.ToName(), SubRace.Hellsguard ),
// ( SubRace.Plainsfolk.ToName(), SubRace.Plainsfolk ),
// ( SubRace.Dunesfolk.ToName(), SubRace.Dunesfolk ),
// ( SubRace.Raen.ToName(), SubRace.Raen ),
// ( SubRace.Xaela.ToName(), SubRace.Xaela ),
// ( SubRace.Rava.ToName(), SubRace.Rava ),
// ( SubRace.Veena.ToName(), SubRace.Veena ),
// ( SubRace.Helion.ToName(), SubRace.Helion ),
// ( SubRace.Lost.ToName(), SubRace.Lost ),
// };
//
// private static readonly (string, RspAttribute)[] RspAttributes =
// {
// ( RspAttribute.MaleMinSize.ToFullString(), RspAttribute.MaleMinSize ),
// ( RspAttribute.MaleMaxSize.ToFullString(), RspAttribute.MaleMaxSize ),
// ( RspAttribute.FemaleMinSize.ToFullString(), RspAttribute.FemaleMinSize ),
// ( RspAttribute.FemaleMaxSize.ToFullString(), RspAttribute.FemaleMaxSize ),
// ( RspAttribute.BustMinX.ToFullString(), RspAttribute.BustMinX ),
// ( RspAttribute.BustMaxX.ToFullString(), RspAttribute.BustMaxX ),
// ( RspAttribute.BustMinY.ToFullString(), RspAttribute.BustMinY ),
// ( RspAttribute.BustMaxY.ToFullString(), RspAttribute.BustMaxY ),
// ( RspAttribute.BustMinZ.ToFullString(), RspAttribute.BustMinZ ),
// ( RspAttribute.BustMaxZ.ToFullString(), RspAttribute.BustMaxZ ),
// ( RspAttribute.MaleMinTail.ToFullString(), RspAttribute.MaleMinTail ),
// ( RspAttribute.MaleMaxTail.ToFullString(), RspAttribute.MaleMaxTail ),
// ( RspAttribute.FemaleMinTail.ToFullString(), RspAttribute.FemaleMinTail ),
// ( RspAttribute.FemaleMaxTail.ToFullString(), RspAttribute.FemaleMaxTail ),
// };
//
//
// private static readonly (string, ObjectType)[] ImcObjectType =
// {
// ( "Equipment", ObjectType.Equipment ),
// ( "Customization", ObjectType.Character ),
// ( "Weapon", ObjectType.Weapon ),
// ( "Demihuman", ObjectType.DemiHuman ),
// ( "Monster", ObjectType.Monster ),
// };
//
// private static readonly (string, BodySlot)[] ImcBodySlots =
// {
// ( "Hair", BodySlot.Hair ),
// ( "Face", BodySlot.Face ),
// ( "Body", BodySlot.Body ),
// ( "Tail", BodySlot.Tail ),
// ( "Ears", BodySlot.Zear ),
// };
//
// private static bool PrintCheckBox( string name, ref bool value, bool def )
// {
// var color = value == def ? 0 : value ? ColorDarkGreen : ColorDarkRed;
// if( color == 0 )
// {
// return ImGui.Checkbox( name, ref value );
// }
//
// using var colorRaii = ImGuiRaii.PushColor( ImGuiCol.Text, color );
// var ret = ImGui.Checkbox( name, ref value );
// return ret;
// }
//
// private bool RestrictedInputInt( string name, ref ushort value, ushort min, ushort max )
// {
// int tmp = value;
// if( ImGui.InputInt( name, ref tmp, 0, 0, _editMode ? ImGuiInputTextFlags.EnterReturnsTrue : ImGuiInputTextFlags.ReadOnly )
// && tmp != value
// && tmp >= min
// && tmp <= max )
// {
// value = ( ushort )tmp;
// return true;
// }
//
// return false;
// }
//
// private static bool DefaultButton< T >( string name, ref T value, T defaultValue ) where T : IComparable< T >
// {
// var compare = defaultValue.CompareTo( value );
// var color = compare < 0 ? ColorDarkGreen :
// compare > 0 ? ColorDarkRed : ImGui.ColorConvertFloat4ToU32( ImGui.GetStyle().Colors[ ( int )ImGuiCol.Button ] );
//
// using var colorRaii = ImGuiRaii.PushColor( ImGuiCol.Button, color );
// var ret = ImGui.Button( name, Vector2.UnitX * 120 ) && compare != 0;
// ImGui.SameLine();
// return ret;
// }
//
// private bool DrawInputWithDefault( string name, ref ushort value, ushort defaultValue, ushort max )
// => DefaultButton( $"{( _editMode ? "Set to " : "" )}Default: {defaultValue}##imc{name}", ref value, defaultValue )
// || RestrictedInputInt( name, ref value, 0, max );
//
// private static bool CustomCombo< T >( string label, IList< (string, T) > namesAndValues, out T value, ref int idx )
// {
// value = idx < namesAndValues.Count ? namesAndValues[ idx ].Item2 : default!;
//
// if( !ImGui.BeginCombo( label, idx < namesAndValues.Count ? namesAndValues[ idx ].Item1 : string.Empty ) )
// {
// 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 )
// {
// continue;
// }
//
// idx = i;
// value = namesAndValues[ i ].Item2;
// return true;
// }
//
// return false;
// }
//
// private bool DrawEqpRow( int manipIdx, IList< MetaManipulation > list )
// {
// var ret = false;
// var id = list[ manipIdx ].Eqp;
// var val = id.Entry;
//
//
// if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
// {
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
// var defaults = ExpandedEqpFile.GetDefault( id.SetId );
// var attributes = Eqp.EqpAttributes[ id.Slot ];
//
// foreach( var flag in attributes )
// {
// var name = flag.ToLocalName();
// var tmp = val.HasFlag( flag );
// if( PrintCheckBox( $"{name}##manip", ref tmp, defaults.HasFlag( flag ) ) && _editMode && tmp != val.HasFlag( flag ) )
// {
// list[ manipIdx ] = new MetaManipulation( new EqpManipulation( tmp ? val | flag : val & ~flag, id.Slot, id.SetId ) );
// ret = true;
// }
// }
// }
//
// ImGui.Text( ObjectType.Equipment.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.SetId.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.Slot.ToString() );
// return ret;
// }
//
// private bool DrawGmpRow( int manipIdx, IList< MetaManipulation > list )
// {
// var ret = false;
// var id = list[ manipIdx ].Gmp;
// var val = id.Entry;
//
// if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
// {
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
// var defaults = ExpandedGmpFile.GetDefault( id.SetId );
// 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 );
// ret |= DrawInputWithDefault( "Rotation A##manip", ref rotationA, defaults.RotationA, 0x3FF );
// ret |= DrawInputWithDefault( "Rotation B##manip", ref rotationB, defaults.RotationB, 0x3FF );
// ret |= DrawInputWithDefault( "Rotation C##manip", ref rotationC, defaults.RotationC, 0x3FF );
// ret |= DrawInputWithDefault( "Unknown Byte##manip", ref unk, defaults.UnknownTotal, 0xFF );
//
// if( ret && _editMode )
// {
// list[ manipIdx ] = new MetaManipulation( new GmpManipulation( new GmpEntry
// {
// Animated = animated, Enabled = enabled, UnknownTotal = ( byte )unk,
// RotationA = rotationA, RotationB = rotationB, RotationC = rotationC,
// }, id.SetId ) );
// }
// }
//
// ImGui.Text( ObjectType.Equipment.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.SetId.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( EquipSlot.Head.ToString() );
// return ret;
// }
//
// private static (bool, bool) GetEqdpBits( EquipSlot slot, EqdpEntry entry )
// {
// 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 ),
// };
// }
//
// private static EqdpEntry SetEqdpBits( EquipSlot slot, EqdpEntry value, bool bit1, bool bit2 )
// {
// switch( slot )
// {
// case EquipSlot.Head:
// value = bit1 ? value | EqdpEntry.Head1 : value & ~EqdpEntry.Head1;
// value = bit2 ? value | EqdpEntry.Head2 : value & ~EqdpEntry.Head2;
// return value;
// case EquipSlot.Body:
// value = bit1 ? value | EqdpEntry.Body1 : value & ~EqdpEntry.Body1;
// value = bit2 ? value | EqdpEntry.Body2 : value & ~EqdpEntry.Body2;
// return value;
// case EquipSlot.Hands:
// value = bit1 ? value | EqdpEntry.Hands1 : value & ~EqdpEntry.Hands1;
// value = bit2 ? value | EqdpEntry.Hands2 : value & ~EqdpEntry.Hands2;
// return value;
// case EquipSlot.Legs:
// value = bit1 ? value | EqdpEntry.Legs1 : value & ~EqdpEntry.Legs1;
// value = bit2 ? value | EqdpEntry.Legs2 : value & ~EqdpEntry.Legs2;
// return value;
// case EquipSlot.Feet:
// value = bit1 ? value | EqdpEntry.Feet1 : value & ~EqdpEntry.Feet1;
// value = bit2 ? value | EqdpEntry.Feet2 : value & ~EqdpEntry.Feet2;
// return value;
// case EquipSlot.Neck:
// value = bit1 ? value | EqdpEntry.Neck1 : value & ~EqdpEntry.Neck1;
// value = bit2 ? value | EqdpEntry.Neck2 : value & ~EqdpEntry.Neck2;
// return value;
// case EquipSlot.Ears:
// value = bit1 ? value | EqdpEntry.Ears1 : value & ~EqdpEntry.Ears1;
// value = bit2 ? value | EqdpEntry.Ears2 : value & ~EqdpEntry.Ears2;
// return value;
// case EquipSlot.Wrists:
// value = bit1 ? value | EqdpEntry.Wrists1 : value & ~EqdpEntry.Wrists1;
// value = bit2 ? value | EqdpEntry.Wrists2 : value & ~EqdpEntry.Wrists2;
// return value;
// case EquipSlot.RFinger:
// value = bit1 ? value | EqdpEntry.RingR1 : value & ~EqdpEntry.RingR1;
// value = bit2 ? value | EqdpEntry.RingR2 : value & ~EqdpEntry.RingR2;
// return value;
// case EquipSlot.LFinger:
// value = bit1 ? value | EqdpEntry.RingL1 : value & ~EqdpEntry.RingL1;
// value = bit2 ? value | EqdpEntry.RingL2 : value & ~EqdpEntry.RingL2;
// return value;
// }
//
// return value;
// }
//
// private bool DrawEqdpRow( int manipIdx, IList< MetaManipulation > list )
// {
// var ret = false;
// var id = list[ manipIdx ].Eqdp;
// var val = id.Entry;
//
// if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
// {
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
// var defaults = ExpandedEqdpFile.GetDefault( id.FileIndex(), id.SetId );
// var (bit1, bit2) = GetEqdpBits( id.Slot, val );
// var (defBit1, defBit2) = GetEqdpBits( id.Slot, defaults );
//
// ret |= PrintCheckBox( "Bit 1##manip", ref bit1, defBit1 );
// ret |= PrintCheckBox( "Bit 2##manip", ref bit2, defBit2 );
//
// if( ret && _editMode )
// {
// list[ manipIdx ] = new MetaManipulation( new EqdpManipulation( SetEqdpBits( id.Slot, val, bit1, bit2 ), id.Slot, id.Gender,
// id.Race, id.SetId ) );
// }
// }
//
// ImGui.Text( id.Slot.IsAccessory()
// ? ObjectType.Accessory.ToString()
// : ObjectType.Equipment.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.SetId.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.Slot.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.Race.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.Gender.ToString() );
// return ret;
// }
//
// private bool DrawEstRow( int manipIdx, IList< MetaManipulation > list )
// {
// var ret = false;
// var id = list[ manipIdx ].Est;
// var val = id.Entry;
//
// if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
// {
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
// var defaults = EstFile.GetDefault( id.Slot, Names.CombinedRace( id.Gender, id.Race ), id.SetId );
// if( DrawInputWithDefault( "No Idea what this does!##manip", ref val, defaults, ushort.MaxValue ) && _editMode )
// {
// list[ manipIdx ] = new MetaManipulation( new EstManipulation( id.Gender, id.Race, id.Slot, id.SetId, val ) );
// ret = true;
// }
// }
//
// ImGui.Text( id.Slot.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.SetId.ToString() );
// ImGui.TableNextColumn();
// ImGui.TableNextColumn();
// ImGui.Text( id.Race.ToName() );
// ImGui.TableNextColumn();
// ImGui.Text( id.Gender.ToName() );
//
// return ret;
// }
//
// private bool DrawImcRow( int manipIdx, IList< MetaManipulation > list )
// {
// var ret = false;
// var id = list[ manipIdx ].Imc;
// var val = id.Entry;
//
// if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
// {
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
// var defaults = new ImcFile( id.GamePath() ).GetEntry( ImcFile.PartIndex( id.EquipSlot ), id.Variant );
// ushort materialId = val.MaterialId;
// ushort vfxId = val.VfxId;
// ushort decalId = val.DecalId;
// var soundId = ( ushort )val.SoundId;
// var attributeMask = val.AttributeMask;
// var materialAnimationId = ( ushort )val.MaterialAnimationId;
// 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 );
// ret |= DrawInputWithDefault( "Sound Id", ref soundId, defaults.SoundId, 0x3F );
// ret |= DrawInputWithDefault( "Attribute Mask", ref attributeMask, defaults.AttributeMask, 0x3FF );
// ret |= DrawInputWithDefault( "Material Animation Id", ref materialAnimationId, defaults.MaterialAnimationId,
// byte.MaxValue );
//
// if( ret && _editMode )
// {
// var value = new ImcEntry( ( byte )materialId, ( byte )decalId, attributeMask, ( byte )soundId, ( byte )vfxId,
// ( byte )materialAnimationId );
// list[ manipIdx ] = new MetaManipulation( new ImcManipulation( id, value ) );
// }
// }
//
// ImGui.Text( id.ObjectType.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.PrimaryId.ToString() );
// ImGui.TableNextColumn();
// if( id.ObjectType is ObjectType.Accessory or ObjectType.Equipment )
// {
// ImGui.Text( id.ObjectType is ObjectType.Equipment or ObjectType.Accessory
// ? id.EquipSlot.ToString()
// : id.BodySlot.ToString() );
// }
//
// ImGui.TableNextColumn();
// ImGui.TableNextColumn();
// ImGui.TableNextColumn();
// if( id.ObjectType != ObjectType.Equipment
// && id.ObjectType != ObjectType.Accessory )
// {
// ImGui.Text( id.SecondaryId.ToString() );
// }
//
// ImGui.TableNextColumn();
// ImGui.Text( id.Variant.ToString() );
// return ret;
// }
//
// private bool DrawRspRow( int manipIdx, IList< MetaManipulation > list )
// {
// var ret = false;
// var id = list[ manipIdx ].Rsp;
// var defaults = CmpFile.GetDefault( id.SubRace, id.Attribute );
// var val = id.Entry;
// 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 )
// {
// list[ manipIdx ] = new MetaManipulation( new RspManipulation( id.SubRace, id.Attribute, val ) );
// ret = true;
// }
//
// ImGui.SetNextItemWidth( 50 * ImGuiHelpers.GlobalScale );
// if( ImGui.InputFloat( "Scale###manip", ref val, 0, 0, "%.3f",
// _editMode ? ImGuiInputTextFlags.EnterReturnsTrue : ImGuiInputTextFlags.ReadOnly )
// && val >= 0
// && val <= 5
// && _editMode )
// {
// list[ manipIdx ] = new MetaManipulation( new RspManipulation( id.SubRace, id.Attribute, val ) );
// ret = true;
// }
// }
//
// ImGui.Text( id.Attribute.ToUngenderedString() );
// ImGui.TableNextColumn();
// ImGui.TableNextColumn();
// ImGui.TableNextColumn();
// ImGui.Text( id.SubRace.ToString() );
// ImGui.TableNextColumn();
// ImGui.Text( id.Attribute.ToGender().ToString() );
// return ret;
// }
//
// private bool DrawManipulationRow( ref int manipIdx, IList< MetaManipulation > list, ref int count )
// {
// var type = list[ manipIdx ].ManipulationType;
//
// if( _editMode )
// {
// ImGui.TableNextColumn();
// using var font = ImGuiRaii.PushFont( UiBuilder.IconFont );
// if( ImGui.Button( $"{FontAwesomeIcon.Trash.ToIconString()}##manipDelete{manipIdx}" ) )
// {
// list.RemoveAt( manipIdx );
// ImGui.TableNextRow();
// --manipIdx;
// --count;
// return true;
// }
// }
//
// ImGui.TableNextColumn();
// ImGui.Text( type.ToString() );
// ImGui.TableNextColumn();
//
// var changes = false;
// switch( type )
// {
// case MetaManipulation.Type.Eqp:
// changes = DrawEqpRow( manipIdx, list );
// ImGui.TableSetColumnIndex( 9 );
// if( ImGui.Selectable( $"{list[ manipIdx ].Eqp.Entry}##{manipIdx}" ) )
// {
// ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
// }
//
// break;
// case MetaManipulation.Type.Gmp:
// changes = DrawGmpRow( manipIdx, list );
// ImGui.TableSetColumnIndex( 9 );
// if( ImGui.Selectable( $"{list[ manipIdx ].Gmp.Entry.Value}##{manipIdx}" ) )
// {
// ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
// }
//
// break;
// case MetaManipulation.Type.Eqdp:
// changes = DrawEqdpRow( manipIdx, list );
// ImGui.TableSetColumnIndex( 9 );
// var (bit1, bit2) = GetEqdpBits( list[ manipIdx ].Eqdp.Slot, list[ manipIdx ].Eqdp.Entry );
// if( ImGui.Selectable( $"{bit1} {bit2}##{manipIdx}" ) )
// {
// ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
// }
//
// break;
// case MetaManipulation.Type.Est:
// changes = DrawEstRow( manipIdx, list );
// ImGui.TableSetColumnIndex( 9 );
// if( ImGui.Selectable( $"{list[ manipIdx ].Est.Entry}##{manipIdx}" ) )
// {
// ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
// }
//
// break;
// case MetaManipulation.Type.Imc:
// changes = DrawImcRow( manipIdx, list );
// ImGui.TableSetColumnIndex( 9 );
// if( ImGui.Selectable( $"{list[ manipIdx ].Imc.Entry.MaterialId}##{manipIdx}" ) )
// {
// ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
// }
//
// break;
// case MetaManipulation.Type.Rsp:
// changes = DrawRspRow( manipIdx, list );
// ImGui.TableSetColumnIndex( 9 );
// if( ImGui.Selectable( $"{list[ manipIdx ].Rsp.Entry}##{manipIdx}" ) )
// {
// ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
// }
//
// break;
// }
//
//
// ImGui.TableNextRow();
// return changes;
// }
//
//
// private MetaManipulation.Type DrawNewTypeSelection()
// {
// ImGui.RadioButton( "IMC##newManipType", ref _newManipTypeIdx, 1 );
// ImGui.SameLine();
// ImGui.RadioButton( "EQDP##newManipType", ref _newManipTypeIdx, 2 );
// ImGui.SameLine();
// ImGui.RadioButton( "EQP##newManipType", ref _newManipTypeIdx, 3 );
// ImGui.SameLine();
// ImGui.RadioButton( "EST##newManipType", ref _newManipTypeIdx, 4 );
// ImGui.SameLine();
// ImGui.RadioButton( "GMP##newManipType", ref _newManipTypeIdx, 5 );
// ImGui.SameLine();
// ImGui.RadioButton( "RSP##newManipType", ref _newManipTypeIdx, 6 );
// return ( MetaManipulation.Type )_newManipTypeIdx;
// }
//
// private bool DrawNewManipulationPopup( string popupName, IList< MetaManipulation > list, ref int count )
// {
// var change = false;
// if( !ImGui.BeginPopup( popupName ) )
// {
// return change;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
// var manipType = DrawNewTypeSelection();
// MetaManipulation? newManip = null;
// switch( manipType )
// {
// case MetaManipulation.Type.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 );
// ImcManipulation imc = new();
// switch( objectType )
// {
// case ObjectType.Equipment:
// CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
// imc = new ImcManipulation( equipSlot, _newManipVariant, _newManipSetId, new ImcEntry() );
// 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 );
// imc = new ImcManipulation( objectType, bodySlot, _newManipSetId, _newManipSecondaryId,
// _newManipVariant, new ImcEntry() );
// break;
// }
//
// newManip = new MetaManipulation( new ImcManipulation( imc.ObjectType, imc.BodySlot, imc.PrimaryId, imc.SecondaryId,
// imc.Variant, imc.EquipSlot, ImcFile.GetDefault( imc.GamePath(), imc.EquipSlot, imc.Variant ) ) );
//
// break;
// }
// case MetaManipulation.Type.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 );
// var eqdp = new EqdpManipulation( new EqdpEntry(), equipSlot, gender, race, _newManipSetId );
// newManip = new MetaManipulation( new EqdpManipulation( ExpandedEqdpFile.GetDefault( eqdp.FileIndex(), eqdp.SetId ),
// equipSlot, gender, race, _newManipSetId ) );
// break;
// }
// case MetaManipulation.Type.Eqp:
// {
// RestrictedInputInt( "Set Id##newManipEqp", ref _newManipSetId, 0, ushort.MaxValue );
// CustomCombo( "Equipment Slot", EqpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
// newManip = new MetaManipulation( new EqpManipulation( ExpandedEqpFile.GetDefault( _newManipSetId ) & Eqp.Mask( equipSlot ),
// equipSlot, _newManipSetId ) );
// break;
// }
// case MetaManipulation.Type.Est:
// {
// RestrictedInputInt( "Set Id##newManipEst", ref _newManipSetId, 0, ushort.MaxValue );
// CustomCombo( "Est Type", EstTypes, out var estType, ref _newManipObjectType );
// CustomCombo( "Race", Races, out var race, ref _newManipRace );
// CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
// newManip = new MetaManipulation( new EstManipulation( gender, race, estType, _newManipSetId,
// EstFile.GetDefault( estType, Names.CombinedRace( gender, race ), _newManipSetId ) ) );
// break;
// }
// case MetaManipulation.Type.Gmp:
// RestrictedInputInt( "Set Id##newManipGmp", ref _newManipSetId, 0, ushort.MaxValue );
// newManip = new MetaManipulation( new GmpManipulation( ExpandedGmpFile.GetDefault( _newManipSetId ), _newManipSetId ) );
// break;
// case MetaManipulation.Type.Rsp:
// CustomCombo( "Subrace", Subraces, out var subRace, ref _newManipSubrace );
// CustomCombo( "Attribute", RspAttributes, out var rspAttribute, ref _newManipAttribute );
// newManip = new MetaManipulation( new RspManipulation( subRace, rspAttribute,
// CmpFile.GetDefault( subRace, rspAttribute ) ) );
// break;
// }
//
// if( ImGui.Button( "Create Manipulation##newManip", Vector2.UnitX * -1 )
// && newManip != null
// && list.All( m => !m.Equals( newManip ) ) )
// {
// list.Add( newManip.Value );
// change = true;
// ++count;
// ImGui.CloseCurrentPopup();
// }
//
// return change;
// }
//
// private bool DrawMetaManipulationsTable( string label, IList< MetaManipulation > list, ref int count )
// {
// var numRows = _editMode ? 11 : 10;
// var changes = false;
//
//
// if( list.Count > 0
// && ImGui.BeginTable( label, numRows,
// ImGuiTableFlags.BordersInner | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ) )
// {
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
// if( _editMode )
// {
// ImGui.TableNextColumn();
// }
//
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Type##{label}" );
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Object Type##{label}" );
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Set##{label}" );
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Slot##{label}" );
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Race##{label}" );
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Gender##{label}" );
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Secondary ID##{label}" );
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Variant##{label}" );
// ImGui.TableNextColumn();
// ImGui.TableNextColumn();
// ImGui.TableHeader( $"Value##{label}" );
// ImGui.TableNextRow();
//
// for( var i = 0; i < list.Count; ++i )
// {
// changes |= DrawManipulationRow( ref i, list, ref count );
// }
// }
//
// var popupName = $"##newManip{label}";
// if( _editMode )
// {
// changes |= DrawNewManipulationPopup( $"##newManip{label}", list, ref count );
// if( ImGui.Button( $"Add New Manipulation##{label}", Vector2.UnitX * -1 ) )
// {
// ImGui.OpenPopup( popupName );
// }
//
// return changes;
// }
//
// return false;
// }
// }
//}

View file

@ -1,177 +0,0 @@
namespace Penumbra.UI;
//public partial class ConfigWindow
//{
// private class TabImport
// {
// private const string LabelTab = "Import Mods";
// private const string LabelImportButton = "Import TexTools Modpacks";
// private const string LabelFileDialog = "Pick one or more modpacks.";
// private const string LabelFileImportRunning = "Import in progress...";
// private const string FileTypeFilter = "TexTools TTMP Modpack (*.ttmp2)|*.ttmp*|All files (*.*)|*.*";
// private const string TooltipModpack1 = "Writing modpack to disk before extracting...";
//
// private const uint ColorRed = 0xFF0000C8;
// private const uint ColorYellow = 0xFF00C8C8;
//
// private static readonly Vector2 ImportBarSize = new(-1, 0);
//
// private bool _isImportRunning;
// private string _errorMessage = string.Empty;
// private TexToolsImport? _texToolsImport;
// private readonly SettingsInterface _base;
//
// public readonly HashSet< string > NewMods = new();
//
// public TabImport( SettingsInterface ui )
// => _base = ui;
//
// public bool IsImporting()
// => _isImportRunning;
//
// private void RunImportTask()
// {
// _isImportRunning = true;
// Task.Run( async () =>
// {
// try
// {
// var picker = new OpenFileDialog
// {
// Multiselect = true,
// Filter = FileTypeFilter,
// CheckFileExists = true,
// Title = LabelFileDialog,
// };
//
// var result = await picker.ShowDialogAsync();
//
// if( result == DialogResult.OK )
// {
// _errorMessage = string.Empty;
//
// foreach( var fileName in picker.FileNames )
// {
// PluginLog.Information( $"-> {fileName} START" );
//
// try
// {
// _texToolsImport = new TexToolsImport( Penumbra.ModManager.BasePath );
// var dir = _texToolsImport.ImportModPack( new FileInfo( fileName ) );
// if( dir.Name.Any() )
// {
// NewMods.Add( dir.Name );
// }
//
// PluginLog.Information( $"-> {fileName} OK!" );
// }
// catch( Exception ex )
// {
// PluginLog.LogError( ex, "Failed to import modpack at {0}", fileName );
// _errorMessage = ex.Message;
// }
// }
//
// var directory = _texToolsImport?.ExtractedDirectory;
// _texToolsImport = null;
// _base.ReloadMods();
// if( directory != null )
// {
// _base._menu.InstalledTab.Selector.SelectModOnUpdate( directory.Name );
// }
// }
// }
// catch( Exception e )
// {
// PluginLog.Error( $"Error opening file picker dialogue:\n{e}" );
// }
//
// _isImportRunning = false;
// } );
// }
//
// private void DrawImportButton()
// {
// if( !Penumbra.ModManager.Valid )
// {
// using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f );
// ImGui.Button( LabelImportButton );
// style.Pop();
//
// 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() );
// 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" );
// color.Push( ImGuiCol.Text, ColorYellow );
// ImGui.Text( " D:\\ffxivmods" );
// color.Pop();
// ImGui.Text( "You can return to this tab once you've done that." );
// }
// else if( ImGui.Button( LabelImportButton ) )
// {
// RunImportTask();
// }
// }
//
// private void DrawImportProgress()
// {
// ImGui.Button( LabelFileImportRunning );
//
// if( _texToolsImport == null )
// {
// return;
// }
//
// switch( _texToolsImport.State )
// {
// case ImporterState.None: break;
// case ImporterState.WritingPackToDisk:
// ImGui.Text( TooltipModpack1 );
// break;
// case ImporterState.ExtractingModFiles:
// {
// var str =
// $"{_texToolsImport.CurrentModPack} - {_texToolsImport.CurrentProgress} of {_texToolsImport.TotalProgress} files";
//
// ImGui.ProgressBar( _texToolsImport.Progress, ImportBarSize, str );
// break;
// }
// case ImporterState.Done: break;
// default: throw new ArgumentOutOfRangeException();
// }
// }
//
// private void DrawFailedImportMessage()
// {
// using var color = ImGuiRaii.PushColor( ImGuiCol.Text, ColorRed );
// ImGui.Text( $"One or more of your modpacks failed to import:\n\t\t{_errorMessage}" );
// }
//
// public void Draw()
// {
// if( !ImGui.BeginTabItem( LabelTab ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
//
// if( !_isImportRunning )
// {
// DrawImportButton();
// }
// else
// {
// DrawImportProgress();
// }
//
// if( _errorMessage.Any() )
// {
// DrawFailedImportMessage();
// }
// }
// }
//}

View file

@ -1,613 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Logging;
using ImGuiNET;
using Penumbra.Mods;
using Penumbra.Util;
namespace Penumbra.UI;
public partial class SettingsInterface
{
//private class ModPanel
//{
// private const string LabelModPanel = "selectedModInfo";
// private const string LabelEditName = "##editName";
// private const string LabelEditVersion = "##editVersion";
// private const string LabelEditAuthor = "##editAuthor";
// private const string LabelEditWebsite = "##editWebsite";
// private const string LabelModEnabled = "Enabled";
// private const string LabelEditingEnabled = "Enable Editing";
// private const string LabelOverWriteDir = "OverwriteDir";
// private const string ButtonOpenWebsite = "Open Website";
// private const string ButtonOpenModFolder = "Open Mod Folder";
// private const string ButtonRenameModFolder = "Rename Mod Folder";
// private const string ButtonEditJson = "Edit JSON";
// private const string ButtonReloadJson = "Reload JSON";
// private const string ButtonDeduplicate = "Deduplicate";
// private const string ButtonNormalize = "Normalize";
// private const string TooltipOpenModFolder = "Open the directory containing this mod in your default file explorer.";
// private const string TooltipRenameModFolder = "Rename the directory containing this mod without opening another application.";
// private const string TooltipEditJson = "Open the JSON configuration file in your default application for .json.";
// private const string TooltipReloadJson = "Reload the configuration of all mods.";
// private const string PopupRenameFolder = "Rename Folder";
//
// private const string TooltipDeduplicate =
// "Try to find identical files and remove duplicate occurences to reduce the mods disk size.\n"
// + "Introduces an invisible single-option Group \"Duplicates\".\nExperimental - use at own risk!";
//
// private const string TooltipNormalize =
// "Try to reduce unnecessary options or subdirectories to default options if possible.\nExperimental - use at own risk!";
//
// private const float HeaderLineDistance = 10f;
// private static readonly Vector4 GreyColor = new(1f, 1f, 1f, 0.66f);
//
// private readonly SettingsInterface _base;
// private readonly Selector _selector;
// private readonly HashSet< string > _newMods;
// public readonly PluginDetails Details;
//
// private bool _editMode;
// private string _currentWebsite;
// private bool _validWebsite;
//
// private string _fromMaterial = string.Empty;
// private string _toMaterial = string.Empty;
//
// public ModPanel( SettingsInterface ui, Selector s, HashSet< string > newMods )
// {
// _base = ui;
// _selector = s;
// _newMods = newMods;
// Details = new PluginDetails( _base, _selector );
// _currentWebsite = Meta?.Website ?? "";
// }
//
// private Mods.FullMod? Mod
// => _selector.Mod;
//
// private ModMeta? Meta
// => Mod?.Data.Meta;
//
// private void DrawName()
// {
// var name = Meta!.Name.Text;
// var modManager = Penumbra.ModManager;
// if( ImGuiCustom.InputOrText( _editMode, LabelEditName, ref name, 64 ) && modManager.RenameMod( name, Mod!.Data ) )
// {
// _selector.SelectModOnUpdate( Mod.Data.BasePath.Name );
// if( !modManager.TemporaryModSortOrder.ContainsKey( Mod!.Data.BasePath.Name ) )
// {
// Mod.Data.Rename( name );
// }
// }
// }
//
// private void DrawVersion()
// {
// if( _editMode )
// {
// ImGui.BeginGroup();
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndGroup );
// ImGui.Text( "(Version " );
//
// using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.ItemSpacing, ZeroVector );
// ImGui.SameLine();
// var version = Meta!.Version;
// if( ImGuiCustom.ResizingTextInput( LabelEditVersion, ref version, 16 )
// && version != Meta.Version )
// {
// Meta.Version = version;
// _selector.SaveCurrentMod();
// }
//
// ImGui.SameLine();
// ImGui.Text( ")" );
// }
// else if( Meta!.Version.Length > 0 )
// {
// ImGui.Text( $"(Version {Meta.Version})" );
// }
// }
//
// private void DrawAuthor()
// {
// ImGui.BeginGroup();
// ImGui.TextColored( GreyColor, "by" );
//
// ImGui.SameLine();
// var author = Meta!.Author.Text;
// if( ImGuiCustom.InputOrText( _editMode, LabelEditAuthor, ref author, 64 )
// && author != Meta.Author )
// {
// Meta.Author = author;
// _selector.SaveCurrentMod();
// _selector.Cache.TriggerFilterReset();
// }
//
// ImGui.EndGroup();
// }
//
// 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( ImGuiCustom.ResizingTextInput( LabelEditWebsite, ref website, 512 )
// && website != Meta.Website )
// {
// Meta.Website = website;
// _selector.SaveCurrentMod();
// }
// }
// else if( Meta!.Website.Length > 0 )
// {
// if( _currentWebsite != Meta.Website )
// {
// _currentWebsite = Meta.Website;
// _validWebsite = Uri.TryCreate( Meta.Website, UriKind.Absolute, out var uriResult )
// && ( uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp );
// }
//
// if( _validWebsite )
// {
// if( ImGui.SmallButton( ButtonOpenWebsite ) )
// {
// try
// {
// var process = new ProcessStartInfo( Meta.Website )
// {
// UseShellExecute = true,
// };
// Process.Start( process );
// }
// catch( System.ComponentModel.Win32Exception )
// {
// // Do nothing.
// }
// }
//
// ImGuiCustom.HoverTooltip( Meta.Website );
// }
// else
// {
// ImGui.TextColored( GreyColor, "from" );
// ImGui.SameLine();
// ImGui.Text( Meta.Website );
// }
// }
// }
//
// private void DrawHeaderLine()
// {
// DrawName();
// ImGui.SameLine();
// DrawVersion();
// ImGui.SameLine();
// DrawAuthor();
// ImGui.SameLine();
// DrawWebsite();
// }
//
// private void DrawPriority()
// {
// var priority = Mod!.Settings.Priority;
// ImGui.SetNextItemWidth( 50 * ImGuiHelpers.GlobalScale );
// if( ImGui.InputInt( "Priority", ref priority, 0 ) && priority != Mod!.Settings.Priority )
// {
// Penumbra.CollectionManager.Current.SetModPriority( Mod.Data.Index, priority );
// _selector.Cache.TriggerFilterReset();
// }
//
// 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()
// {
// var enabled = Mod!.Settings.Enabled;
// if( ImGui.Checkbox( LabelModEnabled, ref enabled ) )
// {
// Penumbra.CollectionManager.Current.SetModState( Mod.Data.Index, enabled );
// if( enabled )
// {
// _newMods.Remove( Mod.Data.BasePath.Name );
// }
// _selector.Cache.TriggerFilterReset();
// }
// }
//
// public static bool DrawSortOrder( Mods.Mod mod, Mods.Mod.Manager manager, Selector selector )
// {
// var currentSortOrder = mod.Order.FullPath;
// ImGui.SetNextItemWidth( 300 * ImGuiHelpers.GlobalScale );
// if( ImGui.InputText( "Sort Order", ref currentSortOrder, 256, ImGuiInputTextFlags.EnterReturnsTrue ) )
// {
// manager.ChangeSortOrder( mod, currentSortOrder );
// selector.SelectModOnUpdate( mod.BasePath.Name );
// return true;
// }
//
// return false;
// }
//
// private void DrawEditableMark()
// {
// ImGui.Checkbox( LabelEditingEnabled, ref _editMode );
// }
//
// private void DrawOpenModFolderButton()
// {
// Mod!.Data.BasePath.Refresh();
// if( ImGui.Button( ButtonOpenModFolder ) && Mod.Data.BasePath.Exists )
// {
// Process.Start( new ProcessStartInfo( Mod!.Data.BasePath.FullName ) { UseShellExecute = true } );
// }
//
// ImGuiCustom.HoverTooltip( TooltipOpenModFolder );
// }
//
// private string _newName = "";
// private bool _keyboardFocus = true;
//
// private void RenameModFolder( string newName )
// {
// _newName = newName.ReplaceBadXivSymbols();
// if( _newName.Length == 0 )
// {
// PluginLog.Debug( "New Directory name {NewName} was empty after removing invalid symbols.", newName );
// ImGui.CloseCurrentPopup();
// }
// else if( !string.Equals( _newName, Mod!.Data.BasePath.Name, StringComparison.InvariantCultureIgnoreCase ) )
// {
// var dir = Mod!.Data.BasePath;
// DirectoryInfo newDir = new(Path.Combine( dir.Parent!.FullName, _newName ));
//
// if( newDir.Exists )
// {
// ImGui.OpenPopup( LabelOverWriteDir );
// }
// else if( Penumbra.ModManager.RenameModFolder( Mod.Data, newDir ) )
// {
// _selector.ReloadCurrentMod();
// ImGui.CloseCurrentPopup();
// }
// }
// else if( !string.Equals( _newName, Mod!.Data.BasePath.Name, StringComparison.InvariantCulture ) )
// {
// var dir = Mod!.Data.BasePath;
// DirectoryInfo newDir = new(Path.Combine( dir.Parent!.FullName, _newName ));
// var sourceUri = new Uri( dir.FullName );
// var targetUri = new Uri( newDir.FullName );
// if( sourceUri.Equals( targetUri ) )
// {
// var tmpFolder = new DirectoryInfo( TempFile.TempFileName( dir.Parent! ).FullName );
// if( Penumbra.ModManager.RenameModFolder( Mod.Data, tmpFolder ) )
// {
// if( !Penumbra.ModManager.RenameModFolder( Mod.Data, newDir ) )
// {
// PluginLog.Error( "Could not recapitalize folder after renaming, reverting rename." );
// Penumbra.ModManager.RenameModFolder( Mod.Data, dir );
// }
//
// _selector.ReloadCurrentMod();
// }
//
// ImGui.CloseCurrentPopup();
// }
// else
// {
// ImGui.OpenPopup( LabelOverWriteDir );
// }
// }
// }
//
// private static bool MergeFolderInto( DirectoryInfo source, DirectoryInfo target )
// {
// try
// {
// foreach( var file in source.EnumerateFiles( "*", SearchOption.AllDirectories ) )
// {
// var targetFile = new FileInfo( Path.Combine( target.FullName, file.FullName.Substring( source.FullName.Length + 1 ) ) );
// if( targetFile.Exists )
// {
// targetFile.Delete();
// }
//
// targetFile.Directory?.Create();
// file.MoveTo( targetFile.FullName );
// }
//
// source.Delete( true );
// return true;
// }
// catch( Exception e )
// {
// PluginLog.Error( $"Could not merge directory {source.FullName} into {target.FullName}:\n{e}" );
// }
//
// return false;
// }
//
// private bool OverwriteDirPopup()
// {
// var closeParent = false;
// var _ = true;
// if( !ImGui.BeginPopupModal( LabelOverWriteDir, ref _, ImGuiWindowFlags.AlwaysAutoResize ) )
// {
// return closeParent;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
//
// var 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 ) && MergeFolderInto( dir, newDir ) )
// {
// Penumbra.ModManager.RenameModFolder( Mod.Data, newDir, false );
//
// _selector.SelectModOnUpdate( _newName );
//
// closeParent = true;
// ImGui.CloseCurrentPopup();
// }
//
// ImGui.SameLine();
//
// if( ImGui.Button( "Cancel", buttonSize ) )
// {
// _keyboardFocus = true;
// ImGui.CloseCurrentPopup();
// }
//
// return closeParent;
// }
//
// private void DrawRenameModFolderPopup()
// {
// var _ = true;
// _keyboardFocus |= !ImGui.IsPopupOpen( PopupRenameFolder );
//
// ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, new Vector2( 0.5f, 1f ) );
// if( !ImGui.BeginPopupModal( PopupRenameFolder, ref _, ImGuiWindowFlags.AlwaysAutoResize ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
//
// if( ImGui.IsKeyPressed( ImGui.GetKeyIndex( ImGuiKey.Escape ) ) )
// {
// ImGui.CloseCurrentPopup();
// }
//
// var newName = Mod!.Data.BasePath.Name;
//
// if( _keyboardFocus )
// {
// ImGui.SetKeyboardFocusHere();
// _keyboardFocus = false;
// }
//
// 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();
// }
// }
//
// private void DrawRenameModFolderButton()
// {
// DrawRenameModFolderPopup();
// if( ImGui.Button( ButtonRenameModFolder ) )
// {
// ImGui.OpenPopup( PopupRenameFolder );
// }
//
// ImGuiCustom.HoverTooltip( TooltipRenameModFolder );
// }
//
// private void DrawEditJsonButton()
// {
// if( ImGui.Button( ButtonEditJson ) )
// {
// _selector.SaveCurrentMod();
// Process.Start( new ProcessStartInfo( Mod!.Data.MetaFile.FullName ) { UseShellExecute = true } );
// }
//
// ImGuiCustom.HoverTooltip( TooltipEditJson );
// }
//
// private void DrawReloadJsonButton()
// {
// if( ImGui.Button( ButtonReloadJson ) )
// {
// _selector.ReloadCurrentMod( true, false );
// }
//
// ImGuiCustom.HoverTooltip( TooltipReloadJson );
// }
//
// private void DrawResetMetaButton()
// {
// if( ImGui.Button( "Recompute Metadata" ) )
// {
// _selector.ReloadCurrentMod( true, true, true );
// }
//
// 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()
// {
// if( ImGui.Button( ButtonDeduplicate ) )
// {
// ModCleanup.Deduplicate( Mod!.Data.BasePath, Meta! );
// _selector.SaveCurrentMod();
// _selector.ReloadCurrentMod( true, true, true );
// }
//
// ImGuiCustom.HoverTooltip( TooltipDeduplicate );
// }
//
// private void DrawNormalizeButton()
// {
// if( ImGui.Button( ButtonNormalize ) )
// {
// ModCleanup.Normalize( Mod!.Data.BasePath, Meta! );
// _selector.SaveCurrentMod();
// _selector.ReloadCurrentMod( true, true, true );
// }
//
// ImGuiCustom.HoverTooltip( TooltipNormalize );
// }
//
// private void DrawAutoGenerateGroupsButton()
// {
// if( ImGui.Button( "Auto-Generate Groups" ) )
// {
// ModCleanup.AutoGenerateGroups( Mod!.Data.BasePath, Meta! );
// _selector.SaveCurrentMod();
// _selector.ReloadCurrentMod( true, true );
// }
//
// ImGuiCustom.HoverTooltip( "Automatically generate single-select groups from all folders (clears existing groups):\n"
// + "First subdirectory: Option Group\n"
// + "Second subdirectory: Option Name\n"
// + "Afterwards: Relative file paths.\n"
// + "Experimental - Use at own risk!" );
// }
//
// private void DrawSplitButton()
// {
// if( ImGui.Button( "Split Mod" ) )
// {
// ModCleanup.SplitMod( Mod!.Data );
// }
//
// 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 DrawMaterialChangeRow()
// {
// ImGui.SetNextItemWidth( 150 * ImGuiHelpers.GlobalScale );
// ImGui.InputTextWithHint( "##fromMaterial", "From Material Suffix...", ref _fromMaterial, 16 );
// ImGui.SameLine();
// using var font = ImGuiRaii.PushFont( UiBuilder.IconFont );
// ImGui.Text( FontAwesomeIcon.LongArrowAltRight.ToIconString() );
// font.Pop();
// ImGui.SameLine();
// ImGui.SetNextItemWidth( 150 * ImGuiHelpers.GlobalScale );
// ImGui.InputTextWithHint( "##toMaterial", "To Material Suffix...", ref _toMaterial, 16 );
// ImGui.SameLine();
// var validStrings = ModelChanger.ValidStrings( _fromMaterial, _toMaterial );
// using var alpha = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f, !validStrings );
// if( ImGui.Button( "Convert" ) && validStrings )
// {
// ModelChanger.ChangeModMaterials( Mod!.Data, _fromMaterial, _toMaterial );
// }
//
// alpha.Pop();
//
// ImGuiCustom.HoverTooltip(
// "Change the skin material of all models in this mod reference "
// + "from the suffix given in the first text input to "
// + "the suffix given in the second input.\n"
// + "Enter only the suffix, e.g. 'd' or 'a' or 'bibo', not the whole path.\n"
// + "This overwrites .mdl files, use at your own risk!" );
// }
//
// private void DrawEditLine()
// {
// DrawOpenModFolderButton();
// ImGui.SameLine();
// DrawRenameModFolderButton();
// ImGui.SameLine();
// DrawEditJsonButton();
// ImGui.SameLine();
// DrawReloadJsonButton();
//
// DrawResetMetaButton();
// ImGui.SameLine();
// DrawDeduplicateButton();
// ImGui.SameLine();
// DrawNormalizeButton();
// ImGui.SameLine();
// DrawAutoGenerateGroupsButton();
// ImGui.SameLine();
// DrawSplitButton();
//
// DrawMaterialChangeRow();
//
// DrawSortOrder( Mod!.Data, Penumbra.ModManager, _selector );
// }
//
// public void Draw()
// {
// try
// {
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndChild );
// var ret = ImGui.BeginChild( LabelModPanel, AutoFillSize, true );
//
// if( !ret || Mod == null )
// {
// return;
// }
//
// DrawHeaderLine();
//
// // Next line with fixed distance.
// ImGuiCustom.VerticalDistance( HeaderLineDistance );
//
// DrawEnabledMark();
// ImGui.SameLine();
// DrawPriority();
// if( Penumbra.Config.ShowAdvanced )
// {
// ImGui.SameLine();
// DrawEditableMark();
// }
//
// // Next line, if editable.
// if( _editMode )
// {
// DrawEditLine();
// }
//
// Details.Draw( _editMode );
// }
// catch( Exception ex )
// {
// PluginLog.LogError( ex, "Oh no" );
// }
// }
//}
}

View file

@ -1,797 +0,0 @@
//using System;
//using System.Collections.Generic;
//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.Collections;
//using Penumbra.Importer;
//using Penumbra.Mods;
//using Penumbra.UI.Classes;
//using Penumbra.UI.Custom;
//using Penumbra.Util;
//
//namespace Penumbra.UI;
//
//public partial class SettingsInterface
//{
// // Constants
// private partial class Selector
// {
// private const string LabelSelectorList = "##availableModList";
// private const string LabelModFilter = "##ModFilter";
// private const string LabelAddModPopup = "AddModPopup";
// private const string LabelModHelpPopup = "Help##Selector";
//
// private const string TooltipModFilter =
// "Filter mods for those containing the given substring.\nEnter c:[string] to filter for mods changing specific items.\nEnter a:[string] to filter for mods by specific authors.";
//
// private const string TooltipDelete = "Delete the selected mod";
// private const string TooltipAdd = "Add an empty mod";
// private const string DialogDeleteMod = "PenumbraDeleteMod";
// private const string ButtonYesDelete = "Yes, delete it";
// private const string ButtonNoDelete = "No, keep it";
//
// private const float SelectorPanelWidth = 240f;
//
// 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
// private partial class Selector
// {
// // === Delete ===
// private int? _deleteIndex;
//
// private void DrawModTrashButton()
// {
// using var raii = ImGuiRaii.PushFont( UiBuilder.IconFont );
//
// if( ImGui.Button( FontAwesomeIcon.Trash.ToIconString(), SelectorButtonSizes * _selectorScalingFactor ) && _index >= 0 )
// {
// _deleteIndex = _index;
// }
//
// raii.Pop();
//
// ImGuiCustom.HoverTooltip( TooltipDelete );
// }
//
// private void DrawDeleteModal()
// {
// if( _deleteIndex == null )
// {
// return;
// }
//
// ImGui.OpenPopup( DialogDeleteMod );
//
// var _ = true;
// ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, Vector2.One / 2 );
// var ret = ImGui.BeginPopupModal( DialogDeleteMod, ref _, ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoDecoration );
// if( !ret )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
//
// if( Mod == null )
// {
// _deleteIndex = null;
// ImGui.CloseCurrentPopup();
// return;
// }
//
// ImGui.Text( "Are you sure you want to delete the following mod:" );
// var halfLine = new Vector2( ImGui.GetTextLineHeight() / 2 );
// ImGui.Dummy( halfLine );
// ImGui.TextColored( DeleteModNameColor, Mod.Data.Meta.Name );
// ImGui.Dummy( halfLine );
//
// var buttonSize = ImGuiHelpers.ScaledVector2( 120, 0 );
// if( ImGui.Button( ButtonYesDelete, buttonSize ) )
// {
// ImGui.CloseCurrentPopup();
// var mod = Mod;
// Cache.RemoveMod( mod );
// Penumbra.ModManager.DeleteMod( mod.Data.BasePath );
// ModFileSystem.InvokeChange();
// ClearSelection();
// }
//
// ImGui.SameLine();
//
// if( ImGui.Button( ButtonNoDelete, buttonSize ) )
// {
// ImGui.CloseCurrentPopup();
// _deleteIndex = null;
// }
// }
//
// // === Add ===
// private bool _modAddKeyboardFocus = true;
//
// private void DrawModAddButton()
// {
// using var raii = ImGuiRaii.PushFont( UiBuilder.IconFont );
//
// if( ImGui.Button( FontAwesomeIcon.Plus.ToIconString(), SelectorButtonSizes * _selectorScalingFactor ) )
// {
// _modAddKeyboardFocus = true;
// ImGui.OpenPopup( LabelAddModPopup );
// }
//
// raii.Pop();
//
// ImGuiCustom.HoverTooltip( TooltipAdd );
//
// DrawModAddPopup();
// }
//
// private void DrawModAddPopup()
// {
// if( !ImGui.BeginPopup( LabelAddModPopup ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
//
// if( _modAddKeyboardFocus )
// {
// ImGui.SetKeyboardFocusHere();
// _modAddKeyboardFocus = false;
// }
//
// var newName = "";
// if( ImGui.InputTextWithHint( "##AddMod", "New Mod Name...", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
// {
// try
// {
// var newDir = TexToolsImport.CreateModFolder( new DirectoryInfo( Penumbra.Config!.ModDirectory ),
// newName );
// var modMeta = new ModMeta
// {
// Author = "Unknown",
// Name = newName.Replace( '/', '\\' ),
// Description = string.Empty,
// };
//
// var metaFile = new FileInfo( Path.Combine( newDir.FullName, "meta.json" ) );
// modMeta.SaveToFile( metaFile );
// Penumbra.ModManager.AddMod( newDir );
// ModFileSystem.InvokeChange();
// SelectModOnUpdate( newDir.Name );
// }
// catch( Exception e )
// {
// PluginLog.Error( $"Could not create directory for new Mod {newName}:\n{e}" );
// }
//
// ImGui.CloseCurrentPopup();
// }
//
// if( ImGui.IsKeyPressed( ImGui.GetKeyIndex( ImGuiKey.Escape ) ) )
// {
// ImGui.CloseCurrentPopup();
// }
// }
//
// // === Help ===
// private void DrawModHelpButton()
// {
// using var raii = ImGuiRaii.PushFont( UiBuilder.IconFont );
// if( ImGui.Button( FontAwesomeIcon.QuestionCircle.ToIconString(), HelpButtonSizes * _selectorScalingFactor ) )
// {
// ImGui.OpenPopup( LabelModHelpPopup );
// }
// }
//
// private static void DrawModHelpPopup()
// {
// ImGui.SetNextWindowPos( ImGui.GetMainViewport().GetCenter(), ImGuiCond.Appearing, Vector2.One / 2 );
// ImGui.SetNextWindowSize( new Vector2( 5 * SelectorPanelWidth, 34 * ImGui.GetTextLineHeightWithSpacing() ),
// ImGuiCond.Appearing );
// var _ = true;
// if( !ImGui.BeginPopupModal( LabelModHelpPopup, ref _, ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove ) )
// {
// 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." );
// ImGui.BulletText( "Mod names are colored according to their current state in the collection:" );
// ImGui.Indent();
// ImGui.Bullet();
// ImGui.SameLine();
// ImGui.Text( "Enabled in the current collection." );
// ImGui.Bullet();
// ImGui.SameLine();
// ImGui.TextColored( ImGui.ColorConvertU32ToFloat4( ColorId.DisabledMod.Value() ), "Disabled in the current collection." );
// ImGui.Bullet();
// ImGui.SameLine();
// ImGui.TextColored( ImGui.ColorConvertU32ToFloat4( ColorId.NewMod.Value() ),
// "Newly imported during this session. Will go away when first enabling a mod or when Penumbra is reloaded." );
// ImGui.Bullet();
// ImGui.SameLine();
// ImGui.TextColored( ImGui.ColorConvertU32ToFloat4( ColorId.HandledConflictMod.Value() ),
// "Enabled and conflicting with another enabled Mod, but on different priorities (i.e. the conflict is solved)." );
// ImGui.Bullet();
// ImGui.SameLine();
// ImGui.TextColored( ImGui.ColorConvertU32ToFloat4( ColorId.DisabledMod.Value() ),
// "Enabled and conflicting with another enabled Mod on the same priority." );
// ImGui.Unindent();
// ImGui.BulletText( "Right-click a mod to enter its sort order, which is its name by default." );
// ImGui.Indent();
// ImGui.BulletText( "A sort order differing from the mods name will not be displayed, it will just be used for ordering." );
// ImGui.BulletText(
// "If the sort order string contains Forward-Slashes ('/'), the preceding substring will be turned into collapsible folders that can group mods." );
// ImGui.BulletText(
// "Collapsible folders can contain further collapsible folders, so \"folder1/folder2/folder3/1\" will produce 3 folders\n"
// + "\t\t[folder1] -> [folder2] -> [folder3] -> [ModName],\n"
// + "where ModName will be sorted as if it was the string '1'." );
// ImGui.Unindent();
// ImGui.BulletText(
// "You can drag and drop mods and subfolders into existing folders. Dropping them onto mods is the same as dropping them onto the parent of the mod." );
// ImGui.BulletText( "Right-clicking a folder opens a context menu." );
// ImGui.Indent();
// ImGui.BulletText(
// "You can rename folders in the context menu. Leave the text blank and press enter to merge the folder with its parent." );
// ImGui.BulletText( "You can also enable or disable all descendant mods of a folder." );
// ImGui.Unindent();
// ImGui.BulletText( "Use the Filter Mods... input at the top to filter the list for mods with names containing the text." );
// ImGui.Indent();
// ImGui.BulletText( "You can enter c:[string] to filter for Changed Items instead." );
// ImGui.BulletText( "You can enter a:[string] to filter for Mod Authors instead." );
// ImGui.Unindent();
// ImGui.BulletText( "Use the expandable menu beside the input to filter for mods fulfilling specific criteria." );
// ImGui.Dummy( Vector2.UnitY * ImGui.GetTextLineHeight() );
// ImGui.Text( "Mod Management" );
// ImGui.BulletText( "You can delete the currently selected mod with the trashcan button." );
// ImGui.BulletText( "You can add a completely empty mod with the plus button." );
// ImGui.BulletText( "You can import TTMP-based mods in the import tab." );
// ImGui.BulletText(
// "You can import penumbra-based mods by moving the corresponding folder into your mod directory in a file explorer, then rediscovering mods." );
// ImGui.BulletText(
// "If you enable Advanced Options in the Settings tab, you can toggle Edit Mode to manipulate your selected mod even further." );
// ImGui.Dummy( Vector2.UnitY * ImGui.GetTextLineHeight() );
// ImGui.Dummy( Vector2.UnitX * 2 * SelectorPanelWidth );
// ImGui.SameLine();
// if( ImGui.Button( "Understood", Vector2.UnitX * SelectorPanelWidth ) )
// {
// ImGui.CloseCurrentPopup();
// }
// }
//
// // === Main ===
// private void DrawModsSelectorButtons()
// {
// // Selector controls
// using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.WindowPadding, ZeroVector )
// .Push( ImGuiStyleVar.FrameRounding, 0 );
//
// DrawModAddButton();
// ImGui.SameLine();
// DrawModHelpButton();
// ImGui.SameLine();
// DrawModTrashButton();
// }
// }
//
// // Filters
// private partial class Selector
// {
// private string _modFilterInput = "";
//
// private void DrawTextFilter()
// {
// ImGui.SetNextItemWidth( SelectorPanelWidth * _selectorScalingFactor - 22 * ImGuiHelpers.GlobalScale );
// var tmp = _modFilterInput;
// if( ImGui.InputTextWithHint( LabelModFilter, "Filter Mods...", ref tmp, 256 ) && _modFilterInput != tmp )
// {
// Cache.SetTextFilter( tmp );
// _modFilterInput = tmp;
// }
//
// ImGuiCustom.HoverTooltip( TooltipModFilter );
// }
//
// private void DrawToggleFilter()
// {
// if( ImGui.BeginCombo( "##ModStateFilter", "",
// ImGuiComboFlags.NoPreview | ImGuiComboFlags.PopupAlignLeft | ImGuiComboFlags.HeightLargest ) )
// {
// 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;
// }
//
// ImGuiCustom.HoverTooltip( "Filter mods for their activation status." );
// }
//
// private void DrawModsSelectorFilter()
// {
// using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.ItemSpacing, ZeroVector );
// DrawTextFilter();
// ImGui.SameLine();
// DrawToggleFilter();
// }
// }
//
// // Drag'n Drop
// private partial class Selector
// {
// private const string DraggedModLabel = "ModIndex";
// private const string DraggedFolderLabel = "FolderName";
//
// private readonly IntPtr _dragDropPayload = Marshal.AllocHGlobal( 4 );
//
// private static unsafe bool IsDropping( string name )
// => ImGui.AcceptDragDropPayload( name ).NativePtr != null;
//
// private void DragDropTarget( ModFolder folder )
// {
// if( !ImGui.BeginDragDropTarget() )
// {
// 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;
// mod?.Data.Move( folder );
// }
// else if( IsDropping( DraggedFolderLabel ) )
// {
// var payload = ImGui.GetDragDropPayload();
// var folderName = Marshal.PtrToStringUni( payload.Data );
// if( ModFileSystem.Find( folderName!, out var droppedFolder )
// && !ReferenceEquals( droppedFolder, folder )
// && !folder.FullName.StartsWith( folderName!, StringComparison.InvariantCultureIgnoreCase ) )
// {
// droppedFolder.Move( folder );
// }
// }
// }
//
// private void DragDropSourceFolder( ModFolder folder )
// {
// if( !ImGui.BeginDragDropSource() )
// {
// 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}..." );
// }
//
// private void DragDropSourceMod( int modIndex, string modName )
// {
// if( !ImGui.BeginDragDropSource() )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndDragDropSource );
//
// Marshal.WriteInt32( _dragDropPayload, modIndex );
// ImGui.SetDragDropPayload( "ModIndex", _dragDropPayload, 4 );
// ImGui.Text( $"Moving {modName}..." );
// }
//
// ~Selector()
// => Marshal.FreeHGlobal( _dragDropPayload );
// }
//
// // Selection
// private partial class Selector
// {
// public Mods.FullMod? Mod { get; private set; }
// private int _index;
// private string _nextDir = string.Empty;
//
// private void SetSelection( int idx, Mods.FullMod? info )
// {
// Mod = info;
// if( idx != _index )
// {
// _base._menu.InstalledTab.ModPanel.Details.ResetState();
// }
//
// _index = idx;
// _deleteIndex = null;
// }
//
// private void SetSelection( int idx )
// {
// if( idx >= Cache.Count )
// {
// idx = -1;
// }
//
// if( idx < 0 )
// {
// SetSelection( 0, null );
// }
// else
// {
// SetSelection( idx, Cache.GetMod( idx ).Item1 );
// }
// }
//
// public void ReloadSelection()
// => SetSelection( _index, Cache.GetMod( _index ).Item1 );
//
// public void ClearSelection()
// => SetSelection( -1 );
//
// public void SelectModOnUpdate( string directory )
// => _nextDir = directory;
//
// public void SelectModByDir( string name )
// {
// var (mod, idx) = Cache.GetModByBasePath( name );
// SetSelection( idx, mod );
// }
//
// public void ReloadCurrentMod( bool reloadMeta = false, bool recomputeMeta = false, bool force = false )
// {
// if( Mod == null )
// {
// return;
// }
//
// if( _index >= 0 && Penumbra.ModManager.UpdateMod( Mod.Data, reloadMeta, recomputeMeta, force ) )
// {
// SelectModOnUpdate( Mod.Data.BasePath.Name );
// _base._menu.InstalledTab.ModPanel.Details.ResetState();
// }
// }
//
// public void SaveCurrentMod()
// => Mod?.Data.SaveMeta();
// }
//
// // Right-Clicks
// private partial class Selector
// {
// // === Mod ===
// private void DrawModOrderPopup( string popupName, Mods.FullMod mod, bool firstOpen )
// {
// if( !ImGui.BeginPopup( popupName ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
//
// if( ModPanel.DrawSortOrder( mod.Data, Penumbra.ModManager, this ) )
// {
// ImGui.CloseCurrentPopup();
// }
//
// if( firstOpen )
// {
// ImGui.SetKeyboardFocusHere( mod.Data.Order.FullPath.Length - 1 );
// }
// }
//
// // === Folder ===
// private string _newFolderName = string.Empty;
// private int _expandIndex = -1;
// private bool _expandCollapse;
// private bool _currentlyExpanding;
//
// private void ChangeStatusOfChildren( ModFolder folder, int currentIdx, bool toWhat )
// {
// var change = false;
// var metaManips = false;
// foreach( var _ in folder.AllMods( Penumbra.ModManager.Config.SortFoldersFirst ) )
// {
// var (mod, _, _) = Cache.GetMod( currentIdx++ );
// if( mod != null )
// {
// change |= mod.Settings.Enabled != toWhat;
// mod!.Settings.Enabled = toWhat;
// metaManips |= mod.Data.Resources.MetaManipulations.Count > 0;
// }
// }
//
// if( !change )
// {
// return;
// }
//
// Cache.TriggerFilterReset();
// var collection = Penumbra.CollectionManager.Current;
// if( collection.HasCache )
// {
// collection.CalculateEffectiveFileList( metaManips, collection == Penumbra.CollectionManager.Default );
// }
//
// collection.Save();
// }
//
// private void DrawRenameFolderInput( ModFolder folder )
// {
// ImGui.SetNextItemWidth( 150 * ImGuiHelpers.GlobalScale );
// if( !ImGui.InputTextWithHint( "##NewFolderName", "Rename Folder...", ref _newFolderName, 64,
// ImGuiInputTextFlags.EnterReturnsTrue ) )
// {
// return;
// }
//
// if( _newFolderName.Any() )
// {
// folder.Rename( _newFolderName );
// }
// else
// {
// folder.Merge( folder.Parent! );
// }
//
// _newFolderName = string.Empty;
// }
//
// private void DrawFolderContextMenu( ModFolder folder, int currentIdx, string treeName )
// {
// if( !ImGui.BeginPopup( treeName ) )
// {
// return;
// }
//
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
//
// if( ImGui.MenuItem( "Expand All Descendants" ) )
// {
// _expandIndex = currentIdx;
// _expandCollapse = false;
// }
//
// if( ImGui.MenuItem( "Collapse All Descendants" ) )
// {
// _expandIndex = currentIdx;
// _expandCollapse = true;
// }
//
// 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 );
// }
// }
//
// // Main-Interface
// private partial class Selector
// {
// private readonly SettingsInterface _base;
// public readonly ModListCache Cache;
//
// private float _selectorScalingFactor = 1;
//
// public Selector( SettingsInterface ui, IReadOnlySet< string > newMods )
// {
// _base = ui;
// Cache = new ModListCache( Penumbra.ModManager, newMods );
// }
//
// private void DrawCollectionButton( string label, string tooltipLabel, float size, ModCollection collection )
// {
// if( collection == ModCollection.Empty
// || collection == Penumbra.CollectionManager.Current )
// {
// using var _ = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f );
// ImGui.Button( label, Vector2.UnitX * size );
// }
// else if( ImGui.Button( label, Vector2.UnitX * size ) )
// {
// _base._menu.CollectionsTab.SetCurrentCollection( collection );
// }
//
// 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( "Current Collection" ).X + ImGui.GetStyle().ItemInnerSpacing.X;
// var comboSize = size * ImGui.GetIO().FontGlobalScale;
// var offset = comboSize + textSize;
//
// var buttonSize = Math.Max( ImGui.GetWindowContentRegionWidth()
// - offset
// - SelectorPanelWidth * _selectorScalingFactor
// - 3 * ImGui.GetStyle().ItemSpacing.X, 5f );
// ImGui.SameLine();
// DrawCollectionButton( "Default", "default", buttonSize, Penumbra.CollectionManager.Default );
//
//
// ImGui.SameLine();
// ImGui.SetNextItemWidth( comboSize );
// using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.ItemSpacing, Vector2.Zero );
// _base._menu.CollectionsTab.DrawCurrentCollectionSelector( false );
// }
//
// private void DrawFolderContent( ModFolder folder, ref int idx )
// {
// // Collection may be manipulated.
// foreach( var item in folder.GetItems( Penumbra.ModManager.Config.SortFoldersFirst ).ToArray() )
// {
// if( item is ModFolder sub )
// {
// var (visible, _) = Cache.GetFolder( sub );
// if( visible )
// {
// DrawModFolder( sub, ref idx );
// }
// else
// {
// idx += sub.TotalDescendantMods();
// }
// }
// else if( item is Mods.Mod _ )
// {
// var (mod, visible, color) = Cache.GetMod( idx );
// if( mod != null && visible )
// {
// DrawMod( mod, idx++, color );
// }
// else
// {
// ++idx;
// }
// }
// }
// }
//
// private void DrawModFolder( ModFolder folder, ref int idx )
// {
// var treeName = $"{folder.Name}##{folder.FullName}";
// var open = ImGui.TreeNodeEx( treeName );
// using var raii = ImGuiRaii.DeferredEnd( ImGui.TreePop, open );
//
// if( idx == _expandIndex )
// {
// _currentlyExpanding = true;
// }
//
// if( _currentlyExpanding )
// {
// ImGui.SetNextItemOpen( !_expandCollapse );
// }
//
// if( ImGui.IsItemClicked( ImGuiMouseButton.Right ) )
// {
// _newFolderName = string.Empty;
// ImGui.OpenPopup( treeName );
// }
//
// DrawFolderContextMenu( folder, idx, treeName );
// DragDropTarget( folder );
// DragDropSourceFolder( folder );
//
// if( open )
// {
// DrawFolderContent( folder, ref idx );
// }
// else
// {
// idx += folder.TotalDescendantMods();
// }
//
// if( idx == _expandIndex )
// {
// _currentlyExpanding = false;
// _expandIndex = -1;
// }
// }
//
// private void DrawMod( Mods.FullMod mod, int modIndex, uint color )
// {
// using var colorRaii = ImGuiRaii.PushColor( ImGuiCol.Text, color, color != 0 );
//
// var selected = ImGui.Selectable( $"{mod.Data.Meta.Name}##{modIndex}", modIndex == _index );
// colorRaii.Pop();
//
// var popupName = $"##SortOrderPopup{modIndex}";
// var firstOpen = false;
// if( ImGui.IsItemClicked( ImGuiMouseButton.Right ) )
// {
// ImGui.OpenPopup( popupName );
// firstOpen = true;
// }
//
// DragDropTarget( mod.Data.Order.ParentFolder );
// DragDropSourceMod( modIndex, mod.Data.Meta.Name );
//
// DrawModOrderPopup( popupName, mod, firstOpen );
//
// if( selected )
// {
// SetSelection( modIndex, mod );
// }
// }
//
// public void Draw()
// {
// if( Cache.Update() )
// {
// if( _nextDir.Any() )
// {
// SelectModByDir( _nextDir );
// _nextDir = string.Empty;
// }
// else if( Mod != null )
// {
// SelectModByDir( Mod.Data.BasePath.Name );
// }
// }
//
// _selectorScalingFactor = ImGuiHelpers.GlobalScale
// * ( Penumbra.Config.ScaleModSelector
// ? ImGui.GetWindowWidth() / SettingsMenu.MinSettingsSize.X
// : 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 ) )
// {
// style.Push( ImGuiStyleVar.IndentSpacing, 12.5f );
//
// var modIndex = 0;
// DrawFolderContent( Penumbra.ModManager.StructuredMods, ref modIndex );
// style.Pop();
// }
//
// raii.Pop();
//
// DrawModsSelectorButtons();
//
// style.Pop();
// DrawModHelpPopup();
//
// DrawDeleteModal();
// }
// }
//}

View file

@ -1,18 +1,17 @@
using System;
using System.Numerics;
using Dalamud.Interface;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.Collections;
using Penumbra.Mods;
using Penumbra.UI.Classes;
using System;
using System.Numerics;
namespace Penumbra.UI;
public partial class ConfigWindow
{
public void DrawModsTab()
private void DrawModsTab()
{
if( !Penumbra.ModManager.Valid )
{
@ -103,12 +102,10 @@ public partial class ConfigWindow
private bool _valid;
private ModFileSystem.Leaf _leaf = null!;
private Mod _mod = null!;
private Mod _mod = null!;
public ModPanel( ConfigWindow window )
{
_window = window;
}
=> _window = window;
public void Draw( ModFileSystemSelector selector )
{

View file

@ -47,10 +47,13 @@ public partial class ConfigWindow
DrawAdvancedSettings();
}
// Changing the base mod directory.
private string? _newModDirectory;
private readonly FileDialogManager _dialogManager = new();
private bool _dialogOpen;
private bool _dialogOpen; // For toggling on/off.
// Do not change the directory without explicitly pressing enter or this button.
// Shows up only if the current input does not correspond to the current directory.
private static bool DrawPressEnterWarning( string old, float width )
{
using var color = ImRaii.PushColor( ImGuiCol.Button, Colors.PressEnterWarningBg );
@ -58,9 +61,11 @@ public partial class ConfigWindow
return ImGui.Button( $"Press Enter or Click Here to Save (Current Directory: {old})", w );
}
// Draw a directory picker button that toggles the directory picker.
// Selecting a directory does behave the same as writing in the text input, i.e. needs to be saved.
private void DrawDirectoryPickerButton()
{
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Folder.ToIconString(), ImGui.GetFrameHeight() * Vector2.One,
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Folder.ToIconString(), _window._iconButtonSize,
"Select a directory via dialog.", false, true ) )
{
if( _dialogOpen )
@ -71,6 +76,8 @@ public partial class ConfigWindow
else
{
_newModDirectory ??= Penumbra.Config.ModDirectory;
// Use the current input as start directory if it exists,
// otherwise the current mod directory, otherwise the current application directory.
var startDir = Directory.Exists( _newModDirectory )
? _newModDirectory
: Directory.Exists( Penumbra.Config.ModDirectory )
@ -103,13 +110,15 @@ public partial class ConfigWindow
}
}
// Draw the text input for the mod directory,
// as well as the directory picker button and the enter warning.
private void DrawRootFolder()
{
_newModDirectory ??= Penumbra.Config.ModDirectory;
var spacing = 3 * ImGuiHelpers.GlobalScale;
using var group = ImRaii.Group();
ImGui.SetNextItemWidth( _window._inputTextWidth.X - spacing - ImGui.GetFrameHeight() );
ImGui.SetNextItemWidth( _window._inputTextWidth.X - spacing - _window._iconButtonSize.X );
var save = ImGui.InputText( "##rootDirectory", ref _newModDirectory, 255, ImGuiInputTextFlags.EnterReturnsTrue );
using var style = ImRaii.PushStyle( ImGuiStyleVar.ItemSpacing, new Vector2( spacing, 0 ) );
ImGui.SameLine();
@ -127,18 +136,14 @@ public partial class ConfigWindow
var pos = ImGui.GetCursorPosX();
ImGui.NewLine();
if( Penumbra.Config.ModDirectory == _newModDirectory || _newModDirectory.Length == 0 )
{
return;
}
if( save || DrawPressEnterWarning( Penumbra.Config.ModDirectory, pos ) )
if( Penumbra.Config.ModDirectory != _newModDirectory
&& _newModDirectory.Length == 0
&& ( save || DrawPressEnterWarning( Penumbra.Config.ModDirectory, pos ) ) )
{
Penumbra.ModManager.DiscoverMods( _newModDirectory );
}
}
private static void DrawRediscoverButton()
{
DrawOpenDirectoryButton( 0, Penumbra.ModManager.BasePath, Penumbra.ModManager.Valid );

View file

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Reflection;
using Dalamud.Interface;
using Dalamud.Interface.Windowing;
using ImGuiNET;
@ -28,7 +27,7 @@ public sealed partial class ConfigWindow : Window, IDisposable
{
_penumbra = penumbra;
_settingsTab = new SettingsTab( this );
_selector = new ModFileSystemSelector( _penumbra.ModFileSystem, new HashSet< Mod >() ); // TODO
_selector = new ModFileSystemSelector( _penumbra.ModFileSystem );
_modPanel = new ModPanel( this );
_collectionsTab = new CollectionsTab( this );
_effectiveTab = new EffectiveTab();

View file

@ -7,36 +7,50 @@ namespace Penumbra.Util;
public static class ArrayExtensions
{
// Iterate over enumerables with additional index.
public static IEnumerable< (T, int) > WithIndex< T >( this IEnumerable< T > list )
=> list.Select( ( x, i ) => ( x, i ) );
public static int IndexOf< T >( this IReadOnlyList< T > array, Predicate< T > predicate )
// Find the index of the first object fulfilling predicate's criteria in the given list.
// Returns -1 if no such object is found.
public static int IndexOf< T >( this IEnumerable< T > array, Predicate< T > predicate )
{
for( var i = 0; i < array.Count; ++i )
var i = 0;
foreach( var obj in array )
{
if( predicate( array[ i ] ) )
if( predicate( obj ) )
{
return i;
}
++i;
}
return -1;
}
public static int IndexOf< T >( this IReadOnlyList< T > array, T needle )
// Find the index of the first occurrence of needle in the given list.
// Returns -1 if needle is not contained in the list.
public static int IndexOf< T >( this IEnumerable< T > array, T needle ) where T : notnull
{
for( var i = 0; i < array.Count; ++i )
var i = 0;
foreach( var obj in array )
{
if( needle!.Equals( array[ i ] ) )
if( needle.Equals( obj ) )
{
return i;
}
++i;
}
return -1;
}
public static bool FindFirst< T >( this IReadOnlyList< T > array, Predicate< T > predicate, [NotNullWhen( true )] out T? result )
// Find the first object fulfilling predicate's criteria in the given list, if one exists.
// Returns true if an object is found, false otherwise.
public static bool FindFirst< T >( this IEnumerable< T > array, Predicate< T > predicate, [NotNullWhen( true )] out T? result )
{
foreach( var obj in array )
{
@ -51,7 +65,9 @@ public static class ArrayExtensions
return false;
}
public static bool FindFirst< T >( this IReadOnlyList< T > array, T needle, [NotNullWhen( true )] out T? result ) where T : IEquatable< T >
// Find the first occurrence of needle in the given list and return the value contained in the list in result.
// Returns true if an object is found, false otherwise.
public static bool FindFirst< T >( this IEnumerable< T > array, T needle, [NotNullWhen( true )] out T? result ) where T : notnull
{
foreach( var obj in array )
{

View file

@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Penumbra.Util;
public static class BinaryReaderExtensions
{
/// <summary>
/// Reads a structure from the current stream position.
/// </summary>
/// <param name="br"></param>
/// <typeparam name="T">The structure to read in to</typeparam>
/// <returns>The file data as a structure</returns>
public static T ReadStructure< T >( this BinaryReader br ) where T : struct
{
ReadOnlySpan< byte > data = br.ReadBytes( Unsafe.SizeOf< T >() );
return MemoryMarshal.Read< T >( data );
}
/// <summary>
/// Reads many structures from the current stream position.
/// </summary>
/// <param name="br"></param>
/// <param name="count">The number of T to read from the stream</param>
/// <typeparam name="T">The structure to read in to</typeparam>
/// <returns>A list containing the structures read from the stream</returns>
public static List< T > ReadStructures< T >( this BinaryReader br, int count ) where T : struct
{
var size = Marshal.SizeOf< T >();
var data = br.ReadBytes( size * count );
var list = new List< T >( count );
for( var i = 0; i < count; i++ )
{
var offset = size * i;
var span = new ReadOnlySpan< byte >( data, offset, size );
list.Add( MemoryMarshal.Read< T >( span ) );
}
return list;
}
/// <summary>
/// Seeks this BinaryReader's position to the given offset. Syntactic sugar.
/// </summary>
public static void Seek( this BinaryReader br, long offset )
{
br.BaseStream.Position = offset;
}
}

View file

@ -75,7 +75,7 @@ public static partial class JsonExtensions
return reader;
}
public static JsonReader ReadAndAssert( this JsonReader reader )
private static JsonReader ReadAndAssert( this JsonReader reader )
{
if( reader == null )
{

View file

@ -4,6 +4,7 @@ using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using Lumina.Data.Structs;
using Lumina.Extensions;
namespace Penumbra.Util;