Add touch tap gesture for back navigation
Implements a reusable touch tap gesture in the top-left corner that maps to the Back button. The gesture is automatically integrated into wasPressed/wasReleased for Back button, making it available across all screens without per-activity code. Also fixes low-power CPU frequency floor to 80 MHz on PSRAM boards to prevent SD write and PSRAM instability caused by APB clock dropping below safe threshold.
This commit is contained in:
@@ -231,6 +231,8 @@ unsigned long HalGPIO::getHeldTime() const { return inputMgr.getHeldTime(); }
|
||||
|
||||
unsigned long HalGPIO::getPowerButtonHeldTime() const { return inputMgr.getPowerButtonHeldTime(); }
|
||||
|
||||
bool HalGPIO::wasTouchTap(float& nx, float& ny) const { return inputMgr.wasTouchTap(nx, ny); }
|
||||
|
||||
void HalGPIO::startDeepSleep() {
|
||||
// Ensure that the power button has been released to avoid immediately turning back on if you're holding it
|
||||
while (inputMgr.isPressed(BTN_POWER)) {
|
||||
|
||||
@@ -72,6 +72,11 @@ class HalGPIO {
|
||||
unsigned long getHeldTime() const;
|
||||
unsigned long getPowerButtonHeldTime() const;
|
||||
|
||||
// Touch: one-shot tap with the release position normalized 0..1 in the panel's
|
||||
// native orientation. Returns false on non-touch devices. (Reusable gesture
|
||||
// primitive; see MappedInputManager for the top-left = Back mapping.)
|
||||
bool wasTouchTap(float& nx, float& ny) const;
|
||||
|
||||
// Setup wake up GPIO and enter deep sleep
|
||||
void startDeepSleep();
|
||||
|
||||
|
||||
@@ -28,7 +28,16 @@ class HalPowerManager {
|
||||
SemaphoreHandle_t modeMutex = nullptr; // Protect access to currentLockMode
|
||||
|
||||
public:
|
||||
static constexpr int LOW_POWER_FREQ = 10; // MHz
|
||||
// On PSRAM boards (classic ESP32 / M5Paper) the APB clock follows the CPU below
|
||||
// 80 MHz, and APB clocks both the SD SPI bus and the 80 MHz PSRAM (which holds
|
||||
// the framebuffer). Dropping to 10 MHz breaks SD writes and PSRAM, so floor the
|
||||
// low-power CPU at 80 MHz (APB stays pinned at 80 for CPU 80/160/240, so power
|
||||
// still drops from the 240 MHz default while SD/PSRAM stay stable).
|
||||
#if defined(BOARD_HAS_PSRAM)
|
||||
static constexpr int LOW_POWER_FREQ = 80; // MHz (APB-safe floor for PSRAM/SD)
|
||||
#else
|
||||
static constexpr int LOW_POWER_FREQ = 10; // MHz
|
||||
#endif
|
||||
static constexpr unsigned long IDLE_POWER_SAVING_MS = 3000; // ms
|
||||
static constexpr unsigned long BATTERY_POLL_MS = 1500; // ms
|
||||
|
||||
|
||||
@@ -54,9 +54,29 @@ bool MappedInputManager::mapButton(const Button button, bool (HalGPIO::*fn)(uint
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MappedInputManager::wasPressed(const Button button) const { return mapButton(button, &HalGPIO::wasPressed); }
|
||||
// Top-left corner of the panel (panel-native, normalized). Generous so it's easy
|
||||
// to hit; v1 is not yet orientation-mapped (see wasBackGesture NOTE in header).
|
||||
static constexpr float BACK_GESTURE_FRAC_X = 0.22f;
|
||||
static constexpr float BACK_GESTURE_FRAC_Y = 0.12f;
|
||||
|
||||
bool MappedInputManager::wasReleased(const Button button) const { return mapButton(button, &HalGPIO::wasReleased); }
|
||||
bool MappedInputManager::wasBackGesture() const {
|
||||
float nx = 0.0f, ny = 0.0f;
|
||||
if (!gpio.wasTouchTap(nx, ny)) return false;
|
||||
return nx <= BACK_GESTURE_FRAC_X && ny <= BACK_GESTURE_FRAC_Y;
|
||||
}
|
||||
|
||||
bool MappedInputManager::wasPressed(const Button button) const {
|
||||
// A top-left tap fires on the release frame; expose it on Back's press edge too
|
||||
// so menus that act on wasPressed(Back) also respond. Deliberately NOT folded
|
||||
// into isPressed, so a quick tap never satisfies the readers' long-press-home.
|
||||
if (button == Button::Back && wasBackGesture()) return true;
|
||||
return mapButton(button, &HalGPIO::wasPressed);
|
||||
}
|
||||
|
||||
bool MappedInputManager::wasReleased(const Button button) const {
|
||||
if (button == Button::Back && wasBackGesture()) return true;
|
||||
return mapButton(button, &HalGPIO::wasReleased);
|
||||
}
|
||||
|
||||
bool MappedInputManager::isPressed(const Button button) const { return mapButton(button, &HalGPIO::isPressed); }
|
||||
|
||||
|
||||
@@ -19,6 +19,11 @@ class MappedInputManager {
|
||||
bool wasPressed(Button button) const;
|
||||
bool wasReleased(Button button) const;
|
||||
bool isPressed(Button button) const;
|
||||
// Reusable touch "back" gesture: a tap released in the top-left corner. Folded
|
||||
// into Back's press/release edges, so every screen gets it with no per-activity
|
||||
// code and no coordinates passed. False on non-touch devices.
|
||||
// NOTE: v1 uses panel-native coordinates (not yet orientation-mapped).
|
||||
bool wasBackGesture() const;
|
||||
bool wasAnyPressed() const;
|
||||
bool wasAnyReleased() const;
|
||||
unsigned long getHeldTime() const;
|
||||
|
||||
Reference in New Issue
Block a user