mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Add SelectTab event, update new clientstructs.
This commit is contained in:
parent
78e772dad9
commit
5fcb07487e
10 changed files with 79 additions and 159 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
29
Penumbra/Communication/SelectTab.cs
Normal file
29
Penumbra/Communication/SelectTab.cs
Normal 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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue