Penumbra/Penumbra/UI/MenuTabs/TabCollections.cs

286 lines
No EOL
11 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Plugin;
using ImGuiNET;
using Penumbra.Mod;
using Penumbra.Mods;
using Penumbra.Util;
namespace Penumbra.UI
{
public partial class SettingsInterface
{
private class TabCollections
{
private readonly Selector _selector;
private readonly ModManager _manager;
private string _collectionNames = null!;
private string _collectionNamesWithNone = null!;
private ModCollection[] _collections = null!;
private int _currentCollectionIndex = 0;
private int _currentForcedIndex = 0;
private int _currentDefaultIndex = 0;
private readonly Dictionary< string, int > _currentCharacterIndices = new();
private string _newCollectionName = string.Empty;
private string _newCharacterName = string.Empty;
private void UpdateNames()
{
_collections = _manager.Collections.Collections.Values.Prepend( ModCollection.Empty ).ToArray();
_collectionNames = string.Join( "\0", _collections.Skip( 1 ).Select( c => c.Name ) ) + '\0';
_collectionNamesWithNone = "None\0" + _collectionNames;
UpdateIndices();
}
private int GetIndex( ModCollection collection )
{
var ret = _collections.IndexOf( c => c.Name == collection.Name );
if( ret < 0 )
{
PluginLog.Error( $"Collection {collection.Name} is not found in collections." );
return 0;
}
return ret;
}
private void UpdateIndex()
=> _currentCollectionIndex = GetIndex( _manager.Collections.CurrentCollection ) - 1;
private void UpdateForcedIndex()
=> _currentForcedIndex = GetIndex( _manager.Collections.ForcedCollection );
private void UpdateDefaultIndex()
=> _currentDefaultIndex = GetIndex( _manager.Collections.DefaultCollection );
private void UpdateCharacterIndices()
{
_currentCharacterIndices.Clear();
foreach( var kvp in _manager.Collections.CharacterCollection )
{
_currentCharacterIndices[ kvp.Key ] = GetIndex( kvp.Value );
}
}
private void UpdateIndices()
{
UpdateIndex();
UpdateDefaultIndex();
UpdateForcedIndex();
UpdateCharacterIndices();
}
public TabCollections( Selector selector )
{
_selector = selector;
_manager = Service< ModManager >.Get();
UpdateNames();
}
private void CreateNewCollection( Dictionary< string, ModSettings > settings )
{
if( _manager.Collections.AddCollection( _newCollectionName, settings ) )
{
_manager.Collections.SetCurrentCollection( _manager.Collections.Collections[ _newCollectionName ] );
UpdateNames();
}
_newCollectionName = string.Empty;
}
private void DrawNewCollectionInput()
{
ImGui.InputTextWithHint( "##New Collection", "New Collection", ref _newCollectionName, 64 );
var changedStyle = false;
if( _newCollectionName.Length == 0 )
{
changedStyle = true;
ImGui.PushStyleVar( ImGuiStyleVar.Alpha, 0.5f );
}
if( ImGui.Button( "Create New Empty Collection" ) && _newCollectionName.Length > 0 )
{
CreateNewCollection( new Dictionary< string, ModSettings >() );
}
ImGui.SameLine();
if( ImGui.Button( "Duplicate Current Collection" ) && _newCollectionName.Length > 0 )
{
CreateNewCollection( _manager.Collections.CurrentCollection.Settings );
}
if( changedStyle )
{
ImGui.PopStyleVar();
}
if( _manager.Collections.Collections.Count > 1
&& _manager.Collections.CurrentCollection.Name != ModCollection.DefaultCollection )
{
ImGui.SameLine();
if( ImGui.Button( "Delete Current Collection" ) )
{
_manager.Collections.RemoveCollection( _manager.Collections.CurrentCollection.Name );
UpdateNames();
}
}
}
private void DrawCurrentCollectionSelector()
{
var index = _currentCollectionIndex;
var combo = ImGui.Combo( "Current Collection", ref index, _collectionNames );
if( ImGui.IsItemHovered() )
{
ImGui.SetTooltip(
"This collection will be modified when using the Installed Mods tab and making changes. It does not apply to anything by itself." );
}
if( combo && index != _currentCollectionIndex )
{
_manager.Collections.SetCurrentCollection( _collections[ index + 1 ] );
_currentCollectionIndex = index;
_selector.ReloadSelection();
}
}
private void DrawDefaultCollectionSelector()
{
var index = _currentDefaultIndex;
if( ImGui.Combo( "##Default Collection", ref index, _collectionNamesWithNone ) && index != _currentDefaultIndex )
{
_manager.Collections.SetDefaultCollection( _collections[ index ] );
_currentDefaultIndex = index;
}
if( ImGui.IsItemHovered() )
{
ImGui.SetTooltip(
"Mods in the default collection are loaded for any character that is not explicitly named in the character collections below.\n"
+ "They also take precedence before the forced collection." );
}
ImGui.SameLine();
ImGui.Dummy( new Vector2( 24, 0 ) );
ImGui.SameLine();
ImGui.Text( "Default Collection" );
}
private void DrawForcedCollectionSelector()
{
var index = _currentForcedIndex;
if( ImGui.Combo( "##Forced Collection", ref index, _collectionNamesWithNone ) && index != _currentForcedIndex )
{
_manager.Collections.SetForcedCollection( _collections[ index ] );
_currentForcedIndex = index;
}
if( ImGui.IsItemHovered() )
{
ImGui.SetTooltip(
"Mods in the forced collection are always loaded if not overwritten by anything in the current or character-based collection.\n"
+ "Please avoid mixing meta-manipulating mods in Forced and other collections, as this will probably not work correctly." );
}
ImGui.SameLine();
ImGui.Dummy( new Vector2( 24, 0 ) );
ImGui.SameLine();
ImGui.Text( "Forced Collection" );
}
private void DrawNewCharacterCollection()
{
ImGui.InputTextWithHint( "##New Character", "New Character Name", ref _newCharacterName, 32 );
var changedStyle = false;
if( _newCharacterName.Length == 0 )
{
changedStyle = true;
ImGui.PushStyleVar( ImGuiStyleVar.Alpha, 0.5f );
}
ImGui.SameLine();
if( ImGui.Button( "Create New Character Collection" ) && _newCharacterName.Length > 0 )
{
_manager.Collections.CreateCharacterCollection( _newCharacterName );
_currentCharacterIndices[ _newCharacterName ] = 0;
_newCharacterName = string.Empty;
}
if( changedStyle )
{
ImGui.PopStyleVar();
}
}
private void DrawCharacterCollectionSelectors()
{
if( !ImGui.BeginChild( "##CollectionChild", AutoFillSize, true ) )
{
return;
}
DrawDefaultCollectionSelector();
DrawForcedCollectionSelector();
foreach( var name in _manager.Collections.CharacterCollection.Keys.ToArray() )
{
var idx = _currentCharacterIndices[ name ];
var tmp = idx;
if( ImGui.Combo( $"##{name}collection", ref tmp, _collectionNamesWithNone ) && idx != tmp )
{
_manager.Collections.SetCharacterCollection( name, _collections[ tmp ] );
_currentCharacterIndices[ name ] = tmp;
}
ImGui.SameLine();
ImGui.PushFont( UiBuilder.IconFont );
if( ImGui.Button( $"{FontAwesomeIcon.Trash.ToIconString()}##{name}" ) )
{
_manager.Collections.RemoveCharacterCollection( name );
}
ImGui.PopFont();
ImGui.SameLine();
ImGui.Text( name );
}
DrawNewCharacterCollection();
ImGui.EndChild();
}
public void Draw()
{
if( !ImGui.BeginTabItem( "Collections" ) )
{
return;
}
if( !ImGui.BeginChild( "##CollectionHandling", new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 6 ), true ) )
{
ImGui.EndTabItem();
return;
}
DrawCurrentCollectionSelector();
ImGui.Dummy( new Vector2( 0, 10 ) );
DrawNewCollectionInput();
ImGui.EndChild();
DrawCharacterCollectionSelectors();
ImGui.EndTabItem();
}
}
}
}