diff --git a/dev/main.c b/dev/main.c index 69493f8..17d4c89 100644 --- a/dev/main.c +++ b/dev/main.c @@ -43,6 +43,10 @@ prv_btn_event(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt) { uint32_t* diff_time_ptr = &last_time_keys[(*(int*)btn->arg) - '0']; uint32_t diff_time = get_tick() - *diff_time_ptr; + /* This is for purpose of test and timing validation */ + if (diff_time > 2000) { + diff_time = 0; + } *diff_time_ptr = get_tick(); /* Set current date as last one */ /* Get event string */ @@ -63,10 +67,8 @@ prv_btn_event(struct lwbtn* lw, struct lwbtn_btn* btn, lwbtn_evt_t evt) { color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; } SetConsoleTextAttribute(hConsole, color); - printf("[%7u][%6u] CH: %c, evt: %s, keep-alive cnt: %3u, click cnt: %3u\r\n", (unsigned)get_tick(), (unsigned)diff_time, *(int*)btn->arg, s, (unsigned)btn->keepalive.cnt, (unsigned)btn->click.cnt); - SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); (void)lw; } diff --git a/docs/static/images/log-btn-event-click-multi-max-over.png b/docs/static/images/log-btn-event-click-multi-max-over.png new file mode 100644 index 0000000..4bcda66 Binary files /dev/null and b/docs/static/images/log-btn-event-click-multi-max-over.png differ diff --git a/docs/static/images/log-btn-event-click-multi-max.png b/docs/static/images/log-btn-event-click-multi-max.png new file mode 100644 index 0000000..a751e89 Binary files /dev/null and b/docs/static/images/log-btn-event-click-multi-max.png differ diff --git a/docs/static/images/log-btn-event-click-multi.png b/docs/static/images/log-btn-event-click-multi.png new file mode 100644 index 0000000..0b9de23 Binary files /dev/null and b/docs/static/images/log-btn-event-click-multi.png differ diff --git a/docs/static/images/log-btn-event-click.png b/docs/static/images/log-btn-event-click.png new file mode 100644 index 0000000..bf97a77 Binary files /dev/null and b/docs/static/images/log-btn-event-click.png differ diff --git a/docs/static/images/log-btn-event-keep-alive.png b/docs/static/images/log-btn-event-keep-alive.png new file mode 100644 index 0000000..8ae9935 Binary files /dev/null and b/docs/static/images/log-btn-event-keep-alive.png differ diff --git a/docs/user-manual/index.rst b/docs/user-manual/index.rst index 0ac7528..475e18b 100644 --- a/docs/user-manual/index.rst +++ b/docs/user-manual/index.rst @@ -70,6 +70,17 @@ When conditions are met, **onclick** event is sent, either immediately after **o Sequence for valid click event +A windows-test program demonstration of events is visible below. + +.. figure:: ../static/images/log-btn-event-click.png + :align: center + :alt: Click event test program + + Click event test program + +Second number for each line is a **milliseconds** difference between events. +OnClick is reported approximately (windows real-time issue) ``400`` ms after on-release event. + Multi-click events ^^^^^^^^^^^^^^^^^^ @@ -92,8 +103,25 @@ Simplified diagram for multi-click, ignoring debounce time indicators, is below. Multi-click event example - with 3 consecutive presses +A windows-test program demonstration of events is visible below. + +.. figure:: ../static/images/log-btn-event-click-multi.png + :align: center + :alt: Multi-click event test program + + Multi-click event test program + +Multi-click event with **onclick** event reported only after second press after minimum timeout of ``400ms``. + Number of consecutive clicks can be upper-limited to the desired value. When user makes more (or equal) consecutive clicks than maximum, an **onclick** event is sent immediately after **onrelease** event for last detected click. + +.. figure:: ../static/images/log-btn-event-click-multi-max.png + :align: center + :alt: Max number of onclick events + + Max number of onclick events, onclick is sent immediately after onrelease + There is no need to wait timeout expiration since upper clicks limit has been reached. This is illustrated in the picture below, showing event sequence when: @@ -106,6 +134,12 @@ This is illustrated in the picture below, showing event sequence when: Multi-click events with too many clicks +.. figure:: ../static/images/log-btn-event-click-multi-max-over.png + :align: center + :alt: 5 presses detected with 3 set as maximum + + 5 presses detected with 3 set as maximum. First on-click is sent immediately, while second is sent after timeout + When **multi-click** feature is disabled, **onclick** event is sent after every valid sequence of **onpress** and **onrelease** events. .. tip:: diff --git a/lwbtn/src/include/lwbtn/lwbtn_opt.h b/lwbtn/src/include/lwbtn/lwbtn_opt.h index 242f87a..c1476b0 100644 --- a/lwbtn/src/include/lwbtn/lwbtn_opt.h +++ b/lwbtn/src/include/lwbtn/lwbtn_opt.h @@ -108,6 +108,20 @@ extern "C" { #define LWBTN_CFG_TIME_KEEPALIVE_PERIOD 100 #endif +/** + * \brief Enables `1` or disables `0` immediate onclick event + * after on-release event, if number of consecutive + * clicks reaches max value. + * + * When this mode is disabled, onclick is sent in one of 2 cases: + * + * - An on-click timeout occurred + * - Next on-press event occurred before timeout expired + */ +#ifndef LWBTN_CFG_CLICK_MAX_CONSECUTIVE_SEND_IMMEDIATELY +#define LWBTN_CFG_CLICK_MAX_CONSECUTIVE_SEND_IMMEDIATELY 1 +#endif + /** * \} */ diff --git a/lwbtn/src/lwbtn/lwbtn.c b/lwbtn/src/lwbtn/lwbtn.c index a7b5045..1d675cc 100644 --- a/lwbtn/src/lwbtn/lwbtn.c +++ b/lwbtn/src/lwbtn/lwbtn.c @@ -137,6 +137,18 @@ lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime) { * these will be sent after the timeout window (and after the on-release event) */ } + +#if LWBTN_CFG_CLICK_MAX_CONSECUTIVE_SEND_IMMEDIATELY + /* + * Depending on the configuration, + * this part will send on-click event immediately after release event, + * if maximum number of consecutive clicks has been reached. + */ + if (btn->click.cnt > 0 && btn->click.cnt == LWBTN_CLICK_MAX_CONSECUTIVE(btn)) { + lw->evt_fn(lw, btn, LWBTN_EVT_ONCLICK); + btn->click.cnt = 0; + } +#endif /* LWBTN_CFG_CLICK_MAX_CONSECUTIVE_SEND_IMMEDIATELY */ } } @@ -163,18 +175,19 @@ lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime) { if (!(btn->flags & LWBTN_FLAG_ONPRESS_SENT)) { /* Check minimum stable time */ if ((mstime - btn->time_change) >= LWBTN_TIME_DEBOUNCE_GET_MIN(btn)) { +#if !LWBTN_CFG_CLICK_MAX_CONSECUTIVE_SEND_IMMEDIATELY /* - * Immediately send click event if number of - * previous consecutive clicks reached maximum level. - * - * Handle this before sending on-press state + * Depending on the configuration, + * this part will send on-click event just before the next on-press release, + * if maximum number of consecutive clicks has been reached. */ if (btn->click.cnt > 0 && btn->click.cnt == LWBTN_CLICK_MAX_CONSECUTIVE(btn)) { lw->evt_fn(lw, btn, LWBTN_EVT_ONCLICK); btn->click.cnt = 0; } +#endif /* !LWBTN_CFG_CLICK_MAX_CONSECUTIVE_SEND_IMMEDIATELY */ - /* Now start with new on-press */ + /* Start with new on-press */ btn->flags |= LWBTN_FLAG_ONPRESS_SENT; lw->evt_fn(lw, btn, LWBTN_EVT_ONPRESS); @@ -182,6 +195,7 @@ lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime) { btn->keepalive.last_time = mstime; } } + /* * Handle keep alive, but only if on-press event has been sent * @@ -201,13 +215,12 @@ lwbtn_process_ex(lwbtn_t* lw, uint32_t mstime) { */ else { /* - * As we want to allow user to perform "multi-click" before sending - * the actual "onclick" event, we shall ensure certain timeout before sending - * that "onclick event". + * Based on te configuration, this part of the code + * will send on-click event after certain timeout. * - * This part checks for number of consecutive clicks being more than 0, - * and will process the onclick event to user, unless there is another click in the meantime, - * that will force the timing to postpone event generation + * This feature is useful if users prefers multi-click feature + * that is reported only after last click event happened, + * including number of clicks made by user */ if (btn->click.cnt > 0) { if ((mstime - btn->click.last_time) >= LWBTN_TIME_CLICK_MAX_MULTI(btn)) {