From e90f85df0a4e8d0669d94047b4705f0fc34080f7 Mon Sep 17 00:00:00 2001 From: cmiguelrn Date: Thu, 18 Dec 2025 21:19:56 -0400 Subject: [PATCH 1/2] Fix Waveshare S3 touch navbar on orientation flip --- main/display.c | 75 ++++++++++++++++++++++++-------------- main/display.h | 5 +++ main/gui.c | 8 ++++ main/input/touchscreen.inc | 11 +++++- 4 files changed, 70 insertions(+), 29 deletions(-) diff --git a/main/display.c b/main/display.c index b85b3ae5..b631f7a9 100644 --- a/main/display.c +++ b/main/display.c @@ -48,6 +48,51 @@ static inline void switch_buffer(void) } #endif +static inline void draw_bitmap(int x, int y, int w, int h, const uint16_t* color_data); + +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) +#define DISPLAY_TOUCH_NAV_BUTTON_AREA 40 +#define DISPLAY_TOUCH_NAV_BUTTON_MARGIN 5 +#define DISPLAY_TOUCH_NAV_BUTTON_WIDTH 40 +static void draw_touch_nav_buttons(void) +{ + uint16_t line[CONFIG_DISPLAY_WIDTH] = { TFT_BLACK }; + for (int16_t i = 0; i < DISPLAY_TOUCH_NAV_BUTTON_AREA; ++i) { + draw_bitmap(CONFIG_DISPLAY_OFFSET_X, CONFIG_DISPLAY_HEIGHT + i + CONFIG_DISPLAY_OFFSET_Y, + CONFIG_DISPLAY_WIDTH + CONFIG_DISPLAY_OFFSET_X, 1, line); + } + + const int16_t nav_y1 = CONFIG_DISPLAY_HEIGHT + DISPLAY_TOUCH_NAV_BUTTON_MARGIN + CONFIG_DISPLAY_OFFSET_Y; + const int16_t nav_y2 = (CONFIG_DISPLAY_HEIGHT + (DISPLAY_TOUCH_NAV_BUTTON_AREA - DISPLAY_TOUCH_NAV_BUTTON_MARGIN)) + + CONFIG_DISPLAY_OFFSET_Y; + + const int16_t center = (CONFIG_DISPLAY_WIDTH / 2) + CONFIG_DISPLAY_OFFSET_X; + const int16_t left = DISPLAY_TOUCH_NAV_BUTTON_MARGIN + CONFIG_DISPLAY_OFFSET_X; + const int16_t right = (CONFIG_DISPLAY_WIDTH - DISPLAY_TOUCH_NAV_BUTTON_MARGIN) + CONFIG_DISPLAY_OFFSET_X; + const int16_t half_width = DISPLAY_TOUCH_NAV_BUTTON_WIDTH / 2; + + const struct { + const char* symbol; + int16_t x1; + int16_t x2; + } buttons[] = { { "H", left, left + DISPLAY_TOUCH_NAV_BUTTON_WIDTH }, + { "J", center - half_width, center + half_width }, + { "I", right - DISPLAY_TOUCH_NAV_BUTTON_WIDTH, right } }; + + display_set_font(JADE_SYMBOLS_16x16_FONT, NULL); + for (size_t i = 0; i < sizeof(buttons) / sizeof(buttons[0]); ++i) { + const dispWin_t button_area + = { .x1 = buttons[i].x1, .y1 = nav_y1, .x2 = buttons[i].x2, .y2 = nav_y2 }; + display_print_in_area(buttons[i].symbol, CENTER, CENTER, button_area, 0); + } + display_set_font(DEFAULT_FONT, NULL); +} + +void display_touch_navbar_redraw(void) { draw_touch_nav_buttons(); } +#else +void display_touch_navbar_redraw(void) {} +#endif + static inline void draw_bitmap(int x, int y, int w, int h, const uint16_t* color_data) { // JADE_ASSERT(color_data == &_fg || color_data == disp_buf); @@ -247,11 +292,7 @@ void display_init(TaskHandle_t* gui_h) JADE_ASSERT(gui_h); display_hw_init(gui_h); -#if defined(CONFIG_BOARD_TYPE_TTGO_TWATCHS3) || defined(CONFIG_BOARD_TYPE_M5_CORES3) \ - || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) -#define TOUCH_BUTTON_AREA 40 -#define TOUCH_BUTTON_MARGIN 5 -#define TOUCH_BUTTON_WIDTH 40 +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) /* The TwatchS3 and core s3 don't have buttons that can be used (just power and reset) but it has a touch panel, we use the bottom 40 pixels worth of height @@ -260,29 +301,7 @@ void display_init(TaskHandle_t* gui_h) vTaskDelay(50 / portTICK_PERIOD_MS); - /* blank the bottom of the display with black */ - uint16_t line[CONFIG_DISPLAY_WIDTH] = { TFT_BLACK }; - for (int16_t i = 0; i < TOUCH_BUTTON_AREA; ++i) { - draw_bitmap(CONFIG_DISPLAY_OFFSET_X, CONFIG_DISPLAY_HEIGHT + i + CONFIG_DISPLAY_OFFSET_Y, - CONFIG_DISPLAY_WIDTH + CONFIG_DISPLAY_OFFSET_X, 1, line); - } - - dispWin_t disp_win_virtual_buttons = { .x1 = TOUCH_BUTTON_MARGIN + CONFIG_DISPLAY_OFFSET_X, - .y1 = CONFIG_DISPLAY_HEIGHT + TOUCH_BUTTON_MARGIN + CONFIG_DISPLAY_OFFSET_Y, - .x2 = TOUCH_BUTTON_WIDTH + CONFIG_DISPLAY_OFFSET_X, - .y2 = (CONFIG_DISPLAY_HEIGHT + (TOUCH_BUTTON_AREA - TOUCH_BUTTON_MARGIN)) + CONFIG_DISPLAY_OFFSET_Y }; - - display_set_font(JADE_SYMBOLS_16x16_FONT, NULL); - display_print_in_area("H", CENTER, CENTER, disp_win_virtual_buttons, 0); - disp_win_virtual_buttons.x1 = ((CONFIG_DISPLAY_WIDTH / 2) + CONFIG_DISPLAY_OFFSET_X) - (TOUCH_BUTTON_WIDTH / 2); - disp_win_virtual_buttons.x2 = ((CONFIG_DISPLAY_WIDTH / 2) + CONFIG_DISPLAY_OFFSET_X) + (TOUCH_BUTTON_WIDTH / 2); - display_print_in_area("J", CENTER, CENTER, disp_win_virtual_buttons, 0); - disp_win_virtual_buttons.x1 - = ((CONFIG_DISPLAY_WIDTH - TOUCH_BUTTON_MARGIN) + CONFIG_DISPLAY_OFFSET_X) - TOUCH_BUTTON_WIDTH; - disp_win_virtual_buttons.x2 = (CONFIG_DISPLAY_WIDTH - TOUCH_BUTTON_MARGIN) + CONFIG_DISPLAY_OFFSET_X; - display_print_in_area("I", CENTER, CENTER, disp_win_virtual_buttons, 0); - display_set_font(DEFAULT_FONT, NULL); - + display_touch_navbar_redraw(); vTaskDelay(50 / portTICK_PERIOD_MS); #endif #endif diff --git a/main/display.h b/main/display.h index ba6350d8..632fc38a 100644 --- a/main/display.h +++ b/main/display.h @@ -101,4 +101,9 @@ int display_get_string_width(const char* str); void display_set_font(uint8_t font, const char* font_file); int display_get_font_height(void); void display_flush(void); +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) +void display_touch_navbar_redraw(void); +#else +static inline void display_touch_navbar_redraw(void) {} +#endif #endif /* DISPLAY_H_ */ diff --git a/main/gui.c b/main/gui.c index dab375d4..31b46ca6 100644 --- a/main/gui.c +++ b/main/gui.c @@ -254,7 +254,15 @@ bool gui_get_flipped_orientation(void) { return gui_orientation_flipped; } bool gui_set_flipped_orientation(const bool flipped_orientation) { +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) + const bool prev_orientation = gui_orientation_flipped; +#endif gui_orientation_flipped = display_flip_orientation(flipped_orientation); +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) + if (gui_orientation_flipped != prev_orientation) { + display_touch_navbar_redraw(); + } +#endif return gui_orientation_flipped; } diff --git a/main/input/touchscreen.inc b/main/input/touchscreen.inc index 7607db01..b9120a21 100644 --- a/main/input/touchscreen.inc +++ b/main/input/touchscreen.inc @@ -1,6 +1,9 @@ #include "gui.h" #include "jade_assert.h" #include "jade_tasks.h" +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) +#define DISPLAY_TOUCH_NAV_BUTTON_AREA 40 +#endif #if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) // No PMU, so relevant power files will not have been included @@ -75,7 +78,13 @@ static void touchscreen_task(void* ignored) if (touchpad_pressed) { const uint16_t first_third_end = CONFIG_DISPLAY_WIDTH / 3; const uint16_t middle_thirds_end = (CONFIG_DISPLAY_WIDTH * 2) / 3; - if (touch_y[0] > 200) { + bool nav_zone = touch_y[0] > 200; +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) + const bool flipped = gui_get_flipped_orientation(); + const uint16_t nav_zone_start = CONFIG_DISPLAY_HEIGHT - DISPLAY_TOUCH_NAV_BUTTON_AREA; + nav_zone = flipped ? (touch_y[0] < DISPLAY_TOUCH_NAV_BUTTON_AREA) : (touch_y[0] > nav_zone_start); +#endif + if (nav_zone) { if (touch_x[0] <= first_third_end) { gui_prev(); } else if (touch_x[0] > first_third_end && touch_x[0] < middle_thirds_end) { From 4b24a2a533d93e19888ed001ce054be0d0caa20f Mon Sep 17 00:00:00 2001 From: cmiguelrn Date: Sat, 20 Dec 2025 15:16:23 -0400 Subject: [PATCH 2/2] Fix Waveshare S3 touch navbar redraw and touch zone --- main/display.c | 60 +++++++++++++++++++++++++++++++++----- main/display.h | 1 + main/gui.c | 9 ++---- main/input/touchscreen.inc | 17 +++++------ 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/main/display.c b/main/display.c index b631f7a9..6526e488 100644 --- a/main/display.c +++ b/main/display.c @@ -164,6 +164,45 @@ const color_t TFT_ORANGE = 0x20FD; const color_t TFT_GREENYELLOW = 0xE5AF; const color_t TFT_PINK = 0x19FE; +#if defined(CONFIG_BOARD_TYPE_TTGO_TWATCHS3) || defined(CONFIG_BOARD_TYPE_M5_CORES3) \ + || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) +static const uint16_t touch_button_area = 40; +static const uint16_t touch_button_margin = 5; +static const uint16_t touch_button_width = 40; + +static void draw_touch_navbar(void) +{ + /* Blank the nav area and draw the virtual navigation buttons */ + vTaskDelay(50 / portTICK_PERIOD_MS); + + uint16_t line[CONFIG_DISPLAY_WIDTH] = { TFT_BLACK }; + for (uint16_t i = 0; i < touch_button_area; ++i) { + draw_bitmap(CONFIG_DISPLAY_OFFSET_X, CONFIG_DISPLAY_HEIGHT + i + CONFIG_DISPLAY_OFFSET_Y, + CONFIG_DISPLAY_WIDTH + CONFIG_DISPLAY_OFFSET_X, 1, line); + } + + dispWin_t disp_win_virtual_buttons = { .x1 = touch_button_margin + CONFIG_DISPLAY_OFFSET_X, + .y1 = CONFIG_DISPLAY_HEIGHT + touch_button_margin + CONFIG_DISPLAY_OFFSET_Y, + .x2 = touch_button_width + CONFIG_DISPLAY_OFFSET_X, + .y2 = (CONFIG_DISPLAY_HEIGHT + (touch_button_area - touch_button_margin)) + CONFIG_DISPLAY_OFFSET_Y }; + + display_set_font(JADE_SYMBOLS_16x16_FONT, NULL); + display_print_in_area("H", CENTER, CENTER, disp_win_virtual_buttons, 0); + + disp_win_virtual_buttons.x1 = ((CONFIG_DISPLAY_WIDTH / 2) + CONFIG_DISPLAY_OFFSET_X) - (touch_button_width / 2); + disp_win_virtual_buttons.x2 = ((CONFIG_DISPLAY_WIDTH / 2) + CONFIG_DISPLAY_OFFSET_X) + (touch_button_width / 2); + display_print_in_area("J", CENTER, CENTER, disp_win_virtual_buttons, 0); + + disp_win_virtual_buttons.x1 = ((CONFIG_DISPLAY_WIDTH - touch_button_margin) + CONFIG_DISPLAY_OFFSET_X) + - touch_button_width; + disp_win_virtual_buttons.x2 = (CONFIG_DISPLAY_WIDTH - touch_button_margin) + CONFIG_DISPLAY_OFFSET_X; + display_print_in_area("I", CENTER, CENTER, disp_win_virtual_buttons, 0); + display_set_font(DEFAULT_FONT, NULL); + + vTaskDelay(50 / portTICK_PERIOD_MS); +} +#endif + color_t _fg = TFT_WHITE; static Font cfont = { @@ -292,17 +331,15 @@ void display_init(TaskHandle_t* gui_h) JADE_ASSERT(gui_h); display_hw_init(gui_h); -#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) +#if defined(CONFIG_BOARD_TYPE_TTGO_TWATCHS3) || defined(CONFIG_BOARD_TYPE_M5_CORES3) /* The TwatchS3 and core s3 don't have buttons that can be used (just power and - reset) - but it has a touch panel, we use the bottom 40 pixels worth of height - to display 3 buttons (prev, OK, next), we handle this here rather than - in display_hw because we want to draw text inside the virtual buttons */ - - vTaskDelay(50 / portTICK_PERIOD_MS); + reset). They use a touch panel and reserve the bottom 40 pixels for three + virtual buttons (prev, OK, next). */ + draw_touch_navbar(); +#endif +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) display_touch_navbar_redraw(); - vTaskDelay(50 / portTICK_PERIOD_MS); #endif #endif @@ -324,6 +361,13 @@ bool display_flip_orientation(const bool flipped_orientation) #endif } +void display_touch_navbar_redraw(void) +{ +#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) + draw_touch_navbar(); +#endif +} + typedef struct { Icon* icon; Picture* pic; diff --git a/main/display.h b/main/display.h index 632fc38a..e441b9a1 100644 --- a/main/display.h +++ b/main/display.h @@ -91,6 +91,7 @@ extern const color_t TFT_PINK; void display_init(TaskHandle_t* gui_h); bool display_flip_orientation(bool flipped_orientation); +void display_touch_navbar_redraw(void); Icon* get_icon(const uint8_t* start, const uint8_t* end); Picture* get_picture(const uint8_t* start, const uint8_t* end); void display_picture(const Picture* imgbuf, int x, int y, dispWin_t area); diff --git a/main/gui.c b/main/gui.c index 31b46ca6..a482bae8 100644 --- a/main/gui.c +++ b/main/gui.c @@ -254,15 +254,10 @@ bool gui_get_flipped_orientation(void) { return gui_orientation_flipped; } bool gui_set_flipped_orientation(const bool flipped_orientation) { -#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) - const bool prev_orientation = gui_orientation_flipped; -#endif - gui_orientation_flipped = display_flip_orientation(flipped_orientation); -#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) - if (gui_orientation_flipped != prev_orientation) { + if (gui_orientation_flipped != display_flip_orientation(flipped_orientation)) { + gui_orientation_flipped = !gui_orientation_flipped; display_touch_navbar_redraw(); } -#endif return gui_orientation_flipped; } diff --git a/main/input/touchscreen.inc b/main/input/touchscreen.inc index b9120a21..4c70fbcf 100644 --- a/main/input/touchscreen.inc +++ b/main/input/touchscreen.inc @@ -1,13 +1,10 @@ #include "gui.h" #include "jade_assert.h" #include "jade_tasks.h" -#if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) -#define DISPLAY_TOUCH_NAV_BUTTON_AREA 40 -#endif - #if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) // No PMU, so relevant power files will not have been included #include "power/i2c.inc" +static const uint16_t display_touch_nav_button_area = 40; #endif #include @@ -69,8 +66,6 @@ static void touchscreen_task(void* ignored) uint8_t touch_cnt = 10; // FIXME: don't allow multiple touches within 300 ms? - // FIXME: this doesn't currently work with Display -> Flip Orientation feature - // but it could by changing the touch_y[0] > 200 logic with < 40 and inverting prev with next and viceversa while (!shutdown_requested) { if (esp_lcd_touch_read_data(ret_touch) == ESP_OK) { bool touchpad_pressed @@ -78,13 +73,15 @@ static void touchscreen_task(void* ignored) if (touchpad_pressed) { const uint16_t first_third_end = CONFIG_DISPLAY_WIDTH / 3; const uint16_t middle_thirds_end = (CONFIG_DISPLAY_WIDTH * 2) / 3; - bool nav_zone = touch_y[0] > 200; #if defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) const bool flipped = gui_get_flipped_orientation(); - const uint16_t nav_zone_start = CONFIG_DISPLAY_HEIGHT - DISPLAY_TOUCH_NAV_BUTTON_AREA; - nav_zone = flipped ? (touch_y[0] < DISPLAY_TOUCH_NAV_BUTTON_AREA) : (touch_y[0] > nav_zone_start); + const uint16_t nav_y_start + = flipped ? CONFIG_DISPLAY_OFFSET_Y : CONFIG_DISPLAY_HEIGHT + CONFIG_DISPLAY_OFFSET_Y; + const uint16_t nav_y_end = nav_y_start + display_touch_nav_button_area; + if (touch_y[0] >= nav_y_start && touch_y[0] < nav_y_end) { +#else + if (touch_y[0] > 200) { #endif - if (nav_zone) { if (touch_x[0] <= first_third_end) { gui_prev(); } else if (touch_x[0] > first_third_end && touch_x[0] < middle_thirds_end) {