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,
80 TOUCH_STATE_TWO_DOWN_UP,
81 TOUCH_STATE_TWO_DOWN_UP_DOWN,
83 TOUCH_STATE_THREE_DOWN
86 typedef enum _One_Drag_Mode
93 typedef struct _Flick_Data Flick_Data;
98 Evas_Coord_Point last;
99 Evas_Coord_Point avg_distance;
102 typedef struct _Mouse_Diff_Data Mouse_Diff_Data;
104 struct _Mouse_Diff_Data
110 typedef struct _Smart_Data Smart_Data;
114 Evas_Object *smart_obj;
115 Evas_Object *child_obj;
121 One_Drag_Mode one_drag_mode;
122 Eina_Bool is_one_drag_mode;
123 Two_Drag_Mode two_drag_mode;
127 int last_move_history_index;
128 int move_history_count;
129 Flick_Data flick_data;
130 Mouse_Diff_Data move_history[MOVE_HISTORY_SIZE];
132 Mouse_Data first_down[N_FINGER];
133 Mouse_Data last_down[N_FINGER];
134 Mouse_Data last_drag[N_FINGER];
136 Ecore_Animator *animator_move;
137 Ecore_Animator *animator_flick;
138 Ecore_Animator *animator_two_move;
141 Ecore_Timer *press_timer;
142 Ecore_Timer *long_press_timer;
143 Ecore_Timer *release_timer;
144 Ecore_Timer *press_release_timer;
147 Ecore_Timer *two_press_timer;
148 Ecore_Timer *two_release_timer;
149 Ecore_Timer *two_press_release_timer;
152 /* local subsystem functions */
154 static float _smart_velocity_easeinoutcubic(int index);
155 static void _smart_mouse_down(void *data, Evas *e, Evas_Object *obj, void *ev);
156 static void _smart_mouse_up(void *data, Evas *e, Evas_Object *obj, void *ev);
157 static void _smart_mouse_move(void *data, Evas *e, Evas_Object *obj, void *ev);
158 static void _smart_multi_down(void *data, Evas *e, Evas_Object *obj, void *ev);
159 static void _smart_multi_up(void *data, Evas *e, Evas_Object *obj, void *ev);
160 static void _smart_multi_move(void *data, Evas *e, Evas_Object *obj, void *ev);
161 // animator callbacks
162 static int _smart_animation_move(void *data);
163 static int _smart_animation_flick(void *data);
164 static int _smart_animation_two_move(void *data);
165 // enter mode functions
166 static void _smart_enter_none(Smart_Data *sd);
167 static void _smart_enter_down(Smart_Data *sd);
168 static void _smart_enter_down_during_drag(Smart_Data *sd);
169 static void _smart_enter_down_up(Smart_Data *sd, int downTime, int time);
170 static void _smart_enter_down_up_down(Smart_Data *sd);
171 static void _smart_enter_hold(Smart_Data *sd);
172 static void _smart_enter_drag(Smart_Data *sd);
173 static void _smart_enter_two_down(Smart_Data *sd);
174 static void _smart_enter_two_down_during_drag(Smart_Data *sd);
175 static void _smart_enter_two_down_up(Smart_Data *sd, int downTime, int time);
176 static void _smart_enter_two_down_up_down(Smart_Data *sd);
177 static void _smart_enter_two_drag(Smart_Data *sd);
178 static void _smart_enter_three_down(Smart_Data *sd);
180 static void _smart_emit_press(Smart_Data *sd);
181 static void _smart_emit_tap(Smart_Data *sd);
182 static void _smart_emit_double_tap(Smart_Data *sd);
183 static void _smart_emit_long_hold(Smart_Data *sd);
184 static void _smart_emit_release(Smart_Data *sd);
185 static void _smart_emit_two_press(Smart_Data *sd);
186 static void _smart_emit_two_tap(Smart_Data *sd);
187 static void _smart_emit_two_double_tap(Smart_Data *sd);
188 static void _smart_emit_two_move_start(Smart_Data *sd);
189 static void _smart_emit_two_move(Smart_Data *sd);
190 static void _smart_emit_two_move_end(Smart_Data *sd);
191 static void _smart_emit_three_press(Smart_Data *sd);
192 static void _smart_emit_three_tap(Smart_Data *sd);
194 static int _smart_press_timer_handler(void *data);
195 static int _smart_long_press_timer_handler(void *data);
196 static int _smart_release_timer_handler(void *data);
197 static int _smart_press_release_timer_handler(void *data);
198 static int _tap_delay_timer_handler(void *data);
199 static int _smart_two_press_timer_handler(void *data);
200 static int _smart_two_release_timer_handler(void *data);
201 static int _smart_two_press_release_timer_handler(void *data);
203 static void _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy);
204 static void _smart_start_flick(Smart_Data *sd);
205 static void _smart_stop_animator_move(Smart_Data *sd);
206 static void _smart_stop_animator_flick(Smart_Data *sd);
207 static void _smart_stop_animator_two_move(Smart_Data *sd);
208 static Two_Drag_Mode _smart_check_two_drag_mode(Smart_Data *sd);
209 static void _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data);
210 static void _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data);
211 static void _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data);
212 static void _smart_stop_all_timers(Smart_Data *sd);
213 static void _smart_stop_all_one_timers(Smart_Data *sd);
214 static void _smart_stop_all_two_timers(Smart_Data *sd);
215 static void _smart_init(void);
216 static void _smart_del(Evas_Object *obj);
217 static void _smart_add(Evas_Object *obj);
219 /* local subsystem globals */
220 static Evas_Smart *_smart = NULL;
222 /* externally accessible functions */
224 _elm_smart_touch_add(Evas *evas)
227 return evas_object_smart_add(evas, _smart);
231 _elm_smart_touch_child_set(Evas_Object *obj, Evas_Object *child)
234 if (child == sd->child_obj) return;
236 if (sd->child_obj) // delete callbacks of old object
238 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
239 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
240 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
241 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
242 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
243 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
244 _smart_stop_all_timers(sd);
245 _smart_stop_animator_move(sd);
246 _smart_stop_animator_flick(sd);
247 _smart_stop_animator_two_move(sd);
249 sd->child_obj = NULL;
254 sd->child_obj = child;
257 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down, sd);
258 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up, sd);
259 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move, sd);
260 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down, sd);
261 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_UP, _smart_multi_up, sd);
262 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move, sd);
264 _smart_enter_none(sd);
266 sd->is_one_drag_mode = EINA_FALSE;
269 evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
273 _elm_smart_touch_start(Evas_Object *obj)
276 if (sd->running) return;
278 sd->running = EINA_TRUE;
279 _smart_enter_none(sd);
283 _elm_smart_touch_stop(Evas_Object *obj)
286 sd->running = EINA_FALSE;
287 _smart_stop_all_timers(sd);
288 _smart_stop_animator_move(sd);
289 _smart_stop_animator_flick(sd);
290 _smart_stop_animator_two_move(sd);
291 _smart_enter_none(sd);
295 _elm_smart_touch_reset(Evas_Object *obj)
298 _smart_stop_all_timers(sd);
299 _smart_stop_animator_move(sd);
300 _smart_stop_animator_flick(sd);
301 _smart_stop_animator_two_move(sd);
302 _smart_enter_none(sd);
306 _elm_smart_touch_screen_angle_update(Evas_Object *obj, int screen_angle)
309 sd->screen_angle = screen_angle;
313 _elm_smart_touch_is_one_drag_mode_enable(Evas_Object *obj, Eina_Bool is_one_drag_mode)
316 sd->is_one_drag_mode = is_one_drag_mode;
319 /* local subsystem functions */
320 /** reference from htsd://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html
321 * Easing equation function for a cubic (t^3) easing in/out: acceleration until halfway, then deceleration
322 * @param t Number Current time (in frames or seconds)
323 * @param b Number Starting value
324 * @param c Number Change needed in value
325 * @param d Number Expected easing duration (in frames or seconds)
326 * @param k1 Number first sustain value
327 * @param k2 Number second sustain value
328 * @return Number The correct value
329 public static function easeInOutCubic (t:Number, b:Number, c:Number, d:Number, p_params:Object):Number {
330 if ((t/=d/2) < 1) return c/2*t*t*t + b;
331 return c/2*((t-=2)*t*t + 2) + b;
335 _smart_velocity_easeinoutcubic(int index)
338 float t = d - index; // we want to get reversed value
343 if ((t /= (d / 2)) < 1)
345 velocity = (c / 2) * t * t * t;
350 velocity = (c / 2) * (t * t * t + 2);
352 if (velocity < k1 && velocity > k2) velocity = 0.1;
353 else if (velocity < k2) velocity = 0.05;
357 /* mouse callbacks */
359 _smart_mouse_down(void *data, Evas *e, Evas_Object *obj, void *ev)
362 Evas_Event_Mouse_Down *event;
363 Mouse_Data mouse_data;
366 if (!sd || sd->running == EINA_FALSE) return;
368 event = (Evas_Event_Mouse_Down*)ev;
372 case TOUCH_STATE_NONE:
373 mouse_data.x = event->canvas.x;
374 mouse_data.y = event->canvas.y;
375 mouse_data.time = event->timestamp;
376 mouse_data.device = -1;
377 _smart_set_first_down(sd, 0, &mouse_data);
378 _smart_set_last_down(sd, 0, &mouse_data);
379 _smart_set_last_drag(sd, 0, &mouse_data);
380 _smart_enter_down(sd);
383 case TOUCH_STATE_DRAG:
384 mouse_data.x = event->canvas.x;
385 mouse_data.y = event->canvas.y;
386 mouse_data.time = event->timestamp;
387 mouse_data.device = -1;
388 _smart_set_first_down(sd, 0, &mouse_data);
389 _smart_set_last_down(sd, 0, &mouse_data);
390 _smart_set_last_drag(sd, 0, &mouse_data);
391 if (sd->animator_move)
393 ecore_animator_del(sd->animator_move);
394 sd->animator_move = NULL;
396 if (sd->animator_flick)
398 ecore_animator_del(sd->animator_flick);
399 sd->animator_flick = NULL;
401 _smart_enter_down_during_drag(sd);
404 case TOUCH_STATE_DOWN_UP:
405 if (event->flags == EVAS_BUTTON_DOUBLE_CLICK) {
406 mouse_data.x = event->canvas.x;
407 mouse_data.y = event->canvas.y;
408 mouse_data.time = event->timestamp;
409 mouse_data.device = -1;
410 _smart_set_last_down(sd, 0, &mouse_data);
411 _smart_set_last_drag(sd, 0, &mouse_data);
412 _smart_enter_down_up_down(sd);
422 _smart_mouse_up(void *data, Evas *e, Evas_Object *obj, void *ev)
426 Evas_Event_Mouse_Up *event;
428 if (!sd || sd->running == EINA_FALSE) return;
430 event = (Evas_Event_Mouse_Up*)ev;
434 case TOUCH_STATE_DOWN:
435 _smart_stop_animator_move(sd);
436 _smart_stop_animator_flick(sd);
437 _smart_enter_down_up(sd, (event->timestamp - sd->last_down[0].time), event->timestamp);
440 case TOUCH_STATE_DOWN_DURING_DRAG:
443 point.x = sd->last_drag[0].x;
444 point.y = sd->last_drag[0].y;
445 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
446 _smart_enter_none(sd);
449 case TOUCH_STATE_DOWN_UP_DOWN:
451 int dx = sd->last_down[0].x - sd->first_down[0].x;
452 int dy = sd->last_down[0].y - sd->first_down[0].y;
453 if ((dx * dx + dy * dy) <= (DBL_TAP_DISTANCE * DBL_TAP_DISTANCE))
454 _smart_emit_double_tap(sd);
455 _smart_stop_all_timers(sd);
456 _smart_enter_none(sd);
459 case TOUCH_STATE_HOLD:
460 _smart_emit_release(sd);
461 _smart_stop_all_timers(sd);
462 _smart_enter_none(sd);
465 case TOUCH_STATE_DRAG:
466 _smart_emit_release(sd);
467 _smart_start_flick(sd);
470 case TOUCH_STATE_TWO_DOWN:
472 _smart_enter_two_down_up(sd, (event->timestamp - sd->last_down[1].time), event->timestamp);
475 case TOUCH_STATE_TWO_DOWN_UP:
478 case TOUCH_STATE_TWO_DOWN_UP_DOWN:
480 int dx = sd->last_down[0].x - sd->first_down[0].x;
481 int dy = sd->last_down[0].y - sd->first_down[0].y;
482 if ((dx * dx + dy * dy) <= (DBL_TAP_DISTANCE * DBL_TAP_DISTANCE))
483 _smart_emit_two_double_tap(sd);
484 _smart_stop_all_timers(sd);
485 _smart_enter_none(sd);
488 case TOUCH_STATE_TWO_DRAG:
489 _smart_stop_animator_two_move(sd);
490 _smart_stop_all_timers(sd);
491 _smart_enter_none(sd);
494 case TOUCH_STATE_THREE_DOWN:
495 _smart_emit_three_tap(sd);
496 _smart_stop_all_timers(sd);
497 _smart_enter_none(sd);
501 _smart_emit_release(sd);
502 _smart_stop_all_timers(sd);
503 _smart_enter_none(sd);
504 DBG("\nERROR: wrong state in mouse_up\n\n");
511 _smart_mouse_move(void *data, Evas *e, Evas_Object *obj, void *ev)
515 if (!sd || sd->running == EINA_FALSE) return;
517 Evas_Event_Mouse_Move *event = (Evas_Event_Mouse_Move*)ev;
521 Mouse_Data mouse_data;
522 mouse_data.x = event->cur.canvas.x;
523 mouse_data.y = event->cur.canvas.y;
524 mouse_data.time = event->timestamp;
525 mouse_data.device = -1;
529 case TOUCH_STATE_DOWN:
530 case TOUCH_STATE_DOWN_DURING_DRAG:
531 dx = mouse_data.x - sd->last_drag[0].x;
532 dy = mouse_data.y - sd->last_drag[0].y;
534 if ((abs(dx) > INIT_DRAG_THRESHOLD) || (abs(dy) > INIT_DRAG_THRESHOLD))
536 if (sd->animator_move)
538 ecore_animator_del(sd->animator_move);
539 sd->animator_move = NULL;
541 if (sd->animator_flick)
543 ecore_animator_del(sd->animator_flick);
544 sd->animator_flick = NULL;
546 _smart_set_last_drag(sd, 0, &mouse_data);
548 // last_down - location where the drag starts
549 // (which is different than fisrtDown)
550 _smart_set_last_down(sd, 0, &mouse_data);
551 _smart_enter_drag(sd);
555 case TOUCH_STATE_DRAG:
556 dx = mouse_data.x - sd->last_drag[0].x;
557 dy = mouse_data.y - sd->last_drag[0].y;
559 if ((abs(dx) > DRAG_THRESHOLD) || (abs(dy) > DRAG_THRESHOLD))
561 _smart_set_last_drag(sd, 0, &mouse_data);
562 _smart_save_move_history(sd, mouse_data.x, mouse_data.y, dx, dy);
566 case TOUCH_STATE_TWO_DOWN:
567 dx = mouse_data.x - sd->last_drag[0].x;
568 dy = mouse_data.y - sd->last_drag[0].y;
570 if ((abs(dx) > INIT_DRAG_THRESHOLD) || (abs(dy) > INIT_DRAG_THRESHOLD))
572 _smart_set_last_drag(sd, 0, &mouse_data);
574 sd->two_drag_mode = _smart_check_two_drag_mode(sd);
575 if (sd->two_drag_mode != TWO_DRAG_NONE)
577 DBG("<< sd->two_drag_mode [%d] >>\n", sd->two_drag_mode);
578 _smart_enter_two_drag(sd);
583 case TOUCH_STATE_TWO_DRAG:
584 _smart_set_last_drag(sd, 0, &mouse_data);
587 case TOUCH_STATE_THREE_DOWN:
588 _smart_set_last_drag(sd, 0, &mouse_data);
597 _smart_multi_down(void *data, Evas *e, Evas_Object *obj, void *ev)
602 if (!sd || sd->running == EINA_FALSE) return;
604 Evas_Event_Multi_Down *event = (Evas_Event_Multi_Down*)ev;
605 Mouse_Data mouse_data;
609 case TOUCH_STATE_DOWN:
610 // add TOUCH_STATE_NONE,
611 // because sometimes multi down is faster then mouse down
612 // in that case, the two touch is recognized as one touch
613 case TOUCH_STATE_NONE:
615 if (sd->numOfTouch == 1)
617 mouse_data.x = event->output.x;
618 mouse_data.y = event->output.y;
619 mouse_data.time = event->timestamp;
620 mouse_data.device = event->device;
621 _smart_set_first_down(sd, 1, &mouse_data);
622 _smart_set_last_down(sd, 1, &mouse_data);
623 _smart_set_last_drag(sd, 1, &mouse_data);
624 _smart_stop_animator_move(sd);
625 _smart_stop_animator_flick(sd);
626 _smart_stop_animator_two_move(sd);
627 _smart_enter_two_down(sd);
631 case TOUCH_STATE_TWO_DOWN_UP:
633 if (sd->numOfTouch == 1)
635 mouse_data.x = event->output.x;
636 mouse_data.y = event->output.y;
637 mouse_data.time = event->timestamp;
638 mouse_data.device = event->device;
639 _smart_set_last_down(sd, 1, &mouse_data);
640 _smart_set_last_drag(sd, 1, &mouse_data);
641 _smart_stop_animator_move(sd);
642 _smart_stop_animator_flick(sd);
643 _smart_stop_animator_two_move(sd);
644 _smart_enter_two_down_up_down(sd);
648 case TOUCH_STATE_DOWN_DURING_DRAG:
649 case TOUCH_STATE_DRAG:
651 if (sd->numOfTouch == 1)
653 mouse_data.x = event->output.x;
654 mouse_data.y = event->output.y;
655 mouse_data.time = event->timestamp;
656 mouse_data.device = event->device;
657 _smart_set_first_down(sd, 1, &mouse_data);
658 _smart_set_last_down(sd, 1, &mouse_data);
659 _smart_set_last_drag(sd, 1, &mouse_data);
660 if (sd->animator_move)
662 ecore_animator_del(sd->animator_move);
663 sd->animator_move = NULL;
665 if (sd->animator_flick)
667 ecore_animator_del(sd->animator_flick);
668 sd->animator_flick = NULL;
670 if (sd->animator_two_move)
672 ecore_animator_del(sd->animator_two_move);
673 sd->animator_two_move = NULL;
675 _smart_enter_two_down_during_drag(sd);
679 case TOUCH_STATE_TWO_DOWN:
680 case TOUCH_STATE_TWO_DRAG:
682 if (sd->numOfTouch == 2)
684 mouse_data.x = event->output.x;
685 mouse_data.y = event->output.y;
686 mouse_data.time = event->timestamp;
687 mouse_data.device = event->device;
688 _smart_set_first_down(sd, 2, &mouse_data);
689 _smart_set_last_down(sd, 2, &mouse_data);
690 _smart_set_last_drag(sd, 2, &mouse_data);
691 _smart_stop_animator_move(sd);
692 _smart_stop_animator_flick(sd);
693 _smart_stop_animator_two_move(sd);
694 _smart_enter_three_down(sd);
704 _smart_multi_up(void *data, Evas *e, Evas_Object *obj, void *ev)
707 Evas_Event_Multi_Up *event;
710 if (!sd || sd->running == EINA_FALSE) return;
712 event = (Evas_Event_Multi_Up*)ev;
716 case TOUCH_STATE_TWO_DOWN:
718 _smart_enter_two_down_up(sd, (event->timestamp - sd->last_down[1].time), event->timestamp);
721 case TOUCH_STATE_TWO_DOWN_UP:
722 case TOUCH_STATE_TWO_DOWN_UP_DOWN:
725 case TOUCH_STATE_TWO_DOWN_DURING_DRAG:
728 point.x = sd->last_drag[0].x;
729 point.y = sd->last_drag[0].y;
730 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
731 _smart_emit_two_tap(sd);
732 _smart_stop_all_timers(sd);
733 _smart_enter_none(sd);
736 case TOUCH_STATE_TWO_DRAG:
737 _smart_stop_animator_two_move(sd);
738 _smart_stop_all_timers(sd);
739 _smart_enter_none(sd);
742 case TOUCH_STATE_THREE_DOWN:
743 _smart_emit_three_tap(sd);
744 _smart_stop_all_timers(sd);
745 _smart_enter_none(sd);
749 _smart_stop_all_timers(sd);
750 _smart_enter_none(sd);
756 _smart_multi_move(void *data, Evas *e, Evas_Object *obj, void *ev)
759 Evas_Event_Multi_Move *event;
760 Mouse_Data mouse_data;
763 if (!sd || sd->running == EINA_FALSE) return;
765 event = (Evas_Event_Multi_Move*)ev;
766 mouse_data.x = event->cur.output.x;
767 mouse_data.y = event->cur.output.y;
768 mouse_data.time = event->timestamp;
769 mouse_data.device = event->device;
773 case TOUCH_STATE_TWO_DOWN:
774 case TOUCH_STATE_TWO_DOWN_DURING_DRAG:
775 if (sd->first_down[1].device == event->device)
777 int dx = mouse_data.x - sd->last_drag[0].x;
778 int dy = mouse_data.y - sd->last_drag[0].y;
780 if ((abs(dx) > INIT_DRAG_THRESHOLD) || (abs(dy) > INIT_DRAG_THRESHOLD))
782 _smart_set_last_drag(sd, 1, &mouse_data);
783 sd->two_drag_mode = _smart_check_two_drag_mode(sd);
784 if (sd->two_drag_mode != TWO_DRAG_NONE)
786 DBG("<< sd->two_drag_mode [%d] >>\n", sd->two_drag_mode);
787 _smart_enter_two_drag(sd);
793 case TOUCH_STATE_TWO_DRAG:
794 if (sd->first_down[1].device == event->device)
796 _smart_set_last_drag(sd, 1, &mouse_data);
800 case TOUCH_STATE_THREE_DOWN:
801 if (sd->first_down[1].device == event->device)
803 _smart_set_last_drag(sd, 1, &mouse_data);
805 else if (sd->first_down[2].device == event->device)
807 _smart_set_last_drag(sd, 2, &mouse_data);
818 _smart_animation_move(void *data)
825 DBG("<< animation_move >>\n");
826 // get the position here instead of mouse_move event
827 Evas *evas = evas_object_evas_get(sd->child_obj);
829 evas_pointer_canvas_xy_get(evas, &point.x, &point.y);
830 if (sd->is_one_drag_mode)
832 if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
835 // first_down - location of mouse down
836 // last_down - location where the drag started
837 point.x = sd->last_down[0].x;
839 else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
841 point.y = sd->last_down[0].y;
844 evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
845 return ECORE_CALLBACK_RENEW;
849 _smart_stop_animator_move(sd);
850 _smart_enter_none(sd);
851 return ECORE_CALLBACK_CANCEL;
856 _smart_animation_flick(void *data)
859 Flick_Data *flick_data;
862 flick_data = &(sd->flick_data);
864 if (flick_data && sd->child_obj)
867 float velocity = _smart_velocity_easeinoutcubic(flick_data->flick_index);
868 Evas_Coord dx = flick_data->avg_distance.x * velocity;
869 Evas_Coord dy = flick_data->avg_distance.y * velocity;
870 flick_data->flick_index++;
871 flick_data->last.x += dx;
872 flick_data->last.y += dy;
873 DBG("<< animation_flick |%d|%d|%f| >>\n", dx, dy, ecore_loop_time_get());
875 // stop flick animator
876 if (dx == 0 && dy == 0)
878 _smart_stop_animator_flick(sd);
879 if (sd->state == TOUCH_STATE_DRAG)
880 _smart_enter_none(sd);
881 return ECORE_CALLBACK_CANCEL;
885 Evas_Coord_Point point;
886 point = flick_data->last;
887 if (sd->is_one_drag_mode)
889 if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
891 point.x = sd->first_down[0].x;
893 else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
895 point.y = sd->first_down[0].y;
898 evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
899 return ECORE_CALLBACK_RENEW;
904 _smart_stop_animator_flick(sd);
905 _smart_enter_none(sd);
906 return ECORE_CALLBACK_CANCEL;
911 _smart_animation_two_move(void *data)
919 _smart_emit_two_move(sd);
920 return ECORE_CALLBACK_RENEW;
924 _smart_stop_animator_two_move(sd);
925 _smart_enter_none(sd);
926 return ECORE_CALLBACK_CANCEL;
931 /* state switching */
933 _smart_enter_none(Smart_Data *sd)
936 sd->two_drag_mode = TWO_DRAG_NONE;
937 sd->state = TOUCH_STATE_NONE;
938 DBG("\nTOUCH_STATE_NONE\n");
942 _smart_enter_down(Smart_Data *sd)
945 sd->press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_press_timer_handler, sd);
947 // set long press timer
948 sd->long_press_timer = ecore_timer_add(((double)LONG_HOLD_TIME)/1000.0, _smart_long_press_timer_handler, sd);
950 sd->state = TOUCH_STATE_DOWN;
951 DBG("\nTOUCH_STATE_DOWN\n");
955 _smart_enter_down_during_drag(Smart_Data *sd)
958 sd->press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_press_timer_handler, sd);
960 sd->state = TOUCH_STATE_DOWN_DURING_DRAG;
961 DBG("\nTOUCH_STATE_DOWN_DURING_DRAG\n");
965 _smart_enter_down_up(Smart_Data *sd, int downTime, int time)
967 // remove sd->press_timer and set new timer
968 int timerTime = RELEASE_TIME - (downTime - PRESS_TIME);
971 ecore_timer_del(sd->press_timer);
972 sd->press_timer = NULL;
973 sd->press_release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_press_release_timer_handler, sd);
978 sd->release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_release_timer_handler, sd);
981 if (sd->long_press_timer) // remove long press timer
983 ecore_timer_del(sd->long_press_timer);
984 sd->long_press_timer = NULL;
987 sd->state = TOUCH_STATE_DOWN_UP;
988 DBG("\nTOUCH_STATE_DOWN_UP\n");
992 _smart_enter_down_up_down(Smart_Data *sd)
994 if (sd->press_release_timer) // remove press_release_timer
996 ecore_timer_del(sd->press_release_timer);
997 sd->press_release_timer = NULL;
1000 if (sd->release_timer) // remove ReleaseTimer
1002 ecore_timer_del(sd->release_timer);
1003 sd->release_timer = NULL;
1006 sd->state = TOUCH_STATE_DOWN_UP_DOWN;
1007 DBG("\nTOUCH_STATE_DOWN_UP_DOWN\n");
1011 _smart_enter_hold(Smart_Data *sd)
1013 sd->state = TOUCH_STATE_HOLD;
1014 DBG("\nTOUCH_STATE_HOLD\n");
1018 _smart_enter_drag(Smart_Data *sd)
1020 if (sd->press_timer) // remove press_timer
1022 ecore_timer_del(sd->press_timer);
1023 sd->press_timer = NULL;
1026 if (sd->press_release_timer) // remove press_release_timer
1028 ecore_timer_del(sd->press_release_timer);
1029 sd->press_release_timer = NULL;
1032 if (sd->release_timer) // remove ReleaseTimer
1034 ecore_timer_del(sd->release_timer);
1035 sd->release_timer = NULL;
1038 if (sd->long_press_timer) // remove long press timer
1040 ecore_timer_del(sd->long_press_timer);
1041 sd->long_press_timer = NULL;
1046 if (sd->is_one_drag_mode)
1048 sd->one_drag_mode = ONE_DRAG_NONE;
1049 int abs_dx = abs(sd->first_down[0].x - sd->last_drag[0].x);
1050 int abs_dy = abs(sd->first_down[0].y - sd->last_drag[0].y);
1051 abs_dx = (abs_dx == 0) ? 1 : abs_dx;
1052 DBG("<< abs_dx[%d], abs_dy[%d] >>\n\n", abs_dx, abs_dy);
1053 float degree = (float)abs_dy / (float)abs_dx;
1054 // more than 70 degree
1055 if (degree > tan(70 * M_PI / 180))
1057 sd->one_drag_mode = ONE_DRAG_VERTICAL;
1059 // less than 20 degree
1060 else if (degree < tan(20 * M_PI / 180))
1062 sd->one_drag_mode = ONE_DRAG_HORIZONTAL;
1066 point.x = sd->last_down[0].x;
1067 point.y = sd->last_down[0].y;
1068 evas_object_smart_callback_call(sd->child_obj, "one,move,start", &point);
1070 // initialize flick variables
1071 sd->last_move_history_index = -1;
1072 sd->move_history_count = 0;
1074 sd->animator_move = ecore_animator_add(_smart_animation_move, sd);
1075 DBG("<< sd->animator_move >>\n");
1076 sd->state = TOUCH_STATE_DRAG;
1077 DBG("\nTOUCH_STATE_DRAG\n");
1081 sd->state = TOUCH_STATE_NONE;
1086 _smart_enter_two_down(Smart_Data *sd)
1088 _smart_stop_all_timers(sd);
1090 // set two press timer
1091 sd->two_press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_two_press_timer_handler, sd);
1093 sd->state = TOUCH_STATE_TWO_DOWN;
1094 DBG("\nTOUCH_STATE_TWO_DOWN\n");
1098 _smart_enter_two_down_during_drag(Smart_Data *sd)
1100 _smart_stop_all_timers(sd);
1102 // set two press timer
1103 sd->two_press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_two_press_timer_handler, sd);
1105 sd->state = TOUCH_STATE_TWO_DOWN_DURING_DRAG;
1106 DBG("<< enter two down >>\n");
1110 _smart_enter_two_down_up(Smart_Data *sd, int downTime, int time)
1112 // remove sd->press_timer and set new timer
1113 int timerTime = RELEASE_TIME - (downTime - PRESS_TIME);
1114 printf("<< time [%d] >>\n", timerTime);
1115 if (sd->two_press_timer)
1117 ecore_timer_del(sd->two_press_timer);
1118 sd->two_press_timer = NULL;
1119 sd->two_press_release_timer =
1120 ecore_timer_add(((double)timerTime)/1000.0, _smart_two_press_release_timer_handler, sd);
1125 sd->two_release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_two_release_timer_handler, sd);
1128 sd->state = TOUCH_STATE_TWO_DOWN_UP;
1129 DBG("\nTOUCH_STATE_TWO_DOWN_UP\n");
1133 _smart_enter_two_down_up_down(Smart_Data *sd)
1135 if (sd->two_press_release_timer) // remove two_press_release_timer
1137 ecore_timer_del(sd->two_press_release_timer);
1138 sd->two_press_release_timer = NULL;
1141 if (sd->two_release_timer) // remove two_release_timer
1143 ecore_timer_del(sd->two_release_timer);
1144 sd->two_release_timer = NULL;
1147 sd->state = TOUCH_STATE_TWO_DOWN_UP_DOWN;
1148 DBG("\nTOUCH_STATE_TWO_DOWN_UP_DOWN\n");
1152 _smart_enter_two_drag(Smart_Data *sd)
1156 DBG("<< sd->animator_two_move >>\n");
1157 sd->state = TOUCH_STATE_TWO_DRAG;
1158 _smart_emit_two_move_start(sd);
1159 sd->animator_two_move = ecore_animator_add(_smart_animation_two_move, sd);
1163 sd->state = TOUCH_STATE_NONE;
1168 _smart_enter_three_down(Smart_Data *sd)
1172 sd->state = TOUCH_STATE_THREE_DOWN;
1173 _smart_emit_three_press(sd);
1177 /* producing output events */
1179 _smart_emit_press(Smart_Data *sd)
1183 DBG("<< emit_press >>\n");
1185 point.x = sd->last_down[0].x;
1186 point.y = sd->last_down[0].y;
1187 evas_object_smart_callback_call(sd->child_obj, "one,press", &point);
1192 _smart_emit_tap(Smart_Data *sd)
1196 DBG("<< emit_tap >>\n");
1198 point.x = sd->last_down[0].x;
1199 point.y = sd->last_down[0].y;
1200 evas_object_smart_callback_call(sd->child_obj, "one,single,tap", &point);
1205 _smart_emit_double_tap(Smart_Data *sd)
1209 DBG("<< emit_double_tap >>\n");
1211 point.x = sd->last_down[0].x;
1212 point.y = sd->last_down[0].y;
1213 evas_object_smart_callback_call(sd->child_obj, "one,double,tap", &point);
1218 _smart_emit_long_hold(Smart_Data *sd)
1222 DBG("<< emit_long_hold >>\n");
1224 point.x = sd->last_down[0].x;
1225 point.y = sd->last_down[0].y;
1226 evas_object_smart_callback_call(sd->child_obj, "one,long,press", &point);
1231 _smart_emit_release(Smart_Data *sd)
1235 DBG("<< emit_release >>\n");
1237 point.x = sd->last_down[0].x;
1238 point.y = sd->last_down[0].y;
1239 evas_object_smart_callback_call(sd->child_obj, "one,release", &point);
1244 _smart_emit_two_press(Smart_Data *sd)
1248 DBG("<< emit_two_press >>\n");
1249 Two_Mouse_Data two_mouse_data;
1250 two_mouse_data.first.x = sd->last_down[0].x;
1251 two_mouse_data.first.y = sd->last_down[0].y;
1252 two_mouse_data.second.x = sd->last_down[1].x;
1253 two_mouse_data.second.y = sd->last_down[1].y;
1254 two_mouse_data.mode = sd->two_drag_mode;
1255 evas_object_smart_callback_call(sd->child_obj, "two,press", &two_mouse_data);
1260 _smart_emit_two_tap(Smart_Data *sd)
1264 DBG("<< emit_two_tap >>\n");
1265 Two_Mouse_Data two_mouse_data;
1266 two_mouse_data.first.x = sd->last_down[0].x;
1267 two_mouse_data.first.y = sd->last_down[0].y;
1268 two_mouse_data.second.x = sd->last_down[1].x;
1269 two_mouse_data.second.y = sd->last_down[1].y;
1270 two_mouse_data.mode = sd->two_drag_mode;
1271 evas_object_smart_callback_call(sd->child_obj, "two,tap", &two_mouse_data);
1276 _smart_emit_two_double_tap(Smart_Data *sd)
1280 DBG("<< emit_two_double_tap >>\n");
1281 Two_Mouse_Data two_mouse_data;
1282 two_mouse_data.first.x = sd->last_down[0].x;
1283 two_mouse_data.first.y = sd->last_down[0].y;
1284 two_mouse_data.second.x = sd->last_down[1].x;
1285 two_mouse_data.second.y = sd->last_down[1].y;
1286 two_mouse_data.mode = sd->two_drag_mode;
1287 evas_object_smart_callback_call(sd->child_obj, "two,double,tap", &two_mouse_data);
1292 _smart_emit_two_move_start(Smart_Data *sd)
1296 DBG("<< emit_two_move_start >>\n");
1297 Two_Mouse_Data two_mouse_data;
1298 two_mouse_data.first.x = sd->last_drag[0].x;
1299 two_mouse_data.first.y = sd->last_drag[0].y;
1300 two_mouse_data.second.x = sd->last_drag[1].x;
1301 two_mouse_data.second.y = sd->last_drag[1].y;
1302 two_mouse_data.mode = sd->two_drag_mode;
1303 evas_object_smart_callback_call(sd->child_obj, "two,move,start", &two_mouse_data);
1308 _smart_emit_two_move(Smart_Data *sd)
1312 Two_Mouse_Data two_mouse_data;
1313 two_mouse_data.first.x = sd->last_drag[0].x;
1314 two_mouse_data.first.y = sd->last_drag[0].y;
1315 two_mouse_data.second.x = sd->last_drag[1].x;
1316 two_mouse_data.second.y = sd->last_drag[1].y;
1317 two_mouse_data.mode = sd->two_drag_mode;
1318 evas_object_smart_callback_call(sd->child_obj, "two,move", &two_mouse_data);
1323 _smart_emit_two_move_end(Smart_Data *sd)
1327 DBG("<< emit_two_move_end >>\n");
1328 Two_Mouse_Data two_mouse_data;
1329 two_mouse_data.first.x = sd->last_drag[0].x;
1330 two_mouse_data.first.y = sd->last_drag[0].y;
1331 two_mouse_data.second.x = sd->last_drag[1].x;
1332 two_mouse_data.second.y = sd->last_drag[1].y;
1333 two_mouse_data.mode = sd->two_drag_mode;
1334 evas_object_smart_callback_call(sd->child_obj, "two,move,end", &two_mouse_data);
1339 _smart_emit_three_press(Smart_Data *sd)
1343 DBG("<< emit_three_press >>\n");
1344 Three_Mouse_Data three_mouse_data;
1345 three_mouse_data.first.x = sd->last_drag[0].x;
1346 three_mouse_data.first.y = sd->last_drag[0].y;
1347 three_mouse_data.second.x = sd->last_drag[1].x;
1348 three_mouse_data.second.y = sd->last_drag[1].y;
1349 three_mouse_data.third.x = sd->last_drag[2].x;
1350 three_mouse_data.third.y = sd->last_drag[2].y;
1351 evas_object_smart_callback_call(sd->child_obj, "three,press", &three_mouse_data);
1356 _smart_emit_three_tap(Smart_Data *sd)
1360 DBG("<< emit_three_tap >>\n");
1361 Three_Mouse_Data three_mouse_data;
1362 three_mouse_data.first.x = sd->last_drag[0].x;
1363 three_mouse_data.first.y = sd->last_drag[0].y;
1364 three_mouse_data.second.x = sd->last_drag[1].x;
1365 three_mouse_data.second.y = sd->last_drag[1].y;
1366 three_mouse_data.third.x = sd->last_drag[2].x;
1367 three_mouse_data.third.y = sd->last_drag[2].y;
1368 evas_object_smart_callback_call(sd->child_obj, "three,tap", &three_mouse_data);
1372 /* timer event handling */
1374 _smart_press_timer_handler(void *data)
1376 DBG("<< %s >>\n", __func__);
1380 _smart_emit_press(sd);
1381 sd->press_timer = NULL;
1382 return ECORE_CALLBACK_CANCEL;
1386 _smart_long_press_timer_handler(void *data)
1388 DBG("<< %s >>\n", __func__);
1392 _smart_emit_long_hold(sd);
1393 _smart_enter_hold(sd);
1394 sd->long_press_timer = NULL;
1395 return ECORE_CALLBACK_CANCEL;
1399 _smart_release_timer_handler(void *data)
1401 DBG("<< %s >>\n", __func__);
1405 _smart_emit_tap(sd);
1406 _smart_stop_all_timers(sd);
1407 _smart_enter_none(sd);
1408 sd->release_timer = NULL;
1409 return ECORE_CALLBACK_CANCEL;
1413 _smart_press_release_timer_handler(void *data)
1415 DBG("<< %s >>\n", __func__);
1416 static int prevent_handler = 0;
1417 if (prevent_handler != 0) return ECORE_CALLBACK_CANCEL;
1418 prevent_handler = 1;
1422 _smart_emit_press(sd);
1423 // emit tap after 10ms later
1424 // because, webkit engine can not draw the focus ring,
1425 // if we emit press and release at the same time
1426 ecore_timer_add((double)10/1000.0, _tap_delay_timer_handler, sd);
1427 _smart_stop_all_timers(sd);
1428 _smart_enter_none(sd);
1429 sd->press_release_timer = NULL;
1430 prevent_handler = 0;
1431 return ECORE_CALLBACK_CANCEL;
1435 _tap_delay_timer_handler(void *data)
1437 DBG("<< %s >>\n", __func__);
1441 _smart_emit_tap(sd);
1442 return ECORE_CALLBACK_CANCEL;
1446 _smart_two_press_timer_handler(void *data)
1448 DBG("<< %s >>\n", __func__);
1452 _smart_emit_two_press(sd);
1453 _smart_stop_all_one_timers(sd);
1454 sd->two_press_timer = NULL;
1455 return ECORE_CALLBACK_CANCEL;
1459 _smart_two_release_timer_handler(void *data)
1461 DBG("<< %s >>\n", __func__);
1465 _smart_emit_two_tap(sd);
1466 _smart_stop_all_timers(sd);
1467 _smart_enter_none(sd);
1468 sd->two_release_timer = NULL;
1469 return ECORE_CALLBACK_CANCEL;
1473 _smart_two_press_release_timer_handler(void *data)
1475 DBG("<< %s >>\n", __func__);
1479 _smart_emit_two_press(sd);
1480 _smart_emit_two_tap(sd);
1481 _smart_stop_all_timers(sd);
1482 _smart_enter_none(sd);
1483 sd->two_press_release_timer = NULL;
1484 return ECORE_CALLBACK_CANCEL;
1487 /* other functions */
1489 _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy)
1491 // save pan information to the pan history
1492 int index = (sd->last_move_history_index + 1) % MOVE_HISTORY_SIZE;
1493 sd->last_move_history_index = index;
1494 sd->move_history[index].dx = dx;
1495 sd->move_history[index].dy = dy;
1496 sd->move_history[index].time = ecore_time_get();
1497 sd->move_history_count++;
1501 _smart_start_flick(Smart_Data *sd)
1503 if (sd->animator_move)
1505 ecore_animator_del(sd->animator_move);
1506 DBG("<< stop_animator_move >>\n");
1507 sd->animator_move = NULL;
1510 // accumulate sd->move_history data
1514 int index = sd->last_move_history_index;
1515 int todo = sd->move_history_count > MOVE_HISTORY_SIZE ? MOVE_HISTORY_SIZE : sd->move_history_count;
1517 double endTime = ecore_time_get();
1518 double startTime = endTime;
1519 for( ; todo > 0; todo--) {
1520 p = sd->move_history + index; // get one sd->move_history
1523 startTime = p->time;
1528 if ((endTime - startTime) > 0.2 && nSamples > 0)
1531 index = (index > 0) ? (index - 1) : (MOVE_HISTORY_SIZE - 1); // set index
1533 double totalTime = endTime - startTime;
1534 if (totalTime < DOUBLE_ERROR)
1537 // calculate average pan_dx and pan_dy (per 1 / DEFAULT_FRAMERATE ms)
1538 double temp = totalTime * DEFAULT_FRAMERATE;
1542 Flick_Data *flick_data = &sd->flick_data;
1543 flick_data->avg_distance.x = totalDx / temp;
1544 flick_data->avg_distance.y = totalDy / temp;
1546 // set max value for pan_dx and pan_dy
1547 int abs_pan_dx = abs(flick_data->avg_distance.x);
1548 int abs_pan_dy = abs(flick_data->avg_distance.y);
1549 if ((abs_pan_dx > MAX_MOVE_DISTANCE) && (abs_pan_dx > abs_pan_dy))
1551 flick_data->avg_distance.x = (flick_data->avg_distance.x > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1552 flick_data->avg_distance.y = flick_data->avg_distance.y * MAX_MOVE_DISTANCE / abs_pan_dx;
1555 else if ((abs_pan_dy > MAX_MOVE_DISTANCE) && (abs_pan_dy > abs_pan_dx))
1557 flick_data->avg_distance.y = (flick_data->avg_distance.y > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1558 flick_data->avg_distance.x = flick_data->avg_distance.x * MAX_MOVE_DISTANCE / abs_pan_dy;
1561 if (abs_pan_dx > FLICK_THRESHOLD || abs_pan_dy > FLICK_THRESHOLD)
1563 // set flick_data and start flick
1564 flick_data->last.x = sd->last_drag[0].x;
1565 flick_data->last.y = sd->last_drag[0].y;
1566 flick_data->flick_index = 0;
1567 sd->animator_flick = ecore_animator_add(_smart_animation_flick, sd);
1568 DBG("<< sd->animator_flick >>\n");
1573 point.x = sd->last_drag[0].x;
1574 point.y = sd->last_drag[0].y;
1575 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1576 _smart_enter_none(sd);
1581 _smart_emit_release(sd);
1582 _smart_stop_all_timers(sd);
1583 _smart_enter_none(sd);
1588 _smart_stop_animator_move(Smart_Data *sd)
1590 if (sd->animator_move)
1592 ecore_animator_del(sd->animator_move);
1593 DBG("<< stop_animator_move >>\n");
1594 sd->animator_move = NULL;
1596 point.x = sd->last_drag[0].x;
1597 point.y = sd->last_drag[0].y;
1598 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1603 _smart_stop_animator_flick(Smart_Data *sd)
1605 if (sd->animator_flick)
1607 ecore_animator_del(sd->animator_flick);
1608 DBG("<< stop_animator_flick >>\n");
1609 sd->animator_flick = NULL;
1610 Evas_Coord_Point point;
1611 point = sd->flick_data.last;
1612 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1617 _smart_stop_animator_two_move(Smart_Data *sd)
1619 if (sd->animator_two_move)
1621 ecore_animator_del(sd->animator_two_move);
1622 DBG("<< stop_animator_two_move >>\n");
1623 sd->animator_two_move = NULL;
1624 _smart_emit_two_move_end(sd);
1628 static Two_Drag_Mode
1629 _smart_check_two_drag_mode(Smart_Data *sd)
1631 // get distance from press to current position
1632 int dx0 = sd->last_drag[0].x - sd->first_down[0].x;
1633 int dy0 = sd->last_drag[0].y - sd->first_down[0].y;
1634 int dx1 = sd->last_drag[1].x - sd->first_down[1].x;
1635 int dy1 = sd->last_drag[1].y - sd->first_down[1].y;
1640 if ((abs(dx1) >= MOVE_THRESHOLD) || (abs(dy1) >= MOVE_THRESHOLD))
1645 else if ((abs(dx0) >= MOVE_THRESHOLD) || (abs(dy0) >= MOVE_THRESHOLD))
1652 return TWO_DRAG_NONE;
1656 if ((abs(dx) > abs(dy)) && ((dx0 > 0 && dx1 > 0) || (dx0 < 0 && dx1 < 0)))
1658 dy = (dy == 0) ? 1 : dy;
1659 // less than 30 degree (1024/root(3) = 591)
1660 if (((abs(dy) << 10) / abs(dx)) < 591)
1662 return TWO_DRAG_HORIZONTAL;
1667 if ((abs(dy) > abs(dx)) && ((dy0 > 0 && dy1 > 0) || (dy0 < 0 && dy1 < 0)))
1669 dx = (dx == 0) ? 1 : dx;
1670 // more than 60 degree (1024 * root(3)/1 = 1773)
1671 if (((abs(dy) << 10) / abs(dx)) > 1773)
1673 return TWO_DRAG_VERTICAL;
1678 int distanceX = abs(abs(sd->first_down[0].x - sd->first_down[1].x)
1679 - abs(sd->last_drag[0].x - sd->last_drag[1].x));
1680 int distanceY = abs(abs(sd->first_down[0].y - sd->first_down[1].y)
1681 - abs(sd->last_drag[0].y - sd->last_drag[1].y));
1682 if ((distanceX > FINGER_DISTANCE) || (distanceY > FINGER_DISTANCE))
1684 return TWO_DRAG_PINCH;
1687 return TWO_DRAG_NONE;
1691 _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data)
1693 if (index > N_FINGER)
1698 if ((sd->screen_angle == 270) && (index > 0))
1700 sd->first_down[index].x = data->y;
1701 sd->first_down[index].y = data->x;
1702 sd->first_down[index].time = data->time;
1703 sd->first_down[index].device = data->device;
1707 sd->first_down[index].x = data->x;
1708 sd->first_down[index].y = data->y;
1709 sd->first_down[index].time = data->time;
1710 sd->first_down[index].device = data->device;
1715 _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data)
1717 if (index > N_FINGER)
1722 if ((sd->screen_angle == 270) && (index > 0))
1724 sd->last_down[index].x = data->y;
1725 sd->last_down[index].y = data->x;
1726 sd->last_down[index].time = data->time;
1727 sd->last_down[index].device = data->device;
1731 sd->last_down[index].x = data->x;
1732 sd->last_down[index].y = data->y;
1733 sd->last_down[index].time = data->time;
1734 sd->last_down[index].device = data->device;
1739 _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data)
1741 if (index > N_FINGER)
1746 if ((sd->screen_angle == 270) && (index > 0))
1748 sd->last_drag[index].x = data->y;
1749 sd->last_drag[index].y = data->x;
1750 sd->last_drag[index].time = data->time;
1751 sd->last_drag[index].device = data->device;
1755 sd->last_drag[index].x = data->x;
1756 sd->last_drag[index].y = data->y;
1757 sd->last_drag[index].time = data->time;
1758 sd->last_drag[index].device = data->device;
1763 _smart_stop_all_timers(Smart_Data *sd)
1765 _smart_stop_all_one_timers(sd);
1766 _smart_stop_all_two_timers(sd);
1770 _smart_stop_all_one_timers(Smart_Data *sd)
1772 if (sd->press_timer) // remove sd->press_timer
1774 ecore_timer_del(sd->press_timer);
1775 sd->press_timer = NULL;
1778 if (sd->long_press_timer) // remove long press timer
1780 ecore_timer_del(sd->long_press_timer);
1781 sd->long_press_timer = NULL;
1784 if (sd->release_timer) // remove release timer
1786 ecore_timer_del(sd->release_timer);
1787 sd->release_timer = NULL;
1790 if (sd->press_release_timer) // remove pressRelease timer
1792 ecore_timer_del(sd->press_release_timer);
1793 sd->press_release_timer = NULL;
1798 _smart_stop_all_two_timers(Smart_Data *sd)
1800 if (sd->two_press_timer)
1802 ecore_timer_del(sd->two_press_timer);
1803 sd->two_press_timer = NULL;
1806 if (sd->two_release_timer)
1808 ecore_timer_del(sd->two_release_timer);
1809 sd->two_release_timer = NULL;
1812 if (sd->two_press_release_timer)
1814 ecore_timer_del(sd->two_press_release_timer);
1815 sd->two_press_release_timer = NULL;
1820 _smart_add(Evas_Object *obj)
1824 sd = calloc(1, sizeof(Smart_Data));
1826 memset((void *)sd, 0x00, sizeof(Smart_Data));
1828 sd->smart_obj = obj;
1830 // set default framerate
1831 ecore_animator_frametime_set(1.0 / DEFAULT_FRAMERATE);
1833 evas_object_smart_data_set(obj, sd);
1837 _smart_del(Evas_Object *obj)
1842 if (sd->press_timer)
1843 ecore_timer_del(sd->press_timer);
1845 if (sd->long_press_timer)
1846 ecore_timer_del(sd->long_press_timer);
1848 if (sd->release_timer)
1849 ecore_timer_del(sd->release_timer);
1851 if (sd->press_release_timer)
1852 ecore_timer_del(sd->press_release_timer);
1854 if (sd->animator_move)
1855 ecore_animator_del(sd->animator_move);
1857 if (sd->animator_flick)
1858 ecore_animator_del(sd->animator_flick);
1860 if (sd->animator_two_move)
1861 ecore_animator_del(sd->animator_two_move);
1865 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
1866 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
1867 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
1868 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
1869 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
1870 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
1882 static const Evas_Smart_Class sc =
1885 EVAS_SMART_CLASS_VERSION,
1903 _smart = evas_smart_class_new(&sc);