Gestion du tactile GT911 avec détection de swipe

#include "app/input/obb_touch_gt911.h"
#include "app/input/obb_touch_gt911_hw.h"

#include <Arduino.h>
#include <cstdlib>
#include <lvgl.h>

namespace {
constexpr int kSwipeThreshold = 60;
lv_indev_t *s_touch_indev = nullptr;
obb::swipe_callback_t s_swipe_cb = nullptr;
bool s_last_touch = false;
lv_point_t s_last_point{0, 0};
lv_point_t s_swipe_origin{0, 0};
uint32_t s_touch_start_ms = 0;

void lv_touch_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
  int16_t x = s_last_point.x;
  int16_t y = s_last_point.y;
  bool touched = obb_gt911_hw_read(x, y);

  if (touched) {
    s_last_point.x = x;
    s_last_point.y = y;
    data->point = s_last_point;
    data->state = LV_INDEV_STATE_PRESSED;
    if (!s_last_touch) {
      s_swipe_origin = s_last_point;
      s_touch_start_ms = millis();
    }
  } else {
    data->point = s_last_point;
    data->state = LV_INDEV_STATE_RELEASED;
    if (s_last_touch && s_swipe_cb) {
      int16_t dx = s_last_point.x - s_swipe_origin.x;
      int16_t dy = s_last_point.y - s_swipe_origin.y;
      uint32_t elapsed = millis() - s_touch_start_ms;
      if (elapsed < 800) {
        if (abs(dx) > abs(dy) && abs(dx) > kSwipeThreshold) {
          s_swipe_cb(dx > 0 ? LV_DIR_RIGHT : LV_DIR_LEFT);
        } else if (abs(dy) > kSwipeThreshold) {
          s_swipe_cb(dy > 0 ? LV_DIR_BOTTOM : LV_DIR_TOP);
        }
      }
    }
  }

  s_last_touch = touched;
}

}  // namespace

namespace obb {

void obb_touch_gt911_init() {
  obb_gt911_hw_init();
}

void obb_touch_gt911_attach_lvgl() {
  static lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_[drv.read](<http://drv.read>)_cb = lv_touch_read;
  s_touch_indev = lv_indev_drv_register(&indev_drv);
  (void)s_touch_indev;
}

void obb_touch_poll() {
  // Placeholder for future debouncing or GT911 background tasks.
}

void obb_touch_set_swipe_cb(swipe_callback_t cb) {
  s_swipe_cb = cb;
}

}  // namespace obb