Updated: October 28, 2024 |
This example contains most of the code snippets that illustrate how to create a gesture application and cascade multiple gesture sets using failure callbacks.
#include <stdio.h> #include <screen/screen.h> #include <input/screen_helpers.h> #include <gestures/types.h> #include <gestures/set.h> #include <gestures/event_list.h> #include <gestures/swipe.h> #include <gestures/pinch.h> #include <gestures/press_and_tap.h> #include <gestures/rotate.h> #include <gestures/two_finger_pan.h> #include <gestures/tap.h> #include <gestures/double_tap.h> #include <gestures/triple_tap.h> #include <gestures/long_press.h> #include <gestures/two_finger_tap.h> /* The callback invoked when a gesture is recognized or updated. */ void gesture_callback(gesture_base_t* gesture, mtouch_event_t* event, void* param, int async) { if (async) { printf("[async] "); } switch (gesture->type) { case GESTURE_TWO_FINGER_PAN: { gesture_tfpan_t* tfpan = (gesture_tfpan_t*)gesture; printf("Two-finger pan: %d, %d", tfpan->centroid.x, tfpan->centroid.y); break; } case GESTURE_ROTATE: { gesture_rotate_t* rotate = (gesture_rotate_t*)gesture; if (rotate->angle != rotate->last_angle) { printf("Rotate: %d degs", rotate->angle - rotate->last_angle); } else { return; } break; } case GESTURE_SWIPE: { gesture_swipe_t* swipe = (gesture_swipe_t*)gesture; printf("Swipe "); if (swipe->direction & GESTURE_DIRECTION_UP) { printf("up %d", swipe->last_coords.y - swipe->coords.y); } else if (swipe->direction & GESTURE_DIRECTION_DOWN) { printf("down %d", swipe->coords.y - swipe->last_coords.y); } else if (swipe->direction & GESTURE_DIRECTION_LEFT) { printf("left %d", swipe->last_coords.x - swipe->coords.x); } else if (swipe->direction & GESTURE_DIRECTION_RIGHT) { printf("right %d", swipe->coords.x - swipe->last_coords.x); } break; } case GESTURE_PINCH: { gesture_pinch_t* pinch = (gesture_pinch_t*)gesture; printf("Pinch %d, %d", (pinch->last_distance.x - pinch->distance.x), (pinch->last_distance.y - pinch->distance.y)); break; } case GESTURE_TAP: printf("Tap"); break; case GESTURE_DOUBLE_TAP: printf("Double tap"); break; case GESTURE_TRIPLE_TAP: printf("Triple tap"); break; case GESTURE_PRESS_AND_TAP: printf("Press and tap"); break; case GESTURE_TWO_FINGER_TAP: printf("Two-finger tap"); break; case GESTURE_LONG_PRESS: printf("Long press"); break; case GESTURE_USER: printf("User"); break; default: printf("Unknown"); break; } printf("\n"); } /** * The set failure callback that's invoked when all gestures in the first set have * transitioned to the failed state. */ void fail_callback(struct gestures_set* set, struct event_list* list, int async) { if (set == first_set) { /* Sample list copy - not necessary if events don't need to be kept following the call to gestures_set_process_event_list() */ struct event_list* new_list = event_list_alloc(0, 0, 0, 1); if (new_list) { event_list_copy(list, new_list); gestures_set_process_event_list(second_set, new_list, NULL); event_list_free(new_list); } } } /** Initialize the gesture sets */ static void init_gestures() { gesture_tap_t* tap; gesture_double_tap_t* double_tap; gesture_triple_tap_t* triple_tap; gesture_tft_t* tft; first_set = gestures_set_alloc(); if (NULL != first_set) { long_press_gesture_alloc(NULL, gesture_callback, first_set); tap = tap_gesture_alloc(NULL, gesture_callback, first_set); double_tap = double_tap_gesture_alloc(NULL, gesture_callback, first_set); triple_tap = triple_tap_gesture_alloc(NULL, gesture_callback, first_set); tft = tft_gesture_alloc(NULL, gesture_callback, first_set); gesture_add_mustfail(&tap->base, &double_tap->base); gesture_add_mustfail(&double_tap->base, &triple_tap->base); gestures_set_register_fail_cb(first_set, fail_callback); second_set = gestures_set_alloc(); if (NULL != second_set) { swipe_gesture_alloc(NULL, gesture_callback, second_set); pinch_gesture_alloc(NULL, gesture_callback, second_set); rotate_gesture_alloc(NULL, gesture_callback, second_set); pt_gesture_alloc(NULL, gesture_callback, second_set); tfpan_gesture_alloc(NULL, gesture_callback, second_set); tft_gesture_alloc(NULL, gesture_callback, second_set); } else { gestures_set_free(first_set); first_set = NULL; } } else { fprintf(stderr, "Failed to allocate gesture sets\n"); } } static void gestures_cleanup() { if (NULL != first_set) { gestures_set_free(first_set); first_set = NULL; } if (NULL != second_set) { gestures_set_free(second_set); second_set = NULL; } } int main(int argc, const char* argv[]) { int screen_val; screen_event_t screen_ev; int rc; ... mtouch_event_t mtouch_event; init_gestures(); while (1) { while (screen_get_event(screen_ctx, screen_ev, ~0L) == EOK) { rc = screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_TYPE, &screen_val); if (rc || screen_val == SCREEN_EVENT_NONE) { break; } switch (screen_val) { case SCREEN_EVENT_MTOUCH_TOUCH: case SCREEN_EVENT_MTOUCH_MOVE: case SCREEN_EVENT_MTOUCH_RELEASE: rc = screen_get_mtouch_event(screen_ev, &mtouch_event, 0); if (rc) { fprintf(stderr, "Error: failed to get mtouch event\n"); continue; } gestures_set_process_event(first_set, &mtouch_event, NULL); break; } } } gestures_cleanup(); return 0; }