mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Improve handling of mod selection.
This commit is contained in:
parent
a3c22f2826
commit
d713d5a112
12 changed files with 227 additions and 148 deletions
|
|
@ -46,5 +46,8 @@ public sealed class CollectionChange()
|
|||
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.OnCollectionChange"/>
|
||||
ModFileSystemSelector = 0,
|
||||
|
||||
/// <seealso cref="Mods.ModSelection.OnCollectionChange"/>
|
||||
ModSelection = 10,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,8 @@ public sealed class CollectionInheritanceChanged()
|
|||
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.OnInheritanceChange"/>
|
||||
ModFileSystemSelector = 0,
|
||||
|
||||
/// <seealso cref="Mods.ModSelection.OnInheritanceChange"/>
|
||||
ModSelection = 10,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using OtterGui.Classes;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.Api.Api;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
|
|
@ -35,5 +34,8 @@ public sealed class ModSettingChanged()
|
|||
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.OnSettingChange"/>
|
||||
ModFileSystemSelector = 0,
|
||||
|
||||
/// <seealso cref="Mods.ModSelection.OnSettingChange"/>
|
||||
ModSelection = 10,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,22 +10,21 @@ using Penumbra.Mods.Manager.OptionEditor;
|
|||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.UI.ModsTab;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
||||
public class ModMerger : IDisposable, IService
|
||||
{
|
||||
private readonly Configuration _config;
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly ModGroupEditor _editor;
|
||||
private readonly ModFileSystemSelector _selector;
|
||||
private readonly DuplicateManager _duplicates;
|
||||
private readonly ModManager _mods;
|
||||
private readonly ModCreator _creator;
|
||||
private readonly Configuration _config;
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly ModGroupEditor _editor;
|
||||
private readonly ModSelection _selection;
|
||||
private readonly DuplicateManager _duplicates;
|
||||
private readonly ModManager _mods;
|
||||
private readonly ModCreator _creator;
|
||||
|
||||
public Mod? MergeFromMod
|
||||
=> _selector.Selected;
|
||||
=> _selection.Mod;
|
||||
|
||||
public Mod? MergeToMod;
|
||||
public string OptionGroupName = "Merges";
|
||||
|
|
@ -41,23 +40,23 @@ public class ModMerger : IDisposable, IService
|
|||
public readonly IReadOnlyList<string> Warnings = new List<string>();
|
||||
public Exception? Error { get; private set; }
|
||||
|
||||
public ModMerger(ModManager mods, ModGroupEditor editor, ModFileSystemSelector selector, DuplicateManager duplicates,
|
||||
public ModMerger(ModManager mods, ModGroupEditor editor, ModSelection selection, DuplicateManager duplicates,
|
||||
CommunicatorService communicator, ModCreator creator, Configuration config)
|
||||
{
|
||||
_editor = editor;
|
||||
_selector = selector;
|
||||
_duplicates = duplicates;
|
||||
_communicator = communicator;
|
||||
_creator = creator;
|
||||
_config = config;
|
||||
_mods = mods;
|
||||
_selector.SelectionChanged += OnSelectionChange;
|
||||
_editor = editor;
|
||||
_selection = selection;
|
||||
_duplicates = duplicates;
|
||||
_communicator = communicator;
|
||||
_creator = creator;
|
||||
_config = config;
|
||||
_mods = mods;
|
||||
_selection.Subscribe(OnSelectionChange, ModSelection.Priority.ModMerger);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModMerger);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_selector.SelectionChanged -= OnSelectionChange;
|
||||
_selection.Unsubscribe(OnSelectionChange);
|
||||
_communicator.ModPathChanged.Unsubscribe(OnModPathChange);
|
||||
}
|
||||
|
||||
|
|
@ -390,7 +389,7 @@ public class ModMerger : IDisposable, IService
|
|||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChange(Mod? oldSelection, Mod? newSelection, in ModFileSystemSelector.ModState state)
|
||||
private void OnSelectionChange(Mod? oldSelection, Mod? newSelection)
|
||||
{
|
||||
if (OptionGroupName == "Merges" && OptionName.Length == 0 || OptionName == oldSelection?.Name.Text)
|
||||
OptionName = newSelection?.Name.Text ?? string.Empty;
|
||||
|
|
|
|||
104
Penumbra/Mods/ModSelection.cs
Normal file
104
Penumbra/Mods/ModSelection.cs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
using OtterGui.Classes;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever the selected mod changes
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the old selected mod. </item>
|
||||
/// <item>Parameter is the new selected mod </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public class ModSelection : EventWrapper<Mod?, Mod?, ModSelection.Priority>
|
||||
{
|
||||
private readonly ActiveCollections _collections;
|
||||
private readonly EphemeralConfig _config;
|
||||
private readonly CommunicatorService _communicator;
|
||||
|
||||
public ModSelection(CommunicatorService communicator, ModManager mods, ActiveCollections collections, EphemeralConfig config)
|
||||
: base(nameof(ModSelection))
|
||||
{
|
||||
_communicator = communicator;
|
||||
_collections = collections;
|
||||
_config = config;
|
||||
if (_config.LastModPath.Length > 0)
|
||||
SelectMod(mods.FirstOrDefault(m => string.Equals(m.Identifier, config.LastModPath, StringComparison.OrdinalIgnoreCase)));
|
||||
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.ModSelection);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnInheritanceChange, CollectionInheritanceChanged.Priority.ModSelection);
|
||||
_communicator.ModSettingChanged.Subscribe(OnSettingChange, ModSettingChanged.Priority.ModSelection);
|
||||
}
|
||||
|
||||
public ModSettings Settings { get; private set; } = ModSettings.Empty;
|
||||
public ModCollection Collection { get; private set; } = ModCollection.Empty;
|
||||
public Mod? Mod { get; private set; }
|
||||
|
||||
|
||||
public void SelectMod(Mod? mod)
|
||||
{
|
||||
if (mod == Mod)
|
||||
return;
|
||||
|
||||
var oldMod = Mod;
|
||||
Mod = mod;
|
||||
OnCollectionChange(CollectionType.Current, null, _collections.Current, string.Empty);
|
||||
Invoke(oldMod, Mod);
|
||||
_config.LastModPath = mod?.ModPath.Name ?? string.Empty;
|
||||
_config.Save();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool _)
|
||||
{
|
||||
_communicator.CollectionChange.Unsubscribe(OnCollectionChange);
|
||||
_communicator.CollectionInheritanceChanged.Unsubscribe(OnInheritanceChange);
|
||||
_communicator.ModSettingChanged.Unsubscribe(OnSettingChange);
|
||||
}
|
||||
|
||||
private void OnCollectionChange(CollectionType type, ModCollection? oldCollection, ModCollection? newCollection, string _2)
|
||||
{
|
||||
if (type is CollectionType.Current && oldCollection != newCollection)
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
private void OnSettingChange(ModCollection collection, ModSettingChange _1, Mod? mod, Setting _2, int _3, bool _4)
|
||||
{
|
||||
if (collection == _collections.Current && mod == Mod)
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
private void OnInheritanceChange(ModCollection collection, bool arg2)
|
||||
{
|
||||
if (collection == _collections.Current)
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
private void UpdateSettings()
|
||||
{
|
||||
if (Mod == null)
|
||||
{
|
||||
Settings = ModSettings.Empty;
|
||||
Collection = ModCollection.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
(var settings, Collection) = _collections.Current[Mod.Index];
|
||||
Settings = settings ?? ModSettings.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="UI.ModsTab.ModPanel.OnSelectionChange"/>
|
||||
ModPanel = 0,
|
||||
|
||||
/// <seealso cref="Editor.ModMerger.OnSelectionChange"/>
|
||||
ModMerger = 0,
|
||||
}
|
||||
}
|
||||
|
|
@ -36,8 +36,6 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
{
|
||||
private const string WindowBaseLabel = "###SubModEdit";
|
||||
|
||||
public readonly MigrationManager MigrationManager;
|
||||
|
||||
private readonly PerformanceTracker _performance;
|
||||
private readonly ModEditor _editor;
|
||||
private readonly Configuration _config;
|
||||
|
|
@ -587,7 +585,7 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
CommunicatorService communicator, TextureManager textures, ModelManager models, IDragDropManager dragDropManager,
|
||||
ResourceTreeViewerFactory resourceTreeViewerFactory, IFramework framework,
|
||||
MetaDrawers metaDrawers, MigrationManager migrationManager,
|
||||
MtrlTabFactory mtrlTabFactory)
|
||||
MtrlTabFactory mtrlTabFactory, ModSelection selection)
|
||||
: base(WindowBaseLabel)
|
||||
{
|
||||
_performance = performance;
|
||||
|
|
@ -604,7 +602,6 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
_models = models;
|
||||
_fileDialog = fileDialog;
|
||||
_framework = framework;
|
||||
MigrationManager = migrationManager;
|
||||
_metaDrawers = metaDrawers;
|
||||
_materialTab = new FileEditor<MtrlTab>(this, _communicator, gameData, config, _editor.Compactor, _fileDialog, "Materials", ".mtrl",
|
||||
() => PopulateIsOnPlayer(_editor.Files.Mtrl, ResourceType.Mtrl), DrawMaterialPanel, () => Mod?.ModPath.FullName ?? string.Empty,
|
||||
|
|
@ -622,6 +619,8 @@ public partial class ModEditWindow : Window, IDisposable, IUiService
|
|||
_quickImportViewer = resourceTreeViewerFactory.Create(2, OnQuickImportRefresh, DrawQuickImportActions);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModEditWindow);
|
||||
IsOpen = _config is { OpenWindowAtStart: true, Ephemeral.AdvancedEditingOpen: true };
|
||||
if (IsOpen && selection.Mod != null)
|
||||
ChangeMod(selection.Mod);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -5,24 +5,24 @@ using OtterGui.Services;
|
|||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Interop.PathResolving;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.CollectionTab;
|
||||
using Penumbra.UI.ModsTab;
|
||||
|
||||
namespace Penumbra.UI.Classes;
|
||||
|
||||
public class CollectionSelectHeader : IUiService
|
||||
{
|
||||
private readonly CollectionCombo _collectionCombo;
|
||||
private readonly ActiveCollections _activeCollections;
|
||||
private readonly TutorialService _tutorial;
|
||||
private readonly ModFileSystemSelector _selector;
|
||||
private readonly CollectionResolver _resolver;
|
||||
private readonly CollectionCombo _collectionCombo;
|
||||
private readonly ActiveCollections _activeCollections;
|
||||
private readonly TutorialService _tutorial;
|
||||
private readonly ModSelection _selection;
|
||||
private readonly CollectionResolver _resolver;
|
||||
|
||||
public CollectionSelectHeader(CollectionManager collectionManager, TutorialService tutorial, ModFileSystemSelector selector,
|
||||
public CollectionSelectHeader(CollectionManager collectionManager, TutorialService tutorial, ModSelection selection,
|
||||
CollectionResolver resolver)
|
||||
{
|
||||
_tutorial = tutorial;
|
||||
_selector = selector;
|
||||
_selection = selection;
|
||||
_resolver = resolver;
|
||||
_activeCollections = collectionManager.Active;
|
||||
_collectionCombo = new CollectionCombo(collectionManager, () => collectionManager.Storage.OrderBy(c => c.Name).ToList());
|
||||
|
|
@ -115,7 +115,7 @@ public class CollectionSelectHeader : IUiService
|
|||
|
||||
private (ModCollection?, string, string, bool) GetInheritedCollectionInfo()
|
||||
{
|
||||
var collection = _selector.Selected == null ? null : _selector.SelectedSettingCollection;
|
||||
var collection = _selection.Mod == null ? null : _selection.Collection;
|
||||
return CheckCollection(collection, true) switch
|
||||
{
|
||||
CollectionState.Unavailable => (null, "Not Inherited",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ namespace Penumbra.UI.ModsTab;
|
|||
public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSystemSelector.ModState>, IUiService
|
||||
{
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly MessageService _messager;
|
||||
private readonly Configuration _config;
|
||||
private readonly FileDialogService _fileDialog;
|
||||
private readonly ModManager _modManager;
|
||||
|
|
@ -33,15 +32,12 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
private readonly TutorialService _tutorial;
|
||||
private readonly ModImportManager _modImportManager;
|
||||
private readonly IDragDropManager _dragDrop;
|
||||
private readonly ModSearchStringSplitter Filter = new();
|
||||
|
||||
public ModSettings SelectedSettings { get; private set; } = ModSettings.Empty;
|
||||
public ModCollection SelectedSettingCollection { get; private set; } = ModCollection.Empty;
|
||||
|
||||
private readonly ModSearchStringSplitter _filter = new();
|
||||
private readonly ModSelection _selection;
|
||||
|
||||
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, ModSelection selection)
|
||||
: base(fileSystem, keyState, Penumbra.Log, HandleException, allowMultipleSelection: true)
|
||||
{
|
||||
_communicator = communicator;
|
||||
|
|
@ -50,9 +46,9 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
_config = config;
|
||||
_tutorial = tutorial;
|
||||
_fileDialog = fileDialog;
|
||||
_messager = messager;
|
||||
_modImportManager = modImportManager;
|
||||
_dragDrop = dragDrop;
|
||||
_selection = selection;
|
||||
|
||||
// @formatter:off
|
||||
SubscribeRightClickFolder(EnableDescendants, 10);
|
||||
|
|
@ -78,24 +74,18 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
// @formatter:on
|
||||
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);
|
||||
}
|
||||
|
||||
if (_selection.Mod != null)
|
||||
SelectByValue(_selection.Mod);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.ModFileSystemSelector);
|
||||
_communicator.ModSettingChanged.Subscribe(OnSettingChange, ModSettingChanged.Priority.ModFileSystemSelector);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnInheritanceChange, CollectionInheritanceChanged.Priority.ModFileSystemSelector);
|
||||
_communicator.ModDataChanged.Subscribe(OnModDataChange, ModDataChanged.Priority.ModFileSystemSelector);
|
||||
_communicator.ModDiscoveryStarted.Subscribe(StoreCurrentSelection, ModDiscoveryStarted.Priority.ModFileSystemSelector);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(RestoreLastSelection, ModDiscoveryFinished.Priority.ModFileSystemSelector);
|
||||
OnCollectionChange(CollectionType.Current, null, _collectionManager.Active.Current, "");
|
||||
}
|
||||
|
||||
SetFilterDirty();
|
||||
SelectionChanged += OnSelectionChanged;
|
||||
}
|
||||
|
||||
public void SetRenameSearchPath(RenameField value)
|
||||
{
|
||||
switch (value)
|
||||
|
|
@ -449,12 +439,8 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
|
||||
private void OnSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, Setting oldValue, int groupIdx, bool inherited)
|
||||
{
|
||||
if (collection != _collectionManager.Active.Current)
|
||||
return;
|
||||
|
||||
SetFilterDirty();
|
||||
if (mod == Selected)
|
||||
OnSelectionChange(Selected, Selected, default);
|
||||
if (collection == _collectionManager.Active.Current)
|
||||
SetFilterDirty();
|
||||
}
|
||||
|
||||
private void OnModDataChange(ModDataChangeType type, Mod mod, string? oldName)
|
||||
|
|
@ -473,41 +459,14 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
|
||||
private void OnInheritanceChange(ModCollection collection, bool _)
|
||||
{
|
||||
if (collection != _collectionManager.Active.Current)
|
||||
return;
|
||||
|
||||
SetFilterDirty();
|
||||
OnSelectionChange(Selected, Selected, default);
|
||||
if (collection == _collectionManager.Active.Current)
|
||||
SetFilterDirty();
|
||||
}
|
||||
|
||||
private void OnCollectionChange(CollectionType collectionType, ModCollection? oldCollection, ModCollection? newCollection, string _)
|
||||
{
|
||||
if (collectionType is not CollectionType.Current || oldCollection == newCollection)
|
||||
return;
|
||||
|
||||
SetFilterDirty();
|
||||
OnSelectionChange(Selected, Selected, default);
|
||||
}
|
||||
|
||||
private void OnSelectionChange(Mod? _1, Mod? newSelection, in ModState _2)
|
||||
{
|
||||
if (newSelection == null)
|
||||
{
|
||||
SelectedSettings = ModSettings.Empty;
|
||||
SelectedSettingCollection = ModCollection.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
(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();
|
||||
}
|
||||
if (collectionType is CollectionType.Current && oldCollection != newCollection)
|
||||
SetFilterDirty();
|
||||
}
|
||||
|
||||
// Keep selections across rediscoveries if possible.
|
||||
|
|
@ -530,6 +489,9 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
_lastSelectedDirectory = string.Empty;
|
||||
}
|
||||
|
||||
private void OnSelectionChanged(Mod? oldSelection, Mod? newSelection, in ModState state)
|
||||
=> _selection.SelectMod(newSelection);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Filters
|
||||
|
|
@ -567,7 +529,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
/// <summary> Appropriately identify and set the string filter and its type. </summary>
|
||||
protected override bool ChangeFilter(string filterValue)
|
||||
{
|
||||
Filter.Parse(filterValue);
|
||||
_filter.Parse(filterValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +559,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
{
|
||||
state = default;
|
||||
return ModFilterExtensions.UnfilteredStateMods != _stateFilter
|
||||
|| !Filter.IsVisible(f);
|
||||
|| !_filter.IsVisible(f);
|
||||
}
|
||||
|
||||
return ApplyFiltersAndState((ModFileSystem.Leaf)path, out state);
|
||||
|
|
@ -605,7 +567,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
|
||||
/// <summary> Apply the string filters. </summary>
|
||||
private bool ApplyStringFilters(ModFileSystem.Leaf leaf, Mod mod)
|
||||
=> !Filter.IsVisible(leaf);
|
||||
=> !_filter.IsVisible(leaf);
|
||||
|
||||
/// <summary> Only get the text color for a mod if no filters are set. </summary>
|
||||
private ColorId GetTextColor(Mod mod, ModSettings? settings, ModCollection collection)
|
||||
|
|
|
|||
|
|
@ -10,22 +10,23 @@ namespace Penumbra.UI.ModsTab;
|
|||
|
||||
public class ModPanel : IDisposable, IUiService
|
||||
{
|
||||
private readonly MultiModPanel _multiModPanel;
|
||||
private readonly ModFileSystemSelector _selector;
|
||||
private readonly ModEditWindow _editWindow;
|
||||
private readonly ModPanelHeader _header;
|
||||
private readonly ModPanelTabBar _tabs;
|
||||
private bool _resetCursor;
|
||||
private readonly MultiModPanel _multiModPanel;
|
||||
private readonly ModSelection _selection;
|
||||
private readonly ModEditWindow _editWindow;
|
||||
private readonly ModPanelHeader _header;
|
||||
private readonly ModPanelTabBar _tabs;
|
||||
private bool _resetCursor;
|
||||
|
||||
public ModPanel(IDalamudPluginInterface pi, ModFileSystemSelector selector, ModEditWindow editWindow, ModPanelTabBar tabs,
|
||||
public ModPanel(IDalamudPluginInterface pi, ModSelection selection, ModEditWindow editWindow, ModPanelTabBar tabs,
|
||||
MultiModPanel multiModPanel, CommunicatorService communicator)
|
||||
{
|
||||
_selector = selector;
|
||||
_editWindow = editWindow;
|
||||
_tabs = tabs;
|
||||
_multiModPanel = multiModPanel;
|
||||
_header = new ModPanelHeader(pi, communicator);
|
||||
_selector.SelectionChanged += OnSelectionChange;
|
||||
_selection = selection;
|
||||
_editWindow = editWindow;
|
||||
_tabs = tabs;
|
||||
_multiModPanel = multiModPanel;
|
||||
_header = new ModPanelHeader(pi, communicator);
|
||||
_selection.Subscribe(OnSelectionChange, ModSelection.Priority.ModPanel);
|
||||
OnSelectionChange(null, _selection.Mod);
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
|
|
@ -52,17 +53,17 @@ public class ModPanel : IDisposable, IUiService
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
_selector.SelectionChanged -= OnSelectionChange;
|
||||
_selection.Unsubscribe(OnSelectionChange);
|
||||
_header.Dispose();
|
||||
}
|
||||
|
||||
private bool _valid;
|
||||
private Mod _mod = null!;
|
||||
|
||||
private void OnSelectionChange(Mod? old, Mod? mod, in ModFileSystemSelector.ModState _)
|
||||
private void OnSelectionChange(Mod? old, Mod? mod)
|
||||
{
|
||||
_resetCursor = true;
|
||||
if (mod == null || _selector.Selected == null)
|
||||
if (mod == null || _selection.Mod == null)
|
||||
{
|
||||
_editWindow.IsOpen = false;
|
||||
_valid = false;
|
||||
|
|
@ -73,7 +74,7 @@ public class ModPanel : IDisposable, IUiService
|
|||
_editWindow.ChangeMod(mod);
|
||||
_valid = true;
|
||||
_mod = mod;
|
||||
_header.UpdateModData(_mod);
|
||||
_header.ChangeMod(_mod);
|
||||
_tabs.Settings.Reset();
|
||||
_tabs.Edit.Reset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ public class ModPanelHeader : IDisposable
|
|||
private readonly IFontHandle _nameFont;
|
||||
|
||||
private readonly CommunicatorService _communicator;
|
||||
private float _lastPreSettingsHeight = 0;
|
||||
private float _lastPreSettingsHeight;
|
||||
private bool _dirty = true;
|
||||
|
||||
public ModPanelHeader(IDalamudPluginInterface pi, CommunicatorService communicator)
|
||||
{
|
||||
|
|
@ -33,6 +34,7 @@ public class ModPanelHeader : IDisposable
|
|||
/// </summary>
|
||||
public void Draw()
|
||||
{
|
||||
UpdateModData();
|
||||
var height = ImGui.GetContentRegionAvail().Y;
|
||||
var maxHeight = 3 * height / 4;
|
||||
using var child = _lastPreSettingsHeight > maxHeight && _communicator.PreSettingsTabBarDraw.HasSubscribers
|
||||
|
|
@ -49,16 +51,25 @@ public class ModPanelHeader : IDisposable
|
|||
_lastPreSettingsHeight = ImGui.GetCursorPosY();
|
||||
}
|
||||
|
||||
public void ChangeMod(Mod mod)
|
||||
{
|
||||
_mod = mod;
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update all mod header data. Should someone change frame padding or item spacing,
|
||||
/// or his default font, this will break, but he will just have to select a different mod to restore.
|
||||
/// </summary>
|
||||
public void UpdateModData(Mod mod)
|
||||
private void UpdateModData()
|
||||
{
|
||||
if (!_dirty)
|
||||
return;
|
||||
|
||||
_dirty = false;
|
||||
_lastPreSettingsHeight = 0;
|
||||
_mod = mod;
|
||||
// Name
|
||||
var name = $" {mod.Name} ";
|
||||
var name = $" {_mod.Name} ";
|
||||
if (name != _modName)
|
||||
{
|
||||
using var f = _nameFont.Push();
|
||||
|
|
@ -67,16 +78,16 @@ public class ModPanelHeader : IDisposable
|
|||
}
|
||||
|
||||
// Author
|
||||
if (mod.Author != _modAuthor)
|
||||
if (_mod.Author != _modAuthor)
|
||||
{
|
||||
var author = mod.Author.IsEmpty ? string.Empty : $"by {mod.Author}";
|
||||
_modAuthor = mod.Author.Text;
|
||||
var author = _mod.Author.IsEmpty ? string.Empty : $"by {_mod.Author}";
|
||||
_modAuthor = _mod.Author.Text;
|
||||
_modAuthorWidth = ImGui.CalcTextSize(author).X;
|
||||
_secondRowWidth = _modAuthorWidth + _modWebsiteButtonWidth + ImGui.GetStyle().ItemSpacing.X;
|
||||
}
|
||||
|
||||
// Version
|
||||
var version = mod.Version.Length > 0 ? $"({mod.Version})" : string.Empty;
|
||||
var version = _mod.Version.Length > 0 ? $"({_mod.Version})" : string.Empty;
|
||||
if (version != _modVersion)
|
||||
{
|
||||
_modVersion = version;
|
||||
|
|
@ -84,9 +95,9 @@ public class ModPanelHeader : IDisposable
|
|||
}
|
||||
|
||||
// Website
|
||||
if (_modWebsite != mod.Website)
|
||||
if (_modWebsite != _mod.Website)
|
||||
{
|
||||
_modWebsite = mod.Website;
|
||||
_modWebsite = _mod.Website;
|
||||
_websiteValid = Uri.TryCreate(_modWebsite, UriKind.Absolute, out var uriResult)
|
||||
&& (uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp);
|
||||
_modWebsiteButton = _websiteValid ? "Open Website" : _modWebsite.Length == 0 ? string.Empty : $"from {_modWebsite}";
|
||||
|
|
@ -253,7 +264,6 @@ public class ModPanelHeader : IDisposable
|
|||
{
|
||||
const ModDataChangeType relevantChanges =
|
||||
ModDataChangeType.Author | ModDataChangeType.Name | ModDataChangeType.Website | ModDataChangeType.Version;
|
||||
if ((changeType & relevantChanges) != 0)
|
||||
UpdateModData(mod);
|
||||
_dirty = (changeType & relevantChanges) != 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ using OtterGui.Raii;
|
|||
using OtterGui;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
|
@ -16,16 +16,14 @@ namespace Penumbra.UI.ModsTab;
|
|||
public class ModPanelSettingsTab(
|
||||
CollectionManager collectionManager,
|
||||
ModManager modManager,
|
||||
ModFileSystemSelector selector,
|
||||
ModSelection selection,
|
||||
TutorialService tutorial,
|
||||
CommunicatorService communicator,
|
||||
ModGroupDrawer modGroupDrawer)
|
||||
: ITab, IUiService
|
||||
{
|
||||
private bool _inherited;
|
||||
private ModSettings _settings = null!;
|
||||
private ModCollection _collection = null!;
|
||||
private int? _currentPriority;
|
||||
private bool _inherited;
|
||||
private int? _currentPriority;
|
||||
|
||||
public ReadOnlySpan<byte> Label
|
||||
=> "Settings"u8;
|
||||
|
|
@ -42,12 +40,10 @@ public class ModPanelSettingsTab(
|
|||
if (!child)
|
||||
return;
|
||||
|
||||
_settings = selector.SelectedSettings;
|
||||
_collection = selector.SelectedSettingCollection;
|
||||
_inherited = _collection != collectionManager.Active.Current;
|
||||
_inherited = selection.Collection != collectionManager.Active.Current;
|
||||
DrawInheritedWarning();
|
||||
UiHelpers.DefaultLineSpace();
|
||||
communicator.PreSettingsPanelDraw.Invoke(selector.Selected!.Identifier);
|
||||
communicator.PreSettingsPanelDraw.Invoke(selection.Mod!.Identifier);
|
||||
DrawEnabledInput();
|
||||
tutorial.OpenTutorial(BasicTutorialSteps.EnablingMods);
|
||||
ImGui.SameLine();
|
||||
|
|
@ -55,11 +51,11 @@ public class ModPanelSettingsTab(
|
|||
tutorial.OpenTutorial(BasicTutorialSteps.Priority);
|
||||
DrawRemoveSettings();
|
||||
|
||||
communicator.PostEnabledDraw.Invoke(selector.Selected!.Identifier);
|
||||
communicator.PostEnabledDraw.Invoke(selection.Mod!.Identifier);
|
||||
|
||||
modGroupDrawer.Draw(selector.Selected!, _settings);
|
||||
modGroupDrawer.Draw(selection.Mod!, selection.Settings);
|
||||
UiHelpers.DefaultLineSpace();
|
||||
communicator.PostSettingsPanelDraw.Invoke(selector.Selected!.Identifier);
|
||||
communicator.PostSettingsPanelDraw.Invoke(selection.Mod!.Identifier);
|
||||
}
|
||||
|
||||
/// <summary> Draw a big red bar if the current setting is inherited. </summary>
|
||||
|
|
@ -70,8 +66,8 @@ public class ModPanelSettingsTab(
|
|||
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Button, Colors.PressEnterWarningBg);
|
||||
var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);
|
||||
if (ImGui.Button($"These settings are inherited from {_collection.Name}.", width))
|
||||
collectionManager.Editor.SetModInheritance(collectionManager.Active.Current, selector.Selected!, false);
|
||||
if (ImGui.Button($"These settings are inherited from {selection.Collection.Name}.", width))
|
||||
collectionManager.Editor.SetModInheritance(collectionManager.Active.Current, selection.Mod!, false);
|
||||
|
||||
ImGuiUtil.HoverTooltip("You can click this button to copy the current settings to the current selection.\n"
|
||||
+ "You can also just change any setting, which will copy the settings with the single setting changed to the current selection.");
|
||||
|
|
@ -80,12 +76,12 @@ public class ModPanelSettingsTab(
|
|||
/// <summary> Draw a checkbox for the enabled status of the mod. </summary>
|
||||
private void DrawEnabledInput()
|
||||
{
|
||||
var enabled = _settings.Enabled;
|
||||
var enabled = selection.Settings.Enabled;
|
||||
if (!ImGui.Checkbox("Enabled", ref enabled))
|
||||
return;
|
||||
|
||||
modManager.SetKnown(selector.Selected!);
|
||||
collectionManager.Editor.SetModState(collectionManager.Active.Current, selector.Selected!, enabled);
|
||||
modManager.SetKnown(selection.Mod!);
|
||||
collectionManager.Editor.SetModState(collectionManager.Active.Current, selection.Mod!, enabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -95,15 +91,16 @@ public class ModPanelSettingsTab(
|
|||
private void DrawPriorityInput()
|
||||
{
|
||||
using var group = ImRaii.Group();
|
||||
var priority = _currentPriority ?? _settings.Priority.Value;
|
||||
var settings = selection.Settings;
|
||||
var priority = _currentPriority ?? settings.Priority.Value;
|
||||
ImGui.SetNextItemWidth(50 * UiHelpers.Scale);
|
||||
if (ImGui.InputInt("##Priority", ref priority, 0, 0))
|
||||
_currentPriority = priority;
|
||||
|
||||
if (ImGui.IsItemDeactivatedAfterEdit() && _currentPriority.HasValue)
|
||||
{
|
||||
if (_currentPriority != _settings.Priority.Value)
|
||||
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, selector.Selected!,
|
||||
if (_currentPriority != settings.Priority.Value)
|
||||
collectionManager.Editor.SetModPriority(collectionManager.Active.Current, selection.Mod!,
|
||||
new ModPriority(_currentPriority.Value));
|
||||
|
||||
_currentPriority = null;
|
||||
|
|
@ -120,13 +117,13 @@ public class ModPanelSettingsTab(
|
|||
private void DrawRemoveSettings()
|
||||
{
|
||||
const string text = "Inherit Settings";
|
||||
if (_inherited || _settings == ModSettings.Empty)
|
||||
if (_inherited || selection.Settings == ModSettings.Empty)
|
||||
return;
|
||||
|
||||
var scroll = ImGui.GetScrollMaxY() > 0 ? ImGui.GetStyle().ScrollbarSize : 0;
|
||||
ImGui.SameLine(ImGui.GetWindowWidth() - ImGui.CalcTextSize(text).X - ImGui.GetStyle().FramePadding.X * 2 - scroll);
|
||||
if (ImGui.Button(text))
|
||||
collectionManager.Editor.SetModInheritance(collectionManager.Active.Current, selector.Selected!, true);
|
||||
collectionManager.Editor.SetModInheritance(collectionManager.Active.Current, selection.Mod!, true);
|
||||
|
||||
ImGuiUtil.HoverTooltip("Remove current settings from this collection so that it can inherit them.\n"
|
||||
+ "If no inherited collection has settings for this mod, it will be disabled.");
|
||||
|
|
|
|||
|
|
@ -82,8 +82,7 @@ public class ModsTab(
|
|||
+ $"{selector.SortMode.Name} Sort Mode\n"
|
||||
+ $"{selector.SelectedLeaf?.Name ?? "NULL"} Selected Leaf\n"
|
||||
+ $"{selector.Selected?.Name ?? "NULL"} Selected Mod\n"
|
||||
+ $"{string.Join(", ", _activeCollections.Current.DirectlyInheritsFrom.Select(c => c.AnonymizedName))} Inheritances\n"
|
||||
+ $"{selector.SelectedSettingCollection.AnonymizedName} Collection\n");
|
||||
+ $"{string.Join(", ", _activeCollections.Current.DirectlyInheritsFrom.Select(c => c.AnonymizedName))} Inheritances\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue