Allow configuration of the changed item display.

This commit is contained in:
Ottermandias 2025-03-01 16:55:50 +01:00
parent 26985e01a2
commit 13adbd5466
4 changed files with 144 additions and 26 deletions

View file

@ -0,0 +1,57 @@
using ImGuiNET;
using OtterGui.Text;
namespace Penumbra;
public enum ChangedItemMode
{
GroupedCollapsed,
GroupedExpanded,
Alphabetical,
}
public static class ChangedItemModeExtensions
{
public static ReadOnlySpan<byte> ToName(this ChangedItemMode mode)
=> mode switch
{
ChangedItemMode.GroupedCollapsed => "Grouped (Collapsed)"u8,
ChangedItemMode.GroupedExpanded => "Grouped (Expanded)"u8,
ChangedItemMode.Alphabetical => "Alphabetical"u8,
_ => "Error"u8,
};
public static ReadOnlySpan<byte> ToTooltip(this ChangedItemMode mode)
=> mode switch
{
ChangedItemMode.GroupedCollapsed =>
"Display items as groups by their model and slot. Collapse those groups to a single item by default. Prefers items with more changes affecting them or configured items as the main item."u8,
ChangedItemMode.GroupedExpanded =>
"Display items as groups by their model and slot. Expand those groups showing all items by default. Prefers items with more changes affecting them or configured items as the main item."u8,
ChangedItemMode.Alphabetical => "Display all changed items in a single list sorted alphabetically."u8,
_ => ""u8,
};
public static bool DrawCombo(ReadOnlySpan<byte> label, ChangedItemMode value, float width, Action<ChangedItemMode> setter)
{
ImGui.SetNextItemWidth(width);
using var combo = ImUtf8.Combo(label, value.ToName());
if (!combo)
return false;
var ret = false;
foreach (var newValue in Enum.GetValues<ChangedItemMode>())
{
var selected = ImUtf8.Selectable(newValue.ToName(), newValue == value);
if (selected)
{
ret = true;
setter(newValue);
}
ImUtf8.HoverTooltip(newValue.ToTooltip());
}
return ret;
}
}

View file

@ -39,11 +39,7 @@ public class Configuration : IPluginConfiguration, ISavable, IService
public bool EnableMods public bool EnableMods
{ {
get => _enableMods; get => _enableMods;
set set => SetField(ref _enableMods, value, ModsEnabled);
{
_enableMods = value;
ModsEnabled?.Invoke(value);
}
} }
public string ModDirectory { get; set; } = string.Empty; public string ModDirectory { get; set; } = string.Empty;
@ -58,21 +54,22 @@ public class Configuration : IPluginConfiguration, ISavable, IService
public bool AutoSelectCollection { get; set; } = false; public bool AutoSelectCollection { get; set; } = false;
public bool ShowModsInLobby { get; set; } = true; public bool ShowModsInLobby { get; set; } = true;
public bool UseCharacterCollectionInMainWindow { get; set; } = true; public bool UseCharacterCollectionInMainWindow { get; set; } = true;
public bool UseCharacterCollectionsInCards { get; set; } = true; public bool UseCharacterCollectionsInCards { get; set; } = true;
public bool UseCharacterCollectionInInspect { get; set; } = true; public bool UseCharacterCollectionInInspect { get; set; } = true;
public bool UseCharacterCollectionInTryOn { get; set; } = true; public bool UseCharacterCollectionInTryOn { get; set; } = true;
public bool UseOwnerNameForCharacterCollection { get; set; } = true; public bool UseOwnerNameForCharacterCollection { get; set; } = true;
public bool UseNoModsInInspect { get; set; } = false; public bool UseNoModsInInspect { get; set; } = false;
public bool HideChangedItemFilters { get; set; } = false; public bool HideChangedItemFilters { get; set; } = false;
public bool ReplaceNonAsciiOnImport { get; set; } = false; public bool ReplaceNonAsciiOnImport { get; set; } = false;
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 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 ChangedItemMode ChangedItemDisplay { get; set; } = ChangedItemMode.GroupedCollapsed;
public int OptionGroupCollapsibleMin { get; set; } = 5;
public Vector2 MinimumSize = new(Constants.MinimumSizeX, Constants.MinimumSizeY); public Vector2 MinimumSize = new(Constants.MinimumSizeX, Constants.MinimumSizeY);
@ -217,4 +214,45 @@ public class Configuration : IPluginConfiguration, ISavable, IService
var serializer = new JsonSerializer { Formatting = Formatting.Indented }; var serializer = new JsonSerializer { Formatting = Formatting.Indented };
serializer.Serialize(jWriter, this); serializer.Serialize(jWriter, this);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private static bool SetField<T>(ref T field, T value, Action<T, T>? @event, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(value))
return false;
var oldValue = field;
field = value;
try
{
@event?.Invoke(oldValue, field);
}
catch (Exception ex)
{
Penumbra.Log.Error($"Error in subscribers updating configuration field {propertyName} from {oldValue} to {field}:\n{ex}");
throw;
}
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private static bool SetField<T>(ref T field, T value, Action<T>? @event, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(value))
return false;
field = value;
try
{
@event?.Invoke(field);
}
catch (Exception ex)
{
Penumbra.Log.Error($"Error in subscribers updating configuration field {propertyName} to {field}:\n{ex}");
throw;
}
return true;
}
} }

View file

