diff --git a/main/display.c b/main/display.c index ef6d2f03..efa011ec 100644 --- a/main/display.c +++ b/main/display.c @@ -144,6 +144,44 @@ static inline void fill_disp_buf_color(size_t opt_loop, color_t original, uint32 #define min(A, B) ((A) < (B) ? (A) : (B)) +#if defined(CONFIG_DISPLAY_TOUCHSCREEN) +#define TOUCH_BUTTON_WIDTH 40 +#define TOUCH_BUTTON_HEIGHT 40 +#define TOUCH_BUTTON_MARGIN 5 + +static void display_draw_touch_buttons(void) +{ + /* 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 */ + + /* blank the bottom of the display with black */ + uint16_t line[CONFIG_DISPLAY_WIDTH] = { TFT_BLACK }; + for (int16_t i = 0; i < TOUCH_BUTTON_HEIGHT; ++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_HEIGHT - 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); +} +#endif + void display_fill_rect(int x, int y, int w, int h, color_t color) { if ((x >= GUI_DISPLAY_WINDOW.x2) || (y > GUI_DISPLAY_WINDOW.y2)) { @@ -183,8 +221,7 @@ void display_fill_rect(int x, int y, int w, int h, color_t color) || ((y - CONFIG_DISPLAY_OFFSET_Y) + h > CONFIG_DISPLAY_HEIGHT)) { JADE_LOGE( "display_fill_rect called with bad params (ignored) x %d y %d w %d h %d color %u\n", x, y, w, h, color); -#if !defined(CONFIG_BOARD_TYPE_M5_CORES3) && !defined(CONFIG_BOARD_TYPE_TTGO_TWATCHS3) \ - && !defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) +#if !defined(CONFIG_DISPLAY_TOUCHSCREEN) return; #endif } @@ -245,43 +282,8 @@ 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 - /* 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); - - /* 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); - - vTaskDelay(50 / portTICK_PERIOD_MS); +#if defined(CONFIG_DISPLAY_TOUCHSCREEN) + display_draw_touch_buttons(); #endif #endif @@ -296,7 +298,13 @@ void display_init(TaskHandle_t* gui_h) bool display_flip_orientation(const bool flipped_orientation) { #ifndef CONFIG_ETH_USE_OPENETH - return display_hw_flip_orientation(flipped_orientation); + display_hw_flip_orientation(flipped_orientation); + +#if defined(CONFIG_DISPLAY_TOUCHSCREEN) + display_draw_touch_buttons(); +#endif + + return flipped_orientation; #else // Not supported for qemu return false; diff --git a/main/display_hw.c b/main/display_hw.c index a1e80a39..a295b270 100644 --- a/main/display_hw.c +++ b/main/display_hw.c @@ -267,9 +267,7 @@ inline void display_hw_draw_bitmap(int x, int y, int w, int h, const uint16_t* c JADE_ASSERT(color_data); const int calculatedx = x - CONFIG_DISPLAY_OFFSET_X; const int calculatedy = y - CONFIG_DISPLAY_OFFSET_Y; -#if (defined(CONFIG_BOARD_TYPE_M5_CORES3) || defined(CONFIG_BOARD_TYPE_TTGO_TWATCHS3) \ - || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2)) \ - && defined(CONFIG_DISPLAY_FULL_FRAME_BUFFER) +#if defined(CONFIG_DISPLAY_TOUCHSCREEN) && defined(CONFIG_DISPLAY_FULL_FRAME_BUFFER) /* this is required for the virtual buttons */ if (calculatedy >= CONFIG_DISPLAY_HEIGHT) { ESP_ERROR_CHECK( diff --git a/main/input/touchscreen.inc b/main/input/touchscreen.inc index 7607db01..790f0206 100644 --- a/main/input/touchscreen.inc +++ b/main/input/touchscreen.inc @@ -19,6 +19,10 @@ #define ESP_LCD_TOUCH_NEW_I2C(han, cfg, ret) esp_lcd_touch_new_i2c_ft5x06(han, cfg, ret) #endif +#define TOUCH_BUTTON_WIDTH 40 +#define TOUCH_BUTTON_HEIGHT 40 +#define TOUCH_BUTTON_MARGIN 5 + static volatile bool shutdown_requested = false; static volatile bool shutdown_finished = false; @@ -28,7 +32,6 @@ esp_err_t _i2c_deinit(i2c_master_bus_handle_t handle); static void touchscreen_task(void* ignored) { esp_lcd_touch_handle_t ret_touch = NULL; - // FIXME: check mirror flags? const esp_lcd_touch_config_t tp_cfg = { .x_max = CONFIG_DISPLAY_WIDTH + CONFIG_DISPLAY_OFFSET_X, .y_max = CONFIG_DISPLAY_HEIGHT + CONFIG_DISPLAY_OFFSET_Y, @@ -63,34 +66,44 @@ static void touchscreen_task(void* ignored) uint16_t touch_x[1]; uint16_t touch_y[1]; uint16_t touch_strength[1]; - uint8_t touch_cnt = 10; + uint8_t touch_cnt = 1; - // 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 = esp_lcd_touch_get_coordinates(ret_touch, touch_x, touch_y, touch_strength, &touch_cnt, 1); + 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) { - if (touch_x[0] <= first_third_end) { + const uint16_t display_left = CONFIG_DISPLAY_OFFSET_X; + const uint16_t display_right = CONFIG_DISPLAY_WIDTH + CONFIG_DISPLAY_OFFSET_X; + const uint16_t display_top = CONFIG_DISPLAY_OFFSET_Y; + const uint16_t display_bottom = CONFIG_DISPLAY_HEIGHT + TOUCH_BUTTON_HEIGHT + CONFIG_DISPLAY_OFFSET_Y; + const uint16_t split_width = CONFIG_DISPLAY_WIDTH / 3; + + bool is_flipped = gui_get_flipped_orientation(); + + if ( + (!is_flipped && touch_y[0] + TOUCH_BUTTON_HEIGHT >= display_bottom && touch_y[0] < display_bottom) || + (is_flipped && touch_y[0] >= display_top && touch_y[0] < display_top + TOUCH_BUTTON_HEIGHT) + ) { + if (touch_x[0] >= display_left && touch_x[0] < display_left + split_width) { gui_prev(); - } else if (touch_x[0] > first_third_end && touch_x[0] < middle_thirds_end) { + } else if (touch_x[0] >= display_left + split_width && touch_x[0] < display_left + split_width * 2) { gui_front_click(); - } else if (touch_x[0] >= middle_thirds_end) { + } else if (touch_x[0] >= display_left + split_width * 2 && touch_x[0] < display_right) { gui_next(); } else { continue; } - vTaskDelay(100 / portTICK_PERIOD_MS); + + vTaskDelay(250 / portTICK_PERIOD_MS); } } } + vTaskDelay(20 / portTICK_PERIOD_MS); } + ESP_ERROR_CHECK(_i2c_deinit(touch_i2c_handle)); shutdown_finished = true; vTaskDelete(NULL);