feat(screen): add resume API and swipe-up gesture for Wio L2

This commit is contained in:
Trail Mate Dev
2026-09-18 14:52:57 +08:00
parent 194c088823
commit 63d04fbfa2
7 changed files with 190 additions and 15 deletions
@@ -6,6 +6,12 @@
namespace platform::ui::screen
{
enum class ResumeMethod : std::uint8_t
{
SpaceKey,
SwipeUp,
};
struct Hooks
{
bool (*format_time)(char* out, std::size_t out_len) = nullptr;
@@ -33,5 +39,9 @@ void wake_for_modal();
void record_activity();
void disable_sleep();
void enable_sleep();
// Explicit user intent to dismiss the screen saver and return to
// the UI/page that was active before sleep.
void request_resume();
ResumeMethod resume_method();
} // namespace platform::ui::screen
@@ -3,6 +3,7 @@
#include <cstdio>
#include "lvgl.h"
#include "platform/ui/screen_runtime.h"
#include "sys/clock.h"
#include "ui/localization.h"
@@ -43,7 +44,21 @@ void set_label_texts(int unread)
}
if (s_hint_label != nullptr)
{
::ui::i18n::set_label_text(s_hint_label, "Press SPACE to resume");
switch (::platform::ui::screen::resume_method())
{
case ::platform::ui::screen::ResumeMethod::SwipeUp:
::ui::i18n::set_label_text(
s_hint_label,
"Swipe up to resume");
break;
case ::platform::ui::screen::ResumeMethod::SpaceKey:
default:
::ui::i18n::set_label_text(
s_hint_label,
"Press SPACE to resume");
break;
}
}
}
+2 -1
View File
@@ -386,7 +386,8 @@ Pairing init failed 配对初始化失败
Pairing not available 当前无法配对
Pairing not ready 配对尚未就绪
Press Back to exit USB mode 按返回键退出 USB 模式
Press SPACE to resume 按 SPACE 唤醒屏幕
Press SPACE to resume 按 SPACE 继续
Swipe up to resume 上滑以继续
RallyTo 集结到
Route configured 已配置路线
Route: %s 路线:%s
1 Action 操作
386 Pairing not available 当前无法配对
387 Pairing not ready 配对尚未就绪
388 Press Back to exit USB mode 按返回键退出 USB 模式
389 Press SPACE to resume 按 SPACE 唤醒屏幕 按 SPACE 继续
390 Swipe up to resume 上滑以继续
391 RallyTo 集结到
392 Route configured 已配置路线
393 Route: %s 路线:%s
+125 -10
View File
@@ -948,48 +948,162 @@ static void disp_flush(lv_display_t* disp_drv, const lv_area_t* area, uint8_t* c
}
#ifdef USING_INPUT_DEV_TOUCHPAD
#if defined(ARDUINO_WIO_TRACKER_L2)
constexpr int16_t kScreenResumeSwipeMinY = 60;
constexpr int16_t kScreenResumeSwipeMaxX = 80;
#endif
static void touchpad_read(lv_indev_t* drv, lv_indev_data_t* data)
{
static int16_t x, y;
static int16_t x = 0;
static int16_t y = 0;
static bool was_touched = false;
#if defined(ARDUINO_WIO_TRACKER_L2)
static bool resume_swipe_tracking = false;
static int16_t resume_start_x = 0;
static int16_t resume_start_y = 0;
static int16_t resume_last_x = 0;
static int16_t resume_last_y = 0;
#endif
#if defined(ARDUINO_T_DECK_PRO)
static bool debug_touch_active = false;
#endif
auto* plane = (LilyGo_Display*)lv_indev_get_user_data(drv);
uint8_t touched = plane->getPoint(&x, &y, 1);
auto* plane =
static_cast<LilyGo_Display*>(lv_indev_get_user_data(drv));
const uint8_t touched =
plane->getPoint(&x, &y, 1);
if (touched)
{
#if defined(ARDUINO_T_DECK_PRO)
if (!debug_touch_active)
{
Serial.printf("[DEBUG-touch-a7682e] down lvgl=%d,%d\n", x, y);
Serial.printf(
"[DEBUG-touch-a7682e] down lvgl=%d,%d\n",
x,
y);
debug_touch_active = true;
}
#endif
const bool touch_started = !was_touched;
was_touched = true;
input::MorseEngine::notifyTouch();
if (::platform::ui::screen::is_sleeping() ||
::platform::ui::screen::is_saver_active())
const bool screen_power_active =
::platform::ui::screen::is_sleeping() ||
::platform::ui::screen::is_saver_active();
if (screen_power_active)
{
#if defined(ARDUINO_WIO_TRACKER_L2)
if (touch_started)
{
resume_swipe_tracking = true;
resume_start_x = x;
resume_start_y = y;
resume_last_x = x;
resume_last_y = y;
}
else if (resume_swipe_tracking)
{
resume_last_x = x;
resume_last_y = y;
}
#endif
// Any touch wakes Sleeping -> WakePreview and refreshes the
// preview timeout. The touch is consumed by the screen-power
// layer and must not reach the underlying UI.
::platform::ui::screen::handle_input();
data->state = LV_INDEV_STATE_REL;
return;
}
#if defined(ARDUINO_WIO_TRACKER_L2)
// If the screen left the saver state while the finger is still down,
// discard any unfinished resume gesture so it cannot leak into the
// normal UI path.
resume_swipe_tracking = false;
#endif
::platform::ui::screen::record_activity();
data->point.x = x;
data->point.y = y;
data->state = LV_INDEV_STATE_PR;
return;
}
if (was_touched)
{
was_touched = false;
#if defined(ARDUINO_WIO_TRACKER_L2)
bool resumed = false;
if (resume_swipe_tracking)
{
const int16_t delta_y =
static_cast<int16_t>(
resume_start_y - resume_last_y);
const int16_t delta_x =
static_cast<int16_t>(
std::abs(
static_cast<int>(
resume_last_x - resume_start_x)));
const bool swipe_up =
delta_y >= kScreenResumeSwipeMinY &&
delta_x <= kScreenResumeSwipeMaxX;
if (swipe_up)
{
Serial.printf(
"[ScreenPower][Touch] resume swipe "
"start=(%d,%d) end=(%d,%d) dx=%d dy=%d\n",
resume_start_x,
resume_start_y,
resume_last_x,
resume_last_y,
delta_x,
delta_y);
::platform::ui::screen::request_resume();
resumed = true;
}
resume_swipe_tracking = false;
}
if (!resumed)
{
::platform::ui::screen::handle_input_release();
}
#else
::platform::ui::screen::handle_input_release();
#endif
}
#if defined(ARDUINO_T_DECK_PRO)
if (debug_touch_active)
{
Serial.printf("[DEBUG-touch-a7682e] up lvgl=%d,%d\n", x, y);
Serial.printf(
"[DEBUG-touch-a7682e] up lvgl=%d,%d\n",
x,
y);
debug_touch_active = false;
}
#endif
@@ -1109,8 +1223,9 @@ static void keypad_read(lv_indev_t* drv, lv_indev_data_t* data)
}
}
// Screen power transitions consume the input event before normal keyboard
// dispatch. Space resumes the page and focus preserved at sleep time.
// Screen-power input is consumed before normal keyboard dispatch.
// Space is the keyboard resume gesture and restores the page/focus
// that was active before sleep.
if (::platform::ui::screen::is_sleeping() ||
::platform::ui::screen::is_saver_active())
{
@@ -1118,7 +1233,7 @@ static void keypad_read(lv_indev_t* drv, lv_indev_data_t* data)
{
if (!from_nav && key == ' ')
{
::platform::ui::screen::handle_confirm_input();
::platform::ui::screen::request_resume();
}
else
{
@@ -336,7 +336,7 @@ void handle_input()
void handle_confirm_input()
{
(void)post_event(Event::ConfirmInput);
request_resume();
}
void handle_input_release()
@@ -364,4 +364,18 @@ void enable_sleep()
(void)post_event(Event::EnableSleep);
}
void request_resume()
{
(void)post_event(Event::ConfirmInput);
}
ResumeMethod resume_method()
{
#if defined(ARDUINO_WIO_TRACKER_L2)
return ResumeMethod::SwipeUp;
#else
return ResumeMethod::SpaceKey;
#endif
}
} // namespace platform::ui::screen
+11 -1
View File
@@ -349,7 +349,7 @@ void handle_input()
void handle_confirm_input()
{
(void)post_event(Event::ConfirmInput);
request_resume();
}
void handle_input_release()
@@ -377,4 +377,14 @@ void enable_sleep()
(void)post_event(Event::EnableSleep);
}
void request_resume()
{
(void)post_event(Event::ConfirmInput);
}
ResumeMethod resume_method()
{
return ResumeMethod::SpaceKey;
}
} // namespace platform::ui::screen
@@ -90,7 +90,7 @@ void handle_input()
void handle_confirm_input()
{
s_machine.dispatch(platform::ui::screen_power::Event::ConfirmInput, now_ms());
request_resume();
}
void handle_input_release()
@@ -118,4 +118,14 @@ void enable_sleep()
s_machine.dispatch(platform::ui::screen_power::Event::EnableSleep, now_ms());
}
void request_resume()
{
s_machine.dispatch(platform::ui::screen_power::Event::ConfirmInput, now_ms());
}
ResumeMethod resume_method()
{
return ResumeMethod::SpaceKey;
}
} // namespace platform::ui::screen