mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +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))
|
if (!Enum.IsDefined(tab))
|
||||||
return PenumbraApiEc.InvalidArgument;
|
return PenumbraApiEc.InvalidArgument;
|
||||||
|
|
||||||
if (tab != TabType.None)
|
|
||||||
_configWindow.SelectTab(tab);
|
|
||||||
|
|
||||||
if (tab == TabType.Mods && (modDirectory.Length > 0 || modName.Length > 0))
|
if (tab == TabType.Mods && (modDirectory.Length > 0 || modName.Length > 0))
|
||||||
{
|
{
|
||||||
if (_modManager.TryGetMod(modDirectory, modName, out var mod))
|
if (_modManager.TryGetMod(modDirectory, modName, out var mod))
|
||||||
_configWindow.SelectMod(mod);
|
_communicator.SelectTab.Invoke(tab, mod);
|
||||||
else
|
else
|
||||||
return PenumbraApiEc.ModMissing;
|
return PenumbraApiEc.ModMissing;
|
||||||
}
|
}
|
||||||
|
else if (tab != TabType.None)
|
||||||
|
{
|
||||||
|
_communicator.SelectTab.Invoke(tab);
|
||||||
|
}
|
||||||
|
|
||||||
return PenumbraApiEc.Success;
|
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.WithName(imcNode.Name ?? $"{subObjectNamePrefix} #{subObjectIndex}, IMC #{i}")
|
||||||
: imcNode);
|
: imcNode);
|
||||||
|
|
||||||
var mdl = (RenderModel*)subObject->ModelArray[i];
|
var mdl = (RenderModel*)subObject->Models[i];
|
||||||
var mdlNode = subObjectContext.CreateNodeFromRenderModel(mdl);
|
var mdlNode = subObjectContext.CreateNodeFromRenderModel(mdl);
|
||||||
if (mdlNode != null)
|
if (mdlNode != null)
|
||||||
subObjectNodes.Add(globalContext.WithNames
|
subObjectNodes.Add(globalContext.WithNames
|
||||||
|
|
|
||||||
|
|
@ -267,7 +267,6 @@ public class ModDataEditor
|
||||||
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Favorite, mod, null);
|
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Favorite, mod, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void ChangeTag(Mod mod, int tagIdx, string newTag, bool local)
|
private void ChangeTag(Mod mod, int tagIdx, string newTag, bool local)
|
||||||
{
|
{
|
||||||
var which = local ? mod.LocalTags : mod.ModTags;
|
var which = local ? mod.LocalTags : mod.ModTags;
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,9 @@ public class CommunicatorService : IDisposable
|
||||||
/// <inheritdoc cref="Communication.ChangedItemClick"/>
|
/// <inheritdoc cref="Communication.ChangedItemClick"/>
|
||||||
public readonly ChangedItemClick ChangedItemClick = new();
|
public readonly ChangedItemClick ChangedItemClick = new();
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Communication.SelectTab"/>
|
||||||
|
public readonly SelectTab SelectTab = new();
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
CollectionChange.Dispose();
|
CollectionChange.Dispose();
|
||||||
|
|
@ -82,5 +85,6 @@ public class CommunicatorService : IDisposable
|
||||||
PostSettingsPanelDraw.Dispose();
|
PostSettingsPanelDraw.Dispose();
|
||||||
ChangedItemHover.Dispose();
|
ChangedItemHover.Dispose();
|
||||||
ChangedItemClick.Dispose();
|
ChangedItemClick.Dispose();
|
||||||
|
SelectTab.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ using Dalamud.Plugin;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Api.Enums;
|
|
||||||
using Penumbra.Mods;
|
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
using Penumbra.UI.Tabs;
|
using Penumbra.UI.Tabs;
|
||||||
|
|
@ -24,12 +22,6 @@ public sealed class ConfigWindow : Window
|
||||||
private ConfigTabBar _configTabs = null!;
|
private ConfigTabBar _configTabs = null!;
|
||||||
private string? _lastException;
|
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,
|
public ConfigWindow(PerformanceTracker tracker, DalamudPluginInterface pi, Configuration config, ValidityChecker checker,
|
||||||
TutorialService tutorial)
|
TutorialService tutorial)
|
||||||
: base(GetLabel(checker))
|
: base(GetLabel(checker))
|
||||||
|
|
@ -41,14 +33,14 @@ public sealed class ConfigWindow : Window
|
||||||
|
|
||||||
RespectCloseHotkey = true;
|
RespectCloseHotkey = true;
|
||||||
tutorial.UpdateTutorialStep();
|
tutorial.UpdateTutorialStep();
|
||||||
IsOpen = _config.DebugMode;
|
IsOpen = _config.DebugMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Setup(Penumbra penumbra, ConfigTabBar configTabs)
|
public void Setup(Penumbra penumbra, ConfigTabBar configTabs)
|
||||||
{
|
{
|
||||||
_penumbra = penumbra;
|
_penumbra = penumbra;
|
||||||
_configTabs = configTabs;
|
_configTabs = configTabs;
|
||||||
SelectTab(_config.SelectedTab);
|
_configTabs.SelectTab = _config.SelectedTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool DrawConditions()
|
public override bool DrawConditions()
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using OtterGui.Widgets;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
using Penumbra.Collections.Manager;
|
using Penumbra.Collections.Manager;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Services;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
||||||
namespace Penumbra.UI.Tabs;
|
namespace Penumbra.UI.Tabs;
|
||||||
|
|
@ -19,18 +20,17 @@ public class ChangedItemsTab : ITab
|
||||||
private readonly CollectionManager _collectionManager;
|
private readonly CollectionManager _collectionManager;
|
||||||
private readonly ChangedItemDrawer _drawer;
|
private readonly ChangedItemDrawer _drawer;
|
||||||
private readonly CollectionSelectHeader _collectionHeader;
|
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;
|
_collectionManager = collectionManager;
|
||||||
_collectionHeader = collectionHeader;
|
_collectionHeader = collectionHeader;
|
||||||
_drawer = drawer;
|
_drawer = drawer;
|
||||||
|
_communicator = communicator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTabBar(ConfigTabBar tabBar)
|
|
||||||
=> _tabBar = tabBar;
|
|
||||||
|
|
||||||
public ReadOnlySpan<byte> Label
|
public ReadOnlySpan<byte> Label
|
||||||
=> "Changed Items"u8;
|
=> "Changed Items"u8;
|
||||||
|
|
||||||
|
|
@ -106,16 +106,12 @@ public class ChangedItemsTab : ITab
|
||||||
if (mods.Count <= 0)
|
if (mods.Count <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var first = mods[0];
|
var first = mods[0];
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.SelectableTextAlign, new Vector2(0, 0.5f));
|
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()))
|
if (ImGui.Selectable(first.Name, false, ImGuiSelectableFlags.None, new Vector2(0, ImGui.GetFrameHeight()))
|
||||||
&& ImGui.GetIO().KeyCtrl
|
&& ImGui.GetIO().KeyCtrl
|
||||||
&& _tabBar != null
|
|
||||||
&& first is Mod mod)
|
&& first is Mod mod)
|
||||||
{
|
_communicator.SelectTab.Invoke(TabType.Mods, mod);
|
||||||
_tabBar.SelectTab = TabType.Mods;
|
|
||||||
_tabBar.Mods.SelectMod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,15 @@ using System;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Services;
|
||||||
|
|
||||||
namespace Penumbra.UI.Tabs;
|
namespace Penumbra.UI.Tabs;
|
||||||
|
|
||||||
public class ConfigTabBar
|
public class ConfigTabBar : IDisposable
|
||||||
{
|
{
|
||||||
|
private readonly CommunicatorService _communicator;
|
||||||
|
|
||||||
public readonly SettingsTab Settings;
|
public readonly SettingsTab Settings;
|
||||||
public readonly ModsTab Mods;
|
public readonly ModsTab Mods;
|
||||||
public readonly CollectionsTab Collections;
|
public readonly CollectionsTab Collections;
|
||||||
|
|
@ -22,9 +26,12 @@ public class ConfigTabBar
|
||||||
/// <summary> The tab to select on the next Draw call, if any. </summary>
|
/// <summary> The tab to select on the next Draw call, if any. </summary>
|
||||||
public TabType SelectTab = TabType.None;
|
public TabType SelectTab = TabType.None;
|
||||||
|
|
||||||
public ConfigTabBar(SettingsTab settings, ModsTab mods, CollectionsTab collections, ChangedItemsTab changedItems, EffectiveTab effective,
|
public ConfigTabBar(CommunicatorService communicator, SettingsTab settings, ModsTab mods, CollectionsTab collections,
|
||||||
DebugTab debug, ResourceTab resource, ResourceWatcher watcher, OnScreenTab onScreenTab)
|
ChangedItemsTab changedItems, EffectiveTab effective, DebugTab debug, ResourceTab resource, ResourceWatcher watcher,
|
||||||
|
OnScreenTab onScreenTab)
|
||||||
{
|
{
|
||||||
|
_communicator = communicator;
|
||||||
|
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
Mods = mods;
|
Mods = mods;
|
||||||
Collections = collections;
|
Collections = collections;
|
||||||
|
|
@ -46,9 +53,12 @@ public class ConfigTabBar
|
||||||
Resource,
|
Resource,
|
||||||
Watcher,
|
Watcher,
|
||||||
};
|
};
|
||||||
ChangedItems.SetTabBar(this);
|
_communicator.SelectTab.Subscribe(OnSelectTab, Communication.SelectTab.Priority.ConfigTabBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
=> _communicator.SelectTab.Unsubscribe(OnSelectTab);
|
||||||
|
|
||||||
public TabType Draw()
|
public TabType Draw()
|
||||||
{
|
{
|
||||||
if (TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ToLabel(SelectTab), out var currentLabel, () => { }, Tabs))
|
if (TabBar.Draw(string.Empty, ImGuiTabBarFlags.NoTooltip, ToLabel(SelectTab), out var currentLabel, () => { }, Tabs))
|
||||||
|
|
@ -87,4 +97,11 @@ public class ConfigTabBar
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
return TabType.None;
|
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)
|
if (imc != null)
|
||||||
UiHelpers.Text(imc);
|
UiHelpers.Text(imc);
|
||||||
|
|
||||||
var mdl = (RenderModel*)model->ModelArray[i];
|
var mdl = (RenderModel*)model->Models[i];
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.TextUnformatted(mdl == null ? "NULL" : $"0x{(ulong)mdl:X}");
|
ImGui.TextUnformatted(mdl == null ? "NULL" : $"0x{(ulong)mdl:X}");
|
||||||
if (mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara)
|
if (mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue