Add collection select headers to Changed Items and Effective Changes.

This commit is contained in:
Ottermandias 2023-04-29 13:12:58 +02:00
parent 2402d0aa6f
commit 290912e7cd
5 changed files with 123 additions and 84 deletions

View file

@ -16,6 +16,7 @@ using Penumbra.Mods;
using Penumbra.Mods.Manager; using Penumbra.Mods.Manager;
using Penumbra.UI; using Penumbra.UI;
using Penumbra.UI.AdvancedWindow; using Penumbra.UI.AdvancedWindow;
using Penumbra.UI.Classes;
using Penumbra.UI.ModsTab; using Penumbra.UI.ModsTab;
using Penumbra.UI.Tabs; using Penumbra.UI.Tabs;
@ -139,6 +140,7 @@ public static class ServiceManager
.AddSingleton<ModsTab>() .AddSingleton<ModsTab>()
.AddSingleton<ModPanel>() .AddSingleton<ModPanel>()
.AddSingleton<ModFileSystemSelector>() .AddSingleton<ModFileSystemSelector>()
.AddSingleton<CollectionSelectHeader>()
.AddSingleton<ImportPopup>() .AddSingleton<ImportPopup>()
.AddSingleton<ModPanelDescriptionTab>() .AddSingleton<ModPanelDescriptionTab>()
.AddSingleton<ModPanelSettingsTab>() .AddSingleton<ModPanelSettingsTab>()

View file

@ -0,0 +1,76 @@
using System.Linq;
using System.Numerics;
using ImGuiNET;
using OtterGui.Raii;
using OtterGui;
using Penumbra.Collections;
using Penumbra.Collections.Manager;
using Penumbra.UI.CollectionTab;
using Penumbra.UI.ModsTab;
namespace Penumbra.UI.Classes;
public class CollectionSelectHeader
{
private readonly CollectionCombo _collectionCombo;
private readonly ActiveCollections _activeCollections;
private readonly TutorialService _tutorial;
private readonly ModFileSystemSelector _selector;
public CollectionSelectHeader(CollectionManager collectionManager, TutorialService tutorial, ModFileSystemSelector selector)
{
_tutorial = tutorial;
_selector = selector;
_activeCollections = collectionManager.Active;
_collectionCombo = new CollectionCombo(collectionManager, () => collectionManager.Storage.OrderBy(c => c.Name).ToList());
}
/// <summary> Draw the header line that can quick switch between collections. </summary>
public void Draw(bool spacing)
{
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0).Push(ImGuiStyleVar.ItemSpacing, new Vector2(0, spacing ? ImGui.GetStyle().ItemSpacing.Y : 0));
var buttonSize = new Vector2(ImGui.GetContentRegionAvail().X / 8f, 0);
using (var _ = ImRaii.Group())
{
DrawDefaultCollectionButton(3 * buttonSize);
ImGui.SameLine();
DrawInheritedCollectionButton(3 * buttonSize);
ImGui.SameLine();
_collectionCombo.Draw("##collectionSelector", 2 * buttonSize.X, ColorId.SelectedCollection.Value());
}
_tutorial.OpenTutorial(BasicTutorialSteps.CollectionSelectors);
if (!_activeCollections.CurrentCollectionInUse)
ImGuiUtil.DrawTextButton("The currently selected collection is not used in any way.", -Vector2.UnitX, Colors.PressEnterWarningBg);
}
private void DrawDefaultCollectionButton(Vector2 width)
{
var name = $"{TutorialService.DefaultCollection} ({_activeCollections.Default.Name})";
var isCurrent = _activeCollections.Default == _activeCollections.Current;
var isEmpty = _activeCollections.Default == ModCollection.Empty;
var tt = isCurrent ? $"The current collection is already the configured {TutorialService.DefaultCollection}."
: isEmpty ? $"The {TutorialService.DefaultCollection} is configured to be empty."
: $"Set the {TutorialService.SelectedCollection} to the configured {TutorialService.DefaultCollection}.";
if (ImGuiUtil.DrawDisabledButton(name, width, tt, isCurrent || isEmpty))
_activeCollections.SetCollection(_activeCollections.Default, CollectionType.Current);
}
private void DrawInheritedCollectionButton(Vector2 width)
{
var noModSelected = _selector.Selected == null;
var collection = _selector.SelectedSettingCollection;
var modInherited = collection != _activeCollections.Current;
var (name, tt) = (noModSelected, modInherited) switch
{
(true, _) => ("Inherited Collection", "No mod selected."),
(false, true) => ($"Inherited Collection ({collection.Name})",
"Set the current collection to the collection the selected mod inherits its settings from."),
(false, false) => ("Not Inherited", "The selected mod does not inherit its settings."),
};
if (ImGuiUtil.DrawDisabledButton(name, width, tt, noModSelected || !modInherited))
_activeCollections.SetCollection(collection, CollectionType.Current);
}
}

