File size: 4,772 Bytes
7ffaa9e
 
 
7b453e7
7ffaa9e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b453e7
 
7ffaa9e
 
 
 
 
 
7b453e7
7ffaa9e
 
 
 
 
 
 
 
 
 
 
7b453e7
7ffaa9e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b453e7
7ffaa9e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b453e7
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { getConfig } from './config.js';
import { EventEmitter, EventTypes } from './event.js';
import { InputHandler, LayerHandler } from './handler.js';

export function createInputHandler(canvas, scene) {
    const eventEmitter = new EventEmitter();
    const inputHandler = new InputHandler(canvas);
    let cameraControlsEnabled = true;

    // Attach DOM events to trigger eventEmitter
    function attachDomEvents() {
        window.addEventListener('keydown', (e) => {
            eventEmitter.emit(EventTypes.KEY_DOWN, e);
        });
        window.addEventListener('keyup', (e) => {
            eventEmitter.emit(EventTypes.KEY_UP, e);
        });
        window.addEventListener('keypress', (e) => {
            eventEmitter.emit(EventTypes.KEY_PRESS, e);
            // Emit TEXT_INPUT for single characters
            if (e.key.length === 1) {
                eventEmitter.emit(EventTypes.TEXT_INPUT, e.key);
            }
        });
        canvas.addEventListener('mousemove', (e) => {
            eventEmitter.emit(EventTypes.MOUSE_MOVE, e);
        });
        canvas.addEventListener('mousedown', (e) => {
            eventEmitter.emit(EventTypes.MOUSE_DOWN, e);
        });
        canvas.addEventListener('mouseup', (e) => {
            eventEmitter.emit(EventTypes.MOUSE_UP, e);
        });
        canvas.addEventListener('wheel', (e) => {
            eventEmitter.emit(EventTypes.MOUSE_WHEEL, e);
        }, { passive: false });
        canvas.addEventListener('click', (e) => {
            eventEmitter.emit(EventTypes.CLICK, e);
        });
    }

    function setupCameraControls() {
        const config = getConfig();
        const moveSpeed = config?.camera?.moveSpeed || 10;
        const zoomSpeed = config?.camera?.zoomSpeed || 0.1;
        const inverted = config?.controls?.inverted || false;
        const moveDir = inverted ? 1 : -1;

        eventEmitter.on(EventTypes.KEY_DOWN, (e) => {
            if (!cameraControlsEnabled) return;
            switch (e.key.toLowerCase()) {
                case 'w': scene.camera.moveBy(0, moveSpeed * moveDir); break;
                case 's': scene.camera.moveBy(0, -moveSpeed * moveDir); break;
                case 'a': scene.camera.moveBy(-moveSpeed * moveDir, 0); break;
                case 'd': scene.camera.moveBy(moveSpeed * moveDir, 0); break;
                case '+':
                case '=': scene.camera.zoomBy(1 + zoomSpeed); break;
                case '-':
                case '_': scene.camera.zoomBy(1 - zoomSpeed); break;
            }
        });

        eventEmitter.on(EventTypes.MOUSE_WHEEL, (e) => {
            if (!cameraControlsEnabled) return;
            const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1;
            scene.camera.zoomBy(zoomFactor);
            e.preventDefault();
        });
    }

    function setupLayerHandlers() {
        scene.getLayers().forEach(layer => {
            const handlers = [
                new LayerHandler(EventTypes.KEY_DOWN, (e, layer) => layer.handleKeyDown?.(e)),
                new LayerHandler(EventTypes.MOUSE_MOVE, (e, layer) => {
                    const pos = inputHandler.getMousePosition(e);
                    layer.handleMouseMove?.(pos.x, pos.y);
                }),
                new LayerHandler(EventTypes.CLICK, (e, layer) => {
                    const pos = inputHandler.getMousePosition(e);
                    layer.handleClick?.(pos.x, pos.y, scene.camera);
                }),
                new LayerHandler(EventTypes.MOUSE_WHEEL, (e, layer) => layer.handleWheel?.(e))
            ];

            handlers.forEach(handler => {
                handler.bind(layer);
                inputHandler.addHandler(handler.eventType, handler);
            });
        });
    }

    attachDomEvents();
    setupCameraControls();
    setupLayerHandlers();

    return {
        listenForKey: (key, callback) => eventEmitter.on(EventTypes.KEY_DOWN, (e) => {
            if (e.key === key) callback(e);
        }),
        removeKeyListener: (key, callback) => eventEmitter.off(EventTypes.KEY_DOWN, (e) => {
            if (e.key === key) callback(e);
        }),
        addTextInputListener: (callback) => eventEmitter.on(EventTypes.TEXT_INPUT, callback),
        removeTextInputListener: (callback) => eventEmitter.off(EventTypes.TEXT_INPUT, callback),
        removeAllListeners: () => eventEmitter.clear(),
        enableCameraControls: () => { cameraControlsEnabled = true; },
        disableCameraControls: () => { cameraControlsEnabled = false; },
        on: (event, callback) => eventEmitter.on(event, callback),
        off: (event, callback) => eventEmitter.off(event, callback),
        cleanup: () => {
            eventEmitter.clear();
            inputHandler.disable();
        }
    };
}