mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Introducing custom Sort Order for mods and collapsible folders inside the mod selector based on '/' in the sort order.
This commit is contained in:
parent
702e3b9305
commit
d52086b69c
7 changed files with 157 additions and 13 deletions
|
|
@ -27,6 +27,8 @@ namespace Penumbra
|
|||
public string CurrentCollection { get; set; } = "Default";
|
||||
public string ForcedCollection { get; set; } = "";
|
||||
public Dictionary< string, string > CharacterCollections { get; set; } = new();
|
||||
public Dictionary< string, string > ModSortOrder { get; set; } = new();
|
||||
|
||||
public bool InvertModListOrder { internal get; set; }
|
||||
|
||||
public static Configuration Load( DalamudPluginInterface pi )
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace Penumbra.Mod
|
|||
public DirectoryInfo BasePath;
|
||||
public ModMeta Meta;
|
||||
public ModResources Resources;
|
||||
public string SortOrder;
|
||||
|
||||
public FileInfo MetaFile { get; set; }
|
||||
|
||||
|
|
@ -20,6 +21,7 @@ namespace Penumbra.Mod
|
|||
Meta = meta;
|
||||
Resources = resources;
|
||||
MetaFile = MetaFileInfo( basePath );
|
||||
SortOrder = meta.Name;
|
||||
}
|
||||
|
||||
public static FileInfo MetaFileInfo( DirectoryInfo basePath )
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Penumbra.Mods
|
|||
|
||||
public void SortMods()
|
||||
{
|
||||
AvailableMods.Sort( ( m1, m2 ) => string.Compare( m1.Data.Meta.Name, m2.Data.Meta.Name, StringComparison.InvariantCulture ) );
|
||||
AvailableMods.Sort( ( m1, m2 ) => string.Compare( m1.Data.SortOrder, m2.Data.SortOrder, StringComparison.InvariantCultureIgnoreCase ) );
|
||||
}
|
||||
|
||||
private void AddFiles( Dictionary< GamePath, Mod.Mod > registeredFiles, Mod.Mod mod )
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Dalamud.Plugin;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Mod;
|
||||
|
|
@ -12,13 +13,18 @@ namespace Penumbra.Mods
|
|||
// It also contains the CollectionManager that handles all collections.
|
||||
public class ModManager
|
||||
{
|
||||
private readonly Plugin _plugin;
|
||||
public DirectoryInfo BasePath { get; private set; }
|
||||
|
||||
public Dictionary< string, ModData > Mods { get; } = new();
|
||||
public CollectionManager Collections { get; }
|
||||
|
||||
public Configuration Config
|
||||
=> _plugin.Configuration;
|
||||
|
||||
public ModManager( Plugin plugin )
|
||||
{
|
||||
_plugin = plugin;
|
||||
BasePath = new DirectoryInfo( plugin.Configuration.ModDirectory );
|
||||
Collections = new CollectionManager( plugin, this );
|
||||
}
|
||||
|
|
@ -29,6 +35,28 @@ namespace Penumbra.Mods
|
|||
DiscoverMods();
|
||||
}
|
||||
|
||||
private void SetModOrders( Configuration config )
|
||||
{
|
||||
var changes = false;
|
||||
foreach( var kvp in config.ModSortOrder.ToArray() )
|
||||
{
|
||||
if( Mods.TryGetValue( kvp.Key, out var mod ) )
|
||||
{
|
||||
mod.SortOrder = string.Join( "/", kvp.Value.Trim().Split( new[] { "/" }, StringSplitOptions.RemoveEmptyEntries ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
changes = true;
|
||||
config.ModSortOrder.Remove( kvp.Key );
|
||||
}
|
||||
}
|
||||
|
||||
if( changes )
|
||||
{
|
||||
config.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public void DiscoverMods()
|
||||
{
|
||||
Mods.Clear();
|
||||
|
|
@ -57,6 +85,7 @@ namespace Penumbra.Mods
|
|||
Mods.Add( modFolder.Name, mod );
|
||||
}
|
||||
|
||||
SetModOrders( _plugin.Configuration );
|
||||
Collections.RecreateCaches();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,36 @@ namespace Penumbra.Mods
|
|||
return true;
|
||||
}
|
||||
|
||||
public static bool ChangeSortOrder( this ModManager manager, ModData mod, string newSortOrder )
|
||||
{
|
||||
newSortOrder = string.Join( "/", newSortOrder.Trim().Split( new[] { "/" }, StringSplitOptions.RemoveEmptyEntries ) );
|
||||
|
||||
if( mod.SortOrder == newSortOrder )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( newSortOrder == string.Empty || newSortOrder == mod.Meta.Name )
|
||||
{
|
||||
mod.SortOrder = mod.Meta.Name;
|
||||
manager.Config.ModSortOrder.Remove( mod.BasePath.Name );
|
||||
}
|
||||
else
|
||||
{
|
||||
mod.SortOrder = newSortOrder;
|
||||
manager.Config.ModSortOrder[ mod.BasePath.Name ] = newSortOrder;
|
||||
}
|
||||
|
||||
manager.Config.Save();
|
||||
|
||||
foreach( var collection in manager.Collections.Collections.Values.Where( c => c.Cache != null ) )
|
||||
{
|
||||
collection.Cache!.SortMods();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool RenameModFolder( this ModManager manager, ModData mod, DirectoryInfo newDir, bool move = true )
|
||||
{
|
||||
if( move )
|
||||
|
|
@ -60,6 +90,13 @@ namespace Penumbra.Mods
|
|||
mod.MetaFile = ModData.MetaFileInfo( newDir );
|
||||
manager.UpdateMod( mod );
|
||||
|
||||
if( manager.Config.ModSortOrder.ContainsKey( oldBasePath.Name ) )
|
||||
{
|
||||
manager.Config.ModSortOrder[ newDir.Name ] = manager.Config.ModSortOrder[ oldBasePath.Name ];
|
||||
manager.Config.ModSortOrder.Remove( oldBasePath.Name );
|
||||
manager.Config.Save();
|
||||
}
|
||||
|
||||
foreach( var collection in manager.Collections.Collections.Values )
|
||||
{
|
||||
if( collection.Settings.TryGetValue( oldBasePath.Name, out var settings ) )
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using System.Windows.Forms;
|
||||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Mod;
|
||||
|
|
@ -224,6 +225,17 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawSortOrder()
|
||||
{
|
||||
var currentSortOrder = Mod!.Data.SortOrder;
|
||||
ImGui.SetNextItemWidth( 300 );
|
||||
if( ImGui.InputText( "Sort Order", ref currentSortOrder, 256, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
_modManager.ChangeSortOrder( Mod.Data, currentSortOrder );
|
||||
_selector.SelectModByDir( Mod.Data.BasePath.Name );
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawEditableMark()
|
||||
{
|
||||
ImGui.Checkbox( LabelEditingEnabled, ref _editMode );
|
||||
|
|
@ -262,7 +274,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
ImGui.OpenPopup( LabelOverWriteDir );
|
||||
}
|
||||
else if( Service< ModManager >.Get()!.RenameModFolder( Mod.Data, newDir ) )
|
||||
else if( _modManager.RenameModFolder( Mod.Data, newDir ) )
|
||||
{
|
||||
_selector.ReloadCurrentMod();
|
||||
ImGui.CloseCurrentPopup();
|
||||
|
|
@ -478,6 +490,8 @@ namespace Penumbra.UI
|
|||
DrawDeduplicateButton();
|
||||
ImGui.SameLine();
|
||||
DrawNormalizeButton();
|
||||
|
||||
DrawSortOrder();
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Numerics;
|
|||
using Dalamud.Interface;
|
||||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
using ImGuiScene;
|
||||
using Penumbra.Importer;
|
||||
using Penumbra.Mod;
|
||||
using Penumbra.Mods;
|
||||
|
|
@ -73,6 +74,7 @@ namespace Penumbra.UI
|
|||
|
||||
private readonly SettingsInterface _base;
|
||||
private readonly ModManager _modManager;
|
||||
private string _currentModGroup = "";
|
||||
|
||||
private List< Mod.Mod >? Mods
|
||||
=> _modManager.Collections.CurrentCollection.Cache?.AvailableMods;
|
||||
|
|
@ -301,17 +303,15 @@ namespace Penumbra.UI
|
|||
return true;
|
||||
}
|
||||
|
||||
private bool CheckFilters( Mod.Mod mod, int modIndex )
|
||||
=> ( _modFilter.Length <= 0 || _modNamesLower[ modIndex ].Contains( _modFilter ) )
|
||||
&& !CheckFlags( mod.Data.Resources.ModFiles.Count, ModFilter.HasNoFiles, ModFilter.HasFiles )
|
||||
&& !CheckFlags( mod.Data.Meta.FileSwaps.Count, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps )
|
||||
&& !CheckFlags( mod.Data.Resources.MetaManipulations.Count, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations )
|
||||
&& !CheckFlags( mod.Data.Meta.HasGroupsWithConfig ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig );
|
||||
|
||||
public void DrawMod( Mod.Mod mod, int modIndex )
|
||||
{
|
||||
if( _modFilter.Length > 0 && !_modNamesLower[ modIndex ].Contains( _modFilter )
|
||||
|| CheckFlags( mod.Data.Resources.ModFiles.Count, ModFilter.HasNoFiles, ModFilter.HasFiles )
|
||||
|| CheckFlags( mod.Data.Meta.FileSwaps.Count, ModFilter.HasNoFileSwaps, ModFilter.HasFileSwaps )
|
||||
|| CheckFlags( mod.Data.Resources.MetaManipulations.Count, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations )
|
||||
|| CheckFlags( mod.Data.Meta.HasGroupsWithConfig ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var changedColour = false;
|
||||
if( !mod.Settings.Enabled )
|
||||
{
|
||||
|
|
@ -372,6 +372,59 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
private bool DrawModGroup( Mod.Mod mod, ref int modIndex )
|
||||
{
|
||||
if( !CheckFilters( mod, modIndex ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if( !mod.Data.SortOrder.StartsWith( _currentModGroup ) )
|
||||
{
|
||||
var count = _currentModGroup.Length - 2;
|
||||
var lastFolder = _currentModGroup.LastIndexOf( '/', _currentModGroup.Length - 2 );
|
||||
_currentModGroup = lastFolder == -1 ? string.Empty : _currentModGroup.Substring( 0, lastFolder + 1 );
|
||||
ImGui.TreePop();
|
||||
return false;
|
||||
}
|
||||
|
||||
var nextFolder = mod.Data.SortOrder.IndexOf( '/', _currentModGroup.Length );
|
||||
if( nextFolder == -1 )
|
||||
{
|
||||
DrawMod( mod, modIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
var mods = Mods!;
|
||||
var folderLabel =
|
||||
$"{mod.Data.SortOrder.Substring( _currentModGroup.Length, nextFolder - _currentModGroup.Length )}##{modIndex}_{_currentModGroup.Length}";
|
||||
_currentModGroup = mod.Data.SortOrder.Substring( 0, nextFolder + 1 );
|
||||
if( ImGui.TreeNodeEx( folderLabel ) )
|
||||
{
|
||||
for( ; modIndex < mods.Count; ++modIndex )
|
||||
{
|
||||
if( !DrawModGroup( mods[ modIndex ], ref modIndex ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TreePush();
|
||||
for( ; modIndex < mods.Count; ++modIndex )
|
||||
{
|
||||
if( !mods[ modIndex ].Data.SortOrder.StartsWith( _currentModGroup ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if( Mods == null )
|
||||
|
|
@ -387,11 +440,18 @@ namespace Penumbra.UI
|
|||
// Inlay selector list
|
||||
ImGui.BeginChild( LabelSelectorList, new Vector2( SelectorPanelWidth, -ImGui.GetFrameHeightWithSpacing() ), true );
|
||||
|
||||
for( var modIndex = 0; modIndex < Mods.Count; modIndex++ )
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.IndentSpacing, 10 );
|
||||
for( var modIndex = 0; modIndex < Mods!.Count; )
|
||||
{
|
||||
DrawMod( Mods[ modIndex ], modIndex );
|
||||
if( DrawModGroup( Mods[ modIndex ], ref modIndex ) )
|
||||
{
|
||||
++modIndex;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
|
||||
|
||||
ImGui.EndChild();
|
||||
|
||||
DrawModsSelectorButtons();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue