#include "event_manager.h" #include "GLOBALS.h" #include "tft_handler.h" #include "input_manager.h" #include #define CARDKB_ADDR 0x5F // M5Stack CardKB I2C address void InputManager::init(DISPLAY_STATE* display_state, TFT_Handler* tf) { _display_state = display_state; _tf = tf; mi = { .x = 5, .y = 5, .size_x = 4, .size_y = 4, .color = 0x0000, }; Wire.begin(); for (int i = 0; i < NUM_BUTTONS; i++) { pinMode(BUTTON_PINS[i], INPUT_PULLUP); } } void InputManager::update() { for (int i = 0; i < NUM_BUTTONS; i++) { short int reading = digitalRead(BUTTON_PINS[i]); if (reading != lastButtonState[i]) { lastDebounceTime[i] = millis(); } if ((millis() - lastDebounceTime[i]) > DEBOUNCE_DELAY) { if (reading != buttonState[i]) { buttonState[i] = reading; if (buttonState[i] == LOW) { handle_button_press(i); } } } lastButtonState[i] = reading; } Wire.requestFrom(CARDKB_ADDR, 1); if (Wire.available()) { char c = Wire.read(); if (c != 0) { handle_keyboard_input(c); } } } void InputManager::handle_keyboard_input(char key) { bool needs_redraw = false; Serial.printf("key: %x\n", key & 0xff); CLICK_EVENT event; switch(key) { case 'd': // Right arrow alternative case 'D': mi.x = (mi.x + 5 > 476) ? 476 : mi.x + 5; needs_redraw = true; break; case 's': // Down arrow alternative case 'S': mi.y = (mi.y + 5 > 316) ? 316 : mi.y + 5; needs_redraw = true; break; case 'w': // Up arrow alternative case 'W': mi.y = (mi.y - 5 < 0) ? 0 : mi.y - 5; needs_redraw = true; break; case 'a': // Left arrow alternative case 'A': mi.x = (mi.x - 5 < 0) ? 0 : mi.x - 5; needs_redraw = true; break; case 0xB4: // Left arrow key (CardKB sends special codes) mi.x = (mi.x - 5 < 0) ? 0 : mi.x - 5; needs_redraw = true; break; case 0xB7: // Right arrow key mi.x = (mi.x + 5 > 476) ? 476 : mi.x + 5; needs_redraw = true; break; case 0xB5: // Up arrow key mi.y = (mi.y - 5 < 0) ? 0 : mi.y - 5; needs_redraw = true; break; case 0xB6: // Down arrow key mi.y = (mi.y + 5 > 316) ? 316 : mi.y + 5; needs_redraw = true; break; case 0xD: // Enter key - left click case ' ': event.x = mi.x; event.y = mi.y; event.event = CLICK_EVENTS::LEFT_CLICK; break; case 'r': // 'R' key - right click case 'R': event.x = mi.x; event.y = mi.y; event.event = CLICK_EVENTS::RIGHT_CLICK; break; default: break; } EventManager::getInstance().publish(event); if (needs_redraw) { _display_state->update_display.store(true); } } void InputManager::handle_button_press(short buttonIndex) { bool needs_redraw = false; switch(buttonIndex) { case 0: mi.x = (mi.x + 5 > 476) ? 476 : mi.x + 5; needs_redraw = true; break; case 1: mi.y = (mi.y + 5 > 316) ? 316 : mi.y + 5; needs_redraw = true; break; case 2: mi.y = (mi.y - 5 < 0) ? 0 : mi.y - 5; needs_redraw = true; break; case 3: mi.x = (mi.x - 5 < 0) ? 0 : mi.x - 5; needs_redraw = true; break; case 4: // Click { CLICK_EVENT event = { .x = mi.x, .y = mi.y, .event = CLICK_EVENTS::LEFT_CLICK }; EventManager::getInstance().publish(event); } break; case 5: // Right click { CLICK_EVENT event = { .x = mi.x, .y = mi.y, .event = CLICK_EVENTS::RIGHT_CLICK }; EventManager::getInstance().publish(event); } break; } if (needs_redraw) { _display_state->update_display.store(true); } } void InputManager::draw_button() { _tf->draw_box(mi.x, mi.y, mi.size_x, mi.size_y, mi.color); } bool InputManager::are_buttons_pressed(short btn1, short btn2) { return (buttonState[btn1] == LOW && buttonState[btn2] == LOW); }