# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tanishisherewith.gitbook.io/dynamic-hud/contextmenu/contextmenu-class.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