@ -18,7 +18,7 @@ public class ModPanelChangedItemsTab(
ModFileSystemSelector selector, ModFileSystemSelector selector,
ChangedItemDrawer drawer, ChangedItemDrawer drawer,
ImGuiCacheService cacheService, ImGuiCacheService cacheService,
EphemeralConfig config) Configuration config)
: ITab, IUiService : ITab, IUiService
{ {
private readonly ImGuiCacheService.CacheId _cacheId = cacheService.GetNewId(); private readonly ImGuiCacheService.CacheId _cacheId = cacheService.GetNewId();
@ -28,6 +28,7 @@ public class ModPanelChangedItemsTab(
private Mod? _lastSelected; private Mod? _lastSelected;
private ushort _lastUpdate; private ushort _lastUpdate;
private ChangedItemIconFlag _filter = ChangedItemFlagExtensions.DefaultFlags; private ChangedItemIconFlag _filter = ChangedItemFlagExtensions.DefaultFlags;
private ChangedItemMode _lastMode;
private bool _reset; private bool _reset;
public readonly List<Container> Data = []; public readonly List<Container> Data = [];
public bool AnyExpandable { get; private set; } public bool AnyExpandable { get; private set; }
@ -90,9 +91,9 @@ public class ModPanelChangedItemsTab(
public void Reset() public void Reset()
=> _reset = true; => _reset = true;
public void Update(Mod? mod, ChangedItemDrawer drawer, ChangedItemIconFlag filter) public void Update(Mod? mod, ChangedItemDrawer drawer, ChangedItemIconFlag filter, ChangedItemMode mode)
{ {
if (mod == _lastSelected && _lastSelected!.LastChangedItemsUpdate == _lastUpdate && _filter == filter && !_reset) if (mod == _lastSelected && _lastSelected!.LastChangedItemsUpdate == _lastUpdate && _filter == filter && !_reset && _lastMode == mode)
return; return;
_reset = false; _reset = false;
@ -100,12 +101,25 @@ public class ModPanelChangedItemsTab(
AnyExpandable = false; AnyExpandable = false;
_lastSelected = mod; _lastSelected = mod;
_filter = filter; _filter = filter;
_lastMode = mode;
if (_lastSelected == null) if (_lastSelected == null)
return; return;
_lastUpdate = _lastSelected.LastChangedItemsUpdate; _lastUpdate = _lastSelected.LastChangedItemsUpdate;
var tmp = new Dictionary<(PrimaryId, FullEquipType), List<IdentifiedItem>>();
if (mode is ChangedItemMode.Alphabetical)
{
foreach (var (s, i) in _lastSelected.ChangedItems)
{
if (drawer.FilterChangedItem(s, i, LowerString.Empty))
Data.Add(Container.Single(s, i));
}
return;
}
var tmp = new Dictionary<(PrimaryId, FullEquipType), List<IdentifiedItem>>();
var defaultExpansion = _lastMode is ChangedItemMode.GroupedExpanded;
foreach (var (s, i) in _lastSelected.ChangedItems) foreach (var (s, i) in _lastSelected.ChangedItems)
{ {
if (i is not IdentifiedItem item) if (i is not IdentifiedItem item)
@ -165,7 +179,7 @@ public class ModPanelChangedItemsTab(
else else
{ {
var id = ImUtf8.GetId($"{mainItem.Item.PrimaryId}{(int)mainItem.Item.Type}"); var id = ImUtf8.GetId($"{mainItem.Item.PrimaryId}{(int)mainItem.Item.Type}");
var expanded = ImGui.GetStateStorage().GetBool(id, false); var expanded = ImGui.GetStateStorage().GetBool(id, defaultExpansion);
Data.Add(Container.Parent(mainItem.Item.Name, mainItem, id, list.Count - 1, expanded)); Data.Add(Container.Parent(mainItem.Item.Name, mainItem, id, list.Count - 1, expanded));
AnyExpandable = true; AnyExpandable = true;
if (!expanded) if (!expanded)
@ -196,7 +210,7 @@ public class ModPanelChangedItemsTab(
drawer.DrawTypeFilter(); drawer.DrawTypeFilter();
_stateStorage = ImGui.GetStateStorage(); _stateStorage = ImGui.GetStateStorage();
cache.Update(selector.Selected, drawer, config.ChangedItemFilter); cache.Update(selector.Selected, drawer, config.Ephemeral.ChangedItemFilter, config.ChangedItemDisplay);
ImGui.Separator(); ImGui.Separator();
_buttonSize = new Vector2(ImGui.GetStyle().ItemSpacing.Y + ImGui.GetFrameHeight()); _buttonSize = new Vector2(ImGui.GetStyle().ItemSpacing.Y + ImGui.GetFrameHeight());
using var style = ImRaii.PushStyle(ImGuiStyleVar.CellPadding, Vector2.Zero) using var style = ImRaii.PushStyle(ImGuiStyleVar.CellPadding, Vector2.Zero)

View file

@ -445,6 +445,15 @@ public class SettingsTab : ITab, IUiService
_config.Ephemeral.Save(); _config.Ephemeral.Save();
} }
}); });
ChangedItemModeExtensions.DrawCombo("##ChangedItemMode"u8, _config.ChangedItemDisplay, UiHelpers.InputTextWidth.X, v =>
{
_config.ChangedItemDisplay = v;
_config.Save();
});
ImUtf8.LabeledHelpMarker("Mod Changed Item Display"u8,
"Configure how to display the changed items of a single mod in the mods info panel."u8);
Checkbox("Omit Machinist Offhands in Changed Items", Checkbox("Omit Machinist Offhands in Changed Items",
"Omits all Aetherotransformers (machinist offhands) in the changed items tabs because any change on them changes all of them at the moment.\n\n" "Omits all Aetherotransformers (machinist offhands) in the changed items tabs because any change on them changes all of them at the moment.\n\n"
+ "Changing this triggers a rediscovery of your mods so all changed items can be updated.", + "Changing this triggers a rediscovery of your mods so all changed items can be updated.",