View file

@ -16,13 +16,15 @@ namespace Penumbra.UI.Tabs;
public class ChangedItemsTab : ITab public class ChangedItemsTab : ITab
{ {
private readonly CollectionManager _collectionManager; private readonly CollectionManager _collectionManager;
private readonly CommunicatorService _communicator; private readonly CommunicatorService _communicator;
private readonly CollectionSelectHeader _collectionHeader;
public ChangedItemsTab(CollectionManager collectionManager, CommunicatorService communicator) public ChangedItemsTab(CollectionManager collectionManager, CommunicatorService communicator, CollectionSelectHeader collectionHeader)
{ {
_collectionManager = collectionManager; _collectionManager = collectionManager;
_communicator = communicator; _communicator = communicator;
_collectionHeader = collectionHeader;
} }
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
@ -32,7 +34,8 @@ public class ChangedItemsTab : ITab
private LowerString _changedItemModFilter = LowerString.Empty; private LowerString _changedItemModFilter = LowerString.Empty;
public void DrawContent() public void DrawContent()
{ {
_collectionHeader.Draw(true);
var varWidth = DrawFilters(); var varWidth = DrawFilters();
using var child = ImRaii.Child("##changedItemsChild", -Vector2.One); using var child = ImRaii.Child("##changedItemsChild", -Vector2.One);
if (!child) if (!child)

View file

@ -9,41 +9,47 @@ using OtterGui.Classes;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Collections.Cache; using Penumbra.Collections.Cache;
using Penumbra.Collections.Manager; using Penumbra.Collections.Manager;
using Penumbra.Meta.Manipulations; using Penumbra.Meta.Manipulations;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.UI.Classes;
namespace Penumbra.UI.Tabs; namespace Penumbra.UI.Tabs;
public class EffectiveTab : ITab public class EffectiveTab : ITab
{ {
private readonly CollectionManager _collectionManager; private readonly CollectionManager _collectionManager;
private readonly CollectionSelectHeader _collectionHeader;
public EffectiveTab(CollectionManager collectionManager)
=> _collectionManager = collectionManager; public EffectiveTab(CollectionManager collectionManager, CollectionSelectHeader collectionHeader)
{
_collectionManager = collectionManager;
_collectionHeader = collectionHeader;
}
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
=> "Effective Changes"u8; => "Effective Changes"u8;
public void DrawContent() public void DrawContent()
{ {
SetupEffectiveSizes(); SetupEffectiveSizes();
_collectionHeader.Draw(true);
DrawFilters(); DrawFilters();
using var child = ImRaii.Child("##EffectiveChangesTab", -Vector2.One, false); using var child = ImRaii.Child("##EffectiveChangesTab", -Vector2.One, false);
if (!child) if (!child)
return; return;
var height = ImGui.GetTextLineHeightWithSpacing() + 2 * ImGui.GetStyle().CellPadding.Y; var height = ImGui.GetTextLineHeightWithSpacing() + 2 * ImGui.GetStyle().CellPadding.Y;
var skips = ImGuiClip.GetNecessarySkips(height); var skips = ImGuiClip.GetNecessarySkips(height);
using var table = ImRaii.Table("##EffectiveChangesTable", 3, ImGuiTableFlags.RowBg); using var table = ImRaii.Table("##EffectiveChangesTable", 3, ImGuiTableFlags.RowBg);
if (!table) if (!table)
return; return;
ImGui.TableSetupColumn("##gamePath", ImGuiTableColumnFlags.WidthFixed, _effectiveLeftTextLength); ImGui.TableSetupColumn("##gamePath", ImGuiTableColumnFlags.WidthFixed, _effectiveLeftTextLength);
ImGui.TableSetupColumn(string.Empty, ImGuiTableColumnFlags.WidthFixed, _effectiveArrowLength); ImGui.TableSetupColumn(string.Empty, ImGuiTableColumnFlags.WidthFixed, _effectiveArrowLength);
ImGui.TableSetupColumn("##file", ImGuiTableColumnFlags.WidthFixed, _effectiveRightTextLength); ImGui.TableSetupColumn("##file", ImGuiTableColumnFlags.WidthFixed, _effectiveRightTextLength);
DrawEffectiveRows(_collectionManager.Active.Current, skips, height, DrawEffectiveRows(_collectionManager.Active.Current, skips, height,
_effectiveFilePathFilter.Length > 0 || _effectiveGamePathFilter.Length > 0); _effectiveFilePathFilter.Length > 0 || _effectiveGamePathFilter.Length > 0);
@ -69,8 +75,8 @@ public class EffectiveTab : ITab
ImGui.CalcTextSize(FontAwesomeIcon.LongArrowAltLeft.ToIconString()).X / UiHelpers.Scale; ImGui.CalcTextSize(FontAwesomeIcon.LongArrowAltLeft.ToIconString()).X / UiHelpers.Scale;
} }
_effectiveArrowLength = _effectiveUnscaledArrowLength * UiHelpers.Scale; _effectiveArrowLength = _effectiveUnscaledArrowLength * UiHelpers.Scale;
_effectiveLeftTextLength = 450 * UiHelpers.Scale; _effectiveLeftTextLength = 450 * UiHelpers.Scale;
_effectiveRightTextLength = ImGui.GetWindowSize().X - _effectiveArrowLength - _effectiveLeftTextLength; _effectiveRightTextLength = ImGui.GetWindowSize().X - _effectiveArrowLength - _effectiveLeftTextLength;
} }
@ -89,7 +95,7 @@ public class EffectiveTab : ITab
_effectiveFilePathFilter = tmp; _effectiveFilePathFilter = tmp;
} }
/// <summary> Draw all rows for one collection respecting filters and using clipping. </summary> /// <summary> Draw all rows for one collection respecting filters and using clipping. </summary>
private void DrawEffectiveRows(ModCollection active, int skips, float height, bool hasFilters) private void DrawEffectiveRows(ModCollection active, int skips, float height, bool hasFilters)
{ {
// We can use the known counts if no filters are active. // We can use the known counts if no filters are active.
@ -134,7 +140,7 @@ public class EffectiveTab : ITab
} }
} }
/// <summary> Draw a line for a game path and its redirected file. </summary> /// <summary> Draw a line for a game path and its redirected file. </summary>
private static void DrawLine(KeyValuePair<Utf8GamePath, ModPath> pair) private static void DrawLine(KeyValuePair<Utf8GamePath, ModPath> pair)
{ {
var (path, name) = pair; var (path, name) = pair;
@ -148,7 +154,7 @@ public class EffectiveTab : ITab
ImGuiUtil.HoverTooltip($"\nChanged by {name.Mod.Name}."); ImGuiUtil.HoverTooltip($"\nChanged by {name.Mod.Name}.");
} }
/// <summary> Draw a line for a path and its name. </summary> /// <summary> Draw a line for a path and its name. </summary>
private static void DrawLine((string, LowerString) pair) private static void DrawLine((string, LowerString) pair)
{ {
var (path, name) = pair; var (path, name) = pair;
@ -161,7 +167,7 @@ public class EffectiveTab : ITab
ImGuiUtil.CopyOnClickSelectable(name); ImGuiUtil.CopyOnClickSelectable(name);
} }
/// <summary> Draw a line for a unfiltered/unconverted manipulation and mod-index pair. </summary> /// <summary> Draw a line for a unfiltered/unconverted manipulation and mod-index pair. </summary>
private static void DrawLine(KeyValuePair<MetaManipulation, IMod> pair) private static void DrawLine(KeyValuePair<MetaManipulation, IMod> pair)
{ {
var (manipulation, mod) = pair; var (manipulation, mod) = pair;
@ -174,7 +180,7 @@ public class EffectiveTab : ITab
ImGuiUtil.CopyOnClickSelectable(mod.Name); ImGuiUtil.CopyOnClickSelectable(mod.Name);
} }
/// <summary> Check filters for file replacements. </summary> /// <summary> Check filters for file replacements. </summary>
private bool CheckFilters(KeyValuePair<Utf8GamePath, ModPath> kvp) private bool CheckFilters(KeyValuePair<Utf8GamePath, ModPath> kvp)
{ {
var (gamePath, fullPath) = kvp; var (gamePath, fullPath) = kvp;
@ -184,7 +190,7 @@ public class EffectiveTab : ITab
return _effectiveFilePathFilter.Length == 0 || fullPath.Path.FullName.ToLowerInvariant().Contains(_effectiveFilePathFilter.Lower); return _effectiveFilePathFilter.Length == 0 || fullPath.Path.FullName.ToLowerInvariant().Contains(_effectiveFilePathFilter.Lower);
} }
/// <summary> Check filters for meta manipulations. </summary> /// <summary> Check filters for meta manipulations. </summary>
private bool CheckFilters((string, LowerString) kvp) private bool CheckFilters((string, LowerString) kvp)
{ {
var (name, path) = kvp; var (name, path) = kvp;

View file

@ -23,18 +23,19 @@ namespace Penumbra.UI.Tabs;
public class ModsTab : ITab public class ModsTab : ITab
{ {
private readonly ModFileSystemSelector _selector; private readonly ModFileSystemSelector _selector;
private readonly ModPanel _panel; private readonly ModPanel _panel;
private readonly TutorialService _tutorial; private readonly TutorialService _tutorial;
private readonly ModManager _modManager; private readonly ModManager _modManager;
private readonly ActiveCollections _activeCollections; private readonly ActiveCollections _activeCollections;
private readonly RedrawService _redrawService; private readonly RedrawService _redrawService;
private readonly Configuration _config; private readonly Configuration _config;
private readonly CollectionCombo _collectionCombo; private readonly ClientState _clientState;
private readonly ClientState _clientState; private readonly CollectionSelectHeader _collectionHeader;
public ModsTab(ModManager modManager, CollectionManager collectionManager, ModFileSystemSelector selector, ModPanel panel, public ModsTab(ModManager modManager, CollectionManager collectionManager, ModFileSystemSelector selector, ModPanel panel,
TutorialService tutorial, RedrawService redrawService, Configuration config, ClientState clientState) TutorialService tutorial, RedrawService redrawService, Configuration config, ClientState clientState,
CollectionSelectHeader collectionHeader)
{ {
_modManager = modManager; _modManager = modManager;
_activeCollections = collectionManager.Active; _activeCollections = collectionManager.Active;
@ -44,7 +45,7 @@ public class ModsTab : ITab
_redrawService = redrawService; _redrawService = redrawService;
_config = config; _config = config;
_clientState = clientState; _clientState = clientState;
_collectionCombo = new CollectionCombo(collectionManager, () => collectionManager.Storage.OrderBy(c => c.Name).ToList()); _collectionHeader = collectionHeader;
} }
public bool IsVisible public bool IsVisible
@ -68,7 +69,7 @@ public class ModsTab : ITab
_selector.Draw(GetModSelectorSize(_config)); _selector.Draw(GetModSelectorSize(_config));
ImGui.SameLine(); ImGui.SameLine();
using var group = ImRaii.Group(); using var group = ImRaii.Group();
DrawHeaderLine(); _collectionHeader.Draw(false);
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
@ -162,53 +163,4 @@ public class ModsTab : ITab
ImGui.SameLine(); ImGui.SameLine();
DrawButton(frameHeight with { X = ImGui.GetContentRegionAvail().X - 1 }, "Focus", "focus"); DrawButton(frameHeight with { X = ImGui.GetContentRegionAvail().X - 1 }, "Focus", "focus");
} }
/// <summary> Draw the header line that can quick switch between collections. </summary>
private void DrawHeaderLine()
{
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 0).Push(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
var buttonSize = new Vector2(ImGui.GetContentRegionAvail().X / 8f, 0);
using (var _ = ImRaii.Group())
{
DrawDefaultCollectionButton(3 * buttonSize);
ImGui.SameLine();
DrawInheritedCollectionButton(3 * buttonSize);
ImGui.SameLine();
_collectionCombo.Draw("##collectionSelector", 2 * buttonSize.X, ColorId.SelectedCollection.Value());
}
_tutorial.OpenTutorial(BasicTutorialSteps.CollectionSelectors);
if (!_activeCollections.CurrentCollectionInUse)
ImGuiUtil.DrawTextButton("The currently selected collection is not used in any way.", -Vector2.UnitX, Colors.PressEnterWarningBg);
}
private void DrawDefaultCollectionButton(Vector2 width)
{
var name = $"{TutorialService.DefaultCollection} ({_activeCollections.Default.Name})";
var isCurrent = _activeCollections.Default == _activeCollections.Current;
var isEmpty = _activeCollections.Default == ModCollection.Empty;
var tt = isCurrent ? $"The current collection is already the configured {TutorialService.DefaultCollection}."
: isEmpty ? $"The {TutorialService.DefaultCollection} is configured to be empty."
: $"Set the {TutorialService.SelectedCollection} to the configured {TutorialService.DefaultCollection}.";
if (ImGuiUtil.DrawDisabledButton(name, width, tt, isCurrent || isEmpty))
_activeCollections.SetCollection(_activeCollections.Default, CollectionType.Current);
}
private void DrawInheritedCollectionButton(Vector2 width)
{
var noModSelected = _selector.Selected == null;
var collection = _selector.SelectedSettingCollection;
var modInherited = collection != _activeCollections.Current;
var (name, tt) = (noModSelected, modInherited) switch
{
(true, _) => ("Inherited Collection", "No mod selected."),
(false, true) => ($"Inherited Collection ({collection.Name})",
"Set the current collection to the collection the selected mod inherits its settings from."),
(false, false) => ("Not Inherited", "The selected mod does not inherit its settings."),
};
if (ImGuiUtil.DrawDisabledButton(name, width, tt, noModSelected || !modInherited))
_activeCollections.SetCollection(collection, CollectionType.Current);
}
} }