[src/lib/elm_button.c, src/lib/elm_imageslider.c] Fixed Compilation Warnings.
[framework/uifw/elementary.git] / src / lib / elm_imageslider.c
1 /* 
2
3 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 
4 */
5 #include <stdio.h>
6 #include <math.h>
7 #include <Elementary.h>
8 #include "elm_priv.h"
9
10 /**
11 * @defgroup Imageslider Imageslider
12 * @ingroup Elementary
13 *
14 * By flicking images on the screen, 
15 * you can see the images in specific path.
16 */
17
18 typedef struct _Widget_Data Widget_Data;
19
20 #define ANI_STEP                        (14 * elm_scale_get())
21 #define ANI_TIME                        (0.005)
22 #define ANI_TIME_MSEC           (12)
23 #define CLICK_TIME_MAX          (180)
24 #define CLICK_WIDTH_MIN         (elm_finger_size_get() >> 1)
25 #define FLICK_TIME_MAX          (200)
26 #define FLICK_WIDTH_MIN         (elm_finger_size_get() >> 2)
27 #define MOVE_STEP                       (3)
28 #define STEP_WEIGHT_DEF         (1)
29 #define STEP_WEIGHT_MAX         (2)
30 #define STEP_WEIGHT_MIN         (0)
31 #define MOVING_IMAGE_SIZE       (128)
32 #define MAX_ZOOM_SIZE           (6)
33 #define INTERVAL_WIDTH          (15)
34 #define MULTITOUCHDEVICE        (11)
35
36 // Enumeration for layout.
37 enum {
38         BLOCK_LEFT = 0,
39         BLOCK_CENTER,
40         BLOCK_RIGHT,
41         BLOCK_MAX
42 };
43
44
45 // Image Slider Item.
46 struct _Imageslider_Item 
47 {
48         Evas_Object *obj;
49         const char *photo_file;
50         void (*func)(void *data, Evas_Object *obj, void *event_info);
51         void *data;
52         Evas_Coord x, y, w, h;
53         Evas_Coord ox, oy, ow, oh;
54         int moving : 1;
55 };
56
57 // Image Slider Widget Data.
58 struct _Widget_Data
59 {
60         Evas_Object *ly[BLOCK_MAX];
61         Evas_Object *clip;
62         Eina_List *its;
63         Eina_List *cur;
64         Evas_Coord x, y, w, h;
65         Evas_Object *obj;
66         Ecore_Idler *queue_idler;
67         Ecore_Timer *anim_timer;
68
69         Evas_Coord_Point down_pos;
70         Evas_Coord move_x;
71         Evas_Coord move_y;
72         Evas_Coord dest_x;
73         struct timeval tv;
74         unsigned int timestamp;
75         int step;
76         int move_cnt;
77         int ani_lock : 1;
78         int moving : 1;
79
80         Eina_Bool on_zoom : 1;
81         Eina_Bool on_hold : 1;
82         int dx, dy, mx, my;
83         int mdx, mdy, mmx, mmy;
84         int dratio;
85         int ratio;
86 };
87
88 // Global value definition.
89 static const char *widtype = NULL;
90 static const char SIG_CLICKED[] = "clicked";
91
92 // Internal function definition.
93 static void _del_hook(Evas_Object *obj);
94 static void _theme_hook(Evas_Object *obj);
95 static void _sizing_eval(Evas_Object *obj);
96 static void _imageslider_del_all(Widget_Data *wd);
97 static void _imageslider_move(void *data,Evas *e, Evas_Object *obj, void *event_info);
98 static void _imageslider_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
99 static void _imageslider_show(void * data, Evas * e, Evas_Object * obj, void * event_info);
100 static void _imageslider_hide(void * data, Evas * e, Evas_Object * obj, void * event_info);
101 static void _imageslider_update(Widget_Data *wd);
102 static void _imageslider_update_pos(Widget_Data *wd, Evas_Coord x, Evas_Coord y, Evas_Coord w);
103 static void _imageslider_update_center_pos(Widget_Data *wd, Evas_Coord x, Evas_Coord my, Evas_Coord y, Evas_Coord w);
104 static Evas_Object *_imageslider_add_obj(Widget_Data *wd);
105 static void _imageslider_obj_shift(Widget_Data *wd, Eina_Bool left);
106 static void _imageslider_obj_move(Widget_Data *wd, Evas_Coord step);
107 static Eina_Bool _icon_to_image(void *data);
108 static int _check_drag(int state, void *data);
109 static void _check_zoom(void *data);
110 static void _anim(Widget_Data *wd);
111 static Eina_Bool _timer_cb(void *data);
112 //static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
113 static void ev_imageslider_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
114 static void ev_imageslider_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
115 static void ev_imageslider_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
116
117
118 // Whenever the Image Slider item is deleted, Call this funtion.
119 static void _del_hook(Evas_Object * obj)
120 {
121         int i;
122         Widget_Data * wd;
123         wd = elm_widget_data_get(obj);
124         
125         if (!wd) return;
126
127         for (i = 0; i < BLOCK_MAX; i++) {
128                 evas_object_del(wd->ly[i]);
129         }
130
131         if (wd->its) {
132                 eina_list_free(wd->its);
133                 wd->its = NULL;
134         }
135
136         if (wd->queue_idler) {
137                 ecore_idler_del(wd->queue_idler);
138                 wd->queue_idler = NULL;         
139         }
140
141         if (wd->anim_timer) {
142                 ecore_timer_del(wd->anim_timer);
143                 wd->anim_timer = NULL;
144         }
145
146         if (wd) free(wd);
147         
148 }
149
150 // Whenever require processing theme, Call this function
151 static void _theme_hook(Evas_Object * obj)
152 {
153         int i;
154         Widget_Data *wd;
155         wd = elm_widget_data_get(obj);
156
157         if (!wd || !wd->ly ) {
158                 return;
159         }
160
161         for (i=0; i < BLOCK_MAX; i++) {
162                 wd->ly[i] = elm_layout_add(obj);
163                 _elm_theme_object_set(obj, wd->ly[i], "imageslider", "base", "default");
164                 elm_widget_resize_object_set(obj, wd->ly[i]);
165                 evas_object_show(wd->ly[i]);                    
166         }
167
168         _sizing_eval(obj);      
169 }
170
171 // Resize Image Slider item.
172 static void _sizing_eval(Evas_Object * obj)
173 {
174         Evas *e;
175         Widget_Data *wd = elm_widget_data_get(obj);
176
177         if (!wd) {
178                 return;
179         }
180
181         e = evas_object_evas_get(wd->obj);
182
183         _imageslider_move(obj, e, obj, NULL);
184         _imageslider_resize(obj, e, obj, NULL);
185
186 }
187
188 // Whenever MOVE event occurs, Call this function.
189 static void _imageslider_move(void * data, Evas * e, Evas_Object * obj, void * event_info)
190 {
191         Widget_Data *wd;
192         Evas_Coord x, y;
193
194         if (!data) {
195                 return;
196         }
197         
198         wd = elm_widget_data_get((Evas_Object *) data);
199         if (!wd) {
200                 return;
201         }
202
203         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
204         wd->x = x;
205         wd->y = y;
206         evas_object_move(wd->clip, x, y);
207         
208         _imageslider_update_pos(wd, wd->x, wd->y, wd->w);
209         
210 }
211
212 // Whenever RESIZE event occurs, Call this fucntion.
213 static void _imageslider_resize(void * data, Evas * e, Evas_Object * obj, void * event_info)
214 {
215         int i;
216         Widget_Data *wd;
217         Evas_Coord w, h;
218
219         if (!data) {
220                 return;
221         }
222                 
223         wd = elm_widget_data_get((Evas_Object *) data);
224         if (!wd || !wd->ly) {
225                 return;         
226         }
227
228         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
229         fprintf( stderr, "%d %d -resize\n" , w, h );
230         wd->w = w;
231         wd->h = h;
232
233         for (i = 0; i < BLOCK_MAX; i++) {
234                 evas_object_resize(wd->ly[i], w, h);
235         }
236
237         evas_object_resize(wd->clip, w, h);
238
239         _imageslider_update_pos(wd, wd->x, wd->y, wd->w);
240         
241 }
242
243 // Whenever SHOW event occurs, Call this function.
244 static void _imageslider_show(void *data, Evas *e, Evas_Object * obj, void *event_info)
245 {
246         Widget_Data *wd;
247
248         if (!data) {
249                 return;
250         }
251         
252         wd = elm_widget_data_get((Evas_Object *) data);
253         if (!wd) {
254                 return;
255         }
256         
257         evas_object_show(wd->clip);
258 }
259
260 // Whenever HIDE event occurs, Call this function.
261 static void _imageslider_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
262 {
263         Widget_Data *wd;
264
265         if (!data) {
266                 return;
267         }
268         
269         wd = elm_widget_data_get((Evas_Object *) data);
270         if (!wd) {
271                 return;
272         }
273         evas_object_hide(wd->clip);
274 }
275
276 // Delete all Image Slider items.
277 static void _imageslider_del_all(Widget_Data * wd)
278 {
279    
280         int i;
281
282         if (!wd) {
283                 return;
284         }
285
286         for (i = 0; i < BLOCK_MAX; i++) {
287                 evas_object_del(wd->ly[i]);
288         }
289 }
290
291 // Update Image Slider item position.
292 static void _imageslider_update_pos(Widget_Data * wd, Evas_Coord x, Evas_Coord y, Evas_Coord w)
293 {
294         evas_object_move(wd->ly[BLOCK_LEFT], x - (w + INTERVAL_WIDTH), y);
295         evas_object_move(wd->ly[BLOCK_CENTER], x, y);
296         evas_object_move(wd->ly[BLOCK_RIGHT], x + (w + INTERVAL_WIDTH), y);
297         evas_render_idle_flush(evas_object_evas_get(wd->obj));
298 }
299
300 // Update the center position of Image Slider item.
301 static void _imageslider_update_center_pos(Widget_Data * wd, Evas_Coord x, Evas_Coord my, Evas_Coord y, Evas_Coord w)
302 {
303         Evas_Object *eo;
304         Evas_Coord ix, iy, iw, ih;
305
306         eo = edje_object_part_swallow_get(elm_layout_edje_get(wd->ly[BLOCK_CENTER]), "swl.photo");
307         evas_object_geometry_get(eo, &ix, &iy, &iw, &ih);
308
309         if ((ix > 0) || (ix + iw < wd->w)) {
310                 edje_object_signal_emit(elm_layout_edje_get(wd->ly[BLOCK_CENTER]), "block.on", "block");
311                 _imageslider_update_pos(wd, x, y, w);
312                 wd->on_zoom = EINA_FALSE;
313         }
314 }
315
316 // Add previous/next Image Slider item.
317 static Evas_Object *_imageslider_add_obj(Widget_Data *wd)
318 {
319         Evas_Object *eo;
320         eo = elm_layout_add(wd->obj);
321         elm_layout_theme_set(eo, "imageslider", "base", "default");
322         elm_widget_resize_object_set(wd->obj, eo);
323         //evas_object_smart_member_add(eo, wd->obj);
324
325         //edje_object_signal_callback_add(elm_layout_edje_get(eo), "elm,photo,clicked", "", _signal_clicked, wd->obj);
326         evas_object_event_callback_add(eo, EVAS_CALLBACK_MOUSE_DOWN, ev_imageslider_down_cb, wd);
327         evas_object_event_callback_add(eo, EVAS_CALLBACK_MOUSE_UP, ev_imageslider_up_cb, wd);
328         evas_object_event_callback_add(eo, EVAS_CALLBACK_MOUSE_MOVE, ev_imageslider_move_cb, wd);
329         evas_object_resize(eo, wd->w, wd->h);
330         evas_object_move(eo, wd->w + INTERVAL_WIDTH, wd->y);
331         evas_object_clip_set(eo, wd->clip);
332         evas_object_show(eo);
333
334         return eo;
335 }
336
337 // Shift next/previous Image Slider item in layouts.
338 static void _imageslider_obj_shift(Widget_Data *wd, Eina_Bool left)
339 {
340         if (!left) {
341                 if (wd->ly[BLOCK_LEFT]) {
342                         evas_object_del(wd->ly[BLOCK_LEFT]);
343                         wd->ly[BLOCK_LEFT] = NULL;
344                 }
345
346                 wd->ly[BLOCK_LEFT] = wd->ly[BLOCK_CENTER];
347                 wd->ly[BLOCK_CENTER]= wd->ly[BLOCK_RIGHT];
348                 wd->ly[BLOCK_RIGHT] = _imageslider_add_obj(wd);
349         } else {
350                 if (wd->ly[BLOCK_RIGHT]) {
351                         evas_object_del(wd->ly[BLOCK_RIGHT]);
352                         wd->ly[BLOCK_RIGHT] = NULL;
353                 }
354
355                 wd->ly[BLOCK_RIGHT]= wd->ly[BLOCK_CENTER];
356                 wd->ly[BLOCK_CENTER]= wd->ly[BLOCK_LEFT];
357                 wd->ly[BLOCK_LEFT]= _imageslider_add_obj(wd);
358         }
359 }
360
361 // Move the current Image Slider item and update.
362 static void _imageslider_obj_move(Widget_Data * wd, Evas_Coord step)
363 {
364         if (step > 0) {
365                 wd->cur = eina_list_next(wd->cur);
366                 if (wd->cur == NULL) {
367                         wd->cur = eina_list_last(wd->its);
368                         wd->step = ANI_STEP;
369                 } else {
370                         wd->step = -ANI_STEP;
371                         wd->move_x += wd->w;
372                         _imageslider_obj_shift(wd, 0);
373                 }
374                 wd->moving = 1;         
375         } else if (step < 0) {
376                 wd->cur = eina_list_prev(wd->cur);
377                 if (wd->cur == NULL) {
378                         wd->cur = wd->its;
379                         wd->step = -ANI_STEP;
380                 } else {
381                         wd->step = ANI_STEP;
382                         wd->move_x -= wd->w;
383                         _imageslider_obj_shift(wd, 1);
384                 }
385                 wd->moving = 1;
386         } else {
387                 if (wd->move_x < 0) wd->step = ANI_STEP;
388                 else wd->step = -ANI_STEP;
389                 wd->moving = 0;
390         }
391
392         _imageslider_update(wd);
393 }
394
395 // Whenever MOUSE DOWN event occurs, Call this function.
396 static void ev_imageslider_down_cb(void * data, Evas * e, Evas_Object * obj, void * event_info)
397 {
398         Widget_Data *wd = data;
399         Evas_Event_Mouse_Down *ev = event_info;
400         Evas_Coord ix, iy, iw, ih;
401         Evas_Object *eo = NULL;
402
403         if (wd->ani_lock) return;
404
405         wd->down_pos = ev->canvas;
406         wd->timestamp = ev->timestamp;
407         wd->move_cnt = MOVE_STEP;
408
409         wd->dx = ev->canvas.x;
410         wd->dy = ev->canvas.y;
411         wd->mx = ev->canvas.x;
412         wd->my = ev->canvas.y;
413
414         wd->dratio = 1;
415         wd->ratio = 1;
416
417         eo = edje_object_part_swallow_get(elm_layout_edje_get(obj), "swl.photo");
418         if (eo) evas_object_geometry_get(eo, &ix, &iy, &iw, &ih);
419
420         if (iw != wd->w) {
421                 wd->on_zoom = EINA_TRUE;
422                 edje_object_signal_emit(elm_layout_edje_get(obj), "block.off", "block");
423 //              edje_thaw();            
424         }
425
426 }
427
428 // Whenever MOUSE UP event occurs, Call this function.
429 // And make Click Event also.
430 static void ev_imageslider_up_cb(void * data, Evas * e, Evas_Object * obj, void * event_info)
431 {
432         Widget_Data *wd = data;
433         Evas_Event_Mouse_Up *ev = event_info;
434         Evas_Coord step;
435         int interval;
436
437         if (wd->ani_lock) return;
438
439         if (wd->on_zoom) {              
440         } else {
441                 step = wd->down_pos.x - ev->canvas.x;
442                 interval = ev->timestamp - wd->timestamp;
443                 if (step == 0 || interval == 0) {
444                      fprintf(stderr, "[[[ DEBUG ]]]: case1: emit CLICK event\n");
445                      evas_object_smart_callback_call(wd->obj, SIG_CLICKED, NULL);
446                      return;
447                 }
448                 if (interval < CLICK_TIME_MAX) {
449                         if (step < CLICK_WIDTH_MIN && step > CLICK_WIDTH_MIN) {
450                                 fprintf(stderr, "[[[ DEBUG ]]]: case2: emit CLICK event\n");
451                                 evas_object_smart_callback_call(wd->obj, SIG_CLICKED, NULL);                    
452                                 return;
453                         }
454                 }
455
456                 if (interval < FLICK_TIME_MAX) {
457                       
458                         if (step < FLICK_WIDTH_MIN && step > FLICK_WIDTH_MIN) {
459                              fprintf(stderr, "[[[ DEBUG ]]]:ev_imageslider_up_cb-black zone (1)\n");
460                              
461                              _imageslider_obj_move(wd, 0);
462                         } else {
463                              fprintf(stderr, "[[[ DEBUG ]]]:ev_imageslider_up_cb-black zone (2)\n");
464
465                              _imageslider_obj_move(wd, step);
466                         }
467                         
468                 } else {
469                         step = (wd->x - wd->move_x) << 1;
470                         if (step <= wd->w && step >= -(wd->w)) {
471                              fprintf(stderr, "[[[ DEBUG ]]]:ev_imageslider_up_cb-white zone (1)\n");
472
473                              _imageslider_obj_move(wd, 0);
474                         } else {
475                              fprintf(stderr, "[[[ DEBUG ]]]:ev_imageslider_up_cb-white zone (2)\n");
476
477                              _imageslider_obj_move(wd, step);
478                         }
479                 }
480         }
481
482 }
483
484 // Whenever MOUSE MOVE event occurs, Call this API.
485 static void ev_imageslider_move_cb(void * data, Evas * e, Evas_Object * obj, void * event_info)
486 {
487         int idx;
488         Evas_Object *eo;
489         Evas_Coord step;
490         Widget_Data *wd = data;
491         Evas_Event_Mouse_Move *ev = event_info;
492         Elm_Imageslider_Item *it;
493
494         if (wd->ani_lock) return;
495
496         if (wd->move_cnt == MOVE_STEP) {
497                 if (wd->on_hold == EINA_FALSE) {
498                         wd->move_cnt = 0;
499
500                         if (ev->buttons) {
501                                 step = ev->cur.canvas.x - wd->down_pos.x;
502                                 if (step > 0) idx = BLOCK_LEFT;
503                                 else idx = BLOCK_RIGHT;
504
505                                 wd->move_x = wd->x + ((ev->cur.canvas.x - wd->down_pos.x));
506                                 wd->move_y = wd->y + ((ev->cur.canvas.y - wd->down_pos.y));
507
508                                 if (wd->on_zoom) {
509                                         _imageslider_update_center_pos(wd, wd->move_x, wd->move_y, wd->y, wd->w);
510                                 } else {
511                                         _imageslider_update_pos(wd, wd->move_x, wd->y, wd->w);
512                                 }
513                         }
514                 } else {
515                         wd->mx = ev->cur.canvas.x;
516                         wd->my = ev->cur.canvas.y;
517
518                         wd->ratio = sqrt((wd->mx -wd->mmx)*(wd->mx -wd->mmx) + (wd->my - wd->mmy)*(wd->my - wd->mmy));
519
520                         eo = edje_object_part_swallow_get(elm_layout_edje_get(obj), "swl.photo");
521                         if (eo) {
522                                 it = eina_list_data_get(wd->cur);
523                                 if (((it->w * wd->ratio/wd->dratio)/it->ow) < MAX_ZOOM_SIZE ) {
524                                         edje_object_part_unswallow(elm_layout_edje_get(obj), eo);
525                                         evas_object_resize(eo, it->w * wd->ratio/wd->dratio, it->h * wd->ratio/wd->dratio);
526                                         evas_object_size_hint_min_set(eo, it->w * wd->ratio/wd->dratio, it->h * wd->ratio/wd->dratio);
527                                         edje_object_part_swallow(elm_layout_edje_get(obj), "swl.photo", eo);
528                                 }
529                         }                       
530                 }
531         }
532
533         wd->move_cnt++;
534
535 }
536
537 #if 0
538 // Whenever CLICK event occurs, Call this API
539 // But, DONOT emit CLICK event.
540 // DO NOT use this callback function. Remove later.
541 static void
542 _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
543 {
544         fprintf(stderr, "[[[ DEBUG ]]]: Call the callback function about Click event!, But DONOT emit CLICK event in the callback function!\n");
545 }
546 #endif
547
548 static inline double time_get(Evas_Coord x, Evas_Coord w)
549 {
550         double time;
551         time = (-sin(x / w) + 1) / 500;
552
553         if (time == 0) time = ANI_TIME;
554         
555         return time;
556 }
557
558 static Eina_Bool _icon_to_image(void *data)
559 {
560         Widget_Data *wd = data;
561         wd->moving = 0;
562         _imageslider_update(wd);
563
564         if (wd->queue_idler) {
565                 ecore_idler_del(wd->queue_idler);
566                 wd->queue_idler = NULL;
567         }
568         return ECORE_CALLBACK_CANCEL;
569 }
570
571 static int _check_drag(int state, void *data)
572 {
573         Widget_Data *wd = data;
574         Elm_Imageslider_Item *it;
575         Evas_Coord ix, iy, iw, ih;
576         double dx, dy = 0;
577         Eina_List *l[BLOCK_MAX];
578         Evas_Object *eo = NULL;
579         l[BLOCK_LEFT] = eina_list_prev(wd->cur);
580         l[BLOCK_CENTER] = wd->cur;
581         l[BLOCK_RIGHT] = eina_list_next(wd->cur);
582
583         it = eina_list_data_get(l[state]);
584
585         eo = edje_object_part_swallow_get(elm_layout_edje_get(wd->ly[state]), "swl.photo");
586         if (eo) evas_object_geometry_get(eo, &ix, &iy, &iw, &ih);
587         evas_object_geometry_get(eo, &ix, &iy, &iw, &ih);
588         edje_object_part_drag_value_get(elm_layout_edje_get(wd->ly[state]), "swl.photo", &dx, &dy);
589
590         if ((iw != wd->w) || ((dx != 0 ) || (dy != 0 ))) {
591                 if (wd->ly[state]) {
592                         evas_object_del(wd->ly[state]);
593                         wd->ly[state] = NULL;
594                 }
595                 wd->ly[state] = _imageslider_add_obj(wd);
596         } else {
597                 return 1;
598         }
599
600         return 0;
601 }
602
603
604 static void _check_zoom(void *data)
605 {
606         Widget_Data *wd = data;
607         Elm_Imageslider_Item *it;
608         Evas_Coord ix, iy, iw, ih;
609         double dx, dy = 0;
610         Evas_Object *eo = NULL;
611
612         it = eina_list_data_get(wd->cur);
613
614         eo = edje_object_part_swallow_get(elm_layout_edje_get(wd->ly[BLOCK_CENTER]), "swl.photo");
615         if (eo) evas_object_geometry_get(eo, &ix, &iy, &iw, &ih);
616         evas_object_geometry_get(eo, &ix, &iy, &iw, &ih);
617         edje_object_part_drag_value_get(elm_layout_edje_get(wd->ly[BLOCK_CENTER]), "swl.photo", &dx, &dy);
618
619         if ((iw != wd->w) || ((dx != 0) || (dy != 0))) {
620                 wd->on_zoom = EINA_TRUE;
621                 edje_object_signal_emit(elm_layout_edje_get(wd->ly[BLOCK_CENTER]), "block.off", "block");
622 //              edje_thaw();
623         } else {
624                 wd->on_zoom = EINA_FALSE;
625                 edje_object_signal_emit(elm_layout_edje_get(wd->ly[BLOCK_CENTER]), "block.on", "block");
626 //              edje_freeze();
627         }
628 }
629
630 static Eina_Bool _timer_cb(void *data)
631 {
632         Widget_Data *wd;
633         Elm_Imageslider_Item *it;
634         struct timeval tv;
635         int t;
636         int ret;
637         wd = data;
638         if (wd->ani_lock == 0 ) return 0;
639
640         gettimeofday(&tv, NULL);
641
642         t = (tv.tv_sec - wd->tv.tv_sec) * 1000 + (tv.tv_usec - wd->tv.tv_usec) / 1000;
643         gettimeofday(&wd->tv, NULL);
644
645         t = t / ANI_TIME_MSEC;
646         if (t <= STEP_WEIGHT_MIN) t = STEP_WEIGHT_DEF;
647         else if (t >  STEP_WEIGHT_MAX) t = STEP_WEIGHT_MAX;
648
649         wd->move_x += (wd->step) * t;
650
651         if (wd->step < 0 && wd->move_x < wd->x) wd->move_x = wd->x;
652         else if (wd->step > 0 && wd->move_x > wd->x) wd->move_x = wd->x;
653
654         _imageslider_update_pos(wd, wd->move_x, wd->y, wd->w);
655
656         if (wd->move_x == wd->x) {
657                 wd->ani_lock = 0;
658                 if (wd->cur) {
659                         it = eina_list_data_get(wd->cur);
660                         if (it->func) it->func(it->data, wd->obj, it);
661                 }
662                 if (wd->cur) {
663                         it = eina_list_data_get(wd->cur);
664                         evas_object_smart_callback_call(wd->obj, "changed", it);
665                 }
666
667                 ret = _check_drag(BLOCK_LEFT, wd);
668                 ret = _check_drag(BLOCK_RIGHT, wd);
669                 _check_zoom(wd);
670
671                 if (!wd->queue_idler) wd->queue_idler = ecore_idler_add(_icon_to_image, wd);
672
673                 if(wd->anim_timer) {
674                         ecore_timer_del(wd->anim_timer);
675                         wd->anim_timer = NULL;
676                 }
677
678                 return ECORE_CALLBACK_CANCEL;
679         }
680
681         return ECORE_CALLBACK_RENEW;    
682 }
683
684
685 static void _anim(Widget_Data *wd)
686 {
687         Evas_Coord w;
688
689         if (wd->x == wd->move_x) {
690                 _imageslider_update_pos(wd, wd->move_x, wd->y, wd->w);
691                 return;
692         }
693
694         wd->ani_lock = 1;
695
696         w = wd->move_x;
697         gettimeofday(&wd->tv, NULL);
698
699         if (!wd->anim_timer) {
700                 wd->anim_timer = ecore_timer_add(ANI_TIME, _timer_cb, wd); 
701         }       
702 }
703
704 // Update Image Slider Items.
705 static void _imageslider_update(Widget_Data *wd)
706 {
707         int i;
708         Eina_List *l[BLOCK_MAX];
709         Elm_Imageslider_Item *it;
710         Evas_Object *eo;
711
712         if (!wd) {
713                 return;
714         }
715
716         if (!wd->cur) {
717                 _imageslider_del_all(wd);
718                 return;
719         }
720
721         l[BLOCK_LEFT] = eina_list_prev(wd->cur);
722         l[BLOCK_CENTER] = wd->cur;
723         l[BLOCK_RIGHT] = eina_list_next(wd->cur);
724
725         for (i = 0; i < BLOCK_MAX; i++) {
726                 eo = edje_object_part_swallow_get(elm_layout_edje_get(wd->ly[i]), "swl.photo");
727                 if (!l[i]) {
728                         elm_layout_content_set(wd->ly[i], "swl.photo", NULL);
729                         evas_object_del(eo);
730                 } else {
731                         it = eina_list_data_get(l[i]);
732                         if (!it) return;
733
734                         if (!eo) {
735                                 eo = elm_image_add(wd->obj);
736                                 elm_layout_content_set(wd->ly[i], "swl.photo", eo);
737                                 elm_image_prescale_set(eo, wd->w);
738                                 elm_image_file_set(eo, it->photo_file, NULL);
739                                 elm_image_object_size_get(eo, &it->w, &it->h);
740                                 evas_object_geometry_get(eo, &it->ox, &it->oy, &it->ow, &it->oh);
741                                 it->ow = it->w;
742                                 it->oh = it->h;
743                         }
744
745                         if (wd->moving != it->moving) {
746                                 it->moving = wd->moving;
747                                 if (wd->moving) {
748                                         elm_image_prescale_set(eo, MOVING_IMAGE_SIZE);
749                                 } else {
750                                         elm_image_prescale_set(eo, it->w > it->h ? it->w : it->h);
751                                 }
752                         }
753                 }
754         }
755
756         _anim(wd);
757
758 }
759
760
761 /** 
762 * Add an Image Slider widget 
763
764 * @param        parent  The parent object 
765 * @return       The new Image slider object or NULL if it cannot be created 
766
767 * @ingroup Imageslider 
768 */
769 EAPI Evas_Object *
770 elm_imageslider_add(Evas_Object * parent)
771 {
772         int i;
773         Evas_Object *obj = NULL;
774         Widget_Data *wd = NULL;
775         Evas *e;
776
777         if (!parent) {
778                 return NULL;
779         }
780
781         wd = ELM_NEW(Widget_Data);
782         e = evas_object_evas_get(parent);
783         if (e == NULL ) {
784                 return NULL;
785         }
786         
787         obj = elm_widget_add(e);
788         ELM_SET_WIDTYPE(widtype, "imageslider");
789         elm_widget_type_set(obj, "imageslider");
790         elm_widget_sub_object_add(parent, obj);
791         elm_widget_data_set(obj, wd);
792         //wd->parent = parent;
793         elm_widget_del_hook_set(obj, _del_hook);
794         elm_widget_theme_hook_set(obj, _theme_hook);
795
796         wd->clip = evas_object_rectangle_add(e);
797         
798         for (i=0; i < BLOCK_MAX; i++) {
799                 wd->ly[i] = elm_layout_add(obj);
800                 elm_layout_theme_set(wd->ly[i], "imageslider", "base", "default");
801                 elm_widget_resize_object_set(obj, wd->ly[i]);
802                 evas_object_smart_member_add(wd->ly[i], obj);
803                 
804                 //edje_object_signal_callback_add(elm_layout_edje_get(wd->ly[i]), "elm,photo,clicked", "", _signal_clicked, obj);
805                 evas_object_event_callback_add(wd->ly[i], EVAS_CALLBACK_MOUSE_DOWN, ev_imageslider_down_cb, wd);
806                 evas_object_event_callback_add(wd->ly[i], EVAS_CALLBACK_MOUSE_UP, ev_imageslider_up_cb, wd);
807                 evas_object_event_callback_add(wd->ly[i], EVAS_CALLBACK_MOUSE_MOVE, ev_imageslider_move_cb, wd);
808                 evas_object_clip_set(wd->ly[i], wd->clip);
809                 evas_object_show(wd->ly[i]);                    
810         }
811
812         wd->obj = obj;
813
814         evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _imageslider_resize, obj);
815         evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _imageslider_move, obj);
816         evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _imageslider_show, obj);
817         evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _imageslider_hide, obj);
818         
819         _sizing_eval(obj);
820
821    return obj;  
822 }
823
824
825 /** 
826 * Append an Image Slider item 
827
828 * @param        obj          The Image Slider object 
829 * @param        photo_file   photo file path 
830 * @param        func         callback function 
831 * @param        data         callback data 
832 * @return       The Image Slider item handle or NULL 
833
834 * @ingroup Imageslider 
835 */
836 EAPI Elm_Imageslider_Item *
837 elm_imageslider_item_append(Evas_Object * obj, const char * photo_file, Elm_Imageslider_Cb func, void * data)
838 {
839         ELM_CHECK_WIDTYPE(obj, widtype) NULL;
840         Widget_Data *wd;
841         Elm_Imageslider_Item *it;
842
843         if (!obj || !(wd = elm_widget_data_get(obj))) {
844                 return NULL;
845         }
846
847         it = (Elm_Imageslider_Item *)calloc(1, sizeof(Elm_Imageslider_Item));
848         if (!it) return NULL;
849         it->photo_file = eina_stringshare_add(photo_file);
850         it->func = func;
851         it->data = data;
852         it->obj = obj;
853         wd->its = eina_list_append(wd->its, it);
854
855         if (!wd->cur) wd->cur = wd->its;
856
857         _imageslider_update(wd);
858
859         return it; 
860 }
861
862 /**
863 * Insert an Image Slider item into the Image Slider Widget by using the given index.
864 *
865 * @param        obj                     The Image Slider object
866 * @param        photo_file      photo file path
867 * @param        func            callback function
868 * @param        index           required position
869 * @param        data            callback data
870 * @return       The Image Slider item handle or NULL
871 *
872 * @ingroup      Imageslider
873 */
874 EAPI Elm_Imageslider_Item *
875 elm_imageslider_item_append_relative(Evas_Object *obj, const char *photo_file, Elm_Imageslider_Cb func, unsigned int index, void *data)
876 {
877         ELM_CHECK_WIDTYPE(obj, widtype) NULL;
878         Widget_Data *wd;
879         Elm_Imageslider_Item *it;
880
881         fprintf(stderr, "[[[ DEBUG ]]]:: New elm_imageslider_item_append_relative()\n");
882
883         if (!obj || !(wd = elm_widget_data_get(obj))) {
884                 return NULL;
885         }
886
887         it = (Elm_Imageslider_Item *)calloc(1, sizeof(Elm_Imageslider_Item));
888         if (!it) return NULL;
889         
890         it->obj = obj;
891         it->photo_file = eina_stringshare_add(photo_file);
892         it->func = func;
893         it->data = data;
894
895         wd->its = eina_list_append_relative(wd->its, it, eina_list_nth(wd->its, index-2));
896
897         if (!wd->cur) wd->cur = wd->its;
898
899         _imageslider_update(wd);
900
901         return it;
902 }
903
904
905 /** 
906 * Prepend Image Slider item 
907
908 * @param        obj          The Image Slider object 
909 * @param        photo_file   photo file path 
910 * @param        func         callback function 
911 * @param        data         callback data 
912 * @return       The imageslider item handle or NULL 
913
914 * @ingroup Imageslider 
915 */
916 EAPI Elm_Imageslider_Item *
917 elm_imageslider_item_prepend(Evas_Object * obj, const char * photo_file, Elm_Imageslider_Cb func, void * data)
918 {
919         ELM_CHECK_WIDTYPE(obj, widtype) NULL;
920         Widget_Data *wd;
921         Elm_Imageslider_Item *it;
922
923         if (!obj || !(wd = elm_widget_data_get(obj))) {
924                 return NULL;
925         }
926
927         it = (Elm_Imageslider_Item *)calloc(1, sizeof(Elm_Imageslider_Item));
928         it->photo_file = eina_stringshare_add(photo_file);
929         it->func = func;
930         it->data = data;
931         it->obj = obj;
932         wd->its = eina_list_prepend(wd->its, it );
933
934         if (!wd->cur) wd->cur = wd->its;
935
936         _imageslider_update(wd);
937
938         return it;
939 }
940
941
942
943 /**
944 * Delete the selected Image Slider item
945 *
946 * @param it             The selected Image Slider item handle
947 *
948 * @ingroup Imageslider
949 */
950 EAPI void
951 elm_imageslider_item_del(Elm_Imageslider_Item * it)
952 {
953         Widget_Data *wd;
954         Elm_Imageslider_Item *_it;
955         Eina_List *l;
956
957         if (!it || !(wd = elm_widget_data_get(it->obj))) {
958                 return ;
959         }
960
961         EINA_LIST_FOREACH(wd->its, l, _it) {
962                 if (_it == it ) {
963                         if (l == wd->cur) wd->cur = eina_list_prev(wd->cur);
964                         wd->its = eina_list_remove(wd->its, it);
965                         if (!wd->cur) wd->cur = wd->its;
966                         break;
967                 }
968         }
969
970         _imageslider_update(wd);
971         
972 }
973
974
975 /**
976 * Get the selected Image Slider item
977 *
978 * @param obj            The Image Slider object
979 * @return The selected Image Slider item or NULL
980 *
981 * @ingroup Imageslider
982 */
983 EAPI Elm_Imageslider_Item *
984 elm_imageslider_selected_item_get(Evas_Object * obj)
985 {
986         ELM_CHECK_WIDTYPE(obj, widtype) NULL;
987         Widget_Data *wd;
988
989         if (!obj || (!(wd = elm_widget_data_get(obj)))) {
990                 return NULL;
991         }
992
993         if (!wd->cur) return NULL;
994
995         return eina_list_data_get(wd->cur);
996 }
997
998 /**
999 * Get whether an Image Slider item is selected or not
1000 *
1001 * @param it              the selected Image Slider item
1002 * @return EINA_TRUE or EINA_FALSE
1003 *
1004 * @ingroup Imageslider
1005 */
1006 EAPI Eina_Bool
1007 elm_imageslider_item_selected_get(Elm_Imageslider_Item * it)
1008 {
1009         Widget_Data *wd;
1010         
1011         if (!it || !it->obj || (!(wd = elm_widget_data_get(it->obj)))) {
1012                 return EINA_FALSE;
1013         }
1014
1015         if (!wd->cur) return EINA_FALSE;
1016
1017         if (eina_list_data_get(wd->cur) == it ) return EINA_TRUE;
1018         else return EINA_FALSE;
1019         
1020 }
1021
1022 /**
1023 * Set the selected Image Slider item
1024 *
1025 * @param it             The Imaga Slider item
1026 *
1027 * @ingroup Imageslider
1028 */
1029 EAPI void
1030 elm_imageslider_item_selected_set(Elm_Imageslider_Item * it)
1031 {
1032         int i;
1033         Widget_Data *wd;
1034         Elm_Imageslider_Item *_it;
1035         Eina_List *l;
1036         Evas_Object *eo;
1037
1038         if (!it || !it->obj || (!(wd = elm_widget_data_get(it->obj)))) {
1039                 return ;
1040         }
1041
1042         EINA_LIST_FOREACH(wd->its, l, _it) {
1043                 if (_it == it ) {
1044                         wd->cur = l;
1045                 }
1046         }
1047
1048         for (i = 0; i < BLOCK_MAX; i++) {
1049                 eo = edje_object_part_swallow_get(elm_layout_edje_get(wd->ly[i]), "swl.photo");
1050                 if (eo) {
1051                         elm_layout_content_set(wd->ly[i], "swl.photo", NULL);
1052                         evas_object_del(eo);
1053                 }
1054         }
1055
1056         _imageslider_update(wd);
1057         
1058 }
1059
1060
1061 /**
1062 * Get the photo file path of given Image Slider item
1063 *
1064 * @param it             The Image Slider item
1065 * @return The photo file path or NULL;
1066 *
1067 * @ingroup Imageslider
1068 */
1069 EAPI const char *
1070 elm_imageslider_item_photo_file_get(Elm_Imageslider_Item * it)
1071 {
1072         if (!it) {
1073                 return NULL;
1074         }
1075
1076         return it->photo_file;
1077 }
1078
1079
1080 /**
1081 * Get the previous Image Slider item
1082 *
1083 * @param it             The Image Slider item
1084 * @return The previous Image Slider item or NULL
1085 *
1086 * @ingroup Imageslider
1087 */
1088 EAPI Elm_Imageslider_Item *
1089 elm_imageslider_item_prev(Elm_Imageslider_Item * it)
1090 {
1091         Widget_Data *wd;
1092         Elm_Imageslider_Item *_it;
1093         Eina_List *l;
1094
1095         if (!it || (!(wd = elm_widget_data_get(it->obj)))) {
1096                 return NULL;
1097         }
1098
1099         EINA_LIST_FOREACH(wd->its, l, _it) {
1100                 if (_it == it) {
1101                         l = eina_list_prev(l);
1102                         if (!l) break;
1103                         return eina_list_data_get(l);
1104                 }
1105         }
1106
1107         return NULL;    
1108 }
1109
1110
1111 /**
1112 * Get the next Image Slider item
1113 *
1114 * @param it             The Image Slider item
1115 * @return The next Image Slider item or NULL
1116 *
1117 * @ingroup Imageslider
1118 */
1119 EAPI Elm_Imageslider_Item *
1120 elm_imageslider_item_next(Elm_Imageslider_Item * it)
1121 {
1122         Widget_Data *wd;
1123         Elm_Imageslider_Item *_it;
1124         Eina_List *l;
1125
1126         if (!it || (!(wd = elm_widget_data_get(it->obj)))) {
1127                 return NULL;
1128         }
1129
1130         EINA_LIST_FOREACH(wd->its, l, _it) {
1131                 if (_it == it) {
1132                         l = eina_list_next(l);
1133                         if (!l) break;
1134                         return eina_list_data_get(l);
1135                 }
1136         }
1137
1138         return NULL;
1139 }
1140
1141
1142 /**
1143 * Move to the previous Image Slider item
1144 *
1145 * @param obj    The Image Slider object
1146 *
1147 * @ingroup Imageslider
1148 */
1149 EAPI void 
1150 elm_imageslider_prev(Evas_Object * obj)
1151 {
1152         ELM_CHECK_WIDTYPE(obj, widtype);
1153         Widget_Data *wd;
1154         
1155         if (!obj || (!(wd = elm_widget_data_get(obj)))) {
1156                 return;
1157         }
1158
1159         if (wd->ani_lock) return;
1160
1161         _imageslider_obj_move(wd, -1);
1162 }
1163
1164
1165 /**
1166 * Move to the next Image Slider item
1167 *
1168 * @param obj The Image Slider object
1169 *
1170 * @ingroup Imageslider
1171 */
1172 EAPI void
1173 elm_imageslider_next(Evas_Object * obj)
1174 {
1175         ELM_CHECK_WIDTYPE(obj, widtype);
1176         Widget_Data *wd;
1177         
1178         if (!obj || (!(wd = elm_widget_data_get(obj)))) {
1179                 return;
1180         }
1181
1182         if (wd->ani_lock) return;
1183
1184         _imageslider_obj_move(wd, 1);
1185         
1186 }
1187
1188
1189
1190
1191