From 3d17e7bab9300bbc76fdc746335a5bf636e95cd6 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Sun, 22 Feb 2026 18:43:54 -0800 Subject: [PATCH] refactor(DisplayManager): add hitTestRaw() and remove touch coordinate filtering --- boards/esp32-32e-4/DisplayDriverTFT.cpp | 20 +++++------- libraries/KlubhausCore/src/DisplayManager.h | 32 ++++++++++++++++++-- libraries/KlubhausCore/src/DoorbellLogic.cpp | 2 +- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/boards/esp32-32e-4/DisplayDriverTFT.cpp b/boards/esp32-32e-4/DisplayDriverTFT.cpp index c56a797..740909b 100644 --- a/boards/esp32-32e-4/DisplayDriverTFT.cpp +++ b/boards/esp32-32e-4/DisplayDriverTFT.cpp @@ -378,18 +378,12 @@ TouchEvent DisplayDriverTFT::readTouch() { uint16_t tx, ty; uint8_t touched = _tft.getTouch(&tx, &ty, 100); - // Filter out invalid coordinates (touch panel can return garbage on release) - // Check against actual display dimensions (320x480 for this board) - bool validCoords = !(tx > 320 || ty > 480); - if(touched && !validCoords) { - touched = 0; - return evt; - } - - // Debug: log touch state changes + // Debug: log touch state changes with transformed coords if(touched != _touchWasPressed) { - Serial.printf("[TOUCH] raw touched=%d wasPressed=%d (x=%d,y=%d)\n", touched, - _touchWasPressed, tx, ty); + int tx_form = tx, ty_form = ty; + transformTouch(&tx_form, &ty_form); + Serial.printf("[TOUCH] raw touched=%d wasPressed=%d (raw=%d,%d trans=%d,%d)\n", touched, + _touchWasPressed, tx, ty, tx_form, ty_form); } // Detect transitions (press/release) @@ -431,7 +425,9 @@ TouchEvent DisplayDriverTFT::readTouch() { } void DisplayDriverTFT::transformTouch(int* x, int* y) { - // Resistive touch panel is rotated 90° vs display - swap coordinates + // Resistive touch panel is rotated 90° vs display - swap and adjust + // Touch panel: 320x480 (portrait), Display: 480x320 (landscape) + // This was the original working transform int temp = *x; *x = *y; *y = temp; diff --git a/libraries/KlubhausCore/src/DisplayManager.h b/libraries/KlubhausCore/src/DisplayManager.h index 2b08308..a9a7ce7 100644 --- a/libraries/KlubhausCore/src/DisplayManager.h +++ b/libraries/KlubhausCore/src/DisplayManager.h @@ -182,16 +182,42 @@ public: int height() { return _drv ? _drv->height() : 0; } /// Handle dashboard touch - returns action for tapped tile, or NONE + /// Note: x,y are already in display coordinates (transformed by driver) TileAction handleDashboardTouch(int x, int y) const { - HitResult hr = hitTest(x, y); - Serial.printf("[HIT] x=%d y=%d type=%d idx=%d _headerHeight=%d\n", x, y, (int)hr.type, - hr.index, _headerHeight); + HitResult hr = hitTestRaw(x, y); if(hr.type == UIElementType::TILE && hr.index >= 0 && hr.index < DASHBOARD_TILE_COUNT) { return DASHBOARD_TILES[hr.index].action; } return TileAction::NONE; } + /// Perform hit test at coordinates (already in display space, no transform) + HitResult hitTestRaw(int x, int y) const { + if(!_drv) + return HitResult(); + + int dispW = _drv->width(); + int dispH = _drv->height(); + int headerH = _headerHeight; + + // Check header + Rect headerRect = UIElements::header(dispW, headerH); + if(headerRect.contains(x, y)) { + return HitResult(UIElementType::HEADER, 0, headerRect); + } + + // Check tiles + for(int i = 0; i < _tileCount; i++) { + const TileLayout& lay = _layouts[i]; + Rect tileRect(lay.x, lay.y, lay.w, lay.h); + if(tileRect.contains(x, y)) { + return HitResult(UIElementType::TILE, i, tileRect); + } + } + + return HitResult(); + } + /// Perform hit test at coordinates - returns element type, index, and bounds HitResult hitTest(int x, int y) const { if(!_drv) diff --git a/libraries/KlubhausCore/src/DoorbellLogic.cpp b/libraries/KlubhausCore/src/DoorbellLogic.cpp index 13850a4..cad88b4 100644 --- a/libraries/KlubhausCore/src/DoorbellLogic.cpp +++ b/libraries/KlubhausCore/src/DoorbellLogic.cpp @@ -312,7 +312,7 @@ void DoorbellLogic::onSerialCommand(const String& cmd) { if(comma > 0) { int x = args.substring(0, comma).toInt(); int y = args.substring(comma + 1).toInt(); - HitResult hr = _display->hitTest(x, y); + HitResult hr = _display->hitTestRaw(x, y); Serial.printf("[Hittest] raw:(%d,%d) type:%d index:%d bounds:(%d,%d,%d,%d)\n", x, y, (int)hr.type, hr.index, hr.bounds.x, hr.bounds.y, hr.bounds.w, hr.bounds.h); Serial.printf("[Display] w:%d h:%d headerH:%d\n", _display->width(), _display->height(),