# ContextMenu class

## ContextMenu

The `ContextMenu` class manages right-click context menus for widgets in **DynamicHUD**, displaying customizable options (e.g., toggles, sliders). It supports animations, skins, and integration with `ContextMenuScreen` for separate rendering, handling input via the `Input` interface.

### Key Properties

* **properties**: `ContextMenuProperties` for styling (background, border, animations).
* **options**: List of `Option<?>` for menu items.
* **screenFactory**: `ContextMenuScreenFactory` to create rendering screens.
* **x, y**: Menu position, offset by `properties.getHeightOffset()`.
* **scale**: Animation scale (0 to 1) for open/close effects.

### Key Methods

* **addOption(Option\<?> option)**: Adds a menu option.
* **render(DrawContext, int, int, int, int)**: Renders the menu using the skin, applying scaling.
* **open()**, **close()**, **toggleDisplay()**: Controls menu visibility.
* **createSubMenu(int, int, ContextMenuProperties)**: Creates nested submenus.
* **mouseClicked(double, double, int)**: Handles option and skin interactions.

### Usage

Create a menu in `AbstractMoveableScreen` or `widget logic`  typically triggered by right-click (`GLFW_MOUSE_BUTTON_RIGHT`) on a `WidgetBox`.

Then implement the `ContextMenuProvider` interface and return the created menu at `getContextMenu()`\
After that register via `ContextMenuManager`.

Example:

```java
public class MyWidget extends Widget implements ContextMenuProvider {
    private ContextMenu<?> menu;
    
    public MyWidget(...) {
        super(...);
        createMenu(); // Create your menu by initialising with all settings you need
        ContextMenuManager.getInstance().registerProvider(this);
    }
    public void createMenu() {
     // Learn about this in the next page and ContextMenuProperties page.
        ContextMenuProperties properties = ContextMenuProperties.builder().build();
        menu = new ContextMenu<>(getX(), getY(), properties);

        menu.addOption(new BooleanOption(Text.of("My Boolean"),
                () -> this.getBoolean(), value -> this.setBoolean(value),
                BooleanOption.BooleanType.YES_NO)
                .description(Text.of("A boolean option in my widget!"))
        );
    }

    //Opening the menu by rightclicking, 
    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        menu.toggleDisplay(widgetBox, mouseX, mouseY, button);
        return super.mouseClicked(mouseX, mouseY, button);
    }

    //and closing when the widget closes (i.e. when the moveable screen gets closed)
    @Override
    public void onClose() {
        super.onClose();
        menu.close();
    }
}
```

{% hint style="warning" %}

* &#x20;Ensure `screenFactory` and `properties` are non-null, or `NullPointerException` occurs.
* &#x20;Unregistered menus in `ContextMenuManager` won’t render and work.
* Don't forget to toggle the context menu using `toggleDisplay(widgetBox, mouseX, mouseY, button)` or `menu.open()`  otherwise your menu will never show up!
  {% endhint %}
