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