Memorize last selected mod and state of advanced editing window.

This commit is contained in:
Ottermandias 2024-01-05 18:13:03 +01:00
parent 306a9c217a
commit 55f38865e3
4 changed files with 82 additions and 30 deletions

View file

@ -19,6 +19,9 @@ public sealed class ModPathChanged()
{
public enum Priority
{
/// <seealso cref="EphemeralConfig.OnModPathChanged"/>
EphemeralConfig = -500,
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModChangeAddition"/>
CollectionCacheManagerAddition = -100,

View file

@ -2,7 +2,10 @@ using Dalamud.Interface.Internal.Notifications;
using Newtonsoft.Json;
using OtterGui.Classes;
using Penumbra.Api.Enums;
using Penumbra.Communication;
using Penumbra.Enums;
using Penumbra.Mods;
using Penumbra.Mods.Manager;
using Penumbra.Services;
using Penumbra.UI;
using Penumbra.UI.ResourceWatcher;
@ -11,11 +14,14 @@ using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Penumbra;
public class EphemeralConfig : ISavable
public class EphemeralConfig : ISavable, IDisposable
{
[JsonIgnore]
private readonly SaveService _saveService;
[JsonIgnore]
private readonly ModPathChanged _modPathChanged;
public int Version { get; set; } = Configuration.Constants.CurrentVersion;
public int LastSeenVersion { get; set; } = PenumbraChangelog.LastChangelogVersion;
public bool DebugSeparateWindow { get; set; } = false;
@ -31,17 +37,24 @@ public class EphemeralConfig : ISavable
public TabType SelectedTab { get; set; } = TabType.Settings;
public ChangedItemDrawer.ChangedItemIcon ChangedItemFilter { get; set; } = ChangedItemDrawer.DefaultFlags;
public bool FixMainWindow { get; set; } = false;
public string LastModPath { get; set; } = string.Empty;
public bool AdvancedEditingOpen { get; set; } = false;
/// <summary>
/// Load the current configuration.
/// Includes adding new colors and migrating from old versions.
/// </summary>
public EphemeralConfig(SaveService saveService)
public EphemeralConfig(SaveService saveService, ModPathChanged modPathChanged)
{
_saveService = saveService;
_modPathChanged = modPathChanged;
Load();
_modPathChanged.Subscribe(OnModPathChanged, ModPathChanged.Priority.EphemeralConfig);
}
public void Dispose()
=> _modPathChanged.Unsubscribe(OnModPathChanged);
private void Load()
{
static void HandleDeserializationError(object? sender, ErrorEventArgs errorArgs)
@ -80,8 +93,19 @@ public class EphemeralConfig : ISavable
public void Save(StreamWriter writer)
{
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
using var jWriter = new JsonTextWriter(writer);
jWriter.Formatting = Formatting.Indented;
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
serializer.Serialize(jWriter, this);
}
/// <summary> Overwrite the last saved mod path if it changes. </summary>
private void OnModPathChanged(ModPathChangeType type, Mod mod, DirectoryInfo? old, DirectoryInfo? _)
{
if (type is not ModPathChangeType.Moved || !string.Equals(old?.Name, LastModPath, StringComparison.OrdinalIgnoreCase))
return;
LastModPath = mod.Identifier;
Save();
}
}

View file

@ -145,12 +145,20 @@ public partial class ModEditWindow : Window, IDisposable
_materialTab.Reset();
_modelTab.Reset();
_shaderPackageTab.Reset();
_config.Ephemeral.AdvancedEditingOpen = false;
_config.Ephemeral.Save();
}
public override void Draw()
{
using var performance = _performance.Measure(PerformanceType.UiAdvancedWindow);
if (!_config.Ephemeral.AdvancedEditingOpen)
{
_config.Ephemeral.AdvancedEditingOpen = true;
_config.Ephemeral.Save();
}
using var tabBar = ImRaii.TabBar("##tabs");
if (!tabBar)
return;
@ -591,9 +599,11 @@ public partial class ModEditWindow : Window, IDisposable
() => PopulateIsOnPlayer(_editor.Files.Mtrl, ResourceType.Mtrl), DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty,
(bytes, path, writable) => new MtrlTab(this, new MtrlFile(bytes), path, writable));
_modelTab = new FileEditor<MdlTab>(this, gameData, config, _editor.Compactor, _fileDialog, "Models", ".mdl",
() => PopulateIsOnPlayer(_editor.Files.Mdl, ResourceType.Mdl), DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty, (bytes, path, _) => new MdlTab(this, bytes, path, _mod));
() => PopulateIsOnPlayer(_editor.Files.Mdl, ResourceType.Mdl), DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty,
(bytes, path, _) => new MdlTab(this, bytes, path, _mod));
_shaderPackageTab = new FileEditor<ShpkTab>(this, gameData, config, _editor.Compactor, _fileDialog, "Shaders", ".shpk",
() => PopulateIsOnPlayer(_editor.Files.Shpk, ResourceType.Shpk), DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty,
() => PopulateIsOnPlayer(_editor.Files.Shpk, ResourceType.Shpk), DrawShaderPackagePanel,
() => _mod?.ModPath.FullName ?? string.Empty,
(bytes, _, _) => new ShpkTab(_fileDialog, bytes));
_center = new CombinedTexture(_left, _right);
_textureSelectCombo = new TextureDrawer.PathSelectCombo(textures, editor, () => GetPlayerResourcesOfType(ResourceType.Tex));
@ -601,6 +611,7 @@ public partial class ModEditWindow : Window, IDisposable
_quickImportViewer =
new ResourceTreeViewer(_config, resourceTreeFactory, changedItemDrawer, 2, OnQuickImportRefresh, DrawQuickImportActions);
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModEditWindow);
IsOpen = _config is { OpenWindowAtStart: true, Ephemeral.AdvancedEditingOpen: true };
}
public void Dispose()

