using System.Collections.Generic; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Component.GUI; namespace Dalamud.Game.Gui.ContextMenu; /// /// Interface representing a context menus args. /// public interface IMenuArgs { /// /// Gets a list of AtkEventInterface pointers associated with the context menu. /// Only available with . /// Almost always an agent pointer. You can use this to find out what type of context menu it is. /// /// Thrown when the context menu is not a . public IReadOnlySet EventInterfaces { get; } /// /// Gets the name of the addon that opened the context menu. /// public string? AddonName { get; } /// /// Gets the memory pointer of the addon that opened the context menu. /// public nint AddonPtr { get; } /// /// Gets the memory pointer of the agent that opened the context menu. /// public nint AgentPtr { get; } /// /// Gets the type of the context menu. /// public ContextMenuType MenuType { get; } /// /// Gets the target info of the context menu. The actual type depends on . /// signifies a . /// signifies a . /// public MenuTarget Target { get; } } /// /// Base class for menu args. /// internal abstract unsafe class MenuArgs : IMenuArgs { private IReadOnlySet? eventInterfaces; /// /// Initializes a new instance of the class. /// /// Addon associated with the context menu. /// Agent associated with the context menu. /// The type of context menu. /// List of AtkEventInterfaces associated with the context menu. protected internal MenuArgs(AtkUnitBase* addon, AgentInterface* agent, ContextMenuType type, IReadOnlySet? eventInterfaces) { this.AddonName = addon != null ? addon->NameString : null; this.AddonPtr = (nint)addon; this.AgentPtr = (nint)agent; this.MenuType = type; this.eventInterfaces = eventInterfaces; this.Target = type switch { ContextMenuType.Default => new MenuTargetDefault((AgentContext*)agent), ContextMenuType.Inventory => new MenuTargetInventory((AgentInventoryContext*)agent), _ => throw new ArgumentException("Invalid context menu type", nameof(type)), }; } /// public string? AddonName { get; } /// public nint AddonPtr { get; } /// public nint AgentPtr { get; } /// public ContextMenuType MenuType { get; } /// public MenuTarget Target { get; } /// public IReadOnlySet EventInterfaces { get { if (this.MenuType is ContextMenuType.Default) { return this.eventInterfaces ?? new HashSet(); } else { throw new InvalidOperationException("Not a default context menu"); } } } }