From 019b9533bffb82fff5d2a68be13f64f5d9a173da Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sat, 1 Nov 2025 20:56:46 +0100 Subject: [PATCH] Update some things for Luna. --- Luna | 2 +- OtterGui | 2 +- .../UI/CollectionTab/CollectionSelector.cs | 14 +- .../CollectionTab/IndividualAssignmentUi.cs | 375 +++++++++--------- Penumbra/UI/CollectionTab/InheritanceUi.cs | 138 ++++--- Penumbra/UI/CollectionTab/ObjectKindCombo.cs | 25 ++ Penumbra/UI/ModsTab/DescriptionEditPopup.cs | 22 +- 7 files changed, 297 insertions(+), 281 deletions(-) create mode 100644 Penumbra/UI/CollectionTab/ObjectKindCombo.cs diff --git a/Luna b/Luna index c872e220..c8f90e53 160000 --- a/Luna +++ b/Luna @@ -1 +1 @@ -Subproject commit c872e220ebf7e8e53c6389be99a54827f0afd222 +Subproject commit c8f90e537ae2b5ab1a9db53eafe3f7f5b2e68f38 diff --git a/OtterGui b/OtterGui index a63f6735..18e62ab2 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit a63f6735cf4bed4f7502a022a10378607082b770 +Subproject commit 18e62ab2d8b9ac7028a33707eb35f8f9c61f245a diff --git a/Penumbra/UI/CollectionTab/CollectionSelector.cs b/Penumbra/UI/CollectionTab/CollectionSelector.cs index 1fa79e34..a4d19e3d 100644 --- a/Penumbra/UI/CollectionTab/CollectionSelector.cs +++ b/Penumbra/UI/CollectionTab/CollectionSelector.cs @@ -1,7 +1,5 @@ -using Dalamud.Bindings.ImGui; using ImSharp; using OtterGui; -using OtterGui.Raii; using Penumbra.Collections; using Penumbra.Collections.Manager; using Penumbra.Communication; @@ -77,8 +75,8 @@ public sealed class CollectionSelector : ItemSelector, IDisposabl protected override bool OnDraw(int idx) { using var color = ImGuiColor.Header.Push(ColorId.SelectedCollection.Value()); - var ret = ImGui.Selectable(Name(Items[idx]), idx == CurrentIdx); - using var source = ImRaii.DragDropSource(); + var ret = Im.Selectable(Name(Items[idx]), idx == CurrentIdx); + using var source = Im.DragDrop.Source(); if (idx == CurrentIdx) _tutorial.OpenTutorial(BasicTutorialSteps.CurrentCollection); @@ -86,8 +84,8 @@ public sealed class CollectionSelector : ItemSelector, IDisposabl if (source) { _dragging = Items[idx]; - ImGui.SetDragDropPayload(PayloadString, null); - ImGui.TextUnformatted($"Assigning {Name(_dragging)} to..."); + source.SetPayload(PayloadString); + Im.Text($"Assigning {Name(_dragging)} to..."); } if (ret) @@ -98,8 +96,8 @@ public sealed class CollectionSelector : ItemSelector, IDisposabl public void DragTargetAssignment(CollectionType type, ActorIdentifier identifier) { - using var target = ImRaii.DragDropTarget(); - if (!target.Success || _dragging == null || !ImGuiUtil.IsDropping(PayloadString)) + using var target = Im.DragDrop.Target(); + if (!target.Success || _dragging is null || !target.IsDropping(PayloadString)) return; _active.SetCollection(_dragging, type, _active.Individuals.GetGroup(identifier)); diff --git a/Penumbra/UI/CollectionTab/IndividualAssignmentUi.cs b/Penumbra/UI/CollectionTab/IndividualAssignmentUi.cs index e0b42b35..b2220574 100644 --- a/Penumbra/UI/CollectionTab/IndividualAssignmentUi.cs +++ b/Penumbra/UI/CollectionTab/IndividualAssignmentUi.cs @@ -1,190 +1,185 @@ -using Dalamud.Game.ClientState.Objects.Enums; -using Dalamud.Bindings.ImGui; -using ImSharp; -using OtterGui.Custom; -using Penumbra.Collections; -using Penumbra.Collections.Manager; -using Penumbra.Communication; -using Penumbra.GameData.Actors; -using Penumbra.GameData.Enums; -using Penumbra.GameData.Gui; -using Penumbra.Services; - -namespace Penumbra.UI.CollectionTab; - -public class IndividualAssignmentUi : IDisposable -{ - private readonly CommunicatorService _communicator; - private readonly ActorManager _actors; - private readonly CollectionManager _collectionManager; - - private WorldCombo _worldCombo = null!; - private NpcCombo _mountCombo = null!; - private NpcCombo _companionCombo = null!; - private NpcCombo _ornamentCombo = null!; - private NpcCombo _bnpcCombo = null!; - private NpcCombo _enpcCombo = null!; - - private bool _ready; - - public IndividualAssignmentUi(CommunicatorService communicator, ActorManager actors, CollectionManager collectionManager) - { - _communicator = communicator; - _actors = actors; - _collectionManager = collectionManager; - _communicator.CollectionChange.Subscribe(UpdateIdentifiers, CollectionChange.Priority.IndividualAssignmentUi); - _actors.Awaiter.ContinueWith(_ => SetupCombos(), TaskScheduler.Default); - } - - public string PlayerTooltip { get; private set; } = NewPlayerTooltipEmpty; - public string RetainerTooltip { get; private set; } = NewRetainerTooltipEmpty; - public string NpcTooltip { get; private set; } = NewNpcTooltipEmpty; - public string OwnedTooltip { get; private set; } = NewPlayerTooltipEmpty; - - public ActorIdentifier[] PlayerIdentifiers - => _playerIdentifiers; - - public ActorIdentifier[] RetainerIdentifiers - => _retainerIdentifiers; - - public ActorIdentifier[] NpcIdentifiers - => _npcIdentifiers; - - public ActorIdentifier[] OwnedIdentifiers - => _ownedIdentifiers; - - public void DrawWorldCombo(float width) - { - if (_ready && _worldCombo.Draw(width)) - UpdateIdentifiersInternal(); - } - - public void DrawObjectKindCombo(float width) - { - if (_ready && IndividualHelpers.DrawObjectKindCombo(width, _newKind, out _newKind, ObjectKinds)) - UpdateIdentifiersInternal(); - } - - public void DrawNewPlayerCollection(float width) - { - if (!_ready) - return; - - ImGui.SetNextItemWidth(width); - if (ImGui.InputTextWithHint("##NewCharacter", "Character Name...", ref _newCharacterName, 32)) - UpdateIdentifiersInternal(); - } - - public void DrawNewNpcCollection(float width) - { - if (!_ready) - return; - - var combo = GetNpcCombo(_newKind); - if (combo.Draw(width)) - UpdateIdentifiersInternal(); - } - - public void Dispose() - => _communicator.CollectionChange.Unsubscribe(UpdateIdentifiers); - - // Input Selections. - private string _newCharacterName = string.Empty; - private ObjectKind _newKind = ObjectKind.BattleNpc; - private ActorIdentifier[] _playerIdentifiers = []; - private ActorIdentifier[] _retainerIdentifiers = []; - private ActorIdentifier[] _npcIdentifiers = []; - private ActorIdentifier[] _ownedIdentifiers = []; - - private const string NewPlayerTooltipEmpty = "Please enter a valid player name and choose an available world or 'Any World'."; - private const string NewRetainerTooltipEmpty = "Please enter a valid retainer name."; - private const string NewPlayerTooltipInvalid = "The entered name is not a valid name for a player character."; - private const string NewRetainerTooltipInvalid = "The entered name is not a valid name for a retainer."; - private const string AlreadyAssigned = "The Individual you specified has already been assigned a collection."; - private const string NewNpcTooltipEmpty = "Please select a valid NPC from the drop down menu first."; - - private static readonly IReadOnlyList ObjectKinds = new[] - { - ObjectKind.BattleNpc, - ObjectKind.EventNpc, - ObjectKind.Companion, - ObjectKind.MountType, - ObjectKind.Ornament, - }; - - private NpcCombo GetNpcCombo(ObjectKind kind) - => kind switch - { - ObjectKind.BattleNpc => _bnpcCombo, - ObjectKind.EventNpc => _enpcCombo, - ObjectKind.MountType => _mountCombo, - ObjectKind.Companion => _companionCombo, - ObjectKind.Ornament => _ornamentCombo, - _ => throw new NotImplementedException(), - }; - - /// Create combos when ready. - private void SetupCombos() - { - _worldCombo = new WorldCombo(_actors.Data.Worlds); - _mountCombo = new NpcCombo(new StringU8("##mounts"u8), _actors.Data.Mounts); - _companionCombo = new NpcCombo(new StringU8("##companions"u8), _actors.Data.Companions); - _ornamentCombo = new NpcCombo(new StringU8("##ornaments"u8), _actors.Data.Ornaments); - _bnpcCombo = new NpcCombo(new StringU8("##bnpc"u8), _actors.Data.BNpcs); - _enpcCombo = new NpcCombo(new StringU8("##enpc"u8), _actors.Data.ENpcs); - _ready = true; - } - - private void UpdateIdentifiers(in CollectionChange.Arguments arguments) - { - if (arguments.Type is CollectionType.Individual) - UpdateIdentifiersInternal(); - } - - private void UpdateIdentifiersInternal() - { - var combo = GetNpcCombo(_newKind); - PlayerTooltip = _collectionManager.Active.Individuals.CanAdd(IdentifierType.Player, _newCharacterName, - _worldCombo.Selected.Key, ObjectKind.None, [], out _playerIdentifiers) switch - { - _ when _newCharacterName.Length == 0 => NewPlayerTooltipEmpty, - IndividualCollections.AddResult.Invalid => NewPlayerTooltipInvalid, - IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, - _ => string.Empty, - }; - RetainerTooltip = - _collectionManager.Active.Individuals.CanAdd(IdentifierType.Retainer, _newCharacterName, 0, ObjectKind.None, [], - out _retainerIdentifiers) switch - { - _ when _newCharacterName.Length == 0 => NewRetainerTooltipEmpty, - IndividualCollections.AddResult.Invalid => NewRetainerTooltipInvalid, - IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, - _ => string.Empty, - }; - if (combo.Selected.Ids.Length > 0) - { - NpcTooltip = _collectionManager.Active.Individuals.CanAdd(IdentifierType.Npc, string.Empty, ushort.MaxValue, _newKind, - combo.Selected.Ids, out _npcIdentifiers) switch - { - IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, - _ => string.Empty, - }; - OwnedTooltip = _collectionManager.Active.Individuals.CanAdd(IdentifierType.Owned, _newCharacterName, - _worldCombo.Selected.Key, _newKind, - combo.Selected.Ids, out _ownedIdentifiers) switch - { - _ when _newCharacterName.Length == 0 => NewPlayerTooltipEmpty, - IndividualCollections.AddResult.Invalid => NewPlayerTooltipInvalid, - IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, - _ => string.Empty, - }; - } - else - { - NpcTooltip = NewNpcTooltipEmpty; - OwnedTooltip = NewNpcTooltipEmpty; - _npcIdentifiers = []; - _ownedIdentifiers = []; - } - } -} +using Dalamud.Game.ClientState.Objects.Enums; +using ImSharp; +using Penumbra.Collections.Manager; +using Penumbra.Communication; +using Penumbra.GameData.Actors; +using Penumbra.GameData.Enums; +using Penumbra.GameData.Gui; +using Penumbra.Services; + +namespace Penumbra.UI.CollectionTab; + +public class IndividualAssignmentUi : IDisposable +{ + private readonly CommunicatorService _communicator; + private readonly ActorManager _actors; + private readonly CollectionManager _collectionManager; + + private readonly ObjectKindCombo _objectKindCombo = new( + ObjectKind.BattleNpc, + ObjectKind.EventNpc, + ObjectKind.Companion, + ObjectKind.MountType, + ObjectKind.Ornament); + + private WorldCombo _worldCombo = null!; + private NpcCombo _mountCombo = null!; + private NpcCombo _companionCombo = null!; + private NpcCombo _ornamentCombo = null!; + private NpcCombo _bnpcCombo = null!; + private NpcCombo _enpcCombo = null!; + + private bool _ready; + + public IndividualAssignmentUi(CommunicatorService communicator, ActorManager actors, CollectionManager collectionManager) + { + _communicator = communicator; + _actors = actors; + _collectionManager = collectionManager; + _communicator.CollectionChange.Subscribe(UpdateIdentifiers, CollectionChange.Priority.IndividualAssignmentUi); + _actors.Awaiter.ContinueWith(_ => SetupCombos(), TaskScheduler.Default); + } + + public string PlayerTooltip { get; private set; } = NewPlayerTooltipEmpty; + public string RetainerTooltip { get; private set; } = NewRetainerTooltipEmpty; + public string NpcTooltip { get; private set; } = NewNpcTooltipEmpty; + public string OwnedTooltip { get; private set; } = NewPlayerTooltipEmpty; + + public ActorIdentifier[] PlayerIdentifiers + => _playerIdentifiers; + + public ActorIdentifier[] RetainerIdentifiers + => _retainerIdentifiers; + + public ActorIdentifier[] NpcIdentifiers + => _npcIdentifiers; + + public ActorIdentifier[] OwnedIdentifiers + => _ownedIdentifiers; + + public void DrawWorldCombo(float width) + { + if (_ready && _worldCombo.Draw(width)) + UpdateIdentifiersInternal(); + } + + public void DrawObjectKindCombo(float width) + { + if (_ready && _objectKindCombo.Draw("##objectKind"u8, ref _newKind, StringU8.Empty, width)) + UpdateIdentifiersInternal(); + } + + public void DrawNewPlayerCollection(float width) + { + if (!_ready) + return; + + Im.Item.SetNextWidth(width); + if (Im.Input.Text("##NewCharacter"u8, ref _newCharacterName, "Character Name..."u8)) + UpdateIdentifiersInternal(); + } + + public void DrawNewNpcCollection(float width) + { + if (!_ready) + return; + + var combo = GetNpcCombo(_newKind); + if (combo.Draw(width)) + UpdateIdentifiersInternal(); + } + + public void Dispose() + => _communicator.CollectionChange.Unsubscribe(UpdateIdentifiers); + + // Input Selections. + private string _newCharacterName = string.Empty; + private ObjectKind _newKind = ObjectKind.BattleNpc; + private ActorIdentifier[] _playerIdentifiers = []; + private ActorIdentifier[] _retainerIdentifiers = []; + private ActorIdentifier[] _npcIdentifiers = []; + private ActorIdentifier[] _ownedIdentifiers = []; + + private const string NewPlayerTooltipEmpty = "Please enter a valid player name and choose an available world or 'Any World'."; + private const string NewRetainerTooltipEmpty = "Please enter a valid retainer name."; + private const string NewPlayerTooltipInvalid = "The entered name is not a valid name for a player character."; + private const string NewRetainerTooltipInvalid = "The entered name is not a valid name for a retainer."; + private const string AlreadyAssigned = "The Individual you specified has already been assigned a collection."; + private const string NewNpcTooltipEmpty = "Please select a valid NPC from the drop down menu first."; + + private NpcCombo GetNpcCombo(ObjectKind kind) + => kind switch + { + ObjectKind.BattleNpc => _bnpcCombo, + ObjectKind.EventNpc => _enpcCombo, + ObjectKind.MountType => _mountCombo, + ObjectKind.Companion => _companionCombo, + ObjectKind.Ornament => _ornamentCombo, + _ => throw new NotImplementedException(), + }; + + /// Create combos when ready. + private void SetupCombos() + { + _worldCombo = new WorldCombo(_actors.Data.Worlds); + _mountCombo = new NpcCombo(new StringU8("##mounts"u8), _actors.Data.Mounts); + _companionCombo = new NpcCombo(new StringU8("##companions"u8), _actors.Data.Companions); + _ornamentCombo = new NpcCombo(new StringU8("##ornaments"u8), _actors.Data.Ornaments); + _bnpcCombo = new NpcCombo(new StringU8("##bnpc"u8), _actors.Data.BNpcs); + _enpcCombo = new NpcCombo(new StringU8("##enpc"u8), _actors.Data.ENpcs); + _ready = true; + } + + private void UpdateIdentifiers(in CollectionChange.Arguments arguments) + { + if (arguments.Type is CollectionType.Individual) + UpdateIdentifiersInternal(); + } + + private void UpdateIdentifiersInternal() + { + var combo = GetNpcCombo(_newKind); + PlayerTooltip = _collectionManager.Active.Individuals.CanAdd(IdentifierType.Player, _newCharacterName, + _worldCombo.Selected.Key, ObjectKind.None, [], out _playerIdentifiers) switch + { + _ when _newCharacterName.Length == 0 => NewPlayerTooltipEmpty, + IndividualCollections.AddResult.Invalid => NewPlayerTooltipInvalid, + IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, + _ => string.Empty, + }; + RetainerTooltip = + _collectionManager.Active.Individuals.CanAdd(IdentifierType.Retainer, _newCharacterName, 0, ObjectKind.None, [], + out _retainerIdentifiers) switch + { + _ when _newCharacterName.Length == 0 => NewRetainerTooltipEmpty, + IndividualCollections.AddResult.Invalid => NewRetainerTooltipInvalid, + IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, + _ => string.Empty, + }; + if (combo.Selected.Ids.Length > 0) + { + NpcTooltip = _collectionManager.Active.Individuals.CanAdd(IdentifierType.Npc, string.Empty, ushort.MaxValue, _newKind, + combo.Selected.Ids, out _npcIdentifiers) switch + { + IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, + _ => string.Empty, + }; + OwnedTooltip = _collectionManager.Active.Individuals.CanAdd(IdentifierType.Owned, _newCharacterName, + _worldCombo.Selected.Key, _newKind, + combo.Selected.Ids, out _ownedIdentifiers) switch + { + _ when _newCharacterName.Length == 0 => NewPlayerTooltipEmpty, + IndividualCollections.AddResult.Invalid => NewPlayerTooltipInvalid, + IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, + _ => string.Empty, + }; + } + else + { + NpcTooltip = NewNpcTooltipEmpty; + OwnedTooltip = NewNpcTooltipEmpty; + _npcIdentifiers = []; + _ownedIdentifiers = []; + } + } +} diff --git a/Penumbra/UI/CollectionTab/InheritanceUi.cs b/Penumbra/UI/CollectionTab/InheritanceUi.cs index fbb3c15e..13be56f4 100644 --- a/Penumbra/UI/CollectionTab/InheritanceUi.cs +++ b/Penumbra/UI/CollectionTab/InheritanceUi.cs @@ -1,19 +1,17 @@ -using Dalamud.Interface; -using Dalamud.Bindings.ImGui; using ImSharp; using Luna; -using OtterGui; -using OtterGui.Raii; using Penumbra.Collections; using Penumbra.Collections.Manager; using Penumbra.UI.Classes; namespace Penumbra.UI.CollectionTab; -public class InheritanceUi(CollectionManager collectionManager, IncognitoService incognito) : Luna.IUiService +public class InheritanceUi(CollectionManager collectionManager, IncognitoService incognito) : IUiService { - private const int InheritedCollectionHeight = 9; - private const string InheritanceDragDropLabel = "##InheritanceMove"; + private const int InheritedCollectionHeight = 9; + + private static ReadOnlySpan InheritanceDragDropLabel + => "##InheritanceMove"u8; private readonly CollectionStorage _collections = collectionManager.Storage; private readonly ActiveCollections _active = collectionManager.Active; @@ -22,10 +20,12 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService /// Draw the whole inheritance block. public void Draw() { - using var id = ImRaii.PushId("##Inheritance"); - ImGuiUtil.DrawColoredText(($"The {TutorialService.SelectedCollection} ", 0), - (Name(_active.Current), ColorId.SelectedCollection.Value().FullAlpha().Color), (" inherits from:", 0)); - ImGui.Dummy(Vector2.One); + using var id = Im.Id.Push("##Inheritance"u8); + ImEx.TextMultiColored("The Selected Collection "u8) + .Then(Name(_active.Current), ColorId.SelectedCollection.Value().FullAlpha().Color) + .Then(" inherits from:"u8) + .End(); + Im.Dummy(Vector2.One); DrawCurrentCollectionInheritance(); Im.Line.Same(); @@ -35,8 +35,8 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService DrawNewInheritanceSelection(); Im.Line.Same(); - if (ImGui.Button("More Information about Inheritance", new Vector2(Im.ContentRegion.Available.X, 0))) - ImGui.OpenPopup("InheritanceHelp"); + if (Im.Button("More Information about Inheritance"u8, Im.ContentRegion.Available with { Y = 0 })) + Im.Popup.Open("InheritanceHelp"u8); DrawHelpPopup(); DelayedActions(); @@ -53,38 +53,38 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService private static void DrawRightText() { - using var group = ImRaii.Group(); - ImGuiUtil.TextWrapped( - "Inheritance is a way to use a baseline of mods across multiple collections, without needing to change all those collections if you want to add a single mod."); - ImGuiUtil.TextWrapped( - "You can select inheritances from the combo below to add them.\nSince the order of inheritances is important, you can reorder them here via drag and drop.\nYou can also delete inheritances by dragging them onto the trash can."); + using var group = Im.Group(); + Im.TextWrapped( + "Inheritance is a way to use a baseline of mods across multiple collections, without needing to change all those collections if you want to add a single mod."u8); + Im.TextWrapped( + "You can select inheritances from the combo below to add them.\nSince the order of inheritances is important, you can reorder them here via drag and drop.\nYou can also delete inheritances by dragging them onto the trash can."u8); } private static void DrawHelpPopup() - => ImGuiUtil.HelpPopup("InheritanceHelp", new Vector2(1000 * Im.Style.GlobalScale, 20 * Im.Style.TextHeightWithSpacing), () => + => ImEx.HelpPopup("InheritanceHelp"u8, new Vector2(1000 * Im.Style.GlobalScale, 20 * Im.Style.TextHeightWithSpacing), () => { Im.Line.New(); - ImGui.TextUnformatted("Every mod in a collection can have three basic states: 'Enabled', 'Disabled' and 'Unconfigured'."); - ImGui.BulletText("If the mod is 'Enabled' or 'Disabled', it does not matter if the collection inherits from other collections."); - ImGui.BulletText( - "If the mod is unconfigured, those inherited-from collections are checked in the order displayed here, including sub-inheritances."); - ImGui.BulletText( - "If a collection is found in which the mod is either 'Enabled' or 'Disabled', the settings from this collection will be used."); - ImGui.BulletText("If no such collection is found, the mod will be treated as disabled."); - ImGui.BulletText( - "Highlighted collections in the left box are never reached because they are already checked in a sub-inheritance before."); + Im.Text("Every mod in a collection can have three basic states: 'Enabled', 'Disabled' and 'Unconfigured'."u8); + Im.BulletText("If the mod is 'Enabled' or 'Disabled', it does not matter if the collection inherits from other collections."u8); + Im.BulletText( + "If the mod is unconfigured, those inherited-from collections are checked in the order displayed here, including sub-inheritances."u8); + Im.BulletText( + "If a collection is found in which the mod is either 'Enabled' or 'Disabled', the settings from this collection will be used."u8); + Im.BulletText("If no such collection is found, the mod will be treated as disabled."u8); + Im.BulletText( + "Highlighted collections in the left box are never reached because they are already checked in a sub-inheritance before."u8); Im.Line.New(); - ImGui.TextUnformatted("Example"); - ImGui.BulletText("Collection A has the Bibo+ body and a Hempen Camise mod enabled."); - ImGui.BulletText( - "Collection B inherits from A, leaves Bibo+ unconfigured, but has the Hempen Camise enabled with different settings than A."); - ImGui.BulletText("Collection C also inherits from A, has Bibo+ explicitly disabled and the Hempen Camise unconfigured."); - ImGui.BulletText("Collection D inherits from C and then B and leaves everything unconfigured."); - using var indent = ImRaii.PushIndent(); - ImGui.BulletText("B uses Bibo+ settings from A and its own Hempen Camise settings."); - ImGui.BulletText("C has Bibo+ disabled and uses A's Hempen Camise settings."); - ImGui.BulletText( - "D has Bibo+ disabled and uses A's Hempen Camise settings, not B's. It traversed the collections in Order D -> (C -> A) -> (B -> A)."); + Im.Text("Example"u8); + Im.BulletText("Collection A has the Bibo+ body and a Hempen Camise mod enabled."u8); + Im.BulletText( + "Collection B inherits from A, leaves Bibo+ unconfigured, but has the Hempen Camise enabled with different settings than A."u8); + Im.BulletText("Collection C also inherits from A, has Bibo+ explicitly disabled and the Hempen Camise unconfigured."u8); + Im.BulletText("Collection D inherits from C and then B and leaves everything unconfigured."u8); + using var indent = Im.Indent(); + Im.BulletText("B uses Bibo+ settings from A and its own Hempen Camise settings."u8); + Im.BulletText("C has Bibo+ disabled and uses A's Hempen Camise settings."u8); + Im.BulletText( + "D has Bibo+ disabled and uses A's Hempen Camise settings, not B's. It traversed the collections in Order D -> (C -> A) -> (B -> A)."u8); }); @@ -94,15 +94,15 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService /// private void DrawInheritedChildren(ModCollection collection) { - using var id = ImRaii.PushId(collection.Identity.Index); - using var indent = ImRaii.PushIndent(); + using var id = Im.Id.Push(collection.Identity.Index); + using var indent = Im.Indent(); // Get start point for the lines (top of the selector). // Tree line stuff. - var lineStart = ImGui.GetCursorScreenPos(); - var offsetX = -ImGui.GetStyle().IndentSpacing + ImGui.GetTreeNodeToLabelSpacing() / 2; - var drawList = ImGui.GetWindowDrawList(); - var lineSize = Math.Max(0, ImGui.GetStyle().IndentSpacing - 9 * Im.Style.GlobalScale); + var lineStart = Im.Cursor.ScreenPosition; + var offsetX = -Im.Style.IndentSpacing + Im.Style.TreeNodeToLabelSpacing / 2; + var drawList = Im.Window.DrawList.Shape; + var lineSize = Math.Max(0, Im.Style.IndentSpacing - 9 * Im.Style.GlobalScale); lineStart.X += offsetX; lineStart.Y -= 2 * Im.Style.GlobalScale; var lineEnd = lineStart; @@ -115,9 +115,9 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService _seenInheritedCollections.Contains(inheritance)); _seenInheritedCollections.Add(inheritance); - ImRaii.TreeNode($"{Name(inheritance)}###{inheritance.Identity.Id}", - ImGuiTreeNodeFlags.NoTreePushOnOpen | ImGuiTreeNodeFlags.Leaf | ImGuiTreeNodeFlags.Bullet); - var (minRect, maxRect) = (ImGui.GetItemRectMin(), ImGui.GetItemRectMax()); + Im.Tree.Node($"{Name(inheritance)}###{inheritance.Identity.Id}", + TreeNodeFlags.NoTreePushOnOpen | TreeNodeFlags.Leaf | TreeNodeFlags.Bullet).Dispose(); + var (minRect, maxRect) = (Im.Item.UpperLeftCorner, Im.Item.LowerRightCorner); DrawInheritanceTreeClicks(inheritance, false); // Tree line stuff. @@ -126,13 +126,13 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService // Draw the notch and increase the line length. var midPoint = (minRect.Y + maxRect.Y) / 2f - 1f; - drawList.AddLine(lineStart with { Y = midPoint }, new Vector2(lineStart.X + lineSize, midPoint), Colors.MetaInfoText, + drawList.Line(lineStart with { Y = midPoint }, new Vector2(lineStart.X + lineSize, midPoint), Colors.MetaInfoText, Im.Style.GlobalScale); lineEnd.Y = midPoint; } // Finally, draw the folder line. - drawList.AddLine(lineStart, lineEnd, Colors.MetaInfoText, Im.Style.GlobalScale); + drawList.Line(lineStart, lineEnd, Colors.MetaInfoText, Im.Style.GlobalScale); } /// Draw a single primary inherited collection. @@ -141,7 +141,7 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService using var color = ImGuiColor.Text.Push(ColorId.HandledConflictMod.Value(), _seenInheritedCollections.Contains(collection)); _seenInheritedCollections.Add(collection); - using var tree = ImRaii.TreeNode($"{Name(collection)}###{collection.Identity.Name}", ImGuiTreeNodeFlags.NoTreePushOnOpen); + using var tree = Im.Tree.Node($"{Name(collection)}###{collection.Identity.Name}", TreeNodeFlags.NoTreePushOnOpen); color.Pop(); DrawInheritanceTreeClicks(collection, true); DrawInheritanceDropSource(collection); @@ -157,7 +157,7 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService /// Draw the list box containing the current inheritance information. private void DrawCurrentCollectionInheritance() { - using var list = ImRaii.ListBox("##inheritanceList", + using var list = Im.ListBox.Begin("##inheritanceList"u8, new Vector2(UiHelpers.InputTextMinusButton, Im.Style.TextHeightWithSpacing * InheritedCollectionHeight)); if (!list) return; @@ -176,11 +176,10 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService // Prevent hovering from highlighting the button. using var color = ImGuiColor.ButtonActive.Push(buttonColor) .Push(ImGuiColor.ButtonHovered, buttonColor); - ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), size, - "Drag primary inheritance here to remove it from the list.", false, true); + ImEx.Icon.Button(LunaStyle.DeleteIcon, "Drag primary inheritance here to remove it from the list."u8, size); - using var target = ImRaii.DragDropTarget(); - if (target.Success && ImGuiUtil.IsDropping(InheritanceDragDropLabel)) + using var target = Im.DragDrop.Target(); + if (target.Success && target.IsDropping(InheritanceDragDropLabel)) _inheritanceAction = (_active.Current.Inheritance.DirectlyInheritsFrom.IndexOf(_movedInheritance!), -1); } @@ -228,8 +227,7 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService InheritanceManager.ValidInheritance.Circle => "Inheriting from this collection would lead to cyclic inheritance.", _ => string.Empty, }; - if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), UiHelpers.IconButtonSize, tt, - inheritance != InheritanceManager.ValidInheritance.Valid, true) + if (ImEx.Icon.Button(LunaStyle.AddObjectIcon, tt, inheritance is not InheritanceManager.ValidInheritance.Valid) && _inheritance.AddInheritance(_active.Current, _newInheritance!)) _newInheritance = null; @@ -243,11 +241,11 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService /// private void DrawNewInheritanceCombo() { - ImGui.SetNextItemWidth(UiHelpers.InputTextMinusButton); + Im.Item.SetNextWidth(UiHelpers.InputTextMinusButton); _newInheritance ??= _collections.FirstOrDefault(c => c != _active.Current && !_active.Current.Inheritance.DirectlyInheritsFrom.Contains(c)) ?? ModCollection.Empty; - using var combo = ImRaii.Combo("##newInheritance", Name(_newInheritance)); + using var combo = Im.Combo.Begin("##newInheritance"u8, Name(_newInheritance)); if (!combo) return; @@ -255,7 +253,7 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService .Where(c => InheritanceManager.CheckValidInheritance(_active.Current, c) == InheritanceManager.ValidInheritance.Valid) .OrderBy(c => c.Identity.Name)) { - if (ImGui.Selectable(Name(collection), _newInheritance == collection)) + if (Im.Selectable(Name(collection), _newInheritance == collection)) _newInheritance = collection; } } @@ -266,8 +264,8 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService /// private void DrawInheritanceDropTarget(ModCollection collection) { - using var target = ImRaii.DragDropTarget(); - if (!target.Success || !ImGuiUtil.IsDropping(InheritanceDragDropLabel)) + using var target = Im.DragDrop.Target(); + if (!target.Success || !target.IsDropping(InheritanceDragDropLabel)) return; if (_movedInheritance != null) @@ -284,13 +282,13 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService /// Move an inherited collection. private void DrawInheritanceDropSource(ModCollection collection) { - using var source = ImRaii.DragDropSource(); + using var source = Im.DragDrop.Source(); if (!source) return; - ImGui.SetDragDropPayload(InheritanceDragDropLabel, null); + source.SetPayload(InheritanceDragDropLabel); _movedInheritance = collection; - ImGui.TextUnformatted($"Moving {(_movedInheritance != null ? Name(_movedInheritance) : "Unknown")}..."); + Im.Text($"Moving {(_movedInheritance != null ? Name(_movedInheritance) : "Unknown")}..."); } /// @@ -300,16 +298,16 @@ public class InheritanceUi(CollectionManager collectionManager, IncognitoService /// private void DrawInheritanceTreeClicks(ModCollection collection, bool withDelete) { - if (ImGui.GetIO().KeyCtrl && Im.Item.RightClicked()) + if (Im.Io.KeyControl && Im.Item.RightClicked()) { - if (withDelete && ImGui.GetIO().KeyShift) + if (withDelete && Im.Io.KeyShift) _inheritanceAction = (_active.Current.Inheritance.DirectlyInheritsFrom.IndexOf(collection), -1); else _newCurrentCollection = collection; } - ImGuiUtil.HoverTooltip($"Control + Right-Click to switch the {TutorialService.SelectedCollection} to this one." - + (withDelete ? "\nControl + Shift + Right-Click to remove this inheritance." : string.Empty)); + Im.Tooltip.OnHover( + $"Control + Right-Click to switch the {TutorialService.SelectedCollection} to this one.{(withDelete ? "\nControl + Shift + Right-Click to remove this inheritance."u8 : StringU8.Empty)}"); } private string Name(ModCollection collection) diff --git a/Penumbra/UI/CollectionTab/ObjectKindCombo.cs b/Penumbra/UI/CollectionTab/ObjectKindCombo.cs new file mode 100644 index 00000000..a916953b --- /dev/null +++ b/Penumbra/UI/CollectionTab/ObjectKindCombo.cs @@ -0,0 +1,25 @@ +using Dalamud.Game.ClientState.Objects.Enums; +using ImSharp; + +namespace Penumbra.UI.CollectionTab; + +public sealed class ObjectKindCombo(params IReadOnlyList kinds) : SimpleFilterCombo(SimpleFilterType.None) +{ + public override StringU8 DisplayString(in ObjectKind value) + => value switch + { + ObjectKind.None => new StringU8("Unknown"u8), + ObjectKind.BattleNpc => new StringU8("Battle NPC"u8), + ObjectKind.EventNpc => new StringU8("Event NPC"u8), + ObjectKind.MountType => new StringU8("Mount"u8), + ObjectKind.Companion => new StringU8("Companion"u8), + ObjectKind.Ornament => new StringU8("Accessory"u8), + _ => new StringU8($"{value}"), + }; + + public override string FilterString(in ObjectKind value) + => string.Empty; + + public override IEnumerable GetBaseItems() + => kinds; +} diff --git a/Penumbra/UI/ModsTab/DescriptionEditPopup.cs b/Penumbra/UI/ModsTab/DescriptionEditPopup.cs index 0a189fa0..dab133f1 100644 --- a/Penumbra/UI/ModsTab/DescriptionEditPopup.cs +++ b/Penumbra/UI/ModsTab/DescriptionEditPopup.cs @@ -12,7 +12,7 @@ public class DescriptionEditPopup(ModManager modManager) : Luna.IUiService => "EditDesc"u8; private bool _hasBeenEdited; - private string _description = string.Empty; + private StringU8 _description = StringU8.Empty; private object? _current; private bool _opened; @@ -22,7 +22,7 @@ public class DescriptionEditPopup(ModManager modManager) : Luna.IUiService _current = mod; _opened = true; _hasBeenEdited = false; - _description = mod.Description; + _description = new StringU8(mod.Description); } public void Open(IModGroup group) @@ -30,7 +30,7 @@ public class DescriptionEditPopup(ModManager modManager) : Luna.IUiService _current = group; _opened = true; _hasBeenEdited = false; - _description = group.Description; + _description = new StringU8(group.Description); } public void Open(IModOption option) @@ -38,7 +38,7 @@ public class DescriptionEditPopup(ModManager modManager) : Luna.IUiService _current = option; _opened = true; _hasBeenEdited = false; - _description = option.Description; + _description = new StringU8(option.Description); } public void Draw() @@ -60,8 +60,8 @@ public class DescriptionEditPopup(ModManager modManager) : Luna.IUiService if (Im.Window.Appearing) Im.Keyboard.SetFocusHere(); - ImEx.InputOnDeactivation.MultiLine("##editDescription"u8, _description, out _description, inputSize); - _hasBeenEdited |= Im.Item.Edited; + if (Im.Input.MultiLine("##editDescription"u8, ref _description, inputSize)) + _hasBeenEdited = true; UiHelpers.DefaultLineSpace(); var buttonSize = new Vector2(Im.Style.GlobalScale * 100, 0); @@ -83,12 +83,12 @@ public class DescriptionEditPopup(ModManager modManager) : Luna.IUiService switch (_current) { - case Mod mod: modManager.DataEditor.ChangeModDescription(mod, _description); break; - case IModGroup group: modManager.OptionEditor.ChangeGroupDescription(group, _description); break; - case IModOption option: modManager.OptionEditor.ChangeOptionDescription(option, _description); break; + case Mod mod: modManager.DataEditor.ChangeModDescription(mod, _description.ToString()); break; + case IModGroup group: modManager.OptionEditor.ChangeGroupDescription(group, _description.ToString()); break; + case IModOption option: modManager.OptionEditor.ChangeOptionDescription(option, _description.ToString()); break; } - _description = string.Empty; + _description = StringU8.Empty; _hasBeenEdited = false; Im.Popup.CloseCurrent(); } @@ -98,7 +98,7 @@ public class DescriptionEditPopup(ModManager modManager) : Luna.IUiService if (!Im.Button("Cancel"u8, buttonSize) && !Im.Keyboard.IsPressed(Key.Escape)) return; - _description = string.Empty; + _description = StringU8.Empty; _hasBeenEdited = false; Im.Popup.CloseCurrent(); }