3 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
5 #include <Elementary.h>
9 #define SMART_NAME "elm_touch"
10 #define API_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME)))
11 #define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
13 #define PRESS_TIME 250 // ms
14 #define RELEASE_TIME 50 // ms
15 #define LONG_HOLD_TIME 500 // ms
18 #define DEFAULT_FRAMERATE 60
19 #define DOUBLE_ERROR 0.00001
22 #define DBL_TAP_DISTANCE 30 // pixel
23 #define DRAG_THRESHOLD 3 // pixel
24 #define INIT_DRAG_THRESHOLD 15 // pixel
25 #define MOVE_HISTORY_SIZE 5
26 #define MAX_MOVE_DISTANCE 15
27 #define FLICK_THRESHOLD 5
30 #define MOVE_THRESHOLD 15
31 #define FINGER_DISTANCE 10
33 typedef struct _Mouse_Data Mouse_Data;
43 typedef enum _Two_Drag_Mode
51 typedef struct _Two_Mouse_Data Two_Mouse_Data;
53 struct _Two_Mouse_Data
60 typedef struct _Three_Mouse_Data Three_Mouse_Data;
62 struct _Three_Mouse_Data
69 typedef enum _Touch_State
73 TOUCH_STATE_DOWN_DURING_DRAG,
75 TOUCH_STATE_DOWN_UP_DOWN,
79 TOUCH_STATE_TWO_DOWN_DURING_DRAG,
81 TOUCH_STATE_THREE_DOWN
84 typedef enum _One_Drag_Mode
91 typedef struct _Flick_Data Flick_Data;
96 Evas_Coord_Point last;
97 Evas_Coord_Point avg_distance;
100 typedef struct _Mouse_Diff_Data Mouse_Diff_Data;
102 struct _Mouse_Diff_Data
108 typedef struct _Smart_Data Smart_Data;
112 Evas_Object *smart_obj;
113 Evas_Object *child_obj;
119 One_Drag_Mode one_drag_mode;
120 Eina_Bool is_one_drag_mode;
121 Two_Drag_Mode two_drag_mode;
125 int last_move_history_index;
126 int move_history_count;
127 Flick_Data flick_data;
128 Mouse_Diff_Data move_history[MOVE_HISTORY_SIZE];
130 Mouse_Data first_down[N_FINGER];
131 Mouse_Data last_down[N_FINGER];
132 Mouse_Data last_drag[N_FINGER];
134 Ecore_Animator *animator_move;
135 Ecore_Animator *animator_flick;
136 Ecore_Animator *animator_two_move;
139 Ecore_Timer *press_timer;
140 Ecore_Timer *long_press_timer;
141 Ecore_Timer *release_timer;
142 Ecore_Timer *press_release_timer;
145 /* local subsystem functions */
147 static float _smart_velocity_easeinoutcubic(int index);
148 static void _smart_mouse_down(void *data, Evas *e, Evas_Object *obj, void *ev);
149 static void _smart_mouse_up(void *data, Evas *e, Evas_Object *obj, void *ev);
150 static void _smart_mouse_move(void *data, Evas *e, Evas_Object *obj, void *ev);
151 static void _smart_multi_down(void *data, Evas *e, Evas_Object *obj, void *ev);
152 static void _smart_multi_up(void *data, Evas *e, Evas_Object *obj, void *ev);
153 static void _smart_multi_move(void *data, Evas *e, Evas_Object *obj, void *ev);
154 // animator callbacks
155 static int _smart_animation_move(void *data);
156 static int _smart_animation_flick(void *data);
157 static int _smart_animation_two_move(void *data);
158 // enter mode functions
159 static void _smart_enter_none(Smart_Data *sd);
160 static void _smart_enter_down(Smart_Data *sd);
161 static void _smart_enter_down_during_drag(Smart_Data *sd);
162 static void _smart_enter_down_up(Smart_Data *sd, int downTime, int time);
163 static void _smart_enter_down_up_down(Smart_Data *sd);
164 static void _smart_enter_hold(Smart_Data *sd);
165 static void _smart_enter_drag(Smart_Data *sd);
166 static void _smart_enter_two_down(Smart_Data *sd);
167 static void _smart_enter_two_down_during_drag(Smart_Data *sd);
168 static void _smart_enter_two_drag(Smart_Data *sd);
169 static void _smart_enter_three_down(Smart_Data *sd);
171 static void _smart_emit_press(Smart_Data *sd);
172 static void _smart_emit_tap(Smart_Data *sd);
173 static void _smart_emit_double_tap(Smart_Data *sd);
174 static void _smart_emit_long_hold(Smart_Data *sd);
175 static void _smart_emit_release(Smart_Data *sd);
176 static void _smart_emit_two_press(Smart_Data *sd);
177 static void _smart_emit_two_tap(Smart_Data *sd);
178 static void _smart_emit_two_move_start(Smart_Data *sd);
179 static void _smart_emit_two_move(Smart_Data *sd);
180 static void _smart_emit_two_move_end(Smart_Data *sd);
181 static void _smart_emit_three_press(Smart_Data *sd);
182 static void _smart_emit_three_tap(Smart_Data *sd);
184 static int _smart_press_timer_handler(void *data);
185 static int _smart_long_press_timer_handler(void *data);
186 static int _smart_release_timer_handler(void *data);
187 static int _smart_press_release_timer_handler(void *data);
189 static void _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy);
190 static void _smart_start_flick(Smart_Data *sd);
191 static void _smart_stop_animator_move(Smart_Data *sd);
192 static void _smart_stop_animator_flick(Smart_Data *sd);
193 static void _smart_stop_animator_two_move(Smart_Data *sd);
194 static Two_Drag_Mode _smart_check_two_drag_mode(Smart_Data *sd);
195 static void _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data);
196 static void _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data);
197 static void _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data);
198 static void _smart_stop_all_timers(Smart_Data *sd);
199 static void _smart_init(void);
200 static void _smart_del(Evas_Object *obj);
201 static void _smart_add(Evas_Object *obj);
203 /* local subsystem globals */
204 static Evas_Smart *_smart = NULL;
206 /* externally accessible functions */
208 _elm_smart_touch_add(Evas *evas)
211 return evas_object_smart_add(evas, _smart);
215 _elm_smart_touch_child_set(Evas_Object *obj, Evas_Object *child)
218 if (child == sd->child_obj) return;
220 if (sd->child_obj) // delete callbacks of old object
222 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
223 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
224 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
225 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
226 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
227 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
228 _smart_stop_all_timers(sd);
229 _smart_stop_animator_move(sd);
230 _smart_stop_animator_flick(sd);
231 _smart_stop_animator_two_move(sd);
233 sd->child_obj = NULL;
238 sd->child_obj = child;
241 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down, sd);
242 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up, sd);
243 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move, sd);
244 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down, sd);
245 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_UP, _smart_multi_up, sd);
246 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move, sd);
248 _smart_enter_none(sd);
250 sd->is_one_drag_mode = EINA_FALSE;
253 evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
257 _elm_smart_touch_start(Evas_Object *obj)
260 if (sd->running) return;
262 sd->running = EINA_TRUE;
263 _smart_enter_none(sd);
267 _elm_smart_touch_stop(Evas_Object *obj)
270 sd->running = EINA_FALSE;
271 _smart_stop_all_timers(sd);
272 _smart_stop_animator_move(sd);
273 _smart_stop_animator_flick(sd);
274 _smart_stop_animator_two_move(sd);
275 _smart_enter_none(sd);
279 _elm_smart_touch_reset(Evas_Object *obj)
282 _smart_stop_all_timers(sd);
283 _smart_stop_animator_move(sd);
284 _smart_stop_animator_flick(sd);
285 _smart_stop_animator_two_move(sd);
286 _smart_enter_none(sd);
290 _elm_smart_touch_screen_angle_update(Evas_Object *obj, int screen_angle)
293 sd->screen_angle = screen_angle;
297 _elm_smart_touch_is_one_drag_mode_enable(Evas_Object *obj, Eina_Bool is_one_drag_mode)
300 sd->is_one_drag_mode = is_one_drag_mode;
303 /* local subsystem functions */
304 /** reference from htsd://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html
305 * Easing equation function for a cubic (t^3) easing in/out: acceleration until halfway, then deceleration
306 * @param t Number Current time (in frames or seconds)
307 * @param b Number Starting value
308 * @param c Number Change needed in value
309 * @param d Number Expected easing duration (in frames or seconds)
310 * @param k1 Number first sustain value
311 * @param k2 Number second sustain value
312 * @return Number The correct value
313 public static function easeInOutCubic (t:Number, b:Number, c:Number, d:Number, p_params:Object):Number {
314 if ((t/=d/2) < 1) return c/2*t*t*t + b;
315 return c/2*((t-=2)*t*t + 2) + b;
319 _smart_velocity_easeinoutcubic(int index)
322 float t = d - index; // we want to get reversed value
327 if ((t /= (d / 2)) < 1)
329 velocity = (c / 2) * t * t * t;
334 velocity = (c / 2) * (t * t * t + 2);
336 if (velocity < k1 && velocity > k2) velocity = 0.1;
337 else if (velocity < k2) velocity = 0.05;
341 /* mouse callbacks */
343 _smart_mouse_down(void *data, Evas *e, Evas_Object *obj, void *ev)
346 Evas_Event_Mouse_Down *event;
347 Mouse_Data mouse_data;
350 if (!sd || sd->running == EINA_FALSE) return;
352 event = (Evas_Event_Mouse_Down*)ev;
356 case TOUCH_STATE_NONE:
357 mouse_data.x = event->canvas.x;
358 mouse_data.y = event->canvas.y;
359 mouse_data.time = event->timestamp;
360 mouse_data.device = -1;
361 _smart_set_first_down(sd, 0, &mouse_data);
362 _smart_set_last_down(sd, 0, &mouse_data);
363 _smart_set_last_drag(sd, 0, &mouse_data);
364 _smart_enter_down(sd);
367 case TOUCH_STATE_DRAG:
368 mouse_data.x = event->canvas.x;
369 mouse_data.y = event->canvas.y;
370 mouse_data.time = event->timestamp;
371 mouse_data.device = -1;
372 _smart_set_first_down(sd, 0, &mouse_data);
373 _smart_set_last_down(sd, 0, &mouse_data);
374 _smart_set_last_drag(sd, 0, &mouse_data);
375 if (sd->animator_move)
377 ecore_animator_del(sd->animator_move);
378 sd->animator_move = NULL;
380 if (sd->animator_flick)
382 ecore_animator_del(sd->animator_flick);
383 sd->animator_flick = NULL;
385 _smart_enter_down_during_drag(sd);
388 case TOUCH_STATE_DOWN_UP:
389 if (event->flags == EVAS_BUTTON_DOUBLE_CLICK) {
390 mouse_data.x = event->canvas.x;
391 mouse_data.y = event->canvas.y;
392 mouse_data.time = event->timestamp;
393 mouse_data.device = -1;
394 _smart_set_last_down(sd, 0, &mouse_data);
395 _smart_set_last_drag(sd, 0, &mouse_data);
396 _smart_enter_down_up_down(sd);
406 _smart_mouse_up(void *data, Evas *e, Evas_Object *obj, void *ev)
410 Evas_Event_Mouse_Up *event;
412 if (!sd || sd->running == EINA_FALSE) return;
414 event = (Evas_Event_Mouse_Up*)ev;
418 case TOUCH_STATE_DOWN:
419 _smart_stop_animator_move(sd);
420 _smart_stop_animator_flick(sd);
421 _smart_enter_down_up(sd, (event->timestamp - sd->last_down[0].time), event->timestamp);
424 case TOUCH_STATE_DOWN_DURING_DRAG:
427 point.x = sd->last_drag[0].x;
428 point.y = sd->last_drag[0].y;
429 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
430 _smart_enter_none(sd);
433 case TOUCH_STATE_DOWN_UP_DOWN:
435 int dx = sd->last_down[0].x - sd->first_down[0].x;
436 int dy = sd->last_down[0].y - sd->first_down[0].y;
437 if ((dx * dx + dy * dy) <= (DBL_TAP_DISTANCE * DBL_TAP_DISTANCE))
438 _smart_emit_double_tap(sd);
439 _smart_stop_all_timers(sd);
440 _smart_enter_none(sd);
443 case TOUCH_STATE_HOLD:
444 _smart_emit_release(sd);
445 _smart_stop_all_timers(sd);
446 _smart_enter_none(sd);
449 case TOUCH_STATE_DRAG:
450 _smart_emit_release(sd);
451 _smart_start_flick(sd);
454 case TOUCH_STATE_TWO_DOWN:
455 _smart_emit_two_tap(sd);
456 _smart_stop_all_timers(sd);
457 _smart_enter_none(sd);
460 case TOUCH_STATE_TWO_DRAG:
461 _smart_stop_animator_two_move(sd);
462 _smart_stop_all_timers(sd);
463 _smart_enter_none(sd);
466 case TOUCH_STATE_THREE_DOWN:
467 _smart_emit_three_tap(sd);
468 _smart_stop_all_timers(sd);
469 _smart_enter_none(sd);
473 _smart_emit_release(sd);
474 _smart_stop_all_timers(sd);
475 _smart_enter_none(sd);
476 DBG("\nERROR: wrong state in mouse_up\n\n");
483 _smart_mouse_move(void *data, Evas *e, Evas_Object *obj, void *ev)
487 if (!sd || sd->running == EINA_FALSE) return;
489 Evas_Event_Mouse_Move *event = (Evas_Event_Mouse_Move*)ev;
493 Mouse_Data mouse_data;
494 mouse_data.x = event->cur.canvas.x;
495 mouse_data.y = event->cur.canvas.y;
496 mouse_data.time = event->timestamp;
497 mouse_data.device = -1;
501 case TOUCH_STATE_DOWN:
502 case TOUCH_STATE_DOWN_DURING_DRAG:
503 dx = mouse_data.x - sd->last_drag[0].x;
504 dy = mouse_data.y - sd->last_drag[0].y;
506 if ((abs(dx) > INIT_DRAG_THRESHOLD) || (abs(dy) > INIT_DRAG_THRESHOLD))
508 if (sd->animator_move)
510 ecore_animator_del(sd->animator_move);
511 sd->animator_move = NULL;
513 if (sd->animator_flick)
515 ecore_animator_del(sd->animator_flick);
516 sd->animator_flick = NULL;
518 _smart_set_last_drag(sd, 0, &mouse_data);
520 // last_down - location where the drag starts
521 // (which is different than fisrtDown)
522 _smart_set_last_down(sd, 0, &mouse_data);
523 _smart_enter_drag(sd);
527 case TOUCH_STATE_DRAG:
528 dx = mouse_data.x - sd->last_drag[0].x;
529 dy = mouse_data.y - sd->last_drag[0].y;
531 if ((abs(dx) > DRAG_THRESHOLD) || (abs(dy) > DRAG_THRESHOLD))
533 _smart_set_last_drag(sd, 0, &mouse_data);
534 _smart_save_move_history(sd, mouse_data.x, mouse_data.y, dx, dy);
538 case TOUCH_STATE_TWO_DOWN:
539 _smart_set_last_drag(sd, 0, &mouse_data);
541 sd->two_drag_mode = _smart_check_two_drag_mode(sd);
542 if (sd->two_drag_mode != TWO_DRAG_NONE)
544 DBG("<< sd->two_drag_mode [%d] >>\n", sd->two_drag_mode);
545 _smart_enter_two_drag(sd);
549 case TOUCH_STATE_TWO_DRAG:
550 _smart_set_last_drag(sd, 0, &mouse_data);
553 case TOUCH_STATE_THREE_DOWN:
554 _smart_set_last_drag(sd, 0, &mouse_data);
563 _smart_multi_down(void *data, Evas *e, Evas_Object *obj, void *ev)
568 if (!sd || sd->running == EINA_FALSE) return;
570 Evas_Event_Multi_Down *event = (Evas_Event_Multi_Down*)ev;
571 Mouse_Data mouse_data;
575 case TOUCH_STATE_DOWN:
577 if (sd->numOfTouch == 1)
579 mouse_data.x = event->output.x;
580 mouse_data.y = event->output.y;
581 mouse_data.time = event->timestamp;
582 mouse_data.device = event->device;
583 _smart_set_first_down(sd, 1, &mouse_data);
584 _smart_set_last_down(sd, 1, &mouse_data);
585 _smart_set_last_drag(sd, 1, &mouse_data);
586 _smart_stop_animator_move(sd);
587 _smart_stop_animator_flick(sd);
588 _smart_stop_animator_two_move(sd);
589 _smart_enter_two_down(sd);
593 case TOUCH_STATE_DOWN_DURING_DRAG:
594 case TOUCH_STATE_DRAG:
596 if (sd->numOfTouch == 1)
598 mouse_data.x = event->output.x;
599 mouse_data.y = event->output.y;
600 mouse_data.time = event->timestamp;
601 mouse_data.device = event->device;
602 _smart_set_first_down(sd, 1, &mouse_data);
603 _smart_set_last_down(sd, 1, &mouse_data);
604 _smart_set_last_drag(sd, 1, &mouse_data);
605 if (sd->animator_move)
607 ecore_animator_del(sd->animator_move);
608 sd->animator_move = NULL;
610 if (sd->animator_flick)
612 ecore_animator_del(sd->animator_flick);
613 sd->animator_flick = NULL;
615 if (sd->animator_two_move)
617 ecore_animator_del(sd->animator_two_move);
618 sd->animator_two_move = NULL;
620 _smart_enter_two_down_during_drag(sd);
624 case TOUCH_STATE_TWO_DOWN:
625 case TOUCH_STATE_TWO_DRAG:
627 if (sd->numOfTouch == 2)
629 mouse_data.x = event->output.x;
630 mouse_data.y = event->output.y;
631 mouse_data.time = event->timestamp;
632 mouse_data.device = event->device;
633 _smart_set_first_down(sd, 2, &mouse_data);
634 _smart_set_last_down(sd, 2, &mouse_data);
635 _smart_set_last_drag(sd, 2, &mouse_data);
636 _smart_stop_animator_move(sd);
637 _smart_stop_animator_flick(sd);
638 _smart_stop_animator_two_move(sd);
639 _smart_enter_three_down(sd);
649 _smart_multi_up(void *data, Evas *e, Evas_Object *obj, void *ev)
652 Evas_Event_Multi_Up *event;
655 if (!sd || sd->running == EINA_FALSE) return;
657 event = (Evas_Event_Multi_Up*)ev;
661 case TOUCH_STATE_TWO_DOWN:
662 _smart_emit_two_tap(sd);
663 _smart_stop_all_timers(sd);
664 _smart_enter_none(sd);
667 case TOUCH_STATE_TWO_DOWN_DURING_DRAG:
670 point.x = sd->last_drag[0].x;
671 point.y = sd->last_drag[0].y;
672 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
673 _smart_emit_two_tap(sd);
674 _smart_stop_all_timers(sd);
675 _smart_enter_none(sd);
678 case TOUCH_STATE_TWO_DRAG:
679 _smart_stop_animator_two_move(sd);
680 _smart_stop_all_timers(sd);
681 _smart_enter_none(sd);
684 case TOUCH_STATE_THREE_DOWN:
685 _smart_emit_three_tap(sd);
686 _smart_stop_all_timers(sd);
687 _smart_enter_none(sd);
691 _smart_stop_all_timers(sd);
692 _smart_enter_none(sd);
698 _smart_multi_move(void *data, Evas *e, Evas_Object *obj, void *ev)
701 Evas_Event_Multi_Move *event;
702 Mouse_Data mouse_data;
705 if (!sd || sd->running == EINA_FALSE) return;
707 event = (Evas_Event_Multi_Move*)ev;
708 mouse_data.x = event->cur.output.x;
709 mouse_data.y = event->cur.output.y;
710 mouse_data.time = event->timestamp;
711 mouse_data.device = event->device;
715 case TOUCH_STATE_TWO_DOWN:
716 case TOUCH_STATE_TWO_DOWN_DURING_DRAG:
717 if (sd->first_down[1].device == event->device)
719 _smart_set_last_drag(sd, 1, &mouse_data);
720 sd->two_drag_mode = _smart_check_two_drag_mode(sd);
721 if (sd->two_drag_mode != TWO_DRAG_NONE)
723 DBG("<< sd->two_drag_mode [%d] >>\n", sd->two_drag_mode);
724 _smart_enter_two_drag(sd);
729 case TOUCH_STATE_TWO_DRAG:
730 if (sd->first_down[1].device == event->device)
732 _smart_set_last_drag(sd, 1, &mouse_data);
736 case TOUCH_STATE_THREE_DOWN:
737 if (sd->first_down[1].device == event->device)
739 _smart_set_last_drag(sd, 1, &mouse_data);
741 else if (sd->first_down[2].device == event->device)
743 _smart_set_last_drag(sd, 2, &mouse_data);
754 _smart_animation_move(void *data)
761 DBG("<< animation_move >>\n");
762 // get the position here instead of mouse_move event
763 Evas *evas = evas_object_evas_get(sd->child_obj);
765 evas_pointer_canvas_xy_get(evas, &point.x, &point.y);
766 if (sd->is_one_drag_mode)
768 if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
771 // first_down - location of mouse down
772 // last_down - location where the drag started
773 point.x = sd->last_down[0].x;
775 else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
777 point.y = sd->last_down[0].y;
780 evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
781 return ECORE_CALLBACK_RENEW;
785 _smart_stop_animator_move(sd);
786 _smart_enter_none(sd);
787 return ECORE_CALLBACK_CANCEL;
792 _smart_animation_flick(void *data)
795 Flick_Data *flick_data;
798 flick_data = &(sd->flick_data);
800 if (flick_data && sd->child_obj)
803 float velocity = _smart_velocity_easeinoutcubic(flick_data->flick_index);
804 Evas_Coord dx = flick_data->avg_distance.x * velocity;
805 Evas_Coord dy = flick_data->avg_distance.y * velocity;
806 flick_data->flick_index++;
807 flick_data->last.x += dx;
808 flick_data->last.y += dy;
809 DBG("<< animation_flick |%d|%d|%f| >>\n", dx, dy, ecore_loop_time_get());
811 // stop flick animator
812 if (dx == 0 && dy == 0)
814 _smart_stop_animator_flick(sd);
815 if (sd->state == TOUCH_STATE_DRAG)
816 _smart_enter_none(sd);
817 return ECORE_CALLBACK_CANCEL;
821 Evas_Coord_Point point;
822 point = flick_data->last;
823 if (sd->is_one_drag_mode)
825 if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
827 point.x = sd->first_down[0].x;
829 else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
831 point.y = sd->first_down[0].y;
834 evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
835 return ECORE_CALLBACK_RENEW;
840 _smart_stop_animator_flick(sd);
841 _smart_enter_none(sd);
842 return ECORE_CALLBACK_CANCEL;
847 _smart_animation_two_move(void *data)
855 _smart_emit_two_move(sd);
856 return ECORE_CALLBACK_RENEW;
860 _smart_stop_animator_two_move(sd);
861 _smart_enter_none(sd);
862 return ECORE_CALLBACK_CANCEL;
867 /* state switching */
869 _smart_enter_none(Smart_Data *sd)
872 sd->two_drag_mode = TWO_DRAG_NONE;
873 sd->state = TOUCH_STATE_NONE;
874 DBG("\nTOUCH_STATE_NONE\n");
878 _smart_enter_down(Smart_Data *sd)
881 sd->press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_press_timer_handler, sd);
883 // set long press timer
884 sd->long_press_timer = ecore_timer_add(((double)LONG_HOLD_TIME)/1000.0, _smart_long_press_timer_handler, sd);
886 sd->state = TOUCH_STATE_DOWN;
887 DBG("\nTOUCH_STATE_DOWN\n");
891 _smart_enter_down_during_drag(Smart_Data *sd)
894 sd->press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_press_timer_handler, sd);
896 sd->state = TOUCH_STATE_DOWN_DURING_DRAG;
897 DBG("\nTOUCH_STATE_DOWN_DURING_DRAG\n");
901 _smart_enter_down_up(Smart_Data *sd, int downTime, int time)
903 // remove sd->press_timer and set new timer
904 int timerTime = RELEASE_TIME - (downTime - PRESS_TIME);
907 ecore_timer_del(sd->press_timer);
908 sd->press_timer = NULL;
909 sd->press_release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_press_release_timer_handler, sd);
914 sd->release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_release_timer_handler, sd);
917 if (sd->long_press_timer) // remove long press timer
919 ecore_timer_del(sd->long_press_timer);
920 sd->long_press_timer = NULL;
923 sd->state = TOUCH_STATE_DOWN_UP;
924 DBG("\nTOUCH_STATE_DOWN_UP\n");
928 _smart_enter_down_up_down(Smart_Data *sd)
930 if (sd->press_release_timer) // remove press_release_timer
932 ecore_timer_del(sd->press_release_timer);
933 sd->press_release_timer = NULL;
936 if (sd->release_timer) // remove ReleaseTimer
938 ecore_timer_del(sd->release_timer);
939 sd->release_timer = NULL;
942 sd->state = TOUCH_STATE_DOWN_UP_DOWN;
943 DBG("\nTOUCH_STATE_DOWN_UP_DOWN\n");
947 _smart_enter_hold(Smart_Data *sd)
949 sd->state = TOUCH_STATE_HOLD;
950 DBG("\nTOUCH_STATE_HOLD\n");
954 _smart_enter_drag(Smart_Data *sd)
956 if (sd->press_timer) // remove press_timer
958 ecore_timer_del(sd->press_timer);
959 sd->press_timer = NULL;
962 if (sd->press_release_timer) // remove press_release_timer
964 ecore_timer_del(sd->press_release_timer);
965 sd->press_release_timer = NULL;
968 if (sd->release_timer) // remove ReleaseTimer
970 ecore_timer_del(sd->release_timer);
971 sd->release_timer = NULL;
974 if (sd->long_press_timer) // remove long press timer
976 ecore_timer_del(sd->long_press_timer);
977 sd->long_press_timer = NULL;
982 if (sd->is_one_drag_mode)
984 sd->one_drag_mode = ONE_DRAG_NONE;
985 int abs_dx = abs(sd->first_down[0].x - sd->last_drag[0].x);
986 int abs_dy = abs(sd->first_down[0].y - sd->last_drag[0].y);
987 abs_dx = (abs_dx == 0) ? 1 : abs_dx;
988 DBG("<< abs_dx[%d], abs_dy[%d] >>\n\n", abs_dx, abs_dy);
989 float degree = (float)abs_dy / (float)abs_dx;
990 // more than 70 degree
991 if (degree > tan(70 * M_PI / 180))
993 sd->one_drag_mode = ONE_DRAG_VERTICAL;
995 // less than 20 degree
996 else if (degree < tan(20 * M_PI / 180))
998 sd->one_drag_mode = ONE_DRAG_HORIZONTAL;
1002 point.x = sd->last_down[0].x;
1003 point.y = sd->last_down[0].y;
1004 evas_object_smart_callback_call(sd->child_obj, "one,move,start", &point);
1006 // initialize flick variables
1007 sd->last_move_history_index = -1;
1008 sd->move_history_count = 0;
1010 sd->animator_move = ecore_animator_add(_smart_animation_move, sd);
1011 DBG("<< sd->animator_move >>\n");
1012 sd->state = TOUCH_STATE_DRAG;
1013 DBG("\nTOUCH_STATE_DRAG\n");
1017 sd->state = TOUCH_STATE_NONE;
1022 _smart_enter_two_down(Smart_Data *sd)
1024 _smart_stop_all_timers(sd);
1028 DBG("<< enter two down >>\n");
1029 sd->state = TOUCH_STATE_TWO_DOWN;
1030 _smart_emit_two_press(sd);
1035 _smart_enter_two_down_during_drag(Smart_Data *sd)
1037 _smart_stop_all_timers(sd);
1041 DBG("<< enter two down >>\n");
1042 sd->state = TOUCH_STATE_TWO_DOWN_DURING_DRAG;
1043 _smart_emit_two_press(sd);
1048 _smart_enter_two_drag(Smart_Data *sd)
1052 DBG("<< sd->animator_two_move >>\n");
1053 sd->state = TOUCH_STATE_TWO_DRAG;
1054 _smart_emit_two_move_start(sd);
1055 sd->animator_two_move = ecore_animator_add(_smart_animation_two_move, sd);
1059 sd->state = TOUCH_STATE_NONE;
1064 _smart_enter_three_down(Smart_Data *sd)
1068 sd->state = TOUCH_STATE_THREE_DOWN;
1069 _smart_emit_three_press(sd);
1073 /* producing output events */
1075 _smart_emit_press(Smart_Data *sd)
1079 DBG("<< emit_press >>\n");
1081 point.x = sd->last_down[0].x;
1082 point.y = sd->last_down[0].y;
1083 evas_object_smart_callback_call(sd->child_obj, "one,press", &point);
1088 _smart_emit_tap(Smart_Data *sd)
1092 DBG("<< emit_tap >>\n");
1094 point.x = sd->last_down[0].x;
1095 point.y = sd->last_down[0].y;
1096 evas_object_smart_callback_call(sd->child_obj, "one,single,tap", &point);
1101 _smart_emit_double_tap(Smart_Data *sd)
1105 DBG("<< emit_double_tap >>\n");
1107 point.x = sd->last_down[0].x;
1108 point.y = sd->last_down[0].y;
1109 evas_object_smart_callback_call(sd->child_obj, "one,double,tap", &point);
1114 _smart_emit_long_hold(Smart_Data *sd)
1118 DBG("<< emit_long_hold >>\n");
1120 point.x = sd->last_down[0].x;
1121 point.y = sd->last_down[0].y;
1122 evas_object_smart_callback_call(sd->child_obj, "one,long,press", &point);
1127 _smart_emit_release(Smart_Data *sd)
1131 DBG("<< emit_release >>\n");
1133 point.x = sd->last_down[0].x;
1134 point.y = sd->last_down[0].y;
1135 evas_object_smart_callback_call(sd->child_obj, "one,release", &point);
1140 _smart_emit_two_press(Smart_Data *sd)
1144 DBG("<< emit_two_press >>\n");
1145 Two_Mouse_Data two_mouse_data;
1146 two_mouse_data.first.x = sd->last_down[0].x;
1147 two_mouse_data.first.y = sd->last_down[0].y;
1148 two_mouse_data.second.x = sd->last_down[1].x;
1149 two_mouse_data.second.y = sd->last_down[1].y;
1150 two_mouse_data.mode = sd->two_drag_mode;
1151 evas_object_smart_callback_call(sd->child_obj, "two,press", &two_mouse_data);
1156 _smart_emit_two_tap(Smart_Data *sd)
1160 DBG("<< emit_two_tap >>\n");
1161 Two_Mouse_Data two_mouse_data;
1162 two_mouse_data.first.x = sd->last_down[0].x;
1163 two_mouse_data.first.y = sd->last_down[0].y;
1164 two_mouse_data.second.x = sd->last_down[1].x;
1165 two_mouse_data.second.y = sd->last_down[1].y;
1166 two_mouse_data.mode = sd->two_drag_mode;
1167 evas_object_smart_callback_call(sd->child_obj, "two,tap", &two_mouse_data);
1172 _smart_emit_two_move_start(Smart_Data *sd)
1176 DBG("<< emit_two_move_start >>\n");
1177 Two_Mouse_Data two_mouse_data;
1178 two_mouse_data.first.x = sd->last_drag[0].x;
1179 two_mouse_data.first.y = sd->last_drag[0].y;
1180 two_mouse_data.second.x = sd->last_drag[1].x;
1181 two_mouse_data.second.y = sd->last_drag[1].y;
1182 two_mouse_data.mode = sd->two_drag_mode;
1183 evas_object_smart_callback_call(sd->child_obj, "two,move,start", &two_mouse_data);
1188 _smart_emit_two_move(Smart_Data *sd)
1192 Two_Mouse_Data two_mouse_data;
1193 two_mouse_data.first.x = sd->last_drag[0].x;
1194 two_mouse_data.first.y = sd->last_drag[0].y;
1195 two_mouse_data.second.x = sd->last_drag[1].x;
1196 two_mouse_data.second.y = sd->last_drag[1].y;
1197 two_mouse_data.mode = sd->two_drag_mode;
1198 evas_object_smart_callback_call(sd->child_obj, "two,move", &two_mouse_data);
1203 _smart_emit_two_move_end(Smart_Data *sd)
1207 DBG("<< emit_two_move_end >>\n");
1208 Two_Mouse_Data two_mouse_data;
1209 two_mouse_data.first.x = sd->last_drag[0].x;
1210 two_mouse_data.first.y = sd->last_drag[0].y;
1211 two_mouse_data.second.x = sd->last_drag[1].x;
1212 two_mouse_data.second.y = sd->last_drag[1].y;
1213 two_mouse_data.mode = sd->two_drag_mode;
1214 evas_object_smart_callback_call(sd->child_obj, "two,move,end", &two_mouse_data);
1219 _smart_emit_three_press(Smart_Data *sd)
1223 DBG("<< emit_three_press >>\n");
1224 Three_Mouse_Data three_mouse_data;
1225 three_mouse_data.first.x = sd->last_drag[0].x;
1226 three_mouse_data.first.y = sd->last_drag[0].y;
1227 three_mouse_data.second.x = sd->last_drag[1].x;
1228 three_mouse_data.second.y = sd->last_drag[1].y;
1229 three_mouse_data.third.x = sd->last_drag[2].x;
1230 three_mouse_data.third.y = sd->last_drag[2].y;
1231 evas_object_smart_callback_call(sd->child_obj, "three,press", &three_mouse_data);
1236 _smart_emit_three_tap(Smart_Data *sd)
1240 DBG("<< emit_three_tap >>\n");
1241 Three_Mouse_Data three_mouse_data;
1242 three_mouse_data.first.x = sd->last_drag[0].x;
1243 three_mouse_data.first.y = sd->last_drag[0].y;
1244 three_mouse_data.second.x = sd->last_drag[1].x;
1245 three_mouse_data.second.y = sd->last_drag[1].y;
1246 three_mouse_data.third.x = sd->last_drag[2].x;
1247 three_mouse_data.third.y = sd->last_drag[2].y;
1248 evas_object_smart_callback_call(sd->child_obj, "three,tap", &three_mouse_data);
1252 /* timer event handling */
1254 _smart_press_timer_handler(void *data)
1259 _smart_emit_press(sd);
1260 sd->press_timer = NULL;
1261 return ECORE_CALLBACK_CANCEL;
1265 _smart_long_press_timer_handler(void *data)
1270 _smart_emit_long_hold(sd);
1271 _smart_enter_hold(sd);
1272 sd->long_press_timer = NULL;
1273 return ECORE_CALLBACK_CANCEL;
1277 _smart_release_timer_handler(void *data)
1282 _smart_emit_tap(sd);
1283 _smart_stop_all_timers(sd);
1284 _smart_enter_none(sd);
1285 sd->release_timer = NULL;
1286 return ECORE_CALLBACK_CANCEL;
1290 _smart_press_release_timer_handler(void *data)
1292 static int prevent_handler = 0;
1293 if (prevent_handler != 0) return ECORE_CALLBACK_CANCEL;
1294 prevent_handler = 1;
1298 _smart_emit_press(sd);
1299 _smart_emit_tap(sd);
1300 _smart_stop_all_timers(sd);
1301 _smart_enter_none(sd);
1302 sd->press_release_timer = NULL;
1303 prevent_handler = 0;
1304 return ECORE_CALLBACK_CANCEL;
1307 /* other functions */
1309 _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy)
1311 // save pan information to the pan history
1312 int index = (sd->last_move_history_index + 1) % MOVE_HISTORY_SIZE;
1313 sd->last_move_history_index = index;
1314 sd->move_history[index].dx = dx;
1315 sd->move_history[index].dy = dy;
1316 sd->move_history[index].time = ecore_time_get();
1317 sd->move_history_count++;
1321 _smart_start_flick(Smart_Data *sd)
1323 if (sd->animator_move)
1325 ecore_animator_del(sd->animator_move);
1326 DBG("<< stop_animator_move >>\n");
1327 sd->animator_move = NULL;
1330 // accumulate sd->move_history data
1334 int index = sd->last_move_history_index;
1335 int todo = sd->move_history_count > MOVE_HISTORY_SIZE ? MOVE_HISTORY_SIZE : sd->move_history_count;
1337 double endTime = ecore_time_get();
1338 double startTime = endTime;
1339 for( ; todo > 0; todo--) {
1340 p = sd->move_history + index; // get one sd->move_history
1343 startTime = p->time;
1348 if ((endTime - startTime) > 0.2 && nSamples > 0)
1351 index = (index > 0) ? (index - 1) : (MOVE_HISTORY_SIZE - 1); // set index
1353 double totalTime = endTime - startTime;
1354 if (totalTime < DOUBLE_ERROR)
1357 // calculate average pan_dx and pan_dy (per 1 / DEFAULT_FRAMERATE ms)
1358 double temp = totalTime * DEFAULT_FRAMERATE;
1362 Flick_Data *flick_data = &sd->flick_data;
1363 flick_data->avg_distance.x = totalDx / temp;
1364 flick_data->avg_distance.y = totalDy / temp;
1366 // set max value for pan_dx and pan_dy
1367 int abs_pan_dx = abs(flick_data->avg_distance.x);
1368 int abs_pan_dy = abs(flick_data->avg_distance.y);
1369 if ((abs_pan_dx > MAX_MOVE_DISTANCE) && (abs_pan_dx > abs_pan_dy))
1371 flick_data->avg_distance.x = (flick_data->avg_distance.x > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1372 flick_data->avg_distance.y = flick_data->avg_distance.y * MAX_MOVE_DISTANCE / abs_pan_dx;
1375 else if ((abs_pan_dy > MAX_MOVE_DISTANCE) && (abs_pan_dy > abs_pan_dx))
1377 flick_data->avg_distance.y = (flick_data->avg_distance.y > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1378 flick_data->avg_distance.x = flick_data->avg_distance.x * MAX_MOVE_DISTANCE / abs_pan_dy;
1381 if (abs_pan_dx > FLICK_THRESHOLD || abs_pan_dy > FLICK_THRESHOLD)
1383 // set flick_data and start flick
1384 flick_data->last.x = sd->last_drag[0].x;
1385 flick_data->last.y = sd->last_drag[0].y;
1386 flick_data->flick_index = 0;
1387 sd->animator_flick = ecore_animator_add(_smart_animation_flick, sd);
1388 DBG("<< sd->animator_flick >>\n");
1393 point.x = sd->last_drag[0].x;
1394 point.y = sd->last_drag[0].y;
1395 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1396 _smart_enter_none(sd);
1401 _smart_emit_release(sd);
1402 _smart_stop_all_timers(sd);
1403 _smart_enter_none(sd);
1408 _smart_stop_animator_move(Smart_Data *sd)
1410 if (sd->animator_move)
1412 ecore_animator_del(sd->animator_move);
1413 DBG("<< stop_animator_move >>\n");
1414 sd->animator_move = NULL;
1416 point.x = sd->last_drag[0].x;
1417 point.y = sd->last_drag[0].y;
1418 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1423 _smart_stop_animator_flick(Smart_Data *sd)
1425 if (sd->animator_flick)
1427 ecore_animator_del(sd->animator_flick);
1428 DBG("<< stop_animator_flick >>\n");
1429 sd->animator_flick = NULL;
1430 Evas_Coord_Point point;
1431 point = sd->flick_data.last;
1432 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1437 _smart_stop_animator_two_move(Smart_Data *sd)
1439 if (sd->animator_two_move)
1441 ecore_animator_del(sd->animator_two_move);
1442 DBG("<< stop_animator_two_move >>\n");
1443 sd->animator_two_move = NULL;
1444 _smart_emit_two_move_end(sd);
1448 static Two_Drag_Mode
1449 _smart_check_two_drag_mode(Smart_Data *sd)
1451 // get distance from press to current position
1452 int dx0 = sd->last_drag[0].x - sd->first_down[0].x;
1453 int dy0 = sd->last_drag[0].y - sd->first_down[0].y;
1454 int dx1 = sd->last_drag[1].x - sd->first_down[1].x;
1455 int dy1 = sd->last_drag[1].y - sd->first_down[1].y;
1460 if ((abs(dx1) >= MOVE_THRESHOLD) || (abs(dy1) >= MOVE_THRESHOLD))
1465 else if ((abs(dx0) >= MOVE_THRESHOLD) || (abs(dy0) >= MOVE_THRESHOLD))
1472 return TWO_DRAG_NONE;
1476 if ((abs(dx) > abs(dy)) && ((dx0 > 0 && dx1 > 0) || (dx0 < 0 && dx1 < 0)))
1478 dy = (dy == 0) ? 1 : dy;
1479 // less than 30 degree (1024/root(3) = 591)
1480 if (((abs(dy) << 10) / abs(dx)) < 591)
1482 return TWO_DRAG_HORIZONTAL;
1487 if ((abs(dy) > abs(dx)) && ((dy0 > 0 && dy1 > 0) || (dy0 < 0 && dy1 < 0)))
1489 dx = (dx == 0) ? 1 : dx;
1490 // more than 60 degree (1024 * root(3)/1 = 1773)
1491 if (((abs(dy) << 10) / abs(dx)) > 1773)
1493 return TWO_DRAG_VERTICAL;
1498 int distanceX = abs(abs(sd->first_down[0].x - sd->first_down[1].x)
1499 - abs(sd->last_drag[0].x - sd->last_drag[1].x));
1500 int distanceY = abs(abs(sd->first_down[0].y - sd->first_down[1].y)
1501 - abs(sd->last_drag[0].y - sd->last_drag[1].y));
1502 if ((distanceX > FINGER_DISTANCE) || (distanceY > FINGER_DISTANCE))
1504 return TWO_DRAG_PINCH;
1507 return TWO_DRAG_NONE;
1511 _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data)
1513 if (index > N_FINGER)
1518 if ((sd->screen_angle == 270) && (index > 0))
1520 sd->first_down[index].x = data->y;
1521 sd->first_down[index].y = data->x;
1522 sd->first_down[index].time = data->time;
1523 sd->first_down[index].device = data->device;
1527 sd->first_down[index].x = data->x;
1528 sd->first_down[index].y = data->y;
1529 sd->first_down[index].time = data->time;
1530 sd->first_down[index].device = data->device;
1535 _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data)
1537 if (index > N_FINGER)
1542 if ((sd->screen_angle == 270) && (index > 0))
1544 sd->last_down[index].x = data->y;
1545 sd->last_down[index].y = data->x;
1546 sd->last_down[index].time = data->time;
1547 sd->last_down[index].device = data->device;
1551 sd->last_down[index].x = data->x;
1552 sd->last_down[index].y = data->y;
1553 sd->last_down[index].time = data->time;
1554 sd->last_down[index].device = data->device;
1559 _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data)
1561 if (index > N_FINGER)
1566 if ((sd->screen_angle == 270) && (index > 0))
1568 sd->last_drag[index].x = data->y;
1569 sd->last_drag[index].y = data->x;
1570 sd->last_drag[index].time = data->time;
1571 sd->last_drag[index].device = data->device;
1575 sd->last_drag[index].x = data->x;
1576 sd->last_drag[index].y = data->y;
1577 sd->last_drag[index].time = data->time;
1578 sd->last_drag[index].device = data->device;
1583 _smart_stop_all_timers(Smart_Data *sd)
1585 if (sd->press_timer) // remove sd->press_timer
1587 ecore_timer_del(sd->press_timer);
1588 sd->press_timer = NULL;
1591 if (sd->long_press_timer) // remove long press timer
1593 ecore_timer_del(sd->long_press_timer);
1594 sd->long_press_timer = NULL;
1597 if (sd->release_timer) // remove release timer
1599 ecore_timer_del(sd->release_timer);
1600 sd->release_timer = NULL;
1603 if (sd->press_release_timer) // remove pressRelease timer
1605 ecore_timer_del(sd->press_release_timer);
1606 sd->press_release_timer = NULL;
1611 _smart_add(Evas_Object *obj)
1615 sd = calloc(1, sizeof(Smart_Data));
1617 memset((void *)sd, 0x00, sizeof(Smart_Data));
1619 sd->smart_obj = obj;
1621 // set default framerate
1622 ecore_animator_frametime_set(1.0 / DEFAULT_FRAMERATE);
1624 evas_object_smart_data_set(obj, sd);
1628 _smart_del(Evas_Object *obj)
1633 if (sd->press_timer)
1634 ecore_timer_del(sd->press_timer);
1636 if (sd->long_press_timer)
1637 ecore_timer_del(sd->long_press_timer);
1639 if (sd->release_timer)
1640 ecore_timer_del(sd->release_timer);
1642 if (sd->press_release_timer)
1643 ecore_timer_del(sd->press_release_timer);
1645 if (sd->animator_move)
1646 ecore_animator_del(sd->animator_move);
1648 if (sd->animator_flick)
1649 ecore_animator_del(sd->animator_flick);
1651 if (sd->animator_two_move)
1652 ecore_animator_del(sd->animator_two_move);
1656 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
1657 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
1658 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
1659 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
1660 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
1661 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
1673 static const Evas_Smart_Class sc =
1676 EVAS_SMART_CLASS_VERSION,
1694 _smart = evas_smart_class_new(&sc);