Make Resource Trees honor Incognito Mode

This commit is contained in:
Exter-N 2024-05-30 23:09:26 +02:00
parent a6661f15e8
commit f4bdbcac53
13 changed files with 123 additions and 75 deletions

View file

@ -15,6 +15,7 @@ namespace Penumbra.Interop.ResourceTree;
public class ResourceTree public class ResourceTree
{ {
public readonly string Name; public readonly string Name;
public readonly string AnonymizedName;
public readonly int GameObjectIndex; public readonly int GameObjectIndex;
public readonly nint GameObjectAddress; public readonly nint GameObjectAddress;
public readonly nint DrawObjectAddress; public readonly nint DrawObjectAddress;
@ -22,6 +23,7 @@ public class ResourceTree
public readonly bool PlayerRelated; public readonly bool PlayerRelated;
public readonly bool Networked; public readonly bool Networked;
public readonly string CollectionName; public readonly string CollectionName;
public readonly string AnonymizedCollectionName;
public readonly List<ResourceNode> Nodes; public readonly List<ResourceNode> Nodes;
public readonly HashSet<ResourceNode> FlatNodes; public readonly HashSet<ResourceNode> FlatNodes;
@ -29,9 +31,10 @@ public class ResourceTree
public CustomizeData CustomizeData; public CustomizeData CustomizeData;
public GenderRace RaceCode; public GenderRace RaceCode;
public ResourceTree(string name, int gameObjectIndex, nint gameObjectAddress, nint drawObjectAddress, bool localPlayerRelated, bool playerRelated, bool networked, string collectionName) public ResourceTree(string name, string anonymizedName, int gameObjectIndex, nint gameObjectAddress, nint drawObjectAddress, bool localPlayerRelated, bool playerRelated, bool networked, string collectionName, string anonymizedCollectionName)
{ {
Name = name; Name = name;
AnonymizedName = anonymizedName;
GameObjectIndex = gameObjectIndex; GameObjectIndex = gameObjectIndex;
GameObjectAddress = gameObjectAddress; GameObjectAddress = gameObjectAddress;
DrawObjectAddress = drawObjectAddress; DrawObjectAddress = drawObjectAddress;
@ -39,6 +42,7 @@ public class ResourceTree
Networked = networked; Networked = networked;
PlayerRelated = playerRelated; PlayerRelated = playerRelated;
CollectionName = collectionName; CollectionName = collectionName;
AnonymizedCollectionName = anonymizedCollectionName;
Nodes = new List<ResourceNode>(); Nodes = new List<ResourceNode>();
FlatNodes = new HashSet<ResourceNode>(); FlatNodes = new HashSet<ResourceNode>();
} }

View file

@ -72,10 +72,10 @@ public class ResourceTreeFactory(
return null; return null;
var localPlayerRelated = cache.IsLocalPlayerRelated(character); var localPlayerRelated = cache.IsLocalPlayerRelated(character);
var (name, related) = GetCharacterName(character, cache); var (name, anonymizedName, related) = GetCharacterName(character);
var networked = character.ObjectId != Dalamud.Game.ClientState.Objects.Types.GameObject.InvalidGameObjectId; var networked = character.ObjectId != Dalamud.Game.ClientState.Objects.Types.GameObject.InvalidGameObjectId;
var tree = new ResourceTree(name, character.ObjectIndex, (nint)gameObjStruct, (nint)drawObjStruct, localPlayerRelated, related, var tree = new ResourceTree(name, anonymizedName, character.ObjectIndex, (nint)gameObjStruct, (nint)drawObjStruct, localPlayerRelated, related,
networked, collectionResolveData.ModCollection.Name); networked, collectionResolveData.ModCollection.Name, collectionResolveData.ModCollection.AnonymizedName);
var globalContext = new GlobalResolveContext(identifier, collectionResolveData.ModCollection, var globalContext = new GlobalResolveContext(identifier, collectionResolveData.ModCollection,
cache, (flags & Flags.WithUiData) != 0); cache, (flags & Flags.WithUiData) != 0);
using (var _ = pathState.EnterInternalResolve()) using (var _ = pathState.EnterInternalResolve())
@ -157,26 +157,29 @@ public class ResourceTreeFactory(
} }
} }
private unsafe (string Name, bool PlayerRelated) GetCharacterName(Dalamud.Game.ClientState.Objects.Types.Character character, private unsafe (string Name, string AnonymizedName, bool PlayerRelated) GetCharacterName(Dalamud.Game.ClientState.Objects.Types.Character character)
TreeBuildCache cache)
{ {
var identifier = actors.FromObject((GameObject*)character.Address, out var owner, true, false, false); var identifier = actors.FromObject((GameObject*)character.Address, out var owner, true, false, false);
switch (identifier.Type) var identifierStr = identifier.ToString();
{ return (identifierStr, identifier.Incognito(identifierStr), IsPlayerRelated(identifier, owner));
case IdentifierType.Player: return (identifier.PlayerName.ToString(), true);
case IdentifierType.Owned:
var ownerChara = objects.Objects.CreateObjectReference(owner) as Dalamud.Game.ClientState.Objects.Types.Character;
if (ownerChara != null)
{
var ownerName = GetCharacterName(ownerChara, cache);
return ($"[{ownerName.Name}] {character.Name} ({identifier.Kind.ToName()})", ownerName.PlayerRelated);
} }
break; private unsafe bool IsPlayerRelated(Dalamud.Game.ClientState.Objects.Types.Character? character)
{
if (character == null)
return false;
var identifier = actors.FromObject((GameObject*)character.Address, out var owner, true, false, false);
return IsPlayerRelated(identifier, owner);
} }
return ($"{character.Name} ({identifier.Kind.ToName()})", false); private bool IsPlayerRelated(ActorIdentifier identifier, Actor owner)
} => identifier.Type switch
{
IdentifierType.Player => true,
IdentifierType.Owned => IsPlayerRelated(objects.Objects.CreateObjectReference(owner) as Dalamud.Game.ClientState.Objects.Types.Character),
_ => false,
};
[Flags] [Flags]
public enum Flags public enum Flags

