Add option to always work in temporary settings.

This commit is contained in:
Ottermandias 2025-02-17 17:39:41 +01:00
parent b7b9defaa6
commit a561e70410
7 changed files with 72 additions and 32 deletions

View file

@ -70,6 +70,7 @@ public class Configuration : IPluginConfiguration, ISavable, IService
public bool HidePrioritiesInSelector { get; set; } = false; public bool HidePrioritiesInSelector { get; set; } = false;
public bool HideRedrawBar { get; set; } = false; public bool HideRedrawBar { get; set; } = false;
public bool HideMachinistOffhandFromChangedItems { get; set; } = true; public bool HideMachinistOffhandFromChangedItems { get; set; } = true;
public bool DefaultTemporaryMode { get; set; } = false;
public RenameField ShowRename { get; set; } = RenameField.BothDataPrio; public RenameField ShowRename { get; set; } = RenameField.BothDataPrio;
public int OptionGroupCollapsibleMin { get; set; } = 5; public int OptionGroupCollapsibleMin { get; set; } = 5;

View file

@ -2,6 +2,7 @@ namespace Penumbra.Mods.Settings;
public sealed class TemporaryModSettings : ModSettings public sealed class TemporaryModSettings : ModSettings
{ {
public const string OwnSource = "yourself";
public string Source = string.Empty; public string Source = string.Empty;
public int Lock = 0; public int Lock = 0;
public bool ForceInherit; public bool ForceInherit;
@ -20,7 +21,7 @@ public sealed class TemporaryModSettings : ModSettings
public TemporaryModSettings() public TemporaryModSettings()
{ } { }
public TemporaryModSettings(Mod mod, ModSettings? clone, string source, int key = 0) public TemporaryModSettings(Mod mod, ModSettings? clone, string source = OwnSource, int key = 0)
{ {
Source = source; Source = source;
Lock = key; Lock = key;

View file

@ -1,7 +1,10 @@
using Dalamud.Interface;
using ImGuiNET; using ImGuiNET;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui; using OtterGui;
using OtterGui.Services; using OtterGui.Services;
using OtterGui.Text;
using OtterGui.Text.Widget;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Collections.Manager; using Penumbra.Collections.Manager;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
@ -17,13 +20,16 @@ public class CollectionSelectHeader : IUiService
private readonly TutorialService _tutorial; private readonly TutorialService _tutorial;
private readonly ModSelection _selection; private readonly ModSelection _selection;
private readonly CollectionResolver _resolver; private readonly CollectionResolver _resolver;
private readonly FontAwesomeCheckbox _temporaryCheckbox = new(FontAwesomeIcon.Stopwatch);
private readonly Configuration _config;
public CollectionSelectHeader(CollectionManager collectionManager, TutorialService tutorial, ModSelection selection, public CollectionSelectHeader(CollectionManager collectionManager, TutorialService tutorial, ModSelection selection,
CollectionResolver resolver) CollectionResolver resolver, Configuration config)
{ {
_tutorial = tutorial; _tutorial = tutorial;
_selection = selection; _selection = selection;
_resolver = resolver; _resolver = resolver;
_config = config;
_activeCollections = collectionManager.Active; _activeCollections = collectionManager.Active;
_collectionCombo = new CollectionCombo(collectionManager, () => collectionManager.Storage.OrderBy(c => c.Identity.Name).ToList()); _collectionCombo = new CollectionCombo(collectionManager, () => collectionManager.Storage.OrderBy(c => c.Identity.Name).ToList());
} }
@ -33,6 +39,8 @@ public class CollectionSelectHeader : IUiService
{ {
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0) using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0)
.Push(ImGuiStyleVar.ItemSpacing, new Vector2(0, spacing ? ImGui.GetStyle().ItemSpacing.Y : 0)); .Push(ImGuiStyleVar.ItemSpacing, new Vector2(0, spacing ? ImGui.GetStyle().ItemSpacing.Y : 0));
DrawTemporaryCheckbox();
ImGui.SameLine();
var comboWidth = ImGui.GetContentRegionAvail().X / 4f; var comboWidth = ImGui.GetContentRegionAvail().X / 4f;
var buttonSize = new Vector2(comboWidth * 3f / 4f, 0f); var buttonSize = new Vector2(comboWidth * 3f / 4f, 0f);
using (var _ = ImRaii.Group()) using (var _ = ImRaii.Group())
@ -51,6 +59,29 @@ public class CollectionSelectHeader : IUiService
ImGuiUtil.DrawTextButton("The currently selected collection is not used in any way.", -Vector2.UnitX, Colors.PressEnterWarningBg); ImGuiUtil.DrawTextButton("The currently selected collection is not used in any way.", -Vector2.UnitX, Colors.PressEnterWarningBg);
} }
private void DrawTemporaryCheckbox()
{
var hold = _config.DeleteModModifier.IsActive();
using (ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImUtf8.GlobalScale))
{
var tint = ImGuiCol.Text.Tinted(ColorId.TemporaryModSettingsTint);
using var color = ImRaii.PushColor(ImGuiCol.FrameBgHovered, ImGui.GetColorU32(ImGuiCol.FrameBg), !hold)
.Push(ImGuiCol.FrameBgActive, ImGui.GetColorU32(ImGuiCol.FrameBg), !hold)
.Push(ImGuiCol.CheckMark, tint)
.Push(ImGuiCol.Border, tint, _config.DefaultTemporaryMode);
if (_temporaryCheckbox.Draw("##tempCheck"u8, _config.DefaultTemporaryMode, out var newValue) && hold)
{
_config.DefaultTemporaryMode = newValue;
_config.Save();
}
}
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled,
"Toggle the temporary settings mode, where all changes you do create temporary settings first and need to be made permanent if desired.\n"u8);
if (!hold)
ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {_config.DeleteModModifier} while clicking to toggle.");
}
private enum CollectionState private enum CollectionState
{ {
Empty, Empty,

View file

@ -20,6 +20,7 @@ public sealed class ModGroupDrawer(Configuration config, CollectionManager colle
private bool _temporary; private bool _temporary;
private bool _locked; private bool _locked;
private TemporaryModSettings? _tempSettings; private TemporaryModSettings? _tempSettings;
private ModSettings? _settings;
public void Draw(Mod mod, ModSettings settings, TemporaryModSettings? tempSettings) public void Draw(Mod mod, ModSettings settings, TemporaryModSettings? tempSettings)
{ {
@ -27,6 +28,7 @@ public sealed class ModGroupDrawer(Configuration config, CollectionManager colle
return; return;
_blockGroupCache.Clear(); _blockGroupCache.Clear();
_settings = settings;
_tempSettings = tempSettings; _tempSettings = tempSettings;
_temporary = tempSettings != null; _temporary = tempSettings != null;
_locked = (tempSettings?.Lock ?? 0) > 0; _locked = (tempSettings?.Lock ?? 0) > 0;
@ -242,8 +244,9 @@ public sealed class ModGroupDrawer(Configuration config, CollectionManager colle
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private void SetModSetting(IModGroup group, int groupIdx, Setting setting) private void SetModSetting(IModGroup group, int groupIdx, Setting setting)
{ {
if (_temporary) if (_temporary || config.DefaultTemporaryMode)
{ {
_tempSettings ??= new TemporaryModSettings(group.Mod, _settings);
_tempSettings!.ForceInherit = false; _tempSettings!.ForceInherit = false;
_tempSettings!.Settings[groupIdx] = setting; _tempSettings!.Settings[groupIdx] = setting;
collectionManager.Editor.SetTemporarySettings(Current, group.Mod, _tempSettings); collectionManager.Editor.SetTemporarySettings(Current, group.Mod, _tempSettings);

View file

@ -274,7 +274,6 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
private void DrawTemporaryOptions(FileSystem<Mod>.Leaf mod) private void DrawTemporaryOptions(FileSystem<Mod>.Leaf mod)
{ {
const string source = "yourself";
var tempSettings = _collectionManager.Active.Current.GetTempSettings(mod.Value.Index); var tempSettings = _collectionManager.Active.Current.GetTempSettings(mod.Value.Index);
if (tempSettings is { Lock: > 0 }) if (tempSettings is { Lock: > 0 })
return; return;
@ -284,19 +283,19 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
var actual = _collectionManager.Active.Current.GetActualSettings(mod.Value.Index).Settings; var actual = _collectionManager.Active.Current.GetActualSettings(mod.Value.Index).Settings;
if (actual?.Enabled is true && ImUtf8.MenuItem("Disable Temporarily"u8)) if (actual?.Enabled is true && ImUtf8.MenuItem("Disable Temporarily"u8))
_collectionManager.Editor.SetTemporarySettings(_collectionManager.Active.Current, mod.Value, _collectionManager.Editor.SetTemporarySettings(_collectionManager.Active.Current, mod.Value,
new TemporaryModSettings(mod.Value, actual, source) { Enabled = false }); new TemporaryModSettings(mod.Value, actual) { Enabled = false });
if (actual is not { Enabled: true } && ImUtf8.MenuItem("Enable Temporarily"u8)) if (actual is not { Enabled: true } && ImUtf8.MenuItem("Enable Temporarily"u8))
{ {
var newSettings = actual is null var newSettings = actual is null
? TemporaryModSettings.DefaultSettings(mod.Value, source, true) ? TemporaryModSettings.DefaultSettings(mod.Value, TemporaryModSettings.OwnSource, true)
: new TemporaryModSettings(mod.Value, actual, source) { Enabled = true }; : new TemporaryModSettings(mod.Value, actual) { Enabled = true };
_collectionManager.Editor.SetTemporarySettings(_collectionManager.Active.Current, mod.Value, newSettings); _collectionManager.Editor.SetTemporarySettings(_collectionManager.Active.Current, mod.Value, newSettings);
} }
if (tempSettings is null && ImUtf8.MenuItem("Turn Temporary"u8)) if (tempSettings is null && ImUtf8.MenuItem("Turn Temporary"u8))
_collectionManager.Editor.SetTemporarySettings(_collectionManager.Active.Current, mod.Value, _collectionManager.Editor.SetTemporarySettings(_collectionManager.Active.Current, mod.Value,
new TemporaryModSettings(mod.Value, actual, source)); new TemporaryModSettings(mod.Value, actual));
} }
private void SetDefaultImportFolder(ModFileSystem.Folder folder) private void SetDefaultImportFolder(ModFileSystem.Folder folder)

View file

@ -120,11 +120,12 @@ public class ModPanelSettingsTab(
return; return;
modManager.SetKnown(selection.Mod!); modManager.SetKnown(selection.Mod!);
if (_temporary) if (_temporary || config.DefaultTemporaryMode)
{ {
selection.TemporarySettings!.ForceInherit = false; var temporarySettings = selection.TemporarySettings ?? new TemporaryModSettings(selection.Mod!, selection.Settings);
selection.TemporarySettings!.Enabled = enabled; temporarySettings.ForceInherit = false;
collectionManager.Editor.SetTemporarySettings(collectionManager.Active.Current, selection.Mod!, selection.TemporarySettings); temporarySettings.Enabled = enabled;
collectionManager.Editor.SetTemporarySettings(collectionManager.Active.Current, selection.Mod!, temporarySettings);
} }
else else
{ {
@ -154,12 +155,13 @@ public class ModPanelSettingsTab(
{ {
if (_currentPriority != settings.Priority.Value) if (_currentPriority != settings.Priority.Value)
{ {
if (_temporary) if (_temporary || config.DefaultTemporaryMode)
{ {
selection.TemporarySettings!.ForceInherit = false; var temporarySettings = selection.TemporarySettings ?? new TemporaryModSettings(selection.Mod!, selection.Settings);
selection.TemporarySettings!.Priority = new ModPriority(_currentPriority.Value); temporarySettings.ForceInherit = false;
temporarySettings.Priority = new ModPriority(_currentPriority.Value);
collectionManager.Editor.SetTemporarySettings(collectionManager.Active.Current, selection.Mod!, collectionManager.Editor.SetTemporarySettings(collectionManager.Active.Current, selection.Mod!,
selection.TemporarySettings); temporarySettings);
} }
else else
{ {
@ -205,11 +207,12 @@ public class ModPanelSettingsTab(
}; };
if (inherit) if (inherit)
{ {
if (_temporary) if (_temporary || config.DefaultTemporaryMode)
{ {
selection.TemporarySettings!.ForceInherit = true; var temporarySettings = selection.TemporarySettings ?? new TemporaryModSettings(selection.Mod!, selection.Settings);
temporarySettings.ForceInherit = true;
collectionManager.Editor.SetTemporarySettings(collectionManager.Active.Current, selection.Mod!, collectionManager.Editor.SetTemporarySettings(collectionManager.Active.Current, selection.Mod!,
selection.TemporarySettings); temporarySettings);
} }
else else
{ {
@ -252,7 +255,7 @@ public class ModPanelSettingsTab(
var actual = collectionManager.Active.Current.GetActualSettings(selection.Mod!.Index).Settings; var actual = collectionManager.Active.Current.GetActualSettings(selection.Mod!.Index).Settings;
if (ImUtf8.ButtonEx("Turn Temporary"u8, "Copy the current settings over to temporary settings to experiment with them."u8)) if (ImUtf8.ButtonEx("Turn Temporary"u8, "Copy the current settings over to temporary settings to experiment with them."u8))
collectionManager.Editor.SetTemporarySettings(collectionManager.Active.Current, selection.Mod!, collectionManager.Editor.SetTemporarySettings(collectionManager.Active.Current, selection.Mod!,
new TemporaryModSettings(selection.Mod!, actual, "yourself")); new TemporaryModSettings(selection.Mod!, actual));
} }
} }
} }

View file

@ -430,7 +430,6 @@ public class SettingsTab : ITab, IUiService
Checkbox("Automatically Select Character-Associated Collection", Checkbox("Automatically Select Character-Associated Collection",
"On every login, automatically select the collection associated with the current character as the current collection for editing.", "On every login, automatically select the collection associated with the current character as the current collection for editing.",
_config.AutoSelectCollection, _autoSelector.SetAutomaticSelection); _config.AutoSelectCollection, _autoSelector.SetAutomaticSelection);
Checkbox("Print Chat Command Success Messages to Chat", Checkbox("Print Chat Command Success Messages to Chat",
"Chat Commands usually print messages on failure but also on success to confirm your action. You can disable this here.", "Chat Commands usually print messages on failure but also on success to confirm your action. You can disable this here.",
_config.PrintSuccessfulCommandsToChat, v => _config.PrintSuccessfulCommandsToChat = v); _config.PrintSuccessfulCommandsToChat, v => _config.PrintSuccessfulCommandsToChat = v);
@ -618,6 +617,9 @@ public class SettingsTab : ITab, IUiService
/// <summary> Draw all settings pertaining to import and export of mods. </summary> /// <summary> Draw all settings pertaining to import and export of mods. </summary>
private void DrawModHandlingSettings() private void DrawModHandlingSettings()
{ {
Checkbox("Use Temporary Settings Per Default",
"When you make any changes to your collection, apply them as temporary changes first and require a click to 'turn permanent' if you want to keep them.",
_config.DefaultTemporaryMode, v => _config.DefaultTemporaryMode = v);
Checkbox("Replace Non-Standard Symbols On Import", Checkbox("Replace Non-Standard Symbols On Import",
"Replace all non-ASCII symbols in mod and option names with underscores when importing mods.", _config.ReplaceNonAsciiOnImport, "Replace all non-ASCII symbols in mod and option names with underscores when importing mods.", _config.ReplaceNonAsciiOnImport,
v => _config.ReplaceNonAsciiOnImport = v); v => _config.ReplaceNonAsciiOnImport = v);