/** * @author RĂ©mi Heredero * @version 1.0.0 * @date July 2023 * @file click_handler.c */ #include "click_handler.h" void CLICK_HANDLER_init(CLICK_HANDLER* me){ me->state = STCH_INIT; me->clickTimer = 250; me->wait.f = NULL; me->long_click.f = NULL; me->single_click.f = NULL; me->double_click.f = NULL; } void CLICK_HANDLER_startBehaviour(CLICK_HANDLER* me){ POST(me, &CLICK_HANDLER_processEvent, evCHinit, 0, 0); } bool CLICK_HANDLER_processEvent(Event* ev) { bool processed = false; CLICK_HANDLER* me = (CLICK_HANDLER*)Event_getTarget(ev); CLICK_HANDLER_STATES oldState = me->state; evIDT evid = Event_getId(ev); switch (me->state) { // onState case STCH_INIT: if (ev->id == evCHinit) { me->state = STCH_WAIT; } break; case STCH_WAIT: if(evid == evCHpbpress) { me->state = STCH_LONG_CLICK; CLICK_HANDLER_emitTimer(me, me->clickTimer); } break; case STCH_LONG_CLICK: if(evid == evCHpbrelease) { me->state = STCH_SINGLE_CLICK; } if(evid == evCHtimer) { me->state = STCH_WAIT; } break; case STCH_SINGLE_CLICK: if(evid == evCHpbpress) { me->state = STCH_DOUBLE_CLICK; } if(evid == evCHtimer) { me->state = STCH_WAIT; } break; case STCH_DOUBLE_CLICK: if(evid == evCHpbrelease) { me->state = STCH_WAIT; } if(evid == evCHtimer) { me->state = STCH_WAIT; } break; } if(oldState != me->state){ switch (oldState) { // onExit case STCH_INIT: break; case STCH_WAIT: break; case STCH_LONG_CLICK: if(evid == evCHtimer) { if (me->long_click.f != NULL) { me->long_click.f(me->long_click.p); } } break; case STCH_SINGLE_CLICK: if(evid == evCHtimer) { if (me->single_click.f != NULL) { me->single_click.f(me->single_click.p); } } break; case STCH_DOUBLE_CLICK: if(evid == evCHtimer) { if(me->double_click.f != NULL) { me->double_click.f(me->double_click.p); } } if(evid == evCHpbrelease) { if(me->double_click.f != NULL) { me->double_click.f(me->double_click.p); } } break; } switch (me->state) { // onEntry case STCH_INIT: break; case STCH_WAIT: break; case STCH_LONG_CLICK: break; case STCH_SINGLE_CLICK: break; case STCH_DOUBLE_CLICK: break; } processed = true; } return processed; } /************* * Callbacks * *************/ void CLICK_HANDLER_onWait(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) { me->wait.f = f; me->wait.p = p; } void CLICK_HANDLER_onLong_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) { me->long_click.f = f; me->long_click.p = p; } void CLICK_HANDLER_onSingle_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) { me->single_click.f = f; me->single_click.p = p; } void CLICK_HANDLER_onDouble_click(CLICK_HANDLER* me, CLICK_HANDLER_CALLBACK_FUNCTION f, void* p) { me->double_click.f = f; me->double_click.p = p; } /************ * EMITTERS * ************/ void CLICK_HANDLER_emitTimer(CLICK_HANDLER* me, uint16_t t) { POST(me, &CLICK_HANDLER_processEvent, evCHtimer, t, 0); } void CLICK_HANDLER_emitPbpress(CLICK_HANDLER* me, uint16_t t) { POST(me, &CLICK_HANDLER_processEvent, evCHpbpress, t, 0); } void CLICK_HANDLER_emitPbrelease(CLICK_HANDLER* me, uint16_t t) { POST(me, &CLICK_HANDLER_processEvent, evCHpbrelease, t, 0); } /*********** * SETTERS * ***********/ void CLICK_HANDLER_setClickTimer(CLICK_HANDLER* me, uint16_t v) { me->clickTimer = v; }