View file

@ -149,6 +149,7 @@ public static class StaticServiceManager
private static ServiceManager AddInterface(this ServiceManager services) private static ServiceManager AddInterface(this ServiceManager services)
=> services.AddSingleton<FileDialogService>() => services.AddSingleton<FileDialogService>()
.AddSingleton<TutorialService>() .AddSingleton<TutorialService>()
.AddSingleton<IncognitoService>()
.AddSingleton<PenumbraChangelog>() .AddSingleton<PenumbraChangelog>()
.AddSingleton<LaunchButton>() .AddSingleton<LaunchButton>()
.AddSingleton<ConfigWindow>() .AddSingleton<ConfigWindow>()
@ -181,6 +182,7 @@ public static class StaticServiceManager
.AddSingleton<ItemSwapTab>() .AddSingleton<ItemSwapTab>()
.AddSingleton<ModMergeTab>() .AddSingleton<ModMergeTab>()
.AddSingleton<ChangedItemDrawer>() .AddSingleton<ChangedItemDrawer>()
.AddSingleton<ResourceTreeViewerFactory>()
.AddSingleton(p => new Diagnostics(p)); .AddSingleton(p => new Diagnostics(p));
private static ServiceManager AddModEditor(this ServiceManager services) private static ServiceManager AddModEditor(this ServiceManager services)

View file

