diff --git a/src/touch/gestures.c b/src/touch/gestures.c index 3450cd876..0d8fc36ed 100644 --- a/src/touch/gestures.c +++ b/src/touch/gestures.c @@ -146,6 +146,8 @@ static void _reset_state(void) /********************************** GESTURE DETECTION **********************************/ +typedef bool (*gesture_detect_fn)(uint8_t location); + static bool _is_continuous_tap(uint8_t location) { return _state[location].max_slide_travel < TAP_SLIDE_TOLERANCE && @@ -192,55 +194,13 @@ static void _gesture_emit_event(uint8_t id, slider_location_t location) emit_event(&event); } -static void _emit_continuous_slide_event(void) -{ - if (_is_continuous_slide(top_slider)) { - _gesture_emit_event(EVENT_SLIDE, top_slider); - } - if (_is_continuous_slide(bottom_slider)) { - _gesture_emit_event(EVENT_SLIDE, bottom_slider); - } -} - -static void _emit_slide_release_event(void) -{ - if (_is_slide_released(top_slider)) { - _gesture_emit_event(EVENT_SLIDE_RELEASED, top_slider); - } - if (_is_slide_released(bottom_slider)) { - _gesture_emit_event(EVENT_SLIDE_RELEASED, bottom_slider); - } -} - -static void _emit_long_tap_event(void) -{ - if (_is_long_tap_release(top_slider)) { - _gesture_emit_event(EVENT_LONG_TAP, top_slider); - } - if (_is_long_tap_release(bottom_slider)) { - _gesture_emit_event(EVENT_LONG_TAP, bottom_slider); - } -} - -static void _emit_short_tap_event(void) -{ - if (_is_tap_release(top_slider)) { - _gesture_emit_event(EVENT_SHORT_TAP, top_slider); - } - if (_is_tap_release(bottom_slider)) { - _gesture_emit_event(EVENT_SHORT_TAP, bottom_slider); - } -} - -static void _emit_continuous_tap_event(void) -{ - if (_is_continuous_tap(top_slider)) { - _gesture_emit_event(EVENT_CONTINUOUS_TAP, top_slider); - } - if (_is_continuous_tap(bottom_slider)) { - _gesture_emit_event(EVENT_CONTINUOUS_TAP, bottom_slider); - } -} +static gesture_detect_fn _emit_event_detect_fns[EVENT_ENUM_MAX] = { + [EVENT_SLIDE] = _is_continuous_slide, + [EVENT_SLIDE_RELEASED] = _is_slide_released, + [EVENT_CONTINUOUS_TAP] = _is_continuous_tap, + [EVENT_LONG_TAP] = _is_long_tap_release, + [EVENT_SHORT_TAP] = _is_tap_release, +}; /********************************** MEASURE, DETECT and CALLBACK **********************************/ @@ -263,11 +223,13 @@ static void _measure_and_emit(void) } if (gesture_detected) { - _emit_continuous_slide_event(); - _emit_slide_release_event(); - _emit_long_tap_event(); - _emit_short_tap_event(); - _emit_continuous_tap_event(); + for (int location = 0; location < TOUCH_NUM_SLIDERS; location++) { + for (int event_idx = 0; event_idx < EVENT_ENUM_MAX; event_idx++) { + if (_emit_event_detect_fns[event_idx](location)) { + _gesture_emit_event(event_idx, location); + } + } + } } bool both_sliders_released_or_inactive = true; diff --git a/src/ui/components/confirm_gesture.c b/src/ui/components/confirm_gesture.c index 81fbbd8df..6118ea505 100644 --- a/src/ui/components/confirm_gesture.c +++ b/src/ui/components/confirm_gesture.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -31,9 +32,9 @@ #define SCALE 6 // Divide active_count by scale to slow down motion typedef struct { - bool active_top; // Marker is 'active', i.e., touched - bool active_bottom; // Marker is 'active', i.e., touched - bool confirmed; // Confirm event occurred + bool gesture_active; // Marker is 'active', i.e., touched. + bool active[2]; // Slider is active + bool confirmed; // Confirm callback called uint16_t active_count; // Start at an offset to allow movement on first touch uint16_t bottom_arrow_slidein; // from zero to arrow height * SCALE void (*callback)(void* user_data); @@ -43,7 +44,7 @@ typedef struct { bool confirm_gesture_is_active(component_t* component) { confirm_data_t* data = (confirm_data_t*)component->data; - return data->active_top; + return data->gesture_active; } /** @@ -57,19 +58,22 @@ static void _render(component_t* component) confirm_data_t* data = (confirm_data_t*)component->data; // Update active_count - if (data->active_top && data->active_bottom) { + if (data->active[0] && data->active[1]) { data->active_count++; + data->gesture_active = true; } else { data->active_count = MAX(SCALE - 1, data->active_count - SCALE); } - // Update bottom arrow slidein - if (data->active_top) { + // Update bottom arrow slidein if top is active + if (data->active[top_slider]) { if (data->bottom_arrow_slidein < arrow_height * SCALE) { data->bottom_arrow_slidein++; } } else if (data->bottom_arrow_slidein > 0) { data->bottom_arrow_slidein--; + } else if (data->bottom_arrow_slidein == 0) { + data->gesture_active = false; } // Draw the top arrow @@ -101,31 +105,18 @@ static void _render(component_t* component) static void _on_event(const event_t* event, component_t* component) { confirm_data_t* data = (confirm_data_t*)component->data; + ASSERT(event->data.source < sizeof(data->active)); switch (event->id) { - case EVENT_SLIDE_RELEASED: - if (event->data.source == top_slider) { - data->active_top = false; - } else { - data->active_bottom = false; - } - break; case EVENT_CONTINUOUS_TAP: if (event->data.position > SLIDER_POSITION_TWO_THIRD && event->data.position <= MAX_SLIDER_POS) { - if (event->data.source == top_slider) { - data->active_top = true; - } else { - data->active_bottom = true; - } + data->active[event->data.source] = true; } break; + case EVENT_SLIDE_RELEASED: case EVENT_SHORT_TAP: - if (event->data.source == top_slider) { - data->active_top = false; - } else { - data->active_bottom = false; - } + data->active[event->data.source] = false; break; default: break; @@ -155,8 +146,9 @@ component_t* confirm_gesture_create(void (*callback)(void*), void* user_data) Abort("Error: malloc confirm_gesture data"); } memset(data, 0, sizeof(confirm_data_t)); - data->active_top = false; - data->active_bottom = false; + data->gesture_active = false; + data->active[0] = false; + data->active[1] = false; data->confirmed = false; data->active_count = SCALE - 1; data->bottom_arrow_slidein = 0; diff --git a/src/ui/components/trinary_input_string.c b/src/ui/components/trinary_input_string.c index 28af00d15..7661b6f07 100644 --- a/src/ui/components/trinary_input_string.c +++ b/src/ui/components/trinary_input_string.c @@ -216,11 +216,6 @@ static void _render(component_t* component) UG_PutString(0, STRING_POS_Y, "...", false); } - // Render sub-components - if (data->can_confirm) { - data->confirm_component->f->render(data->confirm_component); - } - // Do not process events for components which are not rendered. data->trinary_char_component->disabled = true; data->left_arrow_component->disabled = true; @@ -245,6 +240,12 @@ static void _render(component_t* component) if (data->title_on_top || show_title) { data->title_component->f->render(data->title_component); } + + // Render confirm button or gesture (render confirm gesture last so that bottom triangle is + // above keyboard) + if (data->can_confirm) { + data->confirm_component->f->render(data->confirm_component); + } } static void _input_char_set_alphabet(component_t* trinary_char, keyboard_mode_t mode) diff --git a/src/ui/event.h b/src/ui/event.h index cb1e3fd21..e9f269438 100644 --- a/src/ui/event.h +++ b/src/ui/event.h @@ -31,6 +31,7 @@ enum { EVENT_CONTINUOUS_TAP, EVENT_LONG_TAP, EVENT_SHORT_TAP, + EVENT_ENUM_MAX, // MAX must always be last, indicates the number of items in the enumration }; typedef struct {