ea30da27c41e64fc52b417cc497e80c63a4a7466
[framework/uifw/e17.git] / src / modules / everything / evry_view.c
1 #include "e_mod_main.h"
2
3 typedef struct _View View;
4 typedef struct _Smart_Data Smart_Data;
5 typedef struct _Item Item;
6
7 #define SIZE_LIST 28
8 #define SIZE_DETAIL 36
9
10
11 struct _View
12 {
13   Evry_View view;
14   Tab_View *tabs;
15
16   const Evry_State *state;
17   const Evry_Plugin *plugin;
18
19   Evas *evas;
20   Evas_Object *bg, *sframe, *span;
21   int          iw, ih;
22   int          zoom;
23   int         mode;
24   int         mode_prev;
25
26   Eina_List *handlers;
27 };
28
29 /* smart object based on wallpaper module */
30 struct _Smart_Data
31 {
32   View        *view;
33   Eina_List   *items;
34   Item        *cur_item;
35   Ecore_Idle_Enterer *idle_enter;
36   Ecore_Idle_Enterer *thumb_idler;
37   Evas_Coord   x, y, w, h;
38   Evas_Coord   cx, cy, cw, ch;
39   Evas_Coord   sx, sy;
40   Eina_List   *queue;
41
42   double last_select;
43   double scroll_align;
44   double scroll_align_to;
45   Ecore_Animator *animator;
46
47   int slide_offset;
48   double slide;
49   double slide_to;
50
51   int    sliding;
52   int    mouse_act;
53   int    mouse_x;
54   int    mouse_y;
55   int    mouse_button;
56   Item  *it_down;
57 };
58
59 struct _Item
60 {
61   Evry_Item *item;
62   Evas_Object *obj;
63   Evas_Coord x, y, w, h;
64   Evas_Object *frame, *image, *thumb;
65   Eina_Bool selected : 1;
66   Eina_Bool have_thumb : 1;
67   Eina_Bool do_thumb : 1;
68   Eina_Bool get_thumb : 1;
69   Eina_Bool showing : 1;
70   Eina_Bool visible : 1;
71   Eina_Bool changed : 1;
72   int pos;
73 };
74
75 static View *view = NULL;
76
77 static void _view_clear(Evry_View *view);
78 static void _pan_item_select(Evas_Object *obj, Item *it, int scroll);
79 static void _animator_del(Evas_Object *obj);
80 static Eina_Bool _animator(void *data);
81
82 static void
83 _thumb_gen(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
84 {
85    Evas_Coord w, h;
86    Item *it = data;
87
88    if (!it->frame) return;
89
90    e_icon_size_get(it->thumb, &w, &h);
91    edje_extern_object_aspect_set(it->thumb, EDJE_ASPECT_CONTROL_BOTH, w, h);
92    edje_object_part_swallow(it->frame, "e.swallow.thumb", it->thumb);
93    evas_object_show(it->thumb);
94    edje_object_signal_emit(it->frame, "e,action,thumb,show_delayed", "e");
95    edje_object_message_signal_process(it->frame);
96    it->have_thumb = EINA_TRUE;
97    it->do_thumb = EINA_FALSE;
98
99    if (it->image) evas_object_del(it->image);
100    it->image = NULL;
101 }
102
103 static int
104 _check_item(const Evry_Item *it)
105 {
106    char *suffix;
107
108    GET_FILE(file, it);
109
110    if (!evry_file_path_get(file) || !file->mime) return 0;
111
112    if (!strncmp(file->mime, "image/", 6))
113      return 1;
114
115    if ((suffix = strrchr(it->label, '.')))
116      if (!strncmp(suffix, ".edj", 4))
117        return 1;
118
119    return 0;
120 }
121
122 static int _sort_pos_cb(const void *d1, const void *d2)
123 {
124    const Item *it1 = d1;
125    const Item *it2 = d2;
126    return ((it1->x + it1->y * 4) - (it2->x + it2->y * 4));
127 }
128
129 static Eina_Bool
130 _thumb_idler(void *data)
131 {
132    Smart_Data *sd = data;
133    Eina_List *l, *ll;
134    Item *it;
135    char *suffix;
136    int w, h;
137    int cnt = 0;
138    
139    sd->queue = eina_list_sort(sd->queue, -1, _sort_pos_cb);
140
141    EINA_LIST_FOREACH_SAFE(sd->queue, l, ll, it)
142      {
143         if (!it->image && !it->have_thumb)
144           {
145              it->image = evry_util_icon_get(it->item, sd->view->evas);
146
147              if (it->image)
148                {
149                   e_icon_size_get(it->image, &w, &h);
150                   if (w && h)
151                     edje_extern_object_aspect_set(it->thumb, EDJE_ASPECT_CONTROL_BOTH, w, h);
152
153                   edje_object_part_swallow(it->frame, "e.swallow.icon", it->image);
154                   evas_object_show(it->image);
155                   edje_object_signal_emit(it->frame, "e,action,thumb,show", "e");
156                }
157              else it->have_thumb = EINA_TRUE;
158           }
159
160         if ((CHECK_TYPE(it->item, EVRY_TYPE_FILE)) &&
161             ((!it->thumb && !(it->have_thumb || it->do_thumb)) &&
162             (it->get_thumb || _check_item(it->item) ||
163              (it->item->icon && it->item->icon[0] == '/'))))
164           {
165              it->get_thumb = EINA_TRUE;
166
167              it->thumb = e_thumb_icon_add(sd->view->evas);
168
169              GET_FILE(file, it->item);
170
171              evas_object_smart_callback_add(it->thumb, "e_thumb_gen", _thumb_gen, it);
172
173              e_thumb_icon_size_set(it->thumb, it->w, it->h);
174              
175              if (it->item->icon && it->item->icon[0])
176                e_thumb_icon_file_set(it->thumb, it->item->icon, NULL);
177              else if ((suffix = strrchr(file->path, '.')) && (!strncmp(suffix, ".edj", 4)))
178                {
179                   e_thumb_icon_file_set(it->thumb, file->path, "e/desktop/background");
180                   e_thumb_icon_size_set(it->thumb, 128, 80);
181                }
182              else
183                e_thumb_icon_file_set(it->thumb, file->path, NULL);
184
185              e_thumb_icon_begin(it->thumb);
186              it->do_thumb = EINA_TRUE;
187           }
188
189         sd->queue = eina_list_remove_list(sd->queue, l);
190
191         if (cnt++ > 10)
192           {
193              e_util_wakeup();
194              return ECORE_CALLBACK_RENEW;
195           }
196      }
197
198    sd->thumb_idler = NULL;
199
200    return ECORE_CALLBACK_CANCEL;
201 }
202
203 static void
204 _item_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
205 {
206    Evas_Event_Mouse_Down *ev = event_info;
207    Item *it = data;
208    Smart_Data *sd = evas_object_smart_data_get(it->obj);
209    const Evry_State *s;
210    if (!sd) return;
211
212    sd->mouse_act = 1;
213    sd->it_down = it;
214    sd->mouse_button = ev->button;
215
216    s = sd->view->state;
217
218    if ((ev->button == 1) && (ev->flags & EVAS_BUTTON_DOUBLE_CLICK))
219      {
220         if (it != sd->cur_item)
221           {
222              evry_item_select(s, it->item);
223              _pan_item_select(it->obj, it, 0);
224           }
225
226         if (it->item->browseable)
227           evry_browse_item(it->item);
228         else
229           evry_plugin_action(s->selector->win, 1);
230      }
231    else
232      {
233         sd->mouse_x = ev->canvas.x;
234         sd->mouse_y = ev->canvas.y;
235      }
236 }
237
238 static void
239 _item_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
240 {
241    Evas_Event_Mouse_Up *ev = event_info;
242    Item *it = data;
243    Smart_Data *sd = evas_object_smart_data_get(it->obj);
244    const Evry_State *s;
245    if (!sd) return;
246
247    sd->mouse_x = 0;
248    sd->mouse_y = 0;
249    if (!sd->it_down)
250      return;
251
252    edje_object_signal_emit(sd->view->bg, "e,action,hide,into", "e");
253    edje_object_signal_emit(sd->view->bg, "e,action,hide,back", "e");
254    sd->it_down = NULL;
255
256    s = sd->view->state;
257
258    if (ev->button == 1)
259      {
260         if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) &&
261             (it != sd->cur_item))
262           {
263              evry_item_select(s, it->item);
264              _pan_item_select(it->obj, it, 0);
265           }
266      }
267    else if (ev->button == 3)
268      {
269         evry_item_select(s, it->item);
270         _pan_item_select(it->obj, it, 0);
271
272         evry_plugin_action(s->selector->win, 0);
273      }
274 }
275
276 static void
277 _item_select(Item *it)
278 {
279    it->selected = EINA_TRUE;
280    edje_object_signal_emit(it->frame, "e,state,selected", "e");
281
282    if (it->thumb)
283      {
284         if (strcmp(evas_object_type_get(it->thumb), "e_icon"))
285           edje_object_signal_emit(it->thumb, "e,state,selected", "e");
286         else
287           e_icon_selected_set(it->thumb, EINA_TRUE);
288      }
289
290    if (it->image)
291      {
292         if (strcmp(evas_object_type_get(it->image), "e_icon"))
293           edje_object_signal_emit(it->image, "e,state,selected", "e");
294         else
295           e_icon_selected_set(it->image, EINA_TRUE);
296      }
297 }
298
299 static void
300 _item_unselect(Item *it)
301 {
302    it->selected = EINA_FALSE;
303    edje_object_signal_emit(it->frame, "e,state,unselected", "e");
304
305    if (it->thumb)
306      {
307         if (strcmp(evas_object_type_get(it->thumb), "e_icon"))
308           edje_object_signal_emit(it->thumb, "e,state,unselected", "e");
309         else
310           e_icon_selected_set(it->thumb, EINA_FALSE);
311      }
312
313    if (it->image)
314      {
315         if (strcmp(evas_object_type_get(it->image), "e_icon"))
316           edje_object_signal_emit(it->image, "e,state,unselected", "e");
317         else
318           e_icon_selected_set(it->image, EINA_FALSE);
319      }
320 }
321
322 static void
323 _item_show(View *v, Item *it, Evas_Object *list)
324 {
325    if (!it->frame)
326      {
327         it->frame = edje_object_add(v->evas);
328         if (v->mode == VIEW_MODE_THUMB)
329           {
330              e_theme_edje_object_set(it->frame, "base/theme/modules/everything",
331                                      "e/modules/everything/thumbview/item/thumb");
332           }
333         else
334           {
335              e_theme_edje_object_set(it->frame, "base/theme/modules/everything",
336                                      "e/modules/everything/thumbview/item/list");
337
338              if (v->mode == VIEW_MODE_DETAIL)
339                edje_object_signal_emit(it->frame, "e,state,detail,show", "e");
340           }
341
342         evas_object_event_callback_add(it->frame, EVAS_CALLBACK_MOUSE_DOWN,
343                                        _item_down, it);
344         evas_object_event_callback_add(it->frame, EVAS_CALLBACK_MOUSE_UP,
345                                        _item_up, it);
346         evas_object_smart_member_add(it->frame, list);
347
348         evas_object_clip_set(it->frame, evas_object_clip_get(list));
349
350         if (it->item->selected)
351           _item_select(it);
352
353         if (it->item->marked)
354           edje_object_signal_emit(it->frame, "e,state,marked", "e");
355      }
356
357    edje_object_part_text_set(it->frame, "e.text.label", it->item->label);
358
359    if (v->mode == VIEW_MODE_DETAIL && it->item->detail)
360      edje_object_part_text_set(it->frame, "e.text.detail", it->item->detail);
361
362    evas_object_show(it->frame);
363
364    if (it->item->browseable)
365      edje_object_signal_emit(it->frame, "e,state,browseable", "e");
366
367    it->visible = EINA_TRUE;
368 }
369
370 static void
371 _item_hide(Item *it)
372 {
373    if (it->do_thumb) e_thumb_icon_end(it->thumb);
374
375    if (it->thumb) evas_object_del(it->thumb);
376    if (it->image) evas_object_del(it->image);
377    if (it->frame) evas_object_del(it->frame);
378
379    it->thumb = NULL;
380    it->image = NULL;
381    it->frame = NULL;
382
383    it->have_thumb = EINA_FALSE;
384    it->do_thumb = EINA_FALSE;
385    it->visible = EINA_FALSE;
386 }
387
388 static Eina_Bool
389 _e_smart_reconfigure_do(void *data)
390 {
391    Evas_Object *obj = data;
392    Smart_Data *sd = evas_object_smart_data_get(obj);
393    Eina_List *l;
394    Item *it;
395    int iw, changed = 0;
396    Evas_Coord x, y, xx, yy, ww, hh, mw, mh, ox = 0, oy = 0;
397    Evas_Coord aspect_w, aspect_h;
398
399    if (!sd) return ECORE_CALLBACK_CANCEL;
400
401    sd->idle_enter = NULL;
402    if (sd->w < 1) return ECORE_CALLBACK_CANCEL;
403
404    if (sd->cx > (sd->cw - sd->w)) sd->cx = sd->cw - sd->w;
405    if (sd->cy > (sd->ch - sd->h)) sd->cy = sd->ch - sd->h;
406    if (sd->cx < 0) sd->cx = 0;
407    if (sd->cy < 0) sd->cy = 0;
408
409    aspect_w = sd->w;
410    aspect_h = sd->h;
411
412    if (sd->view->mode == VIEW_MODE_LIST)
413      {
414         iw = sd->w;
415         hh = SIZE_LIST;
416      }
417    else if (sd->view->mode == VIEW_MODE_DETAIL)
418      {
419         iw = sd->w;
420         hh = SIZE_DETAIL;
421      }
422    else
423      {
424         int size;
425         int cnt = eina_list_count(sd->items);
426         double col = 1;
427         int width = sd->w - 8;
428
429         if (cnt < 5)
430           {
431              col = 2;
432              aspect_w = width * 2;
433           }
434         else if ((cnt < 9) && (sd->w < (double)sd->h * 1.2))
435           {
436              col = 2;
437              aspect_w = width * 3;
438           }
439         else if (cnt < 10)
440           {
441              col = 3;
442              aspect_w = width * 3;
443           }
444         else if (sd->view->zoom == 0)
445           {
446              size = 96;
447              aspect_w = width  * (1 + (sd->h / size));
448              col = width / size;
449           }
450         else if (sd->view->zoom == 1)
451           {
452              size = 128;
453              col = width / size;
454              aspect_w = width  * (1 + (sd->h / size));
455           }
456
457         else /* if (sd->view->zoom == 2) */
458           {
459              size = 192;
460              col = width / size;
461              aspect_w = width * (1 + (sd->h / size));
462           }
463
464         if (col < 1) col = 1;
465
466         iw = width / col;
467         aspect_w /= col;
468      }
469
470    if (aspect_w <= 0) aspect_w = 1;
471    if (aspect_h <= 0) aspect_h = 1;
472
473    x = 0;
474    y = 0;
475    ww = iw;
476
477    if (sd->view->mode == VIEW_MODE_THUMB)
478      hh = (aspect_h * iw) / (aspect_w);
479
480    mw = mh = 0;
481    EINA_LIST_FOREACH(sd->items, l, it)
482      {
483         if (x > (sd->w - ww))
484           {
485              x = 0;
486              y += hh;
487           }
488
489         it->x = x;
490         it->y = y;
491         it->w = ww;
492         it->h = hh;
493
494         if ((x + ww) > mw) mw = x + ww;
495         if ((y + hh) > mh) mh = y + hh;
496         x += ww;
497      }
498
499    if (sd->view->mode == VIEW_MODE_LIST ||
500        sd->view->mode == VIEW_MODE_DETAIL)
501      mh += sd->h % hh;
502
503    if ((mw != sd->cw) || (mh != sd->ch))
504      {
505         sd->cw = mw;
506         sd->ch = mh;
507
508         if (sd->cx > (sd->cw - sd->w))
509           sd->cx = sd->cw - sd->w;
510         if (sd->cy > (sd->ch - sd->h))
511           sd->cy = sd->ch - sd->h;
512         if (sd->cx < 0)
513           sd->cx = 0;
514         if (sd->cy < 0)
515           sd->cy = 0;
516
517         changed = 1;
518      }
519
520    if (sd->view->mode == VIEW_MODE_THUMB)
521      {
522         if (sd->w > sd->cw) ox = (sd->w - sd->cw) / 2;
523         if (sd->h > sd->ch) oy = (sd->h - sd->ch) / 2;
524      }
525
526    EINA_LIST_FOREACH(sd->items, l, it)
527      {
528         xx = sd->x - sd->cx + it->x + ox;
529         yy = sd->y - sd->cy + it->y + oy;
530
531         if (E_INTERSECTS(xx, yy, it->w, it->h, 0, sd->y - it->h,
532                          sd->x + sd->w, sd->y + sd->h + it->h))
533           {
534              if (!it->visible)
535                _item_show(sd->view, it, obj);
536
537              evas_object_move(it->frame, xx, yy);
538              evas_object_resize(it->frame, it->w, it->h);
539
540              if (!(it->image || it->do_thumb || it->have_thumb) &&
541                  !eina_list_data_find(sd->queue, it))
542                sd->queue = eina_list_append(sd->queue, it);
543           }
544         else if (it->visible)
545           {
546              sd->queue = eina_list_remove(sd->queue, it);
547              _item_hide(it);
548           }
549         it->changed = EINA_FALSE;
550      }
551
552    if (changed)
553      evas_object_smart_callback_call(obj, "changed", NULL);
554
555    if (!sd->thumb_idler)
556      sd->thumb_idler = ecore_idle_enterer_add(_thumb_idler, sd);
557
558    sd->idle_enter = NULL;
559
560    return ECORE_CALLBACK_CANCEL;
561 }
562
563 static void
564 _e_smart_reconfigure(Evas_Object *obj)
565 {
566    Smart_Data *sd = evas_object_smart_data_get(obj);
567
568    if (sd->idle_enter) return;
569    sd->idle_enter = ecore_idle_enterer_before_add(_e_smart_reconfigure_do, obj);
570 }
571
572 static void
573 _e_smart_add(Evas_Object *obj)
574 {
575    Smart_Data *sd = calloc(1, sizeof(Smart_Data));
576    if (!sd) return;
577
578    sd->sx = sd->sy = -1;
579    evas_object_smart_data_set(obj, sd);
580 }
581
582 static void
583 _e_smart_del(Evas_Object *obj)
584 {
585    Smart_Data *sd = evas_object_smart_data_get(obj);
586
587    if (sd->idle_enter)
588      ecore_idle_enterer_del(sd->idle_enter);
589
590    if (sd->thumb_idler)
591      ecore_idle_enterer_del(sd->thumb_idler);
592
593    _animator_del(obj);
594
595    free(sd);
596    evas_object_smart_data_set(obj, NULL);
597 }
598
599 static void
600 _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
601 {
602    Smart_Data *sd = evas_object_smart_data_get(obj);
603    sd->x = x;
604    sd->y = y;
605
606    _e_smart_reconfigure(obj);
607 }
608
609 static void
610 _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
611 {
612    Smart_Data *sd = evas_object_smart_data_get(obj);
613    sd->w = w;
614    sd->h = h;
615    _e_smart_reconfigure(obj);
616    evas_object_smart_callback_call(obj, "changed", NULL);
617 }
618
619 static void
620 _e_smart_show(Evas_Object *obj __UNUSED__){}
621
622 static void
623 _e_smart_hide(Evas_Object *obj __UNUSED__){}
624
625 static void
626 _e_smart_color_set(Evas_Object *obj __UNUSED__, int r __UNUSED__, int g __UNUSED__, int b __UNUSED__, int a __UNUSED__){}
627
628 static void
629 _e_smart_clip_set(Evas_Object *obj __UNUSED__, Evas_Object * clip __UNUSED__){}
630
631 static void
632 _e_smart_clip_unset(Evas_Object *obj __UNUSED__){}
633
634 static Evas_Object *
635 _pan_add(Evas *evas)
636 {
637    static Evas_Smart *smart = NULL;
638    static const Evas_Smart_Class sc =
639      {
640        "wp_pan",
641        EVAS_SMART_CLASS_VERSION,
642        _e_smart_add,
643        _e_smart_del,
644        _e_smart_move,
645        _e_smart_resize,
646        _e_smart_show,
647        _e_smart_hide,
648        _e_smart_color_set,
649        _e_smart_clip_set,
650        _e_smart_clip_unset,
651        NULL,
652        NULL,
653        NULL,
654        NULL,
655        NULL,
656        NULL,
657        NULL
658      };
659    smart = evas_smart_class_new(&sc);
660    return evas_object_smart_add(evas, smart);
661 }
662
663 static void
664 _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
665 {
666    Smart_Data *sd = evas_object_smart_data_get(obj);
667    if (x > (sd->cw - sd->w)) x = sd->cw - sd->w;
668    if (y > (sd->ch - sd->h)) y = sd->ch - sd->h;
669    if (x < 0) x = 0;
670    if (y < 0) y = 0;
671    if ((sd->cx == x) && (sd->cy == y)) return;
672    sd->cx = x;
673    sd->cy = y;
674    _e_smart_reconfigure(obj);
675 }
676
677 static void
678 _pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
679 {
680    Smart_Data *sd = evas_object_smart_data_get(obj);
681    if (x) *x = sd->cx;
682    if (y) *y = sd->cy;
683 }
684
685 static void
686 _pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
687 {
688    Smart_Data *sd = evas_object_smart_data_get(obj);
689    if (x)
690      {
691         if (sd->w < sd->cw) *x = sd->cw - sd->w;
692         else *x = 0;
693      }
694    if (y)
695      {
696         if (sd->h < sd->ch) *y = sd->ch - sd->h;
697         else *y = 0;
698      }
699 }
700
701 static void
702 _pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
703 {
704    Smart_Data *sd = evas_object_smart_data_get(obj);
705    if (w) *w = sd->cw;
706    if (h) *h = sd->ch;
707 }
708
709 static void
710 _pan_view_set(Evas_Object *obj, View *view)
711 {
712    Smart_Data *sd = evas_object_smart_data_get(obj);
713    sd->view = view;
714 }
715
716 static Item *
717 _pan_item_add(Evas_Object *obj, Evry_Item *item)
718 {
719    Smart_Data *sd = evas_object_smart_data_get(obj);
720    Item *it;
721
722    it = E_NEW(Item, 1);
723    if (!it) return NULL;
724
725    sd->items = eina_list_append(sd->items, it);
726    it->obj = obj;
727    it->item = item;
728    it->changed = EINA_TRUE;
729
730    evry_item_ref(item);
731
732    _e_smart_reconfigure(obj);
733
734    return it;
735 }
736
737 static void
738 _pan_item_remove(Evas_Object *obj, Item *it)
739 {
740    Smart_Data *sd = evas_object_smart_data_get(obj);
741
742    sd->items = eina_list_remove(sd->items, it);
743    sd->queue = eina_list_remove(sd->queue, it);
744
745    _item_hide(it);
746
747    evry_item_free(it->item);
748
749    _e_smart_reconfigure(obj);
750
751    E_FREE(it);
752 }
753
754 static void
755 _animator_del(Evas_Object *obj)
756 {
757    Smart_Data *sd = evas_object_smart_data_get(obj);
758
759    sd->animator = NULL;
760 }
761
762 static Eina_Bool
763 _animator(void *data)
764 {
765    Smart_Data *sd = evas_object_smart_data_get(data);
766    if (!sd) return ECORE_CALLBACK_CANCEL;
767
768    double da;
769    double spd = ((25.0/ (double)e_config->framerate) /
770                  (double) (1 + sd->view->zoom));
771    if (spd > 0.9) spd = 0.9;
772
773    int wait = 0;
774
775    if (sd->scroll_align != sd->scroll_align_to)
776      {
777         sd->scroll_align = ((sd->scroll_align * (1.0 - spd)) +
778                             (sd->scroll_align_to * spd));
779
780         da = sd->scroll_align - sd->scroll_align_to;
781         if (da < 0.0) da = -da;
782         if (da < 0.02)
783           sd->scroll_align = sd->scroll_align_to;
784         else
785           wait++;
786
787         e_scrollframe_child_pos_set(sd->view->sframe,
788                                     0, sd->scroll_align);
789      }
790
791    if (wait)
792      return ECORE_CALLBACK_RENEW;
793
794    _animator_del(data);
795
796    return ECORE_CALLBACK_CANCEL;
797
798 }
799
800 static int
801 _child_region_get(Evas_Object *obj, Evas_Coord y, Evas_Coord h)
802 {
803    Smart_Data *sd = evas_object_smart_data_get(obj);
804    Evas_Coord my = 0, ch = 0, py = 0, ny;
805
806    py = sd->cy;
807    ch = sd->ch;
808
809    if (sd->h < sd->ch)
810      my = sd->ch - sd->h;
811    else
812      my = 0;
813
814    ny = py;
815    if (y < py) ny = y;
816    else if ((y + h) > (py + (ch - my)))
817      {
818         ny = y + h - (ch - my);
819         if (ny > y) ny = y;
820      }
821
822    if (ny < 0) ny = 0;
823
824    return ny;
825 }
826
827 static void
828 _pan_item_select(Evas_Object *obj, Item *it, int scroll)
829 {
830    Smart_Data *sd = evas_object_smart_data_get(obj);
831    double align = -1;
832    int prev = -1;
833
834    if (sd->cur_item)
835      {
836         prev = sd->cur_item->y / (1 + sd->cur_item->h);
837         _item_unselect(sd->cur_item);
838         sd->cur_item = NULL;
839      }
840
841    if (!it) return;
842
843    _item_select(it);
844    sd->cur_item = it;
845
846    if (evry_conf->scroll_animate)
847      {
848         double now = ecore_time_get();
849
850         if (now - sd->last_select < 0.08)
851           {
852              sd->scroll_align = sd->scroll_align_to;
853              scroll = 0;
854           }
855
856         sd->last_select = now;
857      }
858    else scroll = 0;
859
860    if (sd->mouse_act)
861      return;
862
863    if (sd->view->mode == VIEW_MODE_THUMB)
864      {
865         if (sd->view->zoom < 2)
866           align = _child_region_get(obj, it->y - it->h, it->h * 3);
867         else
868           align = _child_region_get(obj, it->y, it->h);
869      }
870    else
871      {
872         align = _child_region_get(obj, it->y - it->h*2, it->h * 5);
873      }
874
875    if (scroll && evry_conf->scroll_animate)
876      {
877         sd->scroll_align_to = align;
878
879         if (align != sd->cy && !sd->animator)
880           sd->animator = ecore_animator_add(_animator, obj);
881      }
882    else
883      {
884         sd->scroll_align = sd->scroll_align_to;
885
886         if (align >= 0)
887           {
888              sd->scroll_align = align;
889              sd->scroll_align_to = align;
890              e_scrollframe_child_pos_set(sd->view->sframe,
891                                          0, sd->scroll_align);
892           }
893
894         _animator_del(obj);
895      }
896
897    _e_smart_reconfigure(obj);
898 }
899
900 static void
901 _clear_items(Evas_Object *obj)
902 {
903    Smart_Data *sd = evas_object_smart_data_get(obj);
904    Eina_List *l;
905    Item *it;
906
907    _animator_del(obj);
908
909    EINA_LIST_FOREACH(sd->items, l, it)
910      _item_hide(it);
911
912    if (sd->queue)
913      eina_list_free(sd->queue);
914    sd->queue = NULL;
915
916    if (sd->thumb_idler)
917      ecore_idle_enterer_del(sd->thumb_idler);
918    sd->thumb_idler = NULL;
919 }
920
921 static void
922 _view_clear(Evry_View *view)
923 {
924    View *v = (View*) view;
925    Smart_Data *sd = evas_object_smart_data_get(v->span);
926    Item *it;
927    if (!sd) return;
928
929    sd->mouse_x = 0;
930    sd->mouse_y = 0;
931    sd->mouse_act = 0;
932    sd->it_down = NULL;
933
934    _clear_items(v->span);
935
936    if (sd->items)
937      {
938         EINA_LIST_FREE(sd->items, it)
939           {
940              evry_item_free(it->item);
941              E_FREE(it);
942           }
943      }
944
945    _e_smart_reconfigure(v->span);
946
947    v->tabs->clear(v->tabs);
948 }
949
950 static int
951 _sort_cb(const void *data1, const void *data2)
952 {
953    const Item *it1 = data1;
954    const Item *it2 = data2;
955
956    return it1->pos - it2->pos;
957 }
958
959 static int
960 _update_frame(Evas_Object *obj)
961 {
962    Smart_Data *sd = evas_object_smart_data_get(obj);
963
964    _animator_del(obj);
965
966    sd->scroll_align = 0;
967
968    e_scrollframe_child_pos_set(sd->view->sframe, 0, sd->scroll_align);
969
970    _e_smart_reconfigure_do(obj);
971
972    _pan_item_select(obj, sd->cur_item, 0);
973
974    _e_smart_reconfigure(obj);
975
976    return 0;
977 }
978
979 static int
980 _view_update(Evry_View *view)
981 {
982    GET_VIEW(v, view);
983    Smart_Data *sd = evas_object_smart_data_get(v->span);
984    Item *v_it;
985    Evry_Item *p_it;
986    Eina_List *l, *ll, *v_remove = NULL, *v_items = NULL;
987    int pos, last_pos, last_vis = 0, first_vis = 0;
988    Eina_Bool update = EINA_FALSE;
989    Evry_Plugin *p = v->state->plugin;
990
991    if (!sd) return 0;
992
993    sd->cur_item = NULL;
994    sd->it_down = NULL;
995    sd->mouse_act = 0;
996    sd->mouse_x = 0;
997    sd->mouse_y = 0;
998
999    if (!p)
1000      {
1001         _view_clear(view);
1002         return 1;
1003      }
1004
1005    if (p != v->plugin && (v->plugin || (v->mode == VIEW_MODE_NONE)))
1006      {
1007         if (p->config->view_mode != v->mode)
1008           {
1009              _clear_items(v->span);
1010
1011              if (p->config->view_mode < 0)
1012                v->mode = evry_conf->view_mode;
1013              else
1014                v->mode = p->config->view_mode;
1015           }
1016      }
1017
1018    /* go through current view items */
1019    EINA_LIST_FOREACH(sd->items, l, v_it)
1020      {
1021         last_pos = v_it->pos;
1022         v_it->pos = 0;
1023         pos = 1;
1024
1025         /* go through plugins current items */
1026         EINA_LIST_FOREACH(p->items, ll, p_it)
1027           {
1028              if (v_it->item == p_it)
1029                {
1030                   if (pos != last_pos)
1031                     v_it->changed = EINA_TRUE;
1032
1033                   v_it->pos = pos;
1034
1035                   if (p_it->selected)
1036                     {
1037                        sd->cur_item = v_it;
1038                        v_it->selected = EINA_TRUE;
1039                     }
1040                   else
1041                     {
1042                        if (v_it->selected && v_it->frame)
1043                          edje_object_signal_emit
1044                            (v_it->frame,"e,state,unselected", "e");
1045                        v_it->selected = EINA_FALSE;
1046                     }
1047                   break;
1048                }
1049              pos++;
1050           }
1051
1052         if (v_it->visible)
1053           {
1054              if (!first_vis) first_vis = v_it->pos;
1055              last_vis = v_it->pos;
1056           }
1057
1058         /* view item is in list of current items */
1059         if (v_it->pos)
1060           {
1061              v_items = eina_list_append(v_items, v_it->item);
1062
1063              if (v_it->visible && v_it->changed)
1064                update = EINA_TRUE;
1065           }
1066         else
1067           {
1068              if (v_it->visible) update = EINA_TRUE;
1069              v_remove = eina_list_append(v_remove, v_it);
1070           }
1071      }
1072
1073    EINA_LIST_FREE(v_remove, v_it)
1074      _pan_item_remove(v->span, v_it);
1075
1076    /* go through plugins current items */
1077    pos = 1;
1078    EINA_LIST_FOREACH(p->items, l, p_it)
1079      {
1080         /* item is not already in view */
1081         if (!eina_list_data_find_list(v_items, p_it))
1082           {
1083              v_it = _pan_item_add(v->span, p_it);
1084
1085              if (!v_it) continue;
1086
1087              v_it->pos = pos;
1088
1089              if (p_it == v->state->cur_item)
1090                {
1091                   sd->cur_item = v_it;
1092                   v_it->selected = EINA_TRUE;
1093                }
1094
1095              if (pos > first_vis && pos < last_vis)
1096                update = EINA_TRUE;
1097           }
1098         pos++;
1099      }
1100    if (v_items) eina_list_free(v_items);
1101
1102    sd->items = eina_list_sort(sd->items, -1, _sort_cb);
1103
1104    if (update || !last_vis || v->plugin != p)
1105      {
1106         v->plugin = p;
1107         _update_frame(v->span);
1108      }
1109
1110    v->tabs->update(v->tabs);
1111
1112    return 0;
1113 }
1114
1115 static int
1116 _cb_key_down(Evry_View *view, const Ecore_Event_Key *ev)
1117 {
1118    View *v = (View *) view;
1119    Smart_Data *sd = evas_object_smart_data_get(v->span);
1120    Eina_List *l = NULL, *ll;
1121    Item *it = NULL;
1122    const Evry_State *s;
1123    int slide;
1124
1125    if (!sd || !(s = v->state) || !(s->plugin))
1126      return 0;
1127
1128    const char *key = ev->key;
1129
1130    sd->mouse_act = 0;
1131    sd->mouse_x = 0;
1132    sd->mouse_y = 0;
1133
1134    if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
1135         (!strcmp(key, "2")))
1136      {
1137         if (v->mode == VIEW_MODE_LIST)
1138           v->mode = VIEW_MODE_DETAIL;
1139         else
1140           v->mode = VIEW_MODE_LIST;
1141
1142         v->zoom = 0;
1143         _clear_items(v->span);
1144         _update_frame(v->span);
1145         goto end;
1146      }
1147    else if (((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
1148              (!strcmp(key, "3"))) || !strcmp(key, "XF86Forward"))
1149      {
1150         if (v->mode != VIEW_MODE_THUMB)
1151           {
1152              v->zoom = 0;
1153              v->mode = VIEW_MODE_THUMB;
1154              _clear_items(v->span);
1155           }
1156         else
1157           {
1158              v->zoom++;
1159              if (v->zoom > 2) v->zoom = 0;
1160              if (v->zoom == 2)
1161                _clear_items(v->span);
1162           }
1163         _update_frame(v->span);
1164         goto end;
1165      }
1166    else if (!strcmp(key, "XF86Back"))
1167      {
1168         if (v->mode == VIEW_MODE_LIST ||
1169             v->mode == VIEW_MODE_DETAIL)
1170           {
1171              v->zoom = 0;
1172              v->mode = VIEW_MODE_THUMB;
1173           }
1174         else
1175           {
1176              v->mode = VIEW_MODE_DETAIL;
1177           }
1178
1179         _clear_items(v->span);
1180         _update_frame(v->span);
1181         goto end;
1182      }
1183
1184    if (((ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) ||
1185         (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) &&
1186        (!strcmp(key, "Up")))
1187      {
1188         if (!sd->items) goto end;
1189         it = sd->items->data;
1190
1191         _pan_item_select(v->span, it, 1);
1192         evry_item_select(s, it->item);
1193         goto end;
1194      }
1195    else if (((ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) ||
1196              (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) &&
1197             (!strcmp(key, "Down")))
1198      {
1199         if (!sd->items) goto end;
1200
1201         it = eina_list_last(sd->items)->data;
1202         _pan_item_select(v->span, it, 1);
1203         evry_item_select(s, it->item);
1204         goto end;
1205      }
1206
1207    if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
1208        (!strcmp(key, "plus")))
1209      {
1210         EINA_LIST_FOREACH(sd->items, ll, it)
1211           {
1212              if (!it->item->marked)
1213                {
1214                   if (it->frame)
1215                     edje_object_signal_emit(it->frame, "e,state,marked", "e");
1216                   evry_item_mark(s, it->item, 1);
1217                }
1218           }
1219         goto end;
1220      }
1221    else if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
1222             (!strcmp(key, "minus")))
1223      {
1224         EINA_LIST_FOREACH(sd->items, ll, it)
1225           {
1226              if (it->item->marked)
1227                {
1228                   if (it->frame)
1229                     edje_object_signal_emit(it->frame, "e,state,unmarked", "e");
1230                   evry_item_mark(s, it->item, 0);
1231                }
1232           }
1233         goto end;
1234      }
1235    else if (!strcmp(key, "comma") || !strcmp(key, "semicolon"))
1236      {
1237         if (!sd->cur_item)
1238           goto end;
1239
1240         if (!sd->cur_item->item->marked)
1241           {
1242              edje_object_signal_emit(sd->cur_item->frame, "e,state,marked", "e");
1243              evry_item_mark(s, sd->cur_item->item, 1);
1244           }
1245         else
1246           {
1247              edje_object_signal_emit(sd->cur_item->frame, "e,state,unmarked", "e");
1248              evry_item_mark(s, sd->cur_item->item, 0);
1249           }
1250
1251         if (v->mode == VIEW_MODE_THUMB)
1252           {
1253              if (!strcmp(key, "comma"))
1254                key = "Right";
1255              else
1256                key = "Left";
1257           }
1258         else
1259           {
1260              if (!strcmp(key, "comma"))
1261                key = "Down";
1262              else
1263                key = "Up";
1264           }
1265      }
1266
1267    if ((slide = v->tabs->key_down(v->tabs, ev)))
1268      {
1269         /* _view_update(view, -slide); */
1270         _view_update(view);
1271         return 1;
1272      }
1273
1274    if (sd->items)
1275      l = eina_list_data_find_list(sd->items, sd->cur_item);
1276    if (!l)
1277      l = sd->items;
1278
1279    if (v->mode == VIEW_MODE_THUMB && !evry_conf->cycle_mode)
1280      {
1281         if (!strcmp(key, "Right"))
1282           {
1283              if (l && l->next)
1284                it = l->next->data;
1285
1286              if (it)
1287                {
1288                   _pan_item_select(v->span, it, 1);
1289                   evry_item_select(s, it->item);
1290                }
1291              goto end;
1292           }
1293         else if (!strcmp(key, "Left"))
1294           {
1295              if (l && l->prev)
1296                it = l->prev->data;
1297
1298              if (it)
1299                {
1300                   _pan_item_select(v->span, it, 1);
1301                   evry_item_select(s, it->item);
1302                }
1303              goto end;
1304           }
1305      }
1306    if (!strcmp(key, "Down"))
1307      {
1308         if (v->mode == VIEW_MODE_THUMB &&
1309             (!evry_conf->cycle_mode) &&
1310             (sd->cur_item))
1311           {
1312              EINA_LIST_FOREACH(l, ll, it)
1313                {
1314                   if (it->y > sd->cur_item->y &&
1315                       it->x >= sd->cur_item->x)
1316                     break;
1317                }
1318           }
1319
1320         if (!it && l && l->next)
1321           it = l->next->data;
1322
1323         if (it)
1324           {
1325              _pan_item_select(v->span, it, 1);
1326              evry_item_select(s, it->item);
1327           }
1328         goto end;
1329      }
1330    else if (!strcmp(key, "Up"))
1331      {
1332         if (v->mode == VIEW_MODE_THUMB &&
1333             (!evry_conf->cycle_mode) &&
1334             (sd->cur_item))
1335           {
1336              for(ll = l; ll; ll = ll->prev)
1337                {
1338                   it = ll->data;
1339
1340                   if (it->y < sd->cur_item->y &&
1341                       it->x <= sd->cur_item->x)
1342                     break;
1343                }
1344           }
1345
1346         if (!it && l && l->prev)
1347           it = l->prev->data;
1348
1349         if (it)
1350           {
1351              _pan_item_select(v->span, it, 1);
1352              evry_item_select(s, it->item);
1353           }
1354         goto end;
1355      }
1356    else if ((!strcmp(key, "Prior") || (!strcmp(key, "Next"))))
1357      {
1358         int cur = 0;
1359         int next = (!strcmp(key, "Next"));
1360         if (sd->cur_item)
1361           cur = sd->cur_item->y;
1362
1363         EINA_LIST_FOREACH(sd->items, l, it)
1364           {
1365              if (next)
1366                {
1367                   if (it->y >= cur + sd->h) break;
1368                }
1369              else
1370                {
1371                   if (it->y + it->h >= cur - sd->h) break;
1372                }
1373
1374              if (!l->next)
1375                break;
1376           }
1377
1378         if (it)
1379           {
1380              _pan_item_select(v->span, it, 0);
1381              evry_item_select(s, it->item);
1382           }
1383         goto end;
1384      }
1385    else if (!ev->modifiers && !strcmp(key, "Return"))
1386      {
1387         if (v->mode == VIEW_MODE_THUMB)
1388           {
1389              if (!sd->cur_item)
1390                goto end;
1391
1392              if (evry_browse_item(sd->cur_item->item))
1393                goto end;
1394           }
1395      }
1396
1397    return 0;
1398
1399  end:
1400    return 1;
1401 }
1402
1403 static Eina_Bool
1404 _cb_item_changed(void *data, int type __UNUSED__, void *event)
1405 {
1406    Evry_Event_Item_Changed *ev = event;
1407    View *v = data;
1408    Eina_List *l;
1409    Item *it;
1410    Smart_Data *sd = evas_object_smart_data_get(v->span);
1411    if (!sd) return ECORE_CALLBACK_PASS_ON;
1412
1413    EINA_LIST_FOREACH(sd->items, l, it)
1414      if (it->item == ev->item)
1415        break;
1416
1417    if (!it)
1418      return ECORE_CALLBACK_PASS_ON;
1419
1420    if (ev->changed_selection)
1421      {
1422         _pan_item_select(v->span, it, 1);
1423         evry_item_select(v->state, ev->item);
1424      }
1425
1426    if (!it->visible)
1427      return ECORE_CALLBACK_PASS_ON;
1428
1429    edje_object_part_text_set(it->frame, "e.text.label", it->item->label);
1430
1431    if (ev->changed_icon)
1432      {
1433         if (it->do_thumb) e_thumb_icon_end(it->thumb);
1434         if (it->thumb) evas_object_del(it->thumb);
1435         if (it->image) evas_object_del(it->image);
1436
1437         it->thumb = NULL;
1438         it->image = NULL;
1439
1440         it->have_thumb = EINA_FALSE;
1441         it->do_thumb = EINA_FALSE;
1442
1443         if (!eina_list_data_find(sd->queue, it))
1444           sd->queue = eina_list_append(sd->queue, it);
1445
1446         if (!sd->thumb_idler)
1447           sd->thumb_idler = ecore_idle_enterer_add(_thumb_idler, sd);
1448      }
1449
1450    return ECORE_CALLBACK_PASS_ON;
1451 }
1452
1453 static void
1454 _view_cb_mouse_wheel(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
1455 {
1456    Evas_Event_Mouse_Wheel *ev = event_info;
1457    Smart_Data *sd = evas_object_smart_data_get(obj);
1458    if (!sd) return;
1459    if (ev->z)
1460      {
1461         if (sd->cur_item)
1462           _item_select(sd->cur_item);
1463         sd->mouse_act = 1;
1464      }
1465 }
1466
1467 static void
1468 _view_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1469 {
1470    Evas_Event_Mouse_Down *ev = event_info;
1471    Smart_Data *sd = evas_object_smart_data_get(data);
1472    if (!sd) return;
1473    sd->mouse_act = 1;
1474    sd->mouse_button = ev->button;
1475    sd->mouse_x = ev->canvas.x;
1476    sd->mouse_y = ev->canvas.y;
1477 }
1478
1479 static void
1480 _view_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1481 {
1482    /* Evas_Event_Mouse_Up *ev = event_info; */
1483    Smart_Data *sd = evas_object_smart_data_get(data);
1484    if (!sd) return;
1485    sd->mouse_x = 0;
1486    sd->mouse_y = 0;
1487    sd->mouse_button = 0;
1488    edje_object_signal_emit(sd->view->bg, "e,action,hide,into", "e");
1489    edje_object_signal_emit(sd->view->bg, "e,action,hide,back", "e");
1490 }
1491
1492 #define SLIDE_RESISTANCE 80
1493
1494 static void
1495 _view_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1496 {
1497    Evas_Event_Mouse_Move *ev = event_info;
1498    Smart_Data *sd = evas_object_smart_data_get(data);
1499    Evry_Selector *sel;
1500    int diff_y, diff_x;
1501
1502    if (!sd) return;
1503
1504    if (!sd->mouse_x)
1505      goto end;
1506
1507    sel = sd->view->state->selector;
1508    if (!sel || !sel->states)
1509      return;
1510
1511    diff_x = abs(ev->cur.canvas.x - sd->mouse_x);
1512    diff_y = abs(ev->cur.canvas.y - sd->mouse_y);
1513
1514    if (diff_y > 15 + (diff_x/2))
1515      {
1516         edje_object_signal_emit(sd->view->bg, "e,action,hide,into", "e");
1517         edje_object_signal_emit(sd->view->bg, "e,action,hide,back", "e");
1518         goto end;
1519      }
1520
1521    if ((sel->states->next) || (sel != sel->win->selectors[0]))
1522      edje_object_signal_emit(sd->view->bg, "e,action,show,back", "e");
1523
1524    if (sd->it_down)
1525      {
1526         if ((sd->it_down->item->browseable) ||
1527             (sel != sel->win->selectors[2]))
1528           edje_object_signal_emit(sd->view->bg, "e,action,show,into", "e");
1529
1530         if ((sd->cur_item != sd->it_down) && (diff_x > 10))
1531           {
1532              evry_item_select(sd->view->state, sd->it_down->item);
1533              _pan_item_select(data, sd->it_down, 0);
1534           }
1535      }
1536
1537    if (sd->mouse_button == 1)
1538      {
1539         if (ev->cur.canvas.x - sd->mouse_x > SLIDE_RESISTANCE)
1540           {
1541              sd->it_down = NULL;
1542              sd->mouse_x = 0;
1543              sd->mouse_y = 0;
1544              if (sel->states->next)
1545                evry_browse_back(sel);
1546              else
1547                evry_selectors_switch(sel->win, -1, EINA_TRUE);
1548           }
1549         else if ((sd->it_down && (sd->cur_item == sd->it_down)) &&
1550                  (sd->mouse_x - ev->cur.canvas.x > SLIDE_RESISTANCE))
1551           {
1552              edje_object_signal_emit(sd->view->bg, "e,action,hide,into", "e");
1553              edje_object_signal_emit(sd->view->bg, "e,action,hide,back", "e");
1554
1555              if (sd->it_down->item->browseable)
1556                {
1557                   evry_browse_item(sd->it_down->item);
1558                }
1559              else
1560                {
1561                   evry_selectors_switch(sel->win, 1, EINA_TRUE);
1562                }
1563
1564              sd->it_down = NULL;
1565              sd->mouse_x = 0;
1566              sd->mouse_y = 0;
1567           }
1568      }
1569    return;
1570
1571  end:
1572    sd->it_down = NULL;
1573    sd->mouse_x = 0;
1574    sd->mouse_y = 0;
1575 }
1576
1577 static Evry_View *
1578 _view_create(Evry_View *view, const Evry_State *s, const Evas_Object *swallow)
1579 {
1580    GET_VIEW(parent, view);
1581
1582    View *v;
1583    Ecore_Event_Handler *h;
1584
1585    v = E_NEW(View, 1);
1586    v->view = *view;
1587    v->state = s;
1588    v->evas = evas_object_evas_get(swallow);
1589
1590    if (s->plugin)
1591      {
1592         if ((s->selector->states->next) &&
1593             ((s->plugin->config->view_mode < 0) ||
1594              (!strcmp(s->plugin->name, N_("All")))))
1595           v->mode = parent->mode;
1596         else if (s->plugin->config->view_mode >= 0)
1597           v->mode = s->plugin->config->view_mode;
1598         else
1599           v->mode = evry_conf->view_mode;
1600      }
1601    else
1602      {
1603         if (s->selector->states->next)
1604           v->mode = parent->mode;
1605         else
1606           v->mode = evry_conf->view_mode;
1607      }
1608
1609    v->plugin = s->plugin;
1610    v->mode_prev = v->mode;
1611    v->zoom = parent->zoom;
1612
1613    v->bg = edje_object_add(v->evas);
1614    e_theme_edje_object_set(v->bg, "base/theme/modules/everything",
1615                            "e/modules/everything/thumbview/main/window");
1616    // scrolled thumbs
1617    v->span = _pan_add(v->evas);
1618    _pan_view_set(v->span, v);
1619    evas_object_event_callback_add(v->span, EVAS_CALLBACK_MOUSE_WHEEL,
1620                                   _view_cb_mouse_wheel, NULL);
1621
1622    evas_object_event_callback_add(v->bg, EVAS_CALLBACK_MOUSE_MOVE,
1623                                   _view_cb_mouse_move, v->span);
1624    evas_object_event_callback_add(v->bg, EVAS_CALLBACK_MOUSE_DOWN,
1625                                   _view_cb_mouse_down, v->span);
1626    evas_object_event_callback_add(v->bg, EVAS_CALLBACK_MOUSE_UP,
1627                                   _view_cb_mouse_up, v->span);
1628
1629    // the scrollframe holding the scrolled thumbs
1630    v->sframe = e_scrollframe_add(v->evas);
1631    e_scrollframe_custom_theme_set(v->sframe, "base/theme/modules/everything",
1632                                   "e/modules/everything/thumbview/main/scrollframe");
1633    e_scrollframe_thumbscroll_force(v->sframe, 1);
1634
1635    e_scrollframe_extern_pan_set(v->sframe, v->span,
1636                                 _pan_set, _pan_get, _pan_max_get,
1637                                 _pan_child_size_get);
1638    edje_object_part_swallow(v->bg, "e.swallow.list", v->sframe);
1639
1640    evas_object_show(v->sframe);
1641    evas_object_show(v->span);
1642
1643    v->tabs = evry_tab_view_new(EVRY_VIEW(v), v->state, v->evas);
1644
1645    EVRY_VIEW(v)->o_list = v->bg;
1646    EVRY_VIEW(v)->o_bar = v->tabs->o_tabs;
1647
1648    h = evry_event_handler_add(EVRY_EVENT_ITEM_CHANGED, _cb_item_changed, v);
1649    v->handlers = eina_list_append(v->handlers, h);
1650
1651    return EVRY_VIEW(v);
1652 }
1653
1654 static void
1655 _view_destroy(Evry_View *view)
1656 {
1657    Ecore_Event_Handler *h;
1658
1659    GET_VIEW(v, view);
1660
1661    _view_clear(view);
1662
1663    evas_object_del(v->span);
1664    evas_object_del(v->bg);
1665    evas_object_del(v->sframe);
1666
1667    evry_tab_view_free(v->tabs);
1668
1669    EINA_LIST_FREE(v->handlers, h)
1670      ecore_event_handler_del(h);
1671
1672    E_FREE(v);
1673 }
1674
1675 Eina_Bool
1676 evry_view_init(void)
1677 {
1678    if (!evry_api_version_check(EVRY_API_VERSION))
1679      return EINA_FALSE;
1680
1681    View *v = E_NEW(View, 1);
1682
1683    v->view.id = EVRY_VIEW(v);
1684    v->view.name = "Icon View";
1685    v->view.create = &_view_create;
1686    v->view.destroy = &_view_destroy;
1687    v->view.update = &_view_update;
1688    v->view.clear = &_view_clear;
1689    v->view.cb_key_down = &_cb_key_down;
1690    v->mode = VIEW_MODE_NONE;
1691
1692    evry_view_register(EVRY_VIEW(v), 1);
1693
1694    view = v;
1695
1696    return EINA_TRUE;
1697 }
1698
1699 void
1700 evry_view_shutdown(void)
1701 {
1702    evry_view_unregister(EVRY_VIEW(view));
1703    E_FREE(view);
1704 }