@ -585,7 +585,8 @@ public partial class ModEditWindow : Window, IDisposable
Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, MetaFileManager metaFileManager, Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, MetaFileManager metaFileManager,
StainService stainService, ActiveCollections activeCollections, ModMergeTab modMergeTab, StainService stainService, ActiveCollections activeCollections, ModMergeTab modMergeTab,
CommunicatorService communicator, TextureManager textures, ModelManager models, IDragDropManager dragDropManager, CommunicatorService communicator, TextureManager textures, ModelManager models, IDragDropManager dragDropManager,
ChangedItemDrawer changedItemDrawer, ObjectManager objects, IFramework framework, CharacterBaseDestructor characterBaseDestructor) ResourceTreeViewerFactory resourceTreeViewerFactory, ObjectManager objects, IFramework framework,
CharacterBaseDestructor characterBaseDestructor)
: base(WindowBaseLabel) : base(WindowBaseLabel)
{ {
_performance = performance; _performance = performance;
@ -618,8 +619,7 @@ public partial class ModEditWindow : Window, IDisposable
_center = new CombinedTexture(_left, _right); _center = new CombinedTexture(_left, _right);
_textureSelectCombo = new TextureDrawer.PathSelectCombo(textures, editor, () => GetPlayerResourcesOfType(ResourceType.Tex)); _textureSelectCombo = new TextureDrawer.PathSelectCombo(textures, editor, () => GetPlayerResourcesOfType(ResourceType.Tex));
_resourceTreeFactory = resourceTreeFactory; _resourceTreeFactory = resourceTreeFactory;
_quickImportViewer = _quickImportViewer = resourceTreeViewerFactory.Create(2, OnQuickImportRefresh, DrawQuickImportActions);
new ResourceTreeViewer(_config, resourceTreeFactory, changedItemDrawer, 2, OnQuickImportRefresh, DrawQuickImportActions);
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModEditWindow); _communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModEditWindow);
IsOpen = _config is { OpenWindowAtStart: true, Ephemeral.AdvancedEditingOpen: true }; IsOpen = _config is { OpenWindowAtStart: true, Ephemeral.AdvancedEditingOpen: true };
} }

View file

