struct _Taps_Type
{
Elm_Gesture_Taps_Info info;
- unsigned int count_ups;
unsigned int sum_x;
unsigned int sum_y;
+ unsigned int n_taps_needed;
unsigned int n_taps;
Eina_List *l;
};
/* Clear history if all we have aborted gestures */
Eina_Bool reset_s = EINA_TRUE, all_undefined = EINA_TRUE;
- for (i = ELM_GESTURE_FIRST ; i < ELM_GESTURE_LAST; i++)
+ for (i = ELM_GESTURE_FIRST; i < ELM_GESTURE_LAST; i++)
{ /* If no gesture started and all we have aborted gestures, reset all */
Gesture_Info *p = wd->gesture[i];
if ((p) && (p->state != ELM_GESTURE_STATE_UNDEFINED))
}
}
-// if ((!wd->touched) || (reset_s && !all_undefined))
- /* (!wd->touched && reset_s) - don't stop zoom with mouse-wheel */
if (reset_s && (!all_undefined))
return _event_history_clear(obj);
* This happens when we need to reset our tests.
* for example when gesture is detected or all ABORTed. */
static void
-_dbl_click_test_reset(Gesture_Info *gesture)
+_tap_gestures_test_reset(Gesture_Info *gesture)
{
if (!gesture)
return;
Widget_Data *wd = elm_widget_data_get(gesture->obj);
- if (wd->dbl_timeout) ecore_timer_del(wd->dbl_timeout);
wd->dbl_timeout = NULL;
Eina_List *data;
Pointer_Event *pe;
return;
Long_Tap_Type *st = gesture->data;
- if (st->timeout) ecore_timer_del(st->timeout);
Eina_List *l;
Pointer_Event *p;
EINA_LIST_FOREACH(st->touched, l, p)
free(p);
eina_list_free(st->touched);
+ if (st->timeout) ecore_timer_del(st->timeout);
memset(gesture->data, 0, sizeof(Long_Tap_Type));
}
_reset_states(wd); /* we are ready to start testing for gestures again */
- /* Clear all gestures intermediate date */
- _n_long_tap_test_reset(wd->gesture[ELM_GESTURE_N_LONG_TAPS]);
- _dbl_click_test_reset(wd->gesture[ELM_GESTURE_N_TAPS]);
- _dbl_click_test_reset(wd->gesture[ELM_GESTURE_N_DOUBLE_TAPS]);
- _dbl_click_test_reset(wd->gesture[ELM_GESTURE_N_TRIPLE_TAPS]);
+ /* Clear all gestures intermediate data */
+ if (IS_TESTED(ELM_GESTURE_N_LONG_TAPS))
+ { /* We do not clear a long-tap gesture if fingers still on surface */
+ /* and gesture timer still pending to test gesture state */
+ Long_Tap_Type *st = wd->gesture[ELM_GESTURE_N_LONG_TAPS]->data;
+ if((!eina_list_count(st->touched)) || (!st->timeout))
+ _n_long_tap_test_reset(wd->gesture[ELM_GESTURE_N_LONG_TAPS]);
+ }
+
+ if (wd->dbl_timeout)
+ {
+ ecore_timer_del(wd->dbl_timeout);
+ wd->dbl_timeout = NULL;
+ }
+
+ _tap_gestures_test_reset(wd->gesture[ELM_GESTURE_N_TAPS]);
+ _tap_gestures_test_reset(wd->gesture[ELM_GESTURE_N_DOUBLE_TAPS]);
+ _tap_gestures_test_reset(wd->gesture[ELM_GESTURE_N_TRIPLE_TAPS]);
_momentum_test_reset(wd->gesture[ELM_GESTURE_MOMENTUM]);
_line_test_reset(wd->gesture[ELM_GESTURE_N_LINES]);
_line_test_reset(wd->gesture[ELM_GESTURE_N_FLICKS]);
/**
* @internal
*
- * when this timer expires we ABORT double click gesture.
+ * This function sets state a tap-gesture to END or ABORT
+ *
+ * @param data gesture info pointer
+ *
+ * @ingroup Elm_Gesture_Layer
+ */
+static void
+_tap_gesture_finish(void *data)
+{ /* This function will test each tap gesture when timer expires */
+ Gesture_Info *gesture = data;
+ Elm_Gesture_State s = ELM_GESTURE_STATE_END;
+ /* Here we check if taps-gesture was completed successfuly */
+ /* Count how many taps were recieved on each device then */
+ /* determine if it matches n_taps_needed defined on START */
+ Taps_Type *st = gesture->data;
+ Eina_List *l;
+ Eina_List *pe_list;
+ EINA_LIST_FOREACH(st->l, l, pe_list)
+ {
+ if (eina_list_count(pe_list) != st->n_taps_needed)
+ { /* No match taps number on device, ABORT */
+ s = ELM_GESTURE_STATE_ABORT;
+ break;
+ }
+ }
+
+ st->info.n = eina_list_count(st->l);
+ _set_state(gesture, s, gesture->info, EINA_FALSE);
+ _tap_gestures_test_reset(gesture);
+}
+
+/**
+ * @internal
+ *
+ * when this timer expires we finish tap gestures.
*
* @param data The gesture-layer object.
* @return cancles callback for this timer.
* @ingroup Elm_Gesture_Layer
*/
static Eina_Bool
-_dbl_click_timeout(void *data)
+_multi_tap_timeout(void *data)
{
- Gesture_Info *gesture = data;
- Widget_Data *wd = elm_widget_data_get(gesture->obj);
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return EINA_FALSE;
- wd->dbl_timeout = NULL;
- _set_state(gesture, ELM_GESTURE_STATE_ABORT,
- gesture->info, EINA_FALSE);
+ if (IS_TESTED(ELM_GESTURE_N_TAPS))
+ _tap_gesture_finish(wd->gesture[ELM_GESTURE_N_TAPS]);
+
+ if (IS_TESTED(ELM_GESTURE_N_DOUBLE_TAPS))
+ _tap_gesture_finish(wd->gesture[ELM_GESTURE_N_DOUBLE_TAPS]);
- _dbl_click_test_reset(gesture);
- _clear_if_finished(gesture->obj);
+ if (IS_TESTED(ELM_GESTURE_N_TRIPLE_TAPS))
+ _tap_gesture_finish(wd->gesture[ELM_GESTURE_N_TRIPLE_TAPS]);
+
+ _clear_if_finished(data);
+ wd->dbl_timeout = NULL;
return ECORE_CALLBACK_CANCEL;
}
return ECORE_CALLBACK_CANCEL;
}
+
/**
* @internal
*
- * This function checks all click/tap and double/triple taps
+ * This function checks if a tap gesture should start
*
- * @param obj The gesture-layer object.
+ * @param wd Gesture Layer Widget Data.
* @param pe The recent input event as stored in pe struct.
* @param event_info Original input event pointer.
* @param event_type Type of original input event.
- * @param g_type what Gesture we are testing.
- * @param taps How many click/taps we test for.
+ * @param gesture what gesture is tested
+ * @param how many taps for this gesture (1, 2 or 3)
+ *
+ * @return Flag to determine if we need to set a timer for finish
*
* @ingroup Elm_Gesture_Layer
*/
-static void
-_dbl_click_test(Evas_Object *obj, Pointer_Event *pe,
+static Eina_Bool
+_tap_gesture_start(Widget_Data *wd, Pointer_Event *pe,
void *event_info, Evas_Callback_Type event_type,
- Elm_Gesture_Types g_type, int taps)
-{ /* Here we fill Recent_Taps struct and fire-up click/tap timers */
- Widget_Data *wd = elm_widget_data_get(obj);
- if (!wd) return;
-
- if (!pe) /* this happens when unhandled event arrived */
- return; /* see _make_pointer_event function */
-
- Gesture_Info *gesture = wd->gesture[g_type];
- if (!gesture ) return;
-
+ Gesture_Info *gesture, int taps)
+{ /* Here we fill Tap struct */
Taps_Type *st = gesture->data;
if (!st)
{ /* Allocated once on first time */
st = calloc(1, sizeof(Taps_Type));
gesture->data = st;
- _dbl_click_test_reset(gesture);
+ _tap_gestures_test_reset(gesture);
}
Eina_List *pe_list = NULL;
&st->info, EINA_FALSE);
consume_event(wd, event_info, event_type, ev_flag);
- /* To test dbl_click/dbl_tap */
- /* When this timer expires, gesture ABORTed if not completed */
- if (!wd->dbl_timeout && (taps > 1))
- wd->dbl_timeout = ecore_timer_add(0.4, _dbl_click_timeout,
- gesture);
+ st->n_taps_needed = taps * 2; /* count DOWN and UP */
- return;
+ return EINA_TRUE;
}
break;
+
case EVAS_CALLBACK_MULTI_UP:
case EVAS_CALLBACK_MOUSE_UP:
pe_list = eina_list_search_unsorted(st->l, compare_pe_device, pe);
if (!pe_list)
- return; /* Got only first mouse_down and mouse_up */
+ return EINA_FALSE;
pe_list = _record_pointer_event(st, pe_list, pe, wd, event_info, event_type);
-
- if (eina_list_count(pe_list) <= (unsigned int) ((taps - 1) * 2))
- return; /* Got only first mouse_down and mouse_up */
-
- /* Get first event in first list, this has to be Mouse Down event */
- pe_down = eina_list_data_get(pe_list);
-
- if (_inside(pe_down->x, pe_down->y, pe->x, pe->y))
- {
- st->count_ups++;
- }
- else
- {
- ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT,
- &st->info, EINA_FALSE);
- consume_event(wd, event_info, event_type, ev_flag);
- break;
- }
-
- if (st->count_ups == eina_list_count(st->l))
- {
- st->info.n = st->count_ups;
- ev_flag =_set_state(gesture, ELM_GESTURE_STATE_END,
- &st->info, EINA_FALSE);
- consume_event(wd, event_info, event_type, ev_flag);
-
- return;
- }
-
break;
case EVAS_CALLBACK_MULTI_MOVE:
pe_down = eina_list_data_get(pe_list);
if (!_inside(pe_down->x, pe_down->y, pe->x, pe->y))
{
- ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT,
- &st->info, EINA_FALSE);
- consume_event(wd, event_info, event_type, ev_flag);
+ ev_flag = _set_state(gesture, ELM_GESTURE_STATE_ABORT,
+ &st->info, EINA_FALSE);
+ consume_event(wd, event_info, event_type, ev_flag);
}
}
break;
default:
- return;
+ return EINA_FALSE;
+ }
+
+ return EINA_FALSE;
+}
+
+
+/**
+ * @internal
+ *
+ * This function checks all click/tap and double/triple taps
+ *
+ * @param obj The gesture-layer object.
+ * @param pe The recent input event as stored in pe struct.
+ * @param event_info Original input event pointer.
+ * @param event_type Type of original input event.
+ *
+ * @ingroup Elm_Gesture_Layer
+ */
+static void
+_tap_gestures_test(Evas_Object *obj, Pointer_Event *pe,
+ void *event_info, Evas_Callback_Type event_type)
+{ /* Here we fill Recent_Taps struct and fire-up click/tap timers */
+ Eina_Bool need_timer = EINA_FALSE;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (!pe) /* this happens when unhandled event arrived */
+ return; /* see _make_pointer_event function */
+
+ if (IS_TESTED(ELM_GESTURE_N_TAPS))
+ need_timer |= _tap_gesture_start(wd, pe, event_info, event_type,
+ wd->gesture[ELM_GESTURE_N_TAPS], 1);
+
+ if (IS_TESTED(ELM_GESTURE_N_DOUBLE_TAPS))
+ need_timer |= _tap_gesture_start(wd, pe, event_info, event_type,
+ wd->gesture[ELM_GESTURE_N_DOUBLE_TAPS], 2);
+
+ if (IS_TESTED(ELM_GESTURE_N_TRIPLE_TAPS))
+ need_timer |= _tap_gesture_start(wd, pe, event_info, event_type,
+ wd->gesture[ELM_GESTURE_N_TRIPLE_TAPS], 3);
+
+ if ((need_timer) && (!wd->dbl_timeout))
+ { /* Set a timer to finish these gestures */
+ wd->dbl_timeout = ecore_timer_add(0.4, _multi_tap_timeout,
+ obj);
}
}
{
case EVAS_CALLBACK_MULTI_DOWN:
case EVAS_CALLBACK_MOUSE_DOWN:
- if (st->info.n > eina_list_count(st->touched))
- { /* ABORT: user lifts finger then back before completing gesgure */
- if (st->timeout) ecore_timer_del(st->timeout);
- st->timeout = NULL;
- ev_flag =_set_state(gesture, ELM_GESTURE_STATE_ABORT,
- &st->info, EINA_FALSE);
- }
-
st->touched = _add_touched_device(st->touched, pe);
st->info.n = eina_list_count(st->touched);
if ((pe->device == 0) && (eina_list_count(st->touched) == 1))
/* To test long tap */
/* When this timer expires, gesture STARTED */
if (!st->timeout)
- st->timeout = ecore_timer_add(wd->long_tap_start_timeout, _long_tap_timeout,
- gesture);
+ st->timeout = ecore_timer_add(wd->long_tap_start_timeout,
+ _long_tap_timeout, gesture);
}
consume_event(wd, event_info, event_type, ev_flag);
consume_event(wd, event_info, event_type, ev_flag);
}
}
+ else
+ { /* Stop test, user lifts finger before long-start */
+ if (st->timeout) ecore_timer_del(st->timeout);
+ st->timeout = NULL;
+ ev_flag =_set_state(gesture, ELM_GESTURE_STATE_ABORT,
+ &st->info, EINA_FALSE);
+ consume_event(wd, event_info, event_type, ev_flag);
+ }
+
break;
case EVAS_CALLBACK_MULTI_MOVE:
/* Run through events to restart gestures */
Gesture_Info *g;
Eina_Bool n_lines, n_flicks, zoom, rotate;
-#if defined(DEBUG_GESTURE_LAYER)
- int i;
- printf("Gesture | State | is tested\n");
- for(i = ELM_GESTURE_N_TAPS; i < ELM_GESTURE_LAST; i++)
- {
- g = wd->gesture[i];
- if(g)
- printf(" %d %d %d\n", i, g->state, g->test);
- }
-#endif
/* We turn-on flag for finished, aborted, not-started gestures */
g = wd->gesture[ELM_GESTURE_N_LINES];
n_lines = (g) ? ((states_reset) | ((g->state != ELM_GESTURE_STATE_START)
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
+#if defined(DEBUG_GESTURE_LAYER)
+ int i;
+ Gesture_Info *g;
+ printf("Gesture | State | is tested\n");
+ for(i = ELM_GESTURE_N_TAPS; i < ELM_GESTURE_LAST; i++)
+ {
+ g = wd->gesture[i];
+ if(g)
+ printf(" %d %d %d\n", i, g->state, g->test);
+ }
+#endif
+
/* Start testing candidate gesture from here */
if (_make_pointer_event(data, event_info, event_type, &_pe))
pe = &_pe;
_n_long_tap_test(data, pe, event_info, event_type,
ELM_GESTURE_N_LONG_TAPS);
- if (IS_TESTED(ELM_GESTURE_N_TAPS))
- _dbl_click_test(data, pe, event_info, event_type,
- ELM_GESTURE_N_TAPS, 1);
-
- if (IS_TESTED(ELM_GESTURE_N_DOUBLE_TAPS))
- _dbl_click_test(data, pe, event_info, event_type,
- ELM_GESTURE_N_DOUBLE_TAPS, 2);
-
- if (IS_TESTED(ELM_GESTURE_N_TRIPLE_TAPS))
- _dbl_click_test(data, pe, event_info, event_type,
- ELM_GESTURE_N_TRIPLE_TAPS, 3);
+ /* This takes care of single, double and tripple tap */
+ _tap_gestures_test(data, pe, event_info, event_type);
if (IS_TESTED(ELM_GESTURE_MOMENTUM))
_momentum_test(data, pe, event_info, event_type,
wd->flick_time_limit_ms = _elm_config->glayer_flick_time_limit_ms;
wd->long_tap_start_timeout = _elm_config->glayer_long_tap_start_timeout;
wd->repeat_events = EINA_TRUE;
- wd->glayer_continues_enable = _elm_config->glayer_continues_enable;
+ wd->glayer_continues_enable = EINA_FALSE;//_elm_config->glayer_continues_enable;
#if defined(DEBUG_GESTURE_LAYER)
printf("size of Gestures = <%d>\n", sizeof(wd->gesture));