# Inventool Action Menu

## 📋 InventoolActionMenu Class

A pop-up menu for custom actions.

> **Namespace:** `Esper.Inventool.UI`\
> **Access:** `public`\
> **Type:** `class`\
> **Inherits:** `CrossInputSupportedWindow`

***

### 📦 Fields

| Access      | Field             | Type            | Description                               |
| ----------- | ----------------- | --------------- | ----------------------------------------- |
| `protected` | `root`            | `VisualElement` | The root of the content.                  |
| `protected` | `optionContainer` | `VisualElement` | The visual element that contains options. |
| `protected` | `closeButton`     | `Button`        | The full-screen invisible close button.   |

***

### 🔍 Properties

| Access          | Property   | Type                  | Description                |
| --------------- | ---------- | --------------------- | -------------------------- |
| `public static` | `Instance` | `InventoolActionMenu` | Active singleton instance. |

***

### 🧰 Methods

| Access               | Method                                                          | Returns       | Description                                    |
| -------------------- | --------------------------------------------------------------- | ------------- | ---------------------------------------------- |
| `protected override` | `Awake()`                                                       | `void`        | Initialize singleton and cache UI elements.    |
| `protected virtual`  | `CreateMenuOption(ActionMenuOption actionMenuOption)`           | `Button`      | Create a button for a menu option.             |
| `public virtual`     | `Open(VisualElement target, params ActionMenuOption[] options)` | `void`        | Display menu at target with specified options. |
| `public virtual`     | `Open(VisualElement target, List<ActionMenuOption> options)`    | `void`        | Display menu at target with an option list.    |
| `public virtual`     | `Close()`                                                       | `void`        | Hide menu and invoke close callbacks.          |
| `protected`          | `ForceInsideView()`                                             | `IEnumerator` | Ensure the menu stays within the viewport.     |

## Active Instance

You can get the active `InventoolActionMenu` instance with `InventoolActionMenu.Instance`. Ensure there's an instance of it in your scene before using this field.

## Opening

Opening the action menu requires a `VisualElement` target and a list of [action-menu-option](https://stylishesper.gitbook.io/inventool/scripting/api/ui/action-menu-option "mention").

```csharp
InventoolActionMenu.Instance.Open(targetElement, myMenuOptions);
```

## Closing

```csharp
InventoolActionMenu.Instance.Close();
```

## Customizations

The options displayed on the action menu are customizable through scripting.

### Customize For Inventory Item Stacks

To customize the action menu options displayed when an item stack in the inventory is clicked, edit the `ItemStack.actionMenuOptionsGetter` field.

```csharp
using Esper.Inventool.Items;
using Esper.Inventool.UI;
using System.Collections.Generic;
using UnityEngine;

public class ActionMenuCustomizer : MonoBehaviour
{
    public Sprite myIcon;

    private void Awake()
    {
        // Apply the customization on awake
        ItemStack.actionMenuOptionsGetter = MyActionMenuOptionsGetter;
    }

    /// <summary>
    /// Creates and returns the action menu options.
    /// </summary>
    /// <param name="itemStack">The item stack target to create the options for.</param>
    /// <returns>A list of action menu options.</returns>
    private List<ActionMenuOption> MyActionMenuOptionsGetter(ItemStack itemStack)
    {
        // Create a list that will contain the options
        var options = ItemStack.GetDefaultActionMenuOptions(itemStack);

        // Add an option
        var myOption = new ActionMenuOption()
        {
            // Set the button text (smallcaps is generally used for styling purposes)
            text = $"<smallcaps>My Option</smallcaps>",

            // Set the button color
            backgroundColor = new Color(0.3f, 0.3f, 0.3f),

            // Set its order in the menu (lower numbers appear at the top)
            sortingOrder = 0,

            // Create an on-click action
            action = () => Debug.Log("Do something"),
            
            // Display a small icon beside the text
            icon = myIcon
        };

        options.Add(myOption);

        return options;
    }
}
```

If you'd like a reference, you can find the original in the `ItemStack.actionMenuOptionsGetter` field in the ItemStack.cs script.

### Customize For Equipment Slots

To customize the action menu options displayed when an equipment slot in the inventory is clicked, edit the `EquipmentSlot.actionMenuOptionsGetter` field.

```csharp
using Esper.Inventool;
using Esper.Inventool.UI;
using System.Collections.Generic;
using UnityEngine;

public class ActionMenuCustomizer : MonoBehaviour
{
    private void Awake()
    {
        // Apply the customization on awake
        EquipmentSlot.actionMenuOptionsGetter = MyActionMenuOptionsGetter;
    }

    /// <summary>
    /// Creates and returns the action menu options.
    /// </summary>
    /// <param name="slot">The equipment slot target to create the options for.</param>
    /// <returns>A list of action menu options.</returns>
    private List<ActionMenuOption> MyActionMenuOptionsGetter(EquipmentSlot slot)
    {
        // Create a list that will contain the options
        var options = EquipmentSlot.GetDefaultActionMenuOptions(slot);

        // Add an option
        var myOption = new ActionMenuOption()
        {
            // Set the button text (smallcaps is generally used for styling purposes)
            text = $"<smallcaps>My Option</smallcaps>",

            // Set the button color
            backgroundColor = new Color(0.3f, 0.3f, 0.3f),

            // Set its order in the menu (lower numbers appear at the top)
            sortingOrder = 0,

            // Create an on-click action
            action = () => Debug.Log("Do something")
        };

        options.Add(myOption);

        return options;
    }
}
```

If you'd like a reference, you can find the original in the `EquipmentSlot.actionMenuOptionsGetter` field in the EquipmentSlot.cs script.