@ -6,6 +6,7 @@ using OtterGui;
using Penumbra.Interop.ResourceTree; using Penumbra.Interop.ResourceTree;
using Penumbra.UI.Classes; using Penumbra.UI.Classes;
using Penumbra.String; using Penumbra.String;
using Penumbra.UI.Tabs;
namespace Penumbra.UI.AdvancedWindow; namespace Penumbra.UI.AdvancedWindow;
@ -17,6 +18,7 @@ public class ResourceTreeViewer
private readonly Configuration _config; private readonly Configuration _config;
private readonly ResourceTreeFactory _treeFactory; private readonly ResourceTreeFactory _treeFactory;
private readonly ChangedItemDrawer _changedItemDrawer; private readonly ChangedItemDrawer _changedItemDrawer;
private readonly IncognitoService _incognito;
private readonly int _actionCapacity; private readonly int _actionCapacity;
private readonly Action _onRefresh; private readonly Action _onRefresh;
private readonly Action<ResourceNode, Vector2> _drawActions; private readonly Action<ResourceNode, Vector2> _drawActions;
@ -29,11 +31,12 @@ public class ResourceTreeViewer
private Task<ResourceTree[]>? _task; private Task<ResourceTree[]>? _task;
public ResourceTreeViewer(Configuration config, ResourceTreeFactory treeFactory, ChangedItemDrawer changedItemDrawer, public ResourceTreeViewer(Configuration config, ResourceTreeFactory treeFactory, ChangedItemDrawer changedItemDrawer,
int actionCapacity, Action onRefresh, Action<ResourceNode, Vector2> drawActions) IncognitoService incognito, int actionCapacity, Action onRefresh, Action<ResourceNode, Vector2> drawActions)
{ {
_config = config; _config = config;
_treeFactory = treeFactory; _treeFactory = treeFactory;
_changedItemDrawer = changedItemDrawer; _changedItemDrawer = changedItemDrawer;
_incognito = incognito;
_actionCapacity = actionCapacity; _actionCapacity = actionCapacity;
_onRefresh = onRefresh; _onRefresh = onRefresh;
_drawActions = drawActions; _drawActions = drawActions;
@ -75,7 +78,7 @@ public class ResourceTreeViewer
using (var c = ImRaii.PushColor(ImGuiCol.Text, CategoryColor(category).Value())) using (var c = ImRaii.PushColor(ImGuiCol.Text, CategoryColor(category).Value()))
{ {
var isOpen = ImGui.CollapsingHeader($"{tree.Name}##{index}", index == 0 ? ImGuiTreeNodeFlags.DefaultOpen : 0); var isOpen = ImGui.CollapsingHeader($"{(_incognito.IncognitoMode ? tree.AnonymizedName : tree.Name)}###{index}", index == 0 ? ImGuiTreeNodeFlags.DefaultOpen : 0);
if (debugMode) if (debugMode)
{ {
using var _ = ImRaii.PushFont(UiBuilder.MonoFont); using var _ = ImRaii.PushFont(UiBuilder.MonoFont);
@ -89,7 +92,7 @@ public class ResourceTreeViewer
using var id = ImRaii.PushId(index); using var id = ImRaii.PushId(index);
ImGui.TextUnformatted($"Collection: {tree.CollectionName}"); ImGui.TextUnformatted($"Collection: {(_incognito.IncognitoMode ? tree.AnonymizedCollectionName : tree.CollectionName)}");
using var table = ImRaii.Table("##ResourceTree", _actionCapacity > 0 ? 4 : 3, using var table = ImRaii.Table("##ResourceTree", _actionCapacity > 0 ? 4 : 3,
ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg); ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
@ -137,10 +140,14 @@ public class ResourceTreeViewer
ImGui.SameLine(0, checkPadding); ImGui.SameLine(0, checkPadding);
_changedItemDrawer.DrawTypeFilter(ref _typeFilter, -yOffset); ImGui.SetCursorPosY(ImGui.GetCursorPosY() - yOffset);
using (ImRaii.Child("##typeFilter", new Vector2(ImGui.GetContentRegionAvail().X, ChangedItemDrawer.TypeFilterIconSize.Y)))
_changedItemDrawer.DrawTypeFilter(ref _typeFilter);
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X); ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - checkSpacing - ImGui.GetFrameHeightWithSpacing());
ImGui.InputTextWithHint("##TreeNameFilter", "Filter by Character/Entity Name...", ref _nameFilter, 128); ImGui.InputTextWithHint("##TreeNameFilter", "Filter by Character/Entity Name...", ref _nameFilter, 128);
ImGui.SameLine(0, checkSpacing);
_incognito.DrawToggle();
} }
private Task<ResourceTree[]> RefreshCharacterList() private Task<ResourceTree[]> RefreshCharacterList()

View file

@ -0,0 +1,13 @@
using Penumbra.Interop.ResourceTree;
namespace Penumbra.UI.AdvancedWindow;
public class ResourceTreeViewerFactory(
Configuration config,
ResourceTreeFactory treeFactory,
ChangedItemDrawer changedItemDrawer,
IncognitoService incognito)
{
public ResourceTreeViewer Create(int actionCapacity, Action onRefresh, Action<ResourceNode, Vector2> drawActions)
=> new(config, treeFactory, changedItemDrawer, incognito, actionCapacity, onRefresh, drawActions);
}

View file

@ -212,7 +212,7 @@ public class ChangedItemDrawer : IDisposable
return; return;
var typeFilter = _config.Ephemeral.ChangedItemFilter; var typeFilter = _config.Ephemeral.ChangedItemFilter;
if (DrawTypeFilter(ref typeFilter, 0.0f)) if (DrawTypeFilter(ref typeFilter))
{ {
_config.Ephemeral.ChangedItemFilter = typeFilter; _config.Ephemeral.ChangedItemFilter = typeFilter;
_config.Ephemeral.Save(); _config.Ephemeral.Save();
@ -220,7 +220,7 @@ public class ChangedItemDrawer : IDisposable
} }
/// <summary> Draw a header line with the different icon types to filter them. </summary> /// <summary> Draw a header line with the different icon types to filter them. </summary>
public bool DrawTypeFilter(ref ChangedItemIcon typeFilter, float yOffset) public bool DrawTypeFilter(ref ChangedItemIcon typeFilter)
{ {
var ret = false; var ret = false;
using var _ = ImRaii.PushId("ChangedItemIconFilter"); using var _ = ImRaii.PushId("ChangedItemIconFilter");
@ -233,7 +233,6 @@ public class ChangedItemDrawer : IDisposable
var ret = false; var ret = false;
var icon = _icons[type]; var icon = _icons[type];
var flag = typeFilter.HasFlag(type); var flag = typeFilter.HasFlag(type);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + yOffset);
ImGui.Image(icon.ImGuiHandle, size, Vector2.Zero, Vector2.One, flag ? Vector4.One : new Vector4(0.6f, 0.3f, 0.3f, 1f)); ImGui.Image(icon.ImGuiHandle, size, Vector2.Zero, Vector2.One, flag ? Vector4.One : new Vector4(0.6f, 0.3f, 0.3f, 1f));
if (ImGui.IsItemClicked(ImGuiMouseButton.Left)) if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
{ {
@ -267,7 +266,7 @@ public class ChangedItemDrawer : IDisposable
ImGui.SameLine(); ImGui.SameLine();
} }
ImGui.SetCursorPos(new Vector2(ImGui.GetContentRegionMax().X - size.X, ImGui.GetCursorPosY() + yOffset)); ImGui.SetCursorPosX(ImGui.GetContentRegionMax().X - size.X);
ImGui.Image(_icons[AllFlags].ImGuiHandle, size, Vector2.Zero, Vector2.One, ImGui.Image(_icons[AllFlags].ImGuiHandle, size, Vector2.Zero, Vector2.One,
typeFilter == 0 ? new Vector4(0.6f, 0.3f, 0.3f, 1f) : typeFilter == 0 ? new Vector4(0.6f, 0.3f, 0.3f, 1f) :
typeFilter == AllFlags ? new Vector4(0.75f, 0.75f, 0.75f, 1f) : new Vector4(0.5f, 0.5f, 1f, 1f)); typeFilter == AllFlags ? new Vector4(0.75f, 0.75f, 0.75f, 1f) : new Vector4(0.5f, 0.5f, 1f, 1f));

View file

@ -31,6 +31,7 @@ public sealed class CollectionPanel : IDisposable
private readonly InheritanceUi _inheritanceUi; private readonly InheritanceUi _inheritanceUi;
private readonly ModStorage _mods; private readonly ModStorage _mods;
private readonly FilenameService _fileNames; private readonly FilenameService _fileNames;
private readonly IncognitoService _incognito;
private readonly IFontHandle _nameFont; private readonly IFontHandle _nameFont;
private static readonly IReadOnlyDictionary<CollectionType, (string Name, uint Border)> Buttons = CreateButtons(); private static readonly IReadOnlyDictionary<CollectionType, (string Name, uint Border)> Buttons = CreateButtons();
@ -41,7 +42,8 @@ public sealed class CollectionPanel : IDisposable
private int _draggedIndividualAssignment = -1; private int _draggedIndividualAssignment = -1;
public CollectionPanel(DalamudPluginInterface pi, CommunicatorService communicator, CollectionManager manager, public CollectionPanel(DalamudPluginInterface pi, CommunicatorService communicator, CollectionManager manager,
CollectionSelector selector, ActorManager actors, ITargetManager targets, ModStorage mods, FilenameService fileNames) CollectionSelector selector, ActorManager actors, ITargetManager targets, ModStorage mods, FilenameService fileNames,
IncognitoService incognito)
{ {
_collections = manager.Storage; _collections = manager.Storage;
_active = manager.Active; _active = manager.Active;
@ -50,8 +52,9 @@ public sealed class CollectionPanel : IDisposable
_targets = targets; _targets = targets;
_mods = mods; _mods = mods;
_fileNames = fileNames; _fileNames = fileNames;
_incognito = incognito;
_individualAssignmentUi = new IndividualAssignmentUi(communicator, actors, manager); _individualAssignmentUi = new IndividualAssignmentUi(communicator, actors, manager);
_inheritanceUi = new InheritanceUi(manager, _selector); _inheritanceUi = new InheritanceUi(manager, incognito);
_nameFont = pi.UiBuilder.FontAtlas.NewGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Jupiter23)); _nameFont = pi.UiBuilder.FontAtlas.NewGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Jupiter23));
} }
@ -415,7 +418,7 @@ public sealed class CollectionPanel : IDisposable
/// <summary> Respect incognito mode for names of identifiers. </summary> /// <summary> Respect incognito mode for names of identifiers. </summary>
private string Name(ActorIdentifier id, string? name) private string Name(ActorIdentifier id, string? name)
=> _selector.IncognitoMode && id.Type is IdentifierType.Player or IdentifierType.Owned => _incognito.IncognitoMode && id.Type is IdentifierType.Player or IdentifierType.Owned
? id.Incognito(name) ? id.Incognito(name)
: name ?? id.ToString(); : name ?? id.ToString();
@ -423,7 +426,7 @@ public sealed class CollectionPanel : IDisposable
private string Name(ModCollection? collection) private string Name(ModCollection? collection)
=> collection == null ? "Unassigned" : => collection == null ? "Unassigned" :
collection == ModCollection.Empty ? "Use No Mods" : collection == ModCollection.Empty ? "Use No Mods" :
_selector.IncognitoMode ? collection.AnonymizedName : collection.Name; _incognito.IncognitoMode ? collection.AnonymizedName : collection.Name;
private void DrawIndividualButton(string intro, Vector2 width, string tooltip, char suffix, params ActorIdentifier[] identifiers) private void DrawIndividualButton(string intro, Vector2 width, string tooltip, char suffix, params ActorIdentifier[] identifiers)
{ {

View file

@ -17,13 +17,12 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
private readonly CollectionStorage _storage; private readonly CollectionStorage _storage;
private readonly ActiveCollections _active; private readonly ActiveCollections _active;
private readonly TutorialService _tutorial; private readonly TutorialService _tutorial;
private readonly IncognitoService _incognito;
private ModCollection? _dragging; private ModCollection? _dragging;
public bool IncognitoMode;
public CollectionSelector(Configuration config, CommunicatorService communicator, CollectionStorage storage, ActiveCollections active, public CollectionSelector(Configuration config, CommunicatorService communicator, CollectionStorage storage, ActiveCollections active,
TutorialService tutorial) TutorialService tutorial, IncognitoService incognito)
: base([], Flags.Delete | Flags.Add | Flags.Duplicate | Flags.Filter) : base([], Flags.Delete | Flags.Add | Flags.Duplicate | Flags.Filter)
{ {
_config = config; _config = config;
@ -31,6 +30,7 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
_storage = storage; _storage = storage;
_active = active; _active = active;
_tutorial = tutorial; _tutorial = tutorial;
_incognito = incognito;
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.CollectionSelector); _communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.CollectionSelector);
// Set items. // Set items.
@ -109,7 +109,7 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
} }
private string Name(ModCollection collection) private string Name(ModCollection collection)
=> IncognitoMode ? collection.AnonymizedName : collection.Name; => _incognito.IncognitoMode ? collection.AnonymizedName : collection.Name;
private void OnCollectionChange(CollectionType type, ModCollection? old, ModCollection? @new, string _3) private void OnCollectionChange(CollectionType type, ModCollection? old, ModCollection? @new, string _3)
{ {

View file

@ -9,7 +9,7 @@ using Penumbra.UI.Classes;
namespace Penumbra.UI.CollectionTab; namespace Penumbra.UI.CollectionTab;
public class InheritanceUi(CollectionManager collectionManager, CollectionSelector selector) : IUiService public class InheritanceUi(CollectionManager collectionManager, IncognitoService incognito) : IUiService
{ {
private const int InheritedCollectionHeight = 9; private const int InheritedCollectionHeight = 9;
private const string InheritanceDragDropLabel = "##InheritanceMove"; private const string InheritanceDragDropLabel = "##InheritanceMove";
@ -312,5 +312,5 @@ public class InheritanceUi(CollectionManager collectionManager, CollectionSelect
} }
private string Name(ModCollection collection) private string Name(ModCollection collection)
=> selector.IncognitoMode ? collection.AnonymizedName : collection.Name; => incognito.IncognitoMode ? collection.AnonymizedName : collection.Name;
} }

View file

@ -0,0 +1,29 @@
using Dalamud.Interface.Utility;
using Dalamud.Interface;
using ImGuiNET;
using OtterGui;
using Penumbra.UI.Classes;
using OtterGui.Raii;
namespace Penumbra.UI;
public class IncognitoService(TutorialService tutorial)
{
public bool IncognitoMode;
public void DrawToggle(float? buttonWidth = null)
{
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale);
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.FolderExpanded.Value())
.Push(ImGuiCol.Border, ColorId.FolderExpanded.Value());
if (ImGuiUtil.DrawDisabledButton(
$"{(IncognitoMode ? FontAwesomeIcon.Eye : FontAwesomeIcon.EyeSlash).ToIconString()}###IncognitoMode",
new Vector2(buttonWidth ?? ImGui.GetFrameHeightWithSpacing(), ImGui.GetFrameHeight()), string.Empty, false, true))
IncognitoMode = !IncognitoMode;
var hovered = ImGui.IsItemHovered();
tutorial.OpenTutorial(BasicTutorialSteps.Incognito);
color.Pop(2);
if (hovered)
ImGui.SetTooltip(IncognitoMode ? "Toggle incognito mode off." : "Toggle incognito mode on.");
}
}

