ref: e5b73212f6addcfdb5e306df63d7135e543c4f8d
src/buttonhandler/ButtonHandler.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
#include "buttonhandler/ButtonHandler.h" using namespace Pinetime::Controllers; void ButtonTimerCallback(TimerHandle_t xTimer) { auto* sysTask = static_cast<Pinetime::System::SystemTask*>(pvTimerGetTimerID(xTimer)); sysTask->PushMessage(Pinetime::System::Messages::HandleButtonTimerEvent); } void ButtonHandler::Init(Pinetime::System::SystemTask* systemTask) { buttonTimer = xTimerCreate("buttonTimer", pdMS_TO_TICKS(200), pdFALSE, systemTask, ButtonTimerCallback); } ButtonActions ButtonHandler::HandleEvent(Events event) { static constexpr TickType_t doubleClickTime = pdMS_TO_TICKS(200); static constexpr TickType_t longPressTime = pdMS_TO_TICKS(400); static constexpr TickType_t longerPressTime = pdMS_TO_TICKS(2000); if (event == Events::Press) { buttonPressed = true; } else if (event == Events::Release) { releaseTime = xTaskGetTickCount(); buttonPressed = false; } switch (state) { case States::Idle: if (event == Events::Press) { xTimerChangePeriod(buttonTimer, doubleClickTime, 0); xTimerStart(buttonTimer, 0); state = States::Pressed; } break; case States::Pressed: if (event == Events::Press) { if (xTaskGetTickCount() - releaseTime < doubleClickTime) { xTimerStop(buttonTimer, 0); state = States::Idle; return ButtonActions::DoubleClick; } } else if (event == Events::Release) { xTimerChangePeriod(buttonTimer, doubleClickTime, 0); xTimerStart(buttonTimer, 0); } else if (event == Events::Timer) { if (buttonPressed) { xTimerChangePeriod(buttonTimer, longPressTime - doubleClickTime, 0); xTimerStart(buttonTimer, 0); state = States::Holding; } else { state = States::Idle; return ButtonActions::Click; } } break; case States::Holding: if (event == Events::Release) { xTimerStop(buttonTimer, 0); state = States::Idle; return ButtonActions::Click; } else if (event == Events::Timer) { xTimerChangePeriod(buttonTimer, longerPressTime - longPressTime - doubleClickTime, 0); xTimerStart(buttonTimer, 0); state = States::LongHeld; return ButtonActions::LongPress; } break; case States::LongHeld: if (event == Events::Release) { xTimerStop(buttonTimer, 0); state = States::Idle; } else if (event == Events::Timer) { state = States::Idle; return ButtonActions::LongerPress; } break; } return ButtonActions::None; } |