Skip to content

Migration Guide for PR 3173

halx99 edited this page Jun 13, 2026 · 3 revisions

PR #3173 Migration Guide

Refactor InputSystem: Replace touch/mouse event model with unified pointer events and introduce InputField.


1. Removed Headers / Classes

Removed Replacement
axmol/base/Touch.h axmol/base/PointerEvent.h
axmol/base/EventTouch.h / .cpp axmol/base/PointerEvent.h
axmol/base/EventMouse.h / .cpp axmol/base/PointerEvent.h
axmol/base/EventListenerTouch.h / .cpp axmol/base/PointerEventListener.h
axmol/base/IMEDispatcher.h / .cpp axmol/base/InputSystem.h + axmol/base/InputDelegate.h
axmol/2d/TextFieldTTF.h / .cpp axmol/ui/InputField.h
axmol/ui/UITextField.h / .cpp axmol/ui/InputField.h
axmol/ui/UITextFieldEx.h / .cpp axmol/ui/InputField.h

2. Renamed Headers

Old New
axmol/base/PointerEventListener.h Same name, new API (see below)
axmol/base/KeyboardEvent.h Same name, EventKeyboard typedef deprecated
axmol/base/AccelerationEvent.h Same name, minor changes
axmol/base/ControllerEvent.h Same name, minor changes
axmol/base/FocusEvent.h Same name, minor changes

3. Event System Migration

Old API (Touch Events)

#include "axmol/base/EventListenerTouch.h"
#include "axmol/base/EventTouch.h"

auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [](Touch* touch, Event* event) -> bool {
    Vec2 pos = touch->getLocation();
    return true;
};
listener->onTouchMoved = [](Touch* touch, Event* event) {
    Vec2 delta = touch->getDelta();
};
listener->onTouchEnded = [](Touch* touch, Event* event) {
    Vec2 pos = touch->getLocationInView();
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

New API (Pointer Events)

#include "axmol/base/PointerEventListener.h"
#include "axmol/base/PointerEvent.h"

auto listener = PointerEventListener::create();
listener->onPointerDown = [](PointerEvent* event) -> bool {
    Vec2 pos = event->getLocation();       // world 2D coordinates
    intptr_t id = event->getPointerId();
    PointerType type = event->getPointerType(); // Mouse, Touch, or Pen
    float pressure = event->getPressure();
    return true; // true = claim pointer capture
};
listener->onPointerMove = [](PointerEvent* event) {
    Vec2 delta = event->getDelta();
    uint32_t buttons = event->getPressedButtons(); // bitmask
};
listener->onPointerUp = [](PointerEvent* event) {
    Vec2 pos = event->getScreenLocation();
};
listener->onPointerCancel = [](PointerEvent* event) {
    // pointer interaction was canceled (e.g. system gesture)
};
listener->onPointerScroll = [](PointerEvent* event) -> bool {
    float scrollX = event->getScrollX();
    float scrollY = event->getScrollY();
    return false;
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

Old API (Mouse Events)

#include "axmol/base/EventListenerMouse.h"
#include "axmol/base/EventMouse.h"

auto listener = EventListenerMouse::create();
listener->onMouseDown = [](EventMouse* event) {
    EventMouse::MouseButton button = event->getMouseButton();
    float x = event->getCursorX();
};
listener->onMouseMove = [](EventMouse* event) {
    float x = event->getCursorX();
    float y = event->getCursorY();
};
listener->onMouseScroll = [](EventMouse* event) {
    float scrollX = event->getScrollX();
    float scrollY = event->getScrollY();
};

New API (same Pointer Events)

listener->onPointerDown = [](PointerEvent* event) -> bool {
    if (event->getPointerType() == PointerType::Mouse) {
        int button = event->getButton(); // 0=Left, 1=Right, 2=Middle
    }
    return false;
};
listener->onPointerMove = [](PointerEvent* event) {
    Vec2 pos = event->getLocation();
};
listener->onPointerScroll = [](PointerEvent* event) -> bool {
    return false;
};

4. PointerEvent Key Methods

Method Description
getLocation() World 2D coordinates
getPreviousLocation() Previous frame world coordinates
getStartLocation() Location at PointerDown
getDelta() Current - previous location
getScreenLocation() Screen coordinates
getPreviousScreenLocation() Previous screen coordinates
getStartScreenLocation() Screen coordinates at PointerDown
getPointerId() Unique pointer identifier (intptr_t)
getPointerType() PointerType::Mouse, Touch, or Pen
getButton() Triggering button index (0=Left, 1=Right, 2=Middle, -1=None)
getPressedButtons() Bitmask of currently pressed buttons
isButtonPressed(int) Check specific button
isPrimaryPressed() Is primary button/first-finger down
getPhase() InputPhase::PointerDown, PointerUp, PointerMove, PointerCancel, PointerScroll
getPressure() Normalized pressure (0.0–1.0+, 1.0 default)
isCaptured() Was event routed via pointer capture
isPrimary() Is this the primary pointer
getCamera() Camera used for hit-test (scene-graph listeners only)

5. Keyboard Event Migration

Old API

#include "axmol/base/EventListenerKeyboard.h"

auto listener = EventListenerKeyboard::create();
listener->onKeyPressed = [](EventKeyboard::KeyCode key, Event* event) {
    if (key == EventKeyboard::KeyCode::KEY_SPACE) { }
};
listener->onKeyReleased = [](EventKeyboard::KeyCode key, Event* event) { };

New API

#include "axmol/base/KeyboardEventListener.h"

auto listener = KeyboardEventListener::create();
listener->onKeyPressed = [](KeyboardEvent* event) {
    KeyboardEvent::KeyCode key = event->getKeyCode();
    InputPhase phase = event->getPhase(); // KeyDown, KeyUp, KeyRepeat
    if (key == KeyboardEvent::KeyCode::KEY_SPACE) { }
};
listener->onKeyReleased = [](KeyboardEvent* event) {
    KeyboardEvent::KeyCode key = event->getKeyCode();
};

Note: EventKeyboard is now a deprecated alias for KeyboardEvent. The EventListenerKeyboard class is replaced by KeyboardEventListener.


6. Node Touch Callback Migration

Old API

// Node had built-in touch callbacks
node->setTouchEnabled(true);
node->onTouchBegan = [](Touch* touch, Event* event) -> bool { return true; };
node->onTouchMoved = [](Touch* touch, Event* event) { };
node->onTouchEnded = [](Touch* touch, Event* event) { };

New API

// Use PointerEventListener with scene-graph priority
auto listener = PointerEventListener::create();
listener->onPointerDown = [](PointerEvent* event) -> bool {
    return true;
};
listener->onPointerMove = [](PointerEvent* event) { };
listener->onPointerUp = [](PointerEvent* event) { };
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, node);

7. Pointer Capture

New pointer capture model (similar to W3C Pointer Capture):

listener->onPointerDown = [](PointerEvent* event) -> bool {
    // Return true to capture the pointer
    // Captured pointer receives all subsequent events until PointerUp/PointerCancel
    // isPrimaryPressed return true if mouse-left pressed or the first finger touch down
    return event->isPrimaryPressed();
};

// Check capture state in move/up handlers
listener->onPointerMove = [](PointerEvent* event) {
    if (event->isCaptured()) {
        // This event was routed to us via pointer capture
    }
    else {
        // mouse hover
    }
};

8. Hit-Test Callback (Scene-Graph Listeners)

New per-listener hit-test for custom camera/viewport scenarios:

auto listener = PointerEventListener::create();
listener->onPointerHitTest = [](PointerEvent* event, const Camera* camera, Vec3* hitPoint) -> bool {
    // Custom hit-test logic for this listener's node
    // Return true if the pointer hits this listener's area for the given camera
    Node* target = /* associated node */;
    Vec2 worldPos = event->getLocation();
    // ... perform hit test ...
    *hitPoint = Vec3(worldPos, 0);
    return true;
};

9. Label API Changes

Unified Create

// Old: had to pick the right create method
Label::createWithTTF("Hello", "fonts/arial.ttf", 24);
Label::createWithSystemFont("Hello", "Arial", 24);
Label::createWithBMFont("fonts/myfont.fnt", "Hello");

// New: single entry point with auto-detection
Label::create("Hello", "fonts/arial.ttf", 24);     // auto-detects TTF
Label::create("Hello", "Arial", 24);                // auto-detects system font
Label::create("Hello", "fonts/myfont.fnt", 24);     // auto-detects BMFont (.fnt)

Runtime Font Switching

// New centralized font setter
label->setFontInfo("fonts/newfont.ttf", 32);

String Length

// Old
int len = label->getStringLength();  // deprecated

// New
int len = label->getCharCount();     // UTF-32 character count

// Old
int lines = label->getStringNumLines();  // deprecated

// New
int lines = label->getLineCount();

10. IME / Text Input Migration

Old API (IMEDispatcher)

#include "axmol/base/IMEDispatcher.h"

IMEDispatcher::getInstance()->dispatchInsertText("hello", 5);
IMEDispatcher::getInstance()->dispatchDeleteBackward(1);

New API (InputSystem)

#include "axmol/base/InputSystem.h"

InputSystem::getInstance()->dispatchInsertText("hello");
InputSystem::getInstance()->dispatchDeleteBackward(1);
InputSystem::getInstance()->dispatchControlKey(KeyboardEvent::KeyCode::KEY_A);

InputDelegate

If you implemented IMEDelegate, you now implement InputDelegate:

class MyInputDelegate : public InputDelegate {
    bool canAttachWithIME() const override { return true; }
    void didAttachWithIME() override { }
    bool canDetachWithIME() const override { return true; }
    void didDetachWithIME() override { }
    void insertText(std::string_view text) override { }
    void deleteBackward(unsigned int numChars) override { }
    void controlKey(KeyboardEvent::KeyCode keyCode) override { }
    bool hitTestWithIME(const Vec2& location) override { return false; }
    void performEditAction(EditAction action) override { }
};

11. EditBox / InputField

InputField replaces UITextField / UITextFieldEx and integrates with the new InputDelegate system. Existing EditBox usage continues to work — the underlying implementation now routes through InputField.

For new code, prefer InputField directly:

#include "axmol/ui/InputField.h"

12. Platform-Specific Notes

Android

  • TextInputListener.java removed. Text input now routes through AxmolInputConnection and AxmolKeyboardTracker.
  • AxmolPlayer.java significantly restructured for new input dispatch.

iOS

  • iOS system Copy/Paste menu integrated for InputField editing.
  • InputView and RenderHostView refactored.

Desktop (Windows/Linux/macOS)

  • Old RenderViewImpl removed. New RenderViewCore + platform-specific RenderView-pc.cpp handles all input.
  • GLFW window now reports pointer input directly to InputSystem.

WinRT

  • Old InputEvent, Keyboard-winrt, AxmolRenderer removed.
  • New RenderView-winrt handles all input dispatch.

WASM/Web

  • Application-wasm updated to use InputSystem directly.

13. Lua Bindings

Old New
EventListenerTouchOneByOne PointerEventListener
EventListenerTouchAllAtOnce PointerEventListener (use getPointerId() to distinguish)
EventListenerMouse PointerEventListener
EventListenerKeyboard KeyboardEventListener
EventTouch fields PointerEvent methods
EventMouse fields PointerEvent methods
TextField / TextFieldEx InputField

14. Include Path Quick Reference

// Events
#include "axmol/base/PointerEvent.h"
#include "axmol/base/PointerEventListener.h"
#include "axmol/base/KeyboardEvent.h"
#include "axmol/base/KeyboardEventListener.h"
#include "axmol/base/AccelerationEvent.h"
#include "axmol/base/AccelerationEventListener.h"
#include "axmol/base/CustomEvent.h"
#include "axmol/base/CustomEventListener.h"

// Input system
#include "axmol/base/InputSystem.h"
#include "axmol/base/InputDelegate.h"

// UI
#include "axmol/ui/InputField.h"

// Label
#include "axmol/2d/Label.h"

15. Quick-Reference: Old → New Enum Mapping

Old New
Event::Type::TOUCH Event::Type::POINTER
Event::Type::MOUSE Event::Type::POINTER
Event::Type::KEYBOARD Event::Type::KEYBOARD (unchanged)
EventKeyboard::KeyCode KeyboardEvent::KeyCode
Touch::DispatchMode::ONE_BY_ONE N/A (single listener per pointer via getPointerId())
Touch::DispatchMode::ALL_AT_ONCE N/A (use onPointerDown in scene-graph priority)
EventMouse::MouseButton::LEFT InputButton::Left (0)
EventMouse::MouseButton::RIGHT InputButton::Right (1)
EventMouse::MouseButton::MIDDLE InputButton::Middle (2)

Clone this wiki locally