Introducing custom Sort Order for mods and collapsible folders inside the mod selector based on '/' in the sort order.

This commit is contained in:
Ottermandias 2021-06-28 22:33:36 +02:00
parent 702e3b9305
commit d52086b69c
7 changed files with 157 additions and 13 deletions

View file

@ -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 )

View file

@ -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 )

View file

@ -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 )

View file

@ -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();
}

View file

@ -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 ) )

View file

@ -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()

View file

@ -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,10 +440,17 @@ 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();