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
74 TOUCH_STATE_DOWN_UP_DOWN,
79 TOUCH_STATE_THREE_DOWN
82 typedef enum _One_Drag_Mode
89 typedef struct _Flick_Data Flick_Data;
94 Evas_Coord_Point last;
95 Evas_Coord_Point avg_distance;
98 typedef struct _Mouse_Diff_Data Mouse_Diff_Data;
100 struct _Mouse_Diff_Data
106 typedef struct _Smart_Data Smart_Data;
110 Evas_Object *smart_obj;
111 Evas_Object *child_obj;
117 One_Drag_Mode one_drag_mode;
118 Eina_Bool is_one_drag_mode;
119 Two_Drag_Mode two_drag_mode;
123 int last_move_history_index;
124 int move_history_count;
125 Flick_Data flick_data;
126 Mouse_Diff_Data move_history[MOVE_HISTORY_SIZE];
128 Mouse_Data first_down[N_FINGER];
129 Mouse_Data last_down[N_FINGER];
130 Mouse_Data last_drag[N_FINGER];
132 Ecore_Animator *animator_move;
133 Ecore_Animator *animator_flick;
134 Ecore_Animator *animator_two_move;
137 Ecore_Timer *press_timer;
138 Ecore_Timer *long_press_timer;
139 Ecore_Timer *release_timer;
140 Ecore_Timer *press_release_timer;
143 /* local subsystem functions */
145 static float _smart_velocity_easeinoutcubic(int index);
146 static void _smart_mouse_down(void *data, Evas *e, Evas_Object *obj, void *ev);
147 static void _smart_mouse_up(void *data, Evas *e, Evas_Object *obj, void *ev);
148 static void _smart_mouse_move(void *data, Evas *e, Evas_Object *obj, void *ev);
149 static void _smart_multi_down(void *data, Evas *e, Evas_Object *obj, void *ev);
150 static void _smart_multi_up(void *data, Evas *e, Evas_Object *obj, void *ev);
151 static void _smart_multi_move(void *data, Evas *e, Evas_Object *obj, void *ev);
152 // animator callbacks
153 static int _smart_animation_move(void *data);
154 static int _smart_animation_flick(void *data);
155 static int _smart_animation_two_move(void *data);
156 // enter mode functions
157 static void _smart_enter_none(Smart_Data *sd);
158 static void _smart_enter_down(Smart_Data *sd);
159 static void _smart_enter_down_up(Smart_Data *sd, int downTime, int time);
160 static void _smart_enter_down_up_down(Smart_Data *sd);
161 static void _smart_enter_hold(Smart_Data *sd);
162 static void _smart_enter_drag(Smart_Data *sd);
163 static void _smart_enter_two_down(Smart_Data *sd);
164 static void _smart_enter_two_drag(Smart_Data *sd);
165 static void _smart_enter_three_down(Smart_Data *sd);
167 static void _smart_emit_press(Smart_Data *sd);
168 static void _smart_emit_tap(Smart_Data *sd);
169 static void _smart_emit_double_tap(Smart_Data *sd);
170 static void _smart_emit_long_hold(Smart_Data *sd);
171 static void _smart_emit_release(Smart_Data *sd);
172 static void _smart_emit_two_press(Smart_Data *sd);
173 static void _smart_emit_two_tap(Smart_Data *sd);
174 static void _smart_emit_two_move_start(Smart_Data *sd);
175 static void _smart_emit_two_move(Smart_Data *sd);
176 static void _smart_emit_two_move_end(Smart_Data *sd);
177 static void _smart_emit_three_press(Smart_Data *sd);
178 static void _smart_emit_three_tap(Smart_Data *sd);
180 static int _smart_press_timer_handler(void *data);
181 static int _smart_long_press_timer_handler(void *data);
182 static int _smart_release_timer_handler(void *data);
183 static int _smart_press_release_timer_handler(void *data);
185 static void _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy);
186 static void _smart_start_flick(Smart_Data *sd);
187 static void _smart_stop_animator_move(Smart_Data *sd);
188 static void _smart_stop_animator_flick(Smart_Data *sd);
189 static void _smart_stop_animator_two_move(Smart_Data *sd);
190 static Two_Drag_Mode _smart_check_two_drag_mode(Smart_Data *sd);
191 static void _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data);
192 static void _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data);
193 static void _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data);
194 static void _smart_stop_all_timers(Smart_Data *sd);
195 static void _smart_init(void);
196 static void _smart_del(Evas_Object *obj);
197 static void _smart_add(Evas_Object *obj);
199 /* local subsystem globals */
200 static Evas_Smart *_smart = NULL;
202 /* externally accessible functions */
204 _elm_smart_touch_add(Evas *evas)
207 return evas_object_smart_add(evas, _smart);
211 _elm_smart_touch_child_set(Evas_Object *obj, Evas_Object *child)
214 if (child == sd->child_obj) return;
216 if (sd->child_obj) // delete callbacks of old object
218 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
219 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
220 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
221 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
222 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
223 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
224 _smart_stop_all_timers(sd);
225 _smart_stop_animator_move(sd);
226 _smart_stop_animator_flick(sd);
227 _smart_stop_animator_two_move(sd);
229 sd->child_obj = NULL;
234 sd->child_obj = child;
237 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down, sd);
238 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up, sd);
239 evas_object_event_callback_add(child, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move, sd);
240 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down, sd);
241 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_UP, _smart_multi_up, sd);
242 evas_object_event_callback_add(child, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move, sd);
244 _smart_enter_none(sd);
246 sd->is_one_drag_mode = EINA_FALSE;
249 evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
253 _elm_smart_touch_start(Evas_Object *obj)
256 if (sd->running) return;
258 sd->running = EINA_TRUE;
259 _smart_enter_none(sd);
263 _elm_smart_touch_stop(Evas_Object *obj)
266 sd->running = EINA_FALSE;
267 _smart_stop_all_timers(sd);
268 _smart_stop_animator_move(sd);
269 _smart_stop_animator_flick(sd);
270 _smart_stop_animator_two_move(sd);
271 _smart_enter_none(sd);
275 _elm_smart_touch_reset(Evas_Object *obj)
278 _smart_stop_all_timers(sd);
279 _smart_stop_animator_move(sd);
280 _smart_stop_animator_flick(sd);
281 _smart_stop_animator_two_move(sd);
282 _smart_enter_none(sd);
286 _elm_smart_touch_screen_angle_update(Evas_Object *obj, int screen_angle)
289 sd->screen_angle = screen_angle;
293 _elm_smart_touch_is_one_drag_mode_enable(Evas_Object *obj, Eina_Bool is_one_drag_mode)
296 sd->is_one_drag_mode = is_one_drag_mode;
299 /* local subsystem functions */
300 /** reference from htsd://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html
301 * Easing equation function for a cubic (t^3) easing in/out: acceleration until halfway, then deceleration
302 * @param t Number Current time (in frames or seconds)
303 * @param b Number Starting value
304 * @param c Number Change needed in value
305 * @param d Number Expected easing duration (in frames or seconds)
306 * @return Number The correct value
307 public static function easeInOutCubic (t:Number, b:Number, c:Number, d:Number, p_params:Object):Number {
308 if ((t/=d/2) < 1) return c/2*t*t*t + b;
309 return c/2*((t-=2)*t*t + 2) + b;
313 _smart_velocity_easeinoutcubic(int index)
316 float t = d - index; // we want to get reversed value
318 if ((t /= (d / 2)) < 1)
320 return (c / 2) * t * t * t;
323 return (c / 2) * (t * t * t + 2);
327 /* mouse callbacks */
329 _smart_mouse_down(void *data, Evas *e, Evas_Object *obj, void *ev)
332 Evas_Event_Mouse_Down *event;
333 Mouse_Data mouse_data;
336 if (!sd || sd->running == EINA_FALSE) return;
338 event = (Evas_Event_Mouse_Down*)ev;
342 case TOUCH_STATE_NONE:
343 case TOUCH_STATE_DRAG:
344 mouse_data.x = event->canvas.x;
345 mouse_data.y = event->canvas.y;
346 mouse_data.time = event->timestamp;
347 mouse_data.device = -1;
348 _smart_set_first_down(sd, 0, &mouse_data);
349 _smart_set_last_down(sd, 0, &mouse_data);
350 _smart_set_last_drag(sd, 0, &mouse_data);
351 _smart_enter_down(sd);
354 case TOUCH_STATE_DOWN_UP:
355 if (event->flags == EVAS_BUTTON_DOUBLE_CLICK) {
356 mouse_data.x = event->canvas.x;
357 mouse_data.y = event->canvas.y;
358 mouse_data.time = event->timestamp;
359 mouse_data.device = -1;
360 _smart_set_last_down(sd, 0, &mouse_data);
361 _smart_set_last_drag(sd, 0, &mouse_data);
362 _smart_enter_down_up_down(sd);
372 _smart_mouse_up(void *data, Evas *e, Evas_Object *obj, void *ev)
376 Evas_Event_Mouse_Up *event;
378 if (!sd || sd->running == EINA_FALSE) return;
380 event = (Evas_Event_Mouse_Up*)ev;
384 case TOUCH_STATE_DOWN:
385 _smart_stop_animator_move(sd);
386 _smart_stop_animator_flick(sd);
387 _smart_enter_down_up(sd, (event->timestamp - sd->last_down[0].time), event->timestamp);
390 case TOUCH_STATE_DOWN_UP_DOWN:
392 int dx = sd->last_down[0].x - sd->first_down[0].x;
393 int dy = sd->last_down[0].y - sd->first_down[0].y;
394 if ((dx * dx + dy * dy) <= (DBL_TAP_DISTANCE * DBL_TAP_DISTANCE))
395 _smart_emit_double_tap(sd);
396 _smart_stop_all_timers(sd);
397 _smart_enter_none(sd);
400 case TOUCH_STATE_HOLD:
401 _smart_emit_release(sd);
402 _smart_stop_all_timers(sd);
403 _smart_enter_none(sd);
406 case TOUCH_STATE_DRAG:
407 _smart_emit_release(sd);
408 _smart_start_flick(sd);
411 case TOUCH_STATE_TWO_DOWN:
412 _smart_emit_two_tap(sd);
413 _smart_stop_all_timers(sd);
414 _smart_enter_none(sd);
417 case TOUCH_STATE_TWO_DRAG:
418 _smart_stop_animator_two_move(sd);
419 _smart_stop_all_timers(sd);
420 _smart_enter_none(sd);
423 case TOUCH_STATE_THREE_DOWN:
424 _smart_emit_three_tap(sd);
425 _smart_stop_all_timers(sd);
426 _smart_enter_none(sd);
430 _smart_emit_release(sd);
431 _smart_stop_all_timers(sd);
432 _smart_enter_none(sd);
433 DBG("\nERROR: wrong state in mouse_up\n\n");
440 _smart_mouse_move(void *data, Evas *e, Evas_Object *obj, void *ev)
444 if (!sd || sd->running == EINA_FALSE) return;
446 Evas_Event_Mouse_Move *event = (Evas_Event_Mouse_Move*)ev;
450 Mouse_Data mouse_data;
451 mouse_data.x = event->cur.canvas.x;
452 mouse_data.y = event->cur.canvas.y;
453 mouse_data.time = event->timestamp;
454 mouse_data.device = -1;
458 case TOUCH_STATE_DOWN:
459 dx = mouse_data.x - sd->last_drag[0].x;
460 dy = mouse_data.y - sd->last_drag[0].y;
462 if ((abs(dx) > INIT_DRAG_THRESHOLD) || (abs(dy) > INIT_DRAG_THRESHOLD))
464 if (sd->animator_move)
466 ecore_animator_del(sd->animator_move);
467 sd->animator_move = NULL;
469 if (sd->animator_flick)
471 ecore_animator_del(sd->animator_flick);
472 sd->animator_flick = NULL;
474 _smart_set_last_drag(sd, 0, &mouse_data);
476 // last_down - location where the drag starts
477 // (which is different than fisrtDown)
478 _smart_set_last_down(sd, 0, &mouse_data);
479 _smart_enter_drag(sd);
483 case TOUCH_STATE_DRAG:
484 dx = mouse_data.x - sd->last_drag[0].x;
485 dy = mouse_data.y - sd->last_drag[0].y;
487 if ((abs(dx) > DRAG_THRESHOLD) || (abs(dy) > DRAG_THRESHOLD))
489 _smart_set_last_drag(sd, 0, &mouse_data);
490 _smart_save_move_history(sd, mouse_data.x, mouse_data.y, dx, dy);
494 case TOUCH_STATE_TWO_DOWN:
495 _smart_set_last_drag(sd, 0, &mouse_data);
497 sd->two_drag_mode = _smart_check_two_drag_mode(sd);
498 if (sd->two_drag_mode != TWO_DRAG_NONE)
500 DBG("<< sd->two_drag_mode [%d] >>\n", sd->two_drag_mode);
501 _smart_enter_two_drag(sd);
505 case TOUCH_STATE_TWO_DRAG:
506 _smart_set_last_drag(sd, 0, &mouse_data);
509 case TOUCH_STATE_THREE_DOWN:
510 _smart_set_last_drag(sd, 0, &mouse_data);
519 _smart_multi_down(void *data, Evas *e, Evas_Object *obj, void *ev)
524 if (!sd || sd->running == EINA_FALSE) return;
526 Evas_Event_Multi_Down *event = (Evas_Event_Multi_Down*)ev;
527 Mouse_Data mouse_data;
531 case TOUCH_STATE_DOWN:
532 case TOUCH_STATE_DRAG:
534 if (sd->numOfTouch == 1)
536 mouse_data.x = event->output.x;
537 mouse_data.y = event->output.y;
538 mouse_data.time = event->timestamp;
539 mouse_data.device = event->device;
540 _smart_set_first_down(sd, 1, &mouse_data);
541 _smart_set_last_down(sd, 1, &mouse_data);
542 _smart_set_last_drag(sd, 1, &mouse_data);
543 _smart_stop_animator_move(sd);
544 _smart_stop_animator_flick(sd);
545 _smart_stop_animator_two_move(sd);
546 _smart_enter_two_down(sd);
550 case TOUCH_STATE_TWO_DOWN:
551 case TOUCH_STATE_TWO_DRAG:
553 if (sd->numOfTouch == 2)
555 mouse_data.x = event->output.x;
556 mouse_data.y = event->output.y;
557 mouse_data.time = event->timestamp;
558 mouse_data.device = event->device;
559 _smart_set_first_down(sd, 2, &mouse_data);
560 _smart_set_last_down(sd, 2, &mouse_data);
561 _smart_set_last_drag(sd, 2, &mouse_data);
562 _smart_stop_animator_move(sd);
563 _smart_stop_animator_flick(sd);
564 _smart_stop_animator_two_move(sd);
565 _smart_enter_three_down(sd);
575 _smart_multi_up(void *data, Evas *e, Evas_Object *obj, void *ev)
578 Evas_Event_Multi_Up *event;
581 if (!sd || sd->running == EINA_FALSE) return;
583 event = (Evas_Event_Multi_Up*)ev;
587 case TOUCH_STATE_TWO_DOWN:
588 _smart_emit_two_tap(sd);
589 _smart_stop_all_timers(sd);
590 _smart_enter_none(sd);
593 case TOUCH_STATE_TWO_DRAG:
594 _smart_stop_animator_two_move(sd);
595 _smart_stop_all_timers(sd);
596 _smart_enter_none(sd);
599 case TOUCH_STATE_THREE_DOWN:
600 _smart_emit_three_tap(sd);
601 _smart_stop_all_timers(sd);
602 _smart_enter_none(sd);
606 _smart_stop_all_timers(sd);
607 _smart_enter_none(sd);
613 _smart_multi_move(void *data, Evas *e, Evas_Object *obj, void *ev)
616 Evas_Event_Multi_Move *event;
617 Mouse_Data mouse_data;
620 if (!sd || sd->running == EINA_FALSE) return;
622 event = (Evas_Event_Multi_Move*)ev;
623 mouse_data.x = event->cur.output.x;
624 mouse_data.y = event->cur.output.y;
625 mouse_data.time = event->timestamp;
626 mouse_data.device = event->device;
630 case TOUCH_STATE_TWO_DOWN:
631 if (sd->first_down[1].device == event->device)
633 _smart_set_last_drag(sd, 1, &mouse_data);
634 sd->two_drag_mode = _smart_check_two_drag_mode(sd);
635 if (sd->two_drag_mode != TWO_DRAG_NONE)
637 DBG("<< sd->two_drag_mode [%d] >>\n", sd->two_drag_mode);
638 _smart_enter_two_drag(sd);
643 case TOUCH_STATE_TWO_DRAG:
644 if (sd->first_down[1].device == event->device)
646 _smart_set_last_drag(sd, 1, &mouse_data);
650 case TOUCH_STATE_THREE_DOWN:
651 if (sd->first_down[1].device == event->device)
653 _smart_set_last_drag(sd, 1, &mouse_data);
655 else if (sd->first_down[2].device == event->device)
657 _smart_set_last_drag(sd, 2, &mouse_data);
668 _smart_animation_move(void *data)
675 DBG("<< animation_move >>\n");
676 // get the position here instead of mouse_move event
677 Evas *evas = evas_object_evas_get(sd->child_obj);
679 evas_pointer_canvas_xy_get(evas, &point.x, &point.y);
680 if (sd->is_one_drag_mode)
682 if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
685 // first_down - location of mouse down
686 // last_down - location where the drag started
687 point.x = sd->last_down[0].x;
689 else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
691 point.y = sd->last_down[0].y;
694 evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
695 return ECORE_CALLBACK_RENEW;
699 _smart_stop_animator_move(sd);
700 _smart_enter_none(sd);
701 return ECORE_CALLBACK_CANCEL;
706 _smart_animation_flick(void *data)
709 Flick_Data *flick_data;
712 flick_data = &(sd->flick_data);
714 if (flick_data && sd->child_obj)
717 float velocity = _smart_velocity_easeinoutcubic(flick_data->flick_index);
718 Evas_Coord dx = flick_data->avg_distance.x * velocity;
719 Evas_Coord dy = flick_data->avg_distance.y * velocity;
720 flick_data->flick_index++;
721 flick_data->last.x += dx;
722 flick_data->last.y += dy;
723 DBG("<< animation_flick |%d|%d|%f| >>\n", dx, dy, ecore_loop_time_get());
725 // stop flick animator
726 if (dx == 0 && dy == 0)
728 _smart_stop_animator_flick(sd);
729 if (sd->state == TOUCH_STATE_DRAG)
730 _smart_enter_none(sd);
731 return ECORE_CALLBACK_CANCEL;
735 Evas_Coord_Point point;
736 point = flick_data->last;
737 if (sd->is_one_drag_mode)
739 if (sd->one_drag_mode == ONE_DRAG_VERTICAL)
741 point.x = sd->first_down[0].x;
743 else if (sd->one_drag_mode == ONE_DRAG_HORIZONTAL)
745 point.y = sd->first_down[0].y;
748 evas_object_smart_callback_call(sd->child_obj, "one,move", &point);
749 return ECORE_CALLBACK_RENEW;
754 _smart_stop_animator_flick(sd);
755 _smart_enter_none(sd);
756 return ECORE_CALLBACK_CANCEL;
761 _smart_animation_two_move(void *data)
769 _smart_emit_two_move(sd);
770 return ECORE_CALLBACK_RENEW;
774 _smart_stop_animator_two_move(sd);
775 _smart_enter_none(sd);
776 return ECORE_CALLBACK_CANCEL;
781 /* state switching */
783 _smart_enter_none(Smart_Data *sd)
786 sd->two_drag_mode = TWO_DRAG_NONE;
787 sd->state = TOUCH_STATE_NONE;
788 DBG("\nTOUCH_STATE_NONE\n");
792 _smart_enter_down(Smart_Data *sd)
795 sd->press_timer = ecore_timer_add(((double)PRESS_TIME)/1000.0, _smart_press_timer_handler, sd);
797 // set long press timer
798 sd->long_press_timer = ecore_timer_add(((double)LONG_HOLD_TIME)/1000.0, _smart_long_press_timer_handler, sd);
800 sd->state = TOUCH_STATE_DOWN;
801 DBG("\nTOUCH_STATE_DOWN\n");
805 _smart_enter_down_up(Smart_Data *sd, int downTime, int time)
807 // remove sd->press_timer and set new timer
808 int timerTime = RELEASE_TIME - (downTime - PRESS_TIME);
811 ecore_timer_del(sd->press_timer);
812 sd->press_timer = NULL;
813 sd->press_release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_press_release_timer_handler, sd);
818 sd->release_timer = ecore_timer_add(((double)timerTime)/1000.0, _smart_release_timer_handler, sd);
821 if (sd->long_press_timer) // remove long press timer
823 ecore_timer_del(sd->long_press_timer);
824 sd->long_press_timer = NULL;
827 sd->state = TOUCH_STATE_DOWN_UP;
828 DBG("\nTOUCH_STATE_DOWN_UP\n");
832 _smart_enter_down_up_down(Smart_Data *sd)
834 if (sd->press_release_timer) // remove press_release_timer
836 ecore_timer_del(sd->press_release_timer);
837 sd->press_release_timer = NULL;
840 if (sd->release_timer) // remove ReleaseTimer
842 ecore_timer_del(sd->release_timer);
843 sd->release_timer = NULL;
846 sd->state = TOUCH_STATE_DOWN_UP_DOWN;
847 DBG("\nTOUCH_STATE_DOWN_UP_DOWN\n");
851 _smart_enter_hold(Smart_Data *sd)
853 sd->state = TOUCH_STATE_HOLD;
854 DBG("\nTOUCH_STATE_HOLD\n");
858 _smart_enter_drag(Smart_Data *sd)
860 if (sd->press_timer) // remove press_timer
862 ecore_timer_del(sd->press_timer);
863 sd->press_timer = NULL;
866 if (sd->press_release_timer) // remove press_release_timer
868 ecore_timer_del(sd->press_release_timer);
869 sd->press_release_timer = NULL;
872 if (sd->release_timer) // remove ReleaseTimer
874 ecore_timer_del(sd->release_timer);
875 sd->release_timer = NULL;
878 if (sd->long_press_timer) // remove long press timer
880 ecore_timer_del(sd->long_press_timer);
881 sd->long_press_timer = NULL;
886 if (sd->is_one_drag_mode)
888 sd->one_drag_mode = ONE_DRAG_NONE;
889 int abs_dx = abs(sd->first_down[0].x - sd->last_drag[0].x);
890 int abs_dy = abs(sd->first_down[0].y - sd->last_drag[0].y);
891 abs_dx = (abs_dx == 0) ? 1 : abs_dx;
892 DBG("<< abs_dx[%d], abs_dy[%d] >>\n\n", abs_dx, abs_dy);
893 float degree = (float)abs_dy / (float)abs_dx;
894 // more than 70 degree
895 if (degree > tan(70 * M_PI / 180))
897 sd->one_drag_mode = ONE_DRAG_VERTICAL;
899 // less than 20 degree
900 else if (degree < tan(20 * M_PI / 180))
902 sd->one_drag_mode = ONE_DRAG_HORIZONTAL;
906 point.x = sd->last_down[0].x;
907 point.y = sd->last_down[0].y;
908 evas_object_smart_callback_call(sd->child_obj, "one,move,start", &point);
910 // initialize flick variables
911 sd->last_move_history_index = -1;
912 sd->move_history_count = 0;
914 sd->animator_move = ecore_animator_add(_smart_animation_move, sd);
915 DBG("<< sd->animator_move >>\n");
916 sd->state = TOUCH_STATE_DRAG;
917 DBG("\nTOUCH_STATE_DRAG\n");
921 sd->state = TOUCH_STATE_NONE;
926 _smart_enter_two_down(Smart_Data *sd)
928 _smart_stop_all_timers(sd);
932 DBG("<< enter two down >>\n");
933 sd->state = TOUCH_STATE_TWO_DOWN;
934 _smart_emit_two_press(sd);
939 _smart_enter_two_drag(Smart_Data *sd)
943 DBG("<< sd->animator_two_move >>\n");
944 sd->state = TOUCH_STATE_TWO_DRAG;
945 _smart_emit_two_move_start(sd);
946 sd->animator_two_move = ecore_animator_add(_smart_animation_two_move, sd);
950 sd->state = TOUCH_STATE_NONE;
955 _smart_enter_three_down(Smart_Data *sd)
959 sd->state = TOUCH_STATE_THREE_DOWN;
960 _smart_emit_three_press(sd);
964 /* producing output events */
966 _smart_emit_press(Smart_Data *sd)
970 DBG("<< emit_press >>\n");
972 point.x = sd->last_down[0].x;
973 point.y = sd->last_down[0].y;
974 evas_object_smart_callback_call(sd->child_obj, "one,press", &point);
979 _smart_emit_tap(Smart_Data *sd)
983 DBG("<< emit_tap >>\n");
985 point.x = sd->last_down[0].x;
986 point.y = sd->last_down[0].y;
987 evas_object_smart_callback_call(sd->child_obj, "one,single,tap", &point);
992 _smart_emit_double_tap(Smart_Data *sd)
996 DBG("<< emit_double_tap >>\n");
998 point.x = sd->last_down[0].x;
999 point.y = sd->last_down[0].y;
1000 evas_object_smart_callback_call(sd->child_obj, "one,double,tap", &point);
1005 _smart_emit_long_hold(Smart_Data *sd)
1009 DBG("<< emit_long_hold >>\n");
1011 point.x = sd->last_down[0].x;
1012 point.y = sd->last_down[0].y;
1013 evas_object_smart_callback_call(sd->child_obj, "one,long,press", &point);
1018 _smart_emit_release(Smart_Data *sd)
1022 DBG("<< emit_release >>\n");
1024 point.x = sd->last_down[0].x;
1025 point.y = sd->last_down[0].y;
1026 evas_object_smart_callback_call(sd->child_obj, "one,release", &point);
1031 _smart_emit_two_press(Smart_Data *sd)
1035 DBG("<< emit_two_press >>\n");
1036 Two_Mouse_Data two_mouse_data;
1037 two_mouse_data.first.x = sd->last_down[0].x;
1038 two_mouse_data.first.y = sd->last_down[0].y;
1039 two_mouse_data.second.x = sd->last_down[1].x;
1040 two_mouse_data.second.y = sd->last_down[1].y;
1041 two_mouse_data.mode = sd->two_drag_mode;
1042 evas_object_smart_callback_call(sd->child_obj, "two,press", &two_mouse_data);
1047 _smart_emit_two_tap(Smart_Data *sd)
1051 DBG("<< emit_two_tap >>\n");
1052 Two_Mouse_Data two_mouse_data;
1053 two_mouse_data.first.x = sd->last_down[0].x;
1054 two_mouse_data.first.y = sd->last_down[0].y;
1055 two_mouse_data.second.x = sd->last_down[1].x;
1056 two_mouse_data.second.y = sd->last_down[1].y;
1057 two_mouse_data.mode = sd->two_drag_mode;
1058 evas_object_smart_callback_call(sd->child_obj, "two,tap", &two_mouse_data);
1063 _smart_emit_two_move_start(Smart_Data *sd)
1067 DBG("<< emit_two_move_start >>\n");
1068 Two_Mouse_Data two_mouse_data;
1069 two_mouse_data.first.x = sd->last_drag[0].x;
1070 two_mouse_data.first.y = sd->last_drag[0].y;
1071 two_mouse_data.second.x = sd->last_drag[1].x;
1072 two_mouse_data.second.y = sd->last_drag[1].y;
1073 two_mouse_data.mode = sd->two_drag_mode;
1074 evas_object_smart_callback_call(sd->child_obj, "two,move,start", &two_mouse_data);
1079 _smart_emit_two_move(Smart_Data *sd)
1083 Two_Mouse_Data two_mouse_data;
1084 two_mouse_data.first.x = sd->last_drag[0].x;
1085 two_mouse_data.first.y = sd->last_drag[0].y;
1086 two_mouse_data.second.x = sd->last_drag[1].x;
1087 two_mouse_data.second.y = sd->last_drag[1].y;
1088 two_mouse_data.mode = sd->two_drag_mode;
1089 evas_object_smart_callback_call(sd->child_obj, "two,move", &two_mouse_data);
1094 _smart_emit_two_move_end(Smart_Data *sd)
1098 DBG("<< emit_two_move_end >>\n");
1099 Two_Mouse_Data two_mouse_data;
1100 two_mouse_data.first.x = sd->last_drag[0].x;
1101 two_mouse_data.first.y = sd->last_drag[0].y;
1102 two_mouse_data.second.x = sd->last_drag[1].x;
1103 two_mouse_data.second.y = sd->last_drag[1].y;
1104 two_mouse_data.mode = sd->two_drag_mode;
1105 evas_object_smart_callback_call(sd->child_obj, "two,move,end", &two_mouse_data);
1110 _smart_emit_three_press(Smart_Data *sd)
1114 DBG("<< emit_three_press >>\n");
1115 Three_Mouse_Data three_mouse_data;
1116 three_mouse_data.first.x = sd->last_drag[0].x;
1117 three_mouse_data.first.y = sd->last_drag[0].y;
1118 three_mouse_data.second.x = sd->last_drag[1].x;
1119 three_mouse_data.second.y = sd->last_drag[1].y;
1120 three_mouse_data.third.x = sd->last_drag[2].x;
1121 three_mouse_data.third.y = sd->last_drag[2].y;
1122 evas_object_smart_callback_call(sd->child_obj, "three,press", &three_mouse_data);
1127 _smart_emit_three_tap(Smart_Data *sd)
1131 DBG("<< emit_three_tap >>\n");
1132 Three_Mouse_Data three_mouse_data;
1133 three_mouse_data.first.x = sd->last_drag[0].x;
1134 three_mouse_data.first.y = sd->last_drag[0].y;
1135 three_mouse_data.second.x = sd->last_drag[1].x;
1136 three_mouse_data.second.y = sd->last_drag[1].y;
1137 three_mouse_data.third.x = sd->last_drag[2].x;
1138 three_mouse_data.third.y = sd->last_drag[2].y;
1139 evas_object_smart_callback_call(sd->child_obj, "three,tap", &three_mouse_data);
1143 /* timer event handling */
1145 _smart_press_timer_handler(void *data)
1150 _smart_emit_press(sd);
1151 sd->press_timer = NULL;
1152 return ECORE_CALLBACK_CANCEL;
1156 _smart_long_press_timer_handler(void *data)
1161 _smart_emit_long_hold(sd);
1162 _smart_enter_hold(sd);
1163 sd->long_press_timer = NULL;
1164 return ECORE_CALLBACK_CANCEL;
1168 _smart_release_timer_handler(void *data)
1173 _smart_emit_tap(sd);
1174 _smart_stop_all_timers(sd);
1175 _smart_enter_none(sd);
1176 sd->release_timer = NULL;
1177 return ECORE_CALLBACK_CANCEL;
1181 _smart_press_release_timer_handler(void *data)
1183 static int prevent_handler = 0;
1184 if (prevent_handler != 0) return ECORE_CALLBACK_CANCEL;
1185 prevent_handler = 1;
1189 _smart_emit_press(sd);
1190 _smart_emit_tap(sd);
1191 _smart_stop_all_timers(sd);
1192 _smart_enter_none(sd);
1193 sd->press_release_timer = NULL;
1194 prevent_handler = 0;
1195 return ECORE_CALLBACK_CANCEL;
1198 /* other functions */
1200 _smart_save_move_history(Smart_Data *sd, int x, int y, int dx, int dy)
1202 // save pan information to the pan history
1203 int index = (sd->last_move_history_index + 1) % MOVE_HISTORY_SIZE;
1204 sd->last_move_history_index = index;
1205 sd->move_history[index].dx = dx;
1206 sd->move_history[index].dy = dy;
1207 sd->move_history[index].time = ecore_time_get();
1208 sd->move_history_count++;
1212 _smart_start_flick(Smart_Data *sd)
1214 if (sd->animator_move)
1216 ecore_animator_del(sd->animator_move);
1217 DBG("<< stop_animator_move >>\n");
1218 sd->animator_move = NULL;
1221 // accumulate sd->move_history data
1225 int index = sd->last_move_history_index;
1226 int todo = sd->move_history_count > MOVE_HISTORY_SIZE ? MOVE_HISTORY_SIZE : sd->move_history_count;
1228 double endTime = (sd->move_history + index)->time;
1229 double startTime = endTime;
1230 for( ; todo > 0; todo--) {
1231 p = sd->move_history + index; // get one sd->move_history
1234 startTime = p->time;
1239 if ((endTime - startTime) > 0.2 && nSamples > 0)
1242 index = (index > 0) ? (index - 1) : (MOVE_HISTORY_SIZE - 1); // set index
1244 double totalTime = endTime - startTime;
1245 if (totalTime < DOUBLE_ERROR)
1248 // calculate average pan_dx and pan_dy (per 1 / DEFAULT_FRAMERATE ms)
1249 double temp = totalTime * DEFAULT_FRAMERATE;
1253 Flick_Data *flick_data = &sd->flick_data;
1254 flick_data->avg_distance.x = totalDx / temp;
1255 flick_data->avg_distance.y = totalDy / temp;
1257 // set max value for pan_dx and pan_dy
1258 int abs_pan_dx = abs(flick_data->avg_distance.x);
1259 int abs_pan_dy = abs(flick_data->avg_distance.y);
1260 if ((abs_pan_dx > MAX_MOVE_DISTANCE) && (abs_pan_dx > abs_pan_dy))
1262 flick_data->avg_distance.x = (flick_data->avg_distance.x > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1263 flick_data->avg_distance.y = flick_data->avg_distance.y * MAX_MOVE_DISTANCE / abs_pan_dx;
1266 else if ((abs_pan_dy > MAX_MOVE_DISTANCE) && (abs_pan_dy > abs_pan_dx))
1268 flick_data->avg_distance.y = (flick_data->avg_distance.y > 0) ? MAX_MOVE_DISTANCE : -MAX_MOVE_DISTANCE;
1269 flick_data->avg_distance.x = flick_data->avg_distance.x * MAX_MOVE_DISTANCE / abs_pan_dy;
1272 if (abs_pan_dx > FLICK_THRESHOLD || abs_pan_dy > FLICK_THRESHOLD)
1274 // set flick_data and start flick
1275 flick_data->last.x = sd->last_drag[0].x;
1276 flick_data->last.y = sd->last_drag[0].y;
1277 flick_data->flick_index = 0;
1278 sd->animator_flick = ecore_animator_add(_smart_animation_flick, sd);
1279 DBG("<< sd->animator_flick >>\n");
1284 point.x = sd->last_drag[0].x;
1285 point.y = sd->last_drag[0].y;
1286 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1287 _smart_enter_none(sd);
1292 _smart_emit_release(sd);
1293 _smart_stop_all_timers(sd);
1294 _smart_enter_none(sd);
1299 _smart_stop_animator_move(Smart_Data *sd)
1301 if (sd->animator_move)
1303 ecore_animator_del(sd->animator_move);
1304 DBG("<< stop_animator_move >>\n");
1305 sd->animator_move = NULL;
1307 point.x = sd->last_drag[0].x;
1308 point.y = sd->last_drag[0].y;
1309 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1314 _smart_stop_animator_flick(Smart_Data *sd)
1316 if (sd->animator_flick)
1318 ecore_animator_del(sd->animator_flick);
1319 DBG("<< stop_animator_flick >>\n");
1320 sd->animator_flick = NULL;
1321 Evas_Coord_Point point;
1322 point = sd->flick_data.last;
1323 evas_object_smart_callback_call(sd->child_obj, "one,move,end", &point);
1328 _smart_stop_animator_two_move(Smart_Data *sd)
1330 if (sd->animator_two_move)
1332 ecore_animator_del(sd->animator_two_move);
1333 DBG("<< stop_animator_two_move >>\n");
1334 sd->animator_two_move = NULL;
1335 _smart_emit_two_move_end(sd);
1339 static Two_Drag_Mode
1340 _smart_check_two_drag_mode(Smart_Data *sd)
1342 // get distance from press to current position
1343 int dx0 = sd->last_drag[0].x - sd->first_down[0].x;
1344 int dy0 = sd->last_drag[0].y - sd->first_down[0].y;
1345 int dx1 = sd->last_drag[1].x - sd->first_down[1].x;
1346 int dy1 = sd->last_drag[1].y - sd->first_down[1].y;
1351 if ((abs(dx1) >= MOVE_THRESHOLD) || (abs(dy1) >= MOVE_THRESHOLD))
1356 else if ((abs(dx0) >= MOVE_THRESHOLD) || (abs(dy0) >= MOVE_THRESHOLD))
1363 return TWO_DRAG_NONE;
1367 if ((abs(dx) > abs(dy)) && ((dx0 > 0 && dx1 > 0) || (dx0 < 0 && dx1 < 0)))
1369 dy = (dy == 0) ? 1 : dy;
1370 // less than 30 degree (1024/root(3) = 591)
1371 if (((abs(dy) << 10) / abs(dx)) < 591)
1373 return TWO_DRAG_HORIZONTAL;
1378 if ((abs(dy) > abs(dx)) && ((dy0 > 0 && dy1 > 0) || (dy0 < 0 && dy1 < 0)))
1380 dx = (dx == 0) ? 1 : dx;
1381 // more than 60 degree (1024 * root(3)/1 = 1773)
1382 if (((abs(dy) << 10) / abs(dx)) > 1773)
1384 return TWO_DRAG_VERTICAL;
1389 int distanceX = abs(abs(sd->first_down[0].x - sd->first_down[1].x)
1390 - abs(sd->last_drag[0].x - sd->last_drag[1].x));
1391 int distanceY = abs(abs(sd->first_down[0].y - sd->first_down[1].y)
1392 - abs(sd->last_drag[0].y - sd->last_drag[1].y));
1393 if ((distanceX > FINGER_DISTANCE) || (distanceY > FINGER_DISTANCE))
1395 return TWO_DRAG_PINCH;
1398 return TWO_DRAG_NONE;
1402 _smart_set_first_down(Smart_Data *sd, int index, Mouse_Data *data)
1404 if (index > N_FINGER)
1409 if ((sd->screen_angle == 270) && (index > 0))
1411 sd->first_down[index].x = data->y;
1412 sd->first_down[index].y = data->x;
1413 sd->first_down[index].time = data->time;
1414 sd->first_down[index].device = data->device;
1418 sd->first_down[index].x = data->x;
1419 sd->first_down[index].y = data->y;
1420 sd->first_down[index].time = data->time;
1421 sd->first_down[index].device = data->device;
1426 _smart_set_last_down(Smart_Data *sd, int index, Mouse_Data *data)
1428 if (index > N_FINGER)
1433 if ((sd->screen_angle == 270) && (index > 0))
1435 sd->last_down[index].x = data->y;
1436 sd->last_down[index].y = data->x;
1437 sd->last_down[index].time = data->time;
1438 sd->last_down[index].device = data->device;
1442 sd->last_down[index].x = data->x;
1443 sd->last_down[index].y = data->y;
1444 sd->last_down[index].time = data->time;
1445 sd->last_down[index].device = data->device;
1450 _smart_set_last_drag(Smart_Data *sd, int index, Mouse_Data *data)
1452 if (index > N_FINGER)
1457 if ((sd->screen_angle == 270) && (index > 0))
1459 sd->last_drag[index].x = data->y;
1460 sd->last_drag[index].y = data->x;
1461 sd->last_drag[index].time = data->time;
1462 sd->last_drag[index].device = data->device;
1466 sd->last_drag[index].x = data->x;
1467 sd->last_drag[index].y = data->y;
1468 sd->last_drag[index].time = data->time;
1469 sd->last_drag[index].device = data->device;
1474 _smart_stop_all_timers(Smart_Data *sd)
1476 if (sd->press_timer) // remove sd->press_timer
1478 ecore_timer_del(sd->press_timer);
1479 sd->press_timer = NULL;
1482 if (sd->long_press_timer) // remove long press timer
1484 ecore_timer_del(sd->long_press_timer);
1485 sd->long_press_timer = NULL;
1488 if (sd->release_timer) // remove release timer
1490 ecore_timer_del(sd->release_timer);
1491 sd->release_timer = NULL;
1494 if (sd->press_release_timer) // remove pressRelease timer
1496 ecore_timer_del(sd->press_release_timer);
1497 sd->press_release_timer = NULL;
1502 _smart_add(Evas_Object *obj)
1506 sd = calloc(1, sizeof(Smart_Data));
1508 memset((void *)sd, 0x00, sizeof(Smart_Data));
1510 sd->smart_obj = obj;
1512 // set default framerate
1513 ecore_animator_frametime_set(1.0 / DEFAULT_FRAMERATE);
1515 evas_object_smart_data_set(obj, sd);
1519 _smart_del(Evas_Object *obj)
1524 if (sd->press_timer)
1525 ecore_timer_del(sd->press_timer);
1527 if (sd->long_press_timer)
1528 ecore_timer_del(sd->long_press_timer);
1530 if (sd->release_timer)
1531 ecore_timer_del(sd->release_timer);
1533 if (sd->press_release_timer)
1534 ecore_timer_del(sd->press_release_timer);
1536 if (sd->animator_move)
1537 ecore_animator_del(sd->animator_move);
1539 if (sd->animator_flick)
1540 ecore_animator_del(sd->animator_flick);
1542 if (sd->animator_two_move)
1543 ecore_animator_del(sd->animator_two_move);
1547 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_DOWN, _smart_mouse_down);
1548 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_UP, _smart_mouse_up);
1549 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MOUSE_MOVE, _smart_mouse_move);
1550 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_DOWN, _smart_multi_down);
1551 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_UP, _smart_multi_up);
1552 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_MULTI_MOVE, _smart_multi_move);
1564 static const Evas_Smart_Class sc =
1567 EVAS_SMART_CLASS_VERSION,
1585 _smart = evas_smart_class_new(&sc);