View file

@ -39,8 +39,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
public ModFileSystemSelector(IKeyState keyState, CommunicatorService communicator, ModFileSystem fileSystem, ModManager modManager,
CollectionManager collectionManager, Configuration config, TutorialService tutorial, FileDialogService fileDialog,
MessageService messager,
ModImportManager modImportManager, IDragDropManager dragDrop)
MessageService messager, ModImportManager modImportManager, IDragDropManager dragDrop)
: base(fileSystem, keyState, Penumbra.Log, HandleException, allowMultipleSelection: true)
{
_communicator = communicator;
@ -78,6 +77,14 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
SetFilterTooltip();
SelectionChanged += OnSelectionChange;
if (_config.Ephemeral.LastModPath.Length > 0)
{
var mod = _modManager.FirstOrDefault(m
=> string.Equals(m.Identifier, _config.Ephemeral.LastModPath, StringComparison.OrdinalIgnoreCase));
if (mod != null)
SelectByValue(mod);
}
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.ModFileSystemSelector);
_communicator.ModSettingChanged.Subscribe(OnSettingChange, ModSettingChanged.Priority.ModFileSystemSelector);
_communicator.CollectionInheritanceChanged.Subscribe(OnInheritanceChange, CollectionInheritanceChanged.Priority.ModFileSystemSelector);
@ -87,15 +94,15 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
OnCollectionChange(CollectionType.Current, null, _collectionManager.Active.Current, "");
}
private static readonly string[] ValidModExtensions = new[]
{
private static readonly string[] ValidModExtensions =
[
".ttmp",
".ttmp2",
".pmp",
".zip",
".rar",
".7z",
};
];
public new void Draw(float width)
{
@ -476,6 +483,13 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
(var settings, SelectedSettingCollection) = _collectionManager.Active.Current[newSelection.Index];
SelectedSettings = settings ?? ModSettings.Empty;
}
var name = newSelection?.Identifier ?? string.Empty;
if (name != _config.Ephemeral.LastModPath)
{
_config.Ephemeral.LastModPath = name;
_config.Ephemeral.Save();
}
}
// Keep selections across rediscoveries if possible.
@ -522,7 +536,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
+ "Enter t:[string] to filter for mods set to specific tags.\n"
+ "Enter n:[string] to filter only for mod names and no paths.\n"
+ "Enter a:[string] to filter for mods by specific authors.\n"
+ $"Enter s:[string] to filter for mods by the categories of the items they change (1-{ChangedItemDrawer.NumCategories+1} or partial category name).\n"
+ $"Enter s:[string] to filter for mods by the categories of the items they change (1-{ChangedItemDrawer.NumCategories + 1} or partial category name).\n"
+ "Use None as a placeholder value that only matches empty lists or names.";
}