From 55f38865e3d9885b3643b7d7e588d5c069d966e9 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Fri, 5 Jan 2024 18:13:03 +0100 Subject: [PATCH] Memorize last selected mod and state of advanced editing window. --- Penumbra/Communication/ModPathChanged.cs | 3 ++ Penumbra/EphemeralConfig.cs | 32 +++++++++++-- Penumbra/UI/AdvancedWindow/ModEditWindow.cs | 49 ++++++++++++-------- Penumbra/UI/ModsTab/ModFileSystemSelector.cs | 28 ++++++++--- 4 files changed, 82 insertions(+), 30 deletions(-) diff --git a/Penumbra/Communication/ModPathChanged.cs b/Penumbra/Communication/ModPathChanged.cs index 3ec64f7e..e6291781 100644 --- a/Penumbra/Communication/ModPathChanged.cs +++ b/Penumbra/Communication/ModPathChanged.cs @@ -19,6 +19,9 @@ public sealed class ModPathChanged() { public enum Priority { + /// + EphemeralConfig = -500, + /// CollectionCacheManagerAddition = -100, diff --git a/Penumbra/EphemeralConfig.cs b/Penumbra/EphemeralConfig.cs index 6c87d331..8cf23de6 100644 --- a/Penumbra/EphemeralConfig.cs +++ b/Penumbra/EphemeralConfig.cs @@ -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; /// /// Load the current configuration. /// Includes adding new colors and migrating from old versions. /// - public EphemeralConfig(SaveService saveService) + public EphemeralConfig(SaveService saveService, ModPathChanged modPathChanged) { - _saveService = saveService; + _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); } + + /// Overwrite the last saved mod path if it changes. + 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(); + } } diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.cs index 96957ba8..167adafe 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.cs @@ -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; @@ -566,34 +574,36 @@ public partial class ModEditWindow : Window, IDisposable public ModEditWindow(PerformanceTracker performance, FileDialogService fileDialog, ItemSwapTab itemSwapTab, IDataManager gameData, Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, MetaFileManager metaFileManager, StainService stainService, ActiveCollections activeCollections, ModMergeTab modMergeTab, - CommunicatorService communicator, TextureManager textures, ModelManager models, IDragDropManager dragDropManager, + CommunicatorService communicator, TextureManager textures, ModelManager models, IDragDropManager dragDropManager, ChangedItemDrawer changedItemDrawer, IObjectTable objects, IFramework framework, CharacterBaseDestructor characterBaseDestructor) : base(WindowBaseLabel) { - _performance = performance; - _itemSwapTab = itemSwapTab; - _gameData = gameData; - _config = config; - _editor = editor; - _metaFileManager = metaFileManager; - _stainService = stainService; - _activeCollections = activeCollections; - _modMergeTab = modMergeTab; - _communicator = communicator; - _dragDropManager = dragDropManager; - _textures = textures; - _models = models; - _fileDialog = fileDialog; - _objects = objects; - _framework = framework; + _performance = performance; + _itemSwapTab = itemSwapTab; + _gameData = gameData; + _config = config; + _editor = editor; + _metaFileManager = metaFileManager; + _stainService = stainService; + _activeCollections = activeCollections; + _modMergeTab = modMergeTab; + _communicator = communicator; + _dragDropManager = dragDropManager; + _textures = textures; + _models = models; + _fileDialog = fileDialog; + _objects = objects; + _framework = framework; _characterBaseDestructor = characterBaseDestructor; _materialTab = new FileEditor(this, gameData, config, _editor.Compactor, _fileDialog, "Materials", ".mtrl", () => 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(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(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() diff --git a/Penumbra/UI/ModsTab/ModFileSystemSelector.cs b/Penumbra/UI/ModsTab/ModFileSystemSelector.cs index c42b1018..0990f27b 100644 --- a/Penumbra/UI/ModsTab/ModFileSystemSelector.cs +++ b/Penumbra/UI/ModsTab/ModFileSystemSelector.cs @@ -39,8 +39,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector 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