Add SelectTab event, update new clientstructs.

This commit is contained in:
Ottermandias 2023-06-07 18:29:05 +02:00
parent 78e772dad9
commit 5fcb07487e
10 changed files with 79 additions and 159 deletions

View file

@ -1,118 +0,0 @@
using System;
using Penumbra.GameData.Enums;
using Penumbra.String.Functions;
namespace Penumbra.GameData.Structs;
public readonly unsafe struct CharacterEquip
{
public const int Slots = 10;
public const int Size = CharacterArmor.Size * Slots;
public static readonly CharacterEquip Null = new(null);
private readonly CharacterArmor* _armor;
public IntPtr Address
=> ( IntPtr )_armor;
public ref CharacterArmor this[ int idx ]
=> ref _armor[ idx ];
public ref CharacterArmor this[ uint idx ]
=> ref _armor[ idx ];
public ref CharacterArmor this[ EquipSlot slot ]
=> ref _armor[ IndexOf( slot ) ];
public ref CharacterArmor Head
=> ref _armor[ 0 ];
public ref CharacterArmor Body
=> ref _armor[ 1 ];
public ref CharacterArmor Hands
=> ref _armor[ 2 ];
public ref CharacterArmor Legs
=> ref _armor[ 3 ];
public ref CharacterArmor Feet
=> ref _armor[ 4 ];
public ref CharacterArmor Ears
=> ref _armor[ 5 ];
public ref CharacterArmor Neck
=> ref _armor[ 6 ];
public ref CharacterArmor Wrists
=> ref _armor[ 7 ];
public ref CharacterArmor RFinger
=> ref _armor[ 8 ];
public ref CharacterArmor LFinger
=> ref _armor[ 9 ];
public CharacterEquip( CharacterArmor* val )
=> _armor = val;
public static implicit operator CharacterEquip( CharacterArmor* val )
=> new(val);
public static implicit operator CharacterEquip( IntPtr val )
=> new(( CharacterArmor* )val);
public static implicit operator CharacterEquip( ReadOnlySpan< CharacterArmor > val )
{
if( val.Length != 10 )
{
throw new ArgumentException( "Invalid number of equipment pieces in span." );
}
fixed( CharacterArmor* ptr = val )
{
return new CharacterEquip( ptr );
}
}
public static implicit operator bool( CharacterEquip equip )
=> equip._armor != null;
public static bool operator true( CharacterEquip equip )
=> equip._armor != null;
public static bool operator false( CharacterEquip equip )
=> equip._armor == null;
public static bool operator !( CharacterEquip equip )
=> equip._armor == null;
private static int IndexOf( EquipSlot slot )
{
return slot switch
{
EquipSlot.Head => 0,
EquipSlot.Body => 1,
EquipSlot.Hands => 2,
EquipSlot.Legs => 3,
EquipSlot.Feet => 4,
EquipSlot.Ears => 5,
EquipSlot.Neck => 6,
EquipSlot.Wrists => 7,
EquipSlot.RFinger => 8,
EquipSlot.LFinger => 9,
_ => throw new ArgumentOutOfRangeException( nameof( slot ), slot, null ),
};
}
public void Load( CharacterEquip source )
{
MemoryUtility.MemCpyUnchecked( _armor, source._armor, sizeof( CharacterArmor ) * 10 );
}
public bool Equals( CharacterEquip other )
=> MemoryUtility.MemCmpUnchecked( ( void* )_armor, ( void* )other._armor, sizeof( CharacterArmor ) * 10 ) == 0;
}

View file

@ -258,16 +258,17 @@ public class PenumbraApi : IDisposable, IPenumbraApi
if (!Enum.IsDefined(tab))
return PenumbraApiEc.InvalidArgument;
if (tab != TabType.None)
_configWindow.SelectTab(tab);
if (tab == TabType.Mods && (modDirectory.Length > 0 || modName.Length > 0))
{
if (_modManager.TryGetMod(modDirectory, modName, out var mod))
_configWindow.SelectMod(mod);
_communicator.SelectTab.Invoke(tab, mod);
else
return PenumbraApiEc.ModMissing;
}
else if (tab != TabType.None)
{
_communicator.SelectTab.Invoke(tab);
}
return PenumbraApiEc.Success;
}

View file

@ -0,0 +1,29 @@
using System;
using OtterGui.Classes;
using Penumbra.Api.Enums;
using Penumbra.Mods;
namespace Penumbra.Communication;
/// <summary>
/// Trigger to select a tab and mod in the Config Window.
/// <list type="number">
/// <item>Parameter is the selected tab. </item>
/// <item>Parameter is the selected mod, if any. </item>
/// </list>
/// </summary>
public sealed class SelectTab : EventWrapper<Action<TabType, Mod?>, SelectTab.Priority>
{
public enum Priority
{
/// <seealso cref="UI.Tabs.ConfigTabBar.OnSelectTab"/>
ConfigTabBar = 0,
}
public SelectTab()
: base(nameof(SelectTab))
{ }
public void Invoke(TabType tab = TabType.None, Mod? mod = null)
=> Invoke(this, tab, mod);
}

View file

@ -89,7 +89,7 @@ public class ResourceTree
? imcNode.WithName(imcNode.Name ?? $"{subObjectNamePrefix} #{subObjectIndex}, IMC #{i}")
: imcNode);
var mdl = (RenderModel*)subObject->ModelArray[i];
var mdl = (RenderModel*)subObject->Models[i];
var mdlNode = subObjectContext.CreateNodeFromRenderModel(mdl);
if (mdlNode != null)
subObjectNodes.Add(globalContext.WithNames

View file

@ -267,7 +267,6 @@ public class ModDataEditor
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Favorite, mod, null);
}
private void ChangeTag(Mod mod, int tagIdx, string newTag, bool local)
{
var which = local ? mod.LocalTags : mod.ModTags;

View file

@ -63,6 +63,9 @@ public class CommunicatorService : IDisposable
/// <inheritdoc cref="Communication.ChangedItemClick"/>
public readonly ChangedItemClick ChangedItemClick = new();
/// <inheritdoc cref="Communication.SelectTab"/>
public readonly SelectTab SelectTab = new();
public void Dispose()
{
CollectionChange.Dispose();
@ -82,5 +85,6 @@ public class CommunicatorService : IDisposable
PostSettingsPanelDraw.Dispose();
ChangedItemHover.Dispose();
ChangedItemClick.Dispose();
SelectTab.Dispose();
}
}

View file

@ -5,8 +5,6 @@ using Dalamud.Plugin;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.Api.Enums;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI.Classes;
using Penumbra.UI.Tabs;
@ -24,12 +22,6 @@ public sealed class ConfigWindow : Window
private ConfigTabBar _configTabs = null!;
private string? _lastException;
public void SelectTab(TabType tab)
=> _configTabs.SelectTab = tab;
public void SelectMod(Mod mod)
=> _configTabs.Mods.SelectMod = mod;
public ConfigWindow(PerformanceTracker tracker, DalamudPluginInterface pi, Configuration config, ValidityChecker checker,
TutorialService tutorial)
: base(GetLabel(checker))
@ -48,7 +40,7 @@ public sealed class ConfigWindow : Window
{
_penumbra = penumbra;
_configTabs = configTabs;
SelectTab(_config.SelectedTab);
_configTabs.SelectTab = _config.SelectedTab;
}
public override bool DrawConditions()

View file