View file

@ -21,6 +21,7 @@ public sealed class CollectionsTab : IDisposable, ITab
private readonly CollectionSelector _selector; private readonly CollectionSelector _selector;
private readonly CollectionPanel _panel; private readonly CollectionPanel _panel;
private readonly TutorialService _tutorial; private readonly TutorialService _tutorial;
private readonly IncognitoService _incognito;
public enum PanelMode public enum PanelMode
{ {
@ -40,13 +41,14 @@ public sealed class CollectionsTab : IDisposable, ITab
} }
} }
public CollectionsTab(DalamudPluginInterface pi, Configuration configuration, CommunicatorService communicator, public CollectionsTab(DalamudPluginInterface pi, Configuration configuration, CommunicatorService communicator, IncognitoService incognito,
CollectionManager collectionManager, ModStorage modStorage, ActorManager actors, ITargetManager targets, TutorialService tutorial, FilenameService fileNames) CollectionManager collectionManager, ModStorage modStorage, ActorManager actors, ITargetManager targets, TutorialService tutorial, FilenameService fileNames)
{ {
_config = configuration.Ephemeral; _config = configuration.Ephemeral;
_tutorial = tutorial; _tutorial = tutorial;
_selector = new CollectionSelector(configuration, communicator, collectionManager.Storage, collectionManager.Active, _tutorial); _incognito = incognito;
_panel = new CollectionPanel(pi, communicator, collectionManager, _selector, actors, targets, modStorage, fileNames); _selector = new CollectionSelector(configuration, communicator, collectionManager.Storage, collectionManager.Active, _tutorial, incognito);
_panel = new CollectionPanel(pi, communicator, collectionManager, _selector, actors, targets, modStorage, fileNames, incognito);
} }
public void Dispose() public void Dispose()
@ -116,18 +118,7 @@ public sealed class CollectionsTab : IDisposable, ITab
_tutorial.OpenTutorial(BasicTutorialSteps.CollectionDetails); _tutorial.OpenTutorial(BasicTutorialSteps.CollectionDetails);
ImGui.SameLine(); ImGui.SameLine();
style.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale); _incognito.DrawToggle(withSpacing);
color.Push(ImGuiCol.Text, ColorId.FolderExpanded.Value())
.Push(ImGuiCol.Border, ColorId.FolderExpanded.Value());
if (ImGuiUtil.DrawDisabledButton(
$"{(_selector.IncognitoMode ? FontAwesomeIcon.Eye : FontAwesomeIcon.EyeSlash).ToIconString()}###IncognitoMode",
buttonSize with { X = withSpacing }, string.Empty, false, true))
_selector.IncognitoMode = !_selector.IncognitoMode;
var hovered = ImGui.IsItemHovered();
_tutorial.OpenTutorial(BasicTutorialSteps.Incognito);
color.Pop(2);
if (hovered)
ImGui.SetTooltip(_selector.IncognitoMode ? "Toggle incognito mode off." : "Toggle incognito mode on.");
} }
private void DrawPanel() private void DrawPanel()

View file

@ -1,18 +1,15 @@
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Interop.ResourceTree;
using Penumbra.UI.AdvancedWindow; using Penumbra.UI.AdvancedWindow;
namespace Penumbra.UI.Tabs; namespace Penumbra.UI.Tabs;
public class OnScreenTab : ITab public class OnScreenTab : ITab
{ {
private readonly Configuration _config;
private readonly ResourceTreeViewer _viewer; private readonly ResourceTreeViewer _viewer;
public OnScreenTab(Configuration config, ResourceTreeFactory treeFactory, ChangedItemDrawer changedItemDrawer) public OnScreenTab(ResourceTreeViewerFactory resourceTreeViewerFactory)
{ {
_config = config; _viewer = resourceTreeViewerFactory.Create(0, delegate { }, delegate { });
_viewer = new ResourceTreeViewer(_config, treeFactory, changedItemDrawer, 0, delegate { }, delegate { });
} }
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label