Skip to content

CursorController

fishstiz edited this page Feb 5, 2025 · 7 revisions

The CursorController instance allows you to bypass the element-based system and directly control the cursor. This is useful for scenarios where the element hierarchy is too complex or unnecessary.

Note: Make sure Minecraft Cursor is loaded either by checking with a condition or by being a required dependency if you need to use the CursorController instance outside of the Minecraft Cursor entry point.

Getting the CursorController instance

The CursorController follows a singleton pattern. Use the following method to retrieve its instance:

CursorController cursorController = CursorController.getInstance();

Methods

The CursorController instance provides methods for changing the cursor's cursor type.

void setSingleCycleCursor(CursorType cursorType)

Changes the cursor to a specified CursorType for only one render or tick cycle.

  • render: The cursor type is computed every render cycle if the currentScreen is not null (i.e., there’s an active screen).
  • tick: The cursor type is computed during the tick cycle only in rare cases when:
    • currentScreen is null (i.e., no screen is active),
    • a Screen is initialized,
    • and the cursor is not locked.

    Note: These conditions are usually met by mods that render an interactable Screen in-game by themselves (e.g., Axiom).

Example Usage:

public class MyNestedButton extends ClickableWidget {
    // ...

    @Override
    protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
        // ...

        if (this.isMouseOver(mouseX, mouseY)) {
            CursorController.getInstance().setSingleCycleCursor(CursorType.POINTER);
        }
    }
}

void overrideCursor(CursorType cursorType, int index)

Overrides the current cursor with a specified CursorType and priority index. Higher index values take precedence when multiple overrides exist.

void removeOverride(int index)

Removes the cursor override at the given index.

Note: Use positive values for the index as Minecraft Cursor uses negative index values internally to ensure they do not override your custom cursor overrides.

Example usage of overrideCursor and removeOverride:

public class MyScreen extends Screen {
    // ...

    private static final CursorController CURSOR_CONTROLLER = CursorController.getInstance();
    private boolean doingSomething;

    public void setDoingSomething(boolean isDoingSomething) {
        if (isDoingSomething) {
            // doingSomethingCursor is a custom cursor type
            // 100 is just an arbitrary number
            CURSOR_CONTROLLER.overrideCursor(doingSomethingCursor, 100); 
        } else {
            CURSOR_CONTROLLER.removeOverride(100);
        }
    }

    @Override
    public void close() {
        // Remove the override on close to ensure the cursor doesn't get stuck.
        CURSOR_CONTROLLER.removeOverride(100);

        super.close();
    }
}

Take Complete Control of the Adaptive Behavior

By using only overrideCursor with the same index throughout your whole mod and never removing the override, you can almost completely override the default adaptive behavior of the cursor.

USE WITH CAUTION: This makes the element-based system obsolete.

Completely overriding Minecraft Cursor's sytem may also not be the best for mods that also depend on Minecraft Cursor if mod compatibility is a concern.

Create a CursorController Utility or Wrapper class for Cursor Management

public CursorControllerUtil {
    public static setCursor(CursorType cursorType) {
        // 1 is just an arbitrary number
        CursorController.getInstance().overrideCursor(cursorType, 1);
    }
}

With this, you've effectively overriden most of Minecraft Cursor's cursor type specifications. Manage the cursor type yourself—build an event-based system, reinvent the wheel and use another registry-based approach, make it adaptive in whatever way your mod requires. Minecraft Cursor now only abstracts the internal logic of creating and setting cursors.

This approach does not override Minecraft Cursor's:

  • Default fallback system.
  • Cursor overrides with a higher index.

Clone this wiki locally