@ -10,6 +10,7 @@ using OtterGui.Widgets;
using Penumbra.Api.Enums;
using Penumbra.Collections.Manager;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI.Classes;
namespace Penumbra.UI.Tabs;
@ -19,18 +20,17 @@ public class ChangedItemsTab : ITab
private readonly CollectionManager _collectionManager;
private readonly ChangedItemDrawer _drawer;
private readonly CollectionSelectHeader _collectionHeader;
private ConfigTabBar? _tabBar = null;
private readonly CommunicatorService _communicator;
public ChangedItemsTab(CollectionManager collectionManager, CollectionSelectHeader collectionHeader, ChangedItemDrawer drawer)
public ChangedItemsTab(CollectionManager collectionManager, CollectionSelectHeader collectionHeader, ChangedItemDrawer drawer,
CommunicatorService communicator)
{
_collectionManager = collectionManager;
_collectionHeader = collectionHeader;
_drawer = drawer;
_communicator = communicator;
}
public void SetTabBar(ConfigTabBar tabBar)
=> _tabBar = tabBar;
public ReadOnlySpan<byte> Label
=> "Changed Items"u8;
@ -110,12 +110,8 @@ public class ChangedItemsTab : ITab
using var style = ImRaii.PushStyle(ImGuiStyleVar.SelectableTextAlign, new Vector2(0, 0.5f));
if (ImGui.Selectable(first.Name, false, ImGuiSelectableFlags.None, new Vector2(0, ImGui.GetFrameHeight()))
&& ImGui.GetIO().KeyCtrl
&& _tabBar != null
&& first is Mod mod)
{
_tabBar.SelectTab = TabType.Mods;
_tabBar.Mods.SelectMod = mod;
}
_communicator.SelectTab.Invoke(TabType.Mods, mod);
if (ImGui.IsItemHovered())
{

View file

@ -2,11 +2,15 @@ using System;
using ImGuiNET;
using OtterGui.Widgets;
using Penumbra.Api.Enums;
using Penumbra.Mods;
using Penumbra.Services;
namespace Penumbra.UI.Tabs;
public class ConfigTabBar
public class ConfigTabBar : IDisposable
{
private readonly CommunicatorService _communicator;
public readonly SettingsTab Settings;
public readonly ModsTab Mods;
public readonly CollectionsTab Collections;
@ -22,9 +26,12 @@ public class ConfigTabBar
/// <summary> The tab to select on the next Draw call, if any. </summary>
public TabType SelectTab = TabType.None;
public ConfigTabBar(SettingsTab settings, ModsTab mods, CollectionsTab collections, ChangedItemsTab changedItems, EffectiveTab effective,
DebugTab debug, ResourceTab resource, ResourceWatcher watcher, OnScreenTab onScreenTab)
public ConfigTabBar(CommunicatorService communicator, SettingsTab settings, ModsTab mods, CollectionsTab collections,
ChangedItemsTab changedItems, EffectiveTab effective, DebugTab debug, ResourceTab resource, ResourceWatcher watcher,
OnScreenTab onScreenTab)
{
_communicator = communicator;
Settings = settings;
Mods = mods;
Collections = collections;
@ -46,9 +53,12 @@ public class ConfigTabBar
Resource,
Watcher,
};
ChangedItems.SetTabBar(this);
_communicator.SelectTab.Subscribe(OnSelectTab, Communication.SelectTab.Priority.ConfigTabBar);
}
public void Dispose()
=> _communicator.SelectTab.Unsubscribe(OnSelectTab);
public TabType Draw()
{
if (TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ToLabel(SelectTab), out var currentLabel, () => { }, Tabs))
@ -87,4 +97,11 @@ public class ConfigTabBar
// @formatter:on
return TabType.None;
}
private void OnSelectTab(TabType tab, Mod? mod)
{
SelectTab = tab;
if (mod != null)
Mods.SelectMod = mod;
}
}

View file

@ -696,7 +696,7 @@ public class DebugTab : Window, ITab
if (imc != null)
UiHelpers.Text(imc);
var mdl = (RenderModel*)model->ModelArray[i];
var mdl = (RenderModel*)model->Models[i];
ImGui.TableNextColumn();
ImGui.TextUnformatted(mdl == null ? "NULL" : $"0x{(ulong)mdl:X}");
if (mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara)