Tizen 2.1 base
[framework/uifw/elementary.git] / src / lib / elm_toolbar.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "elm_widget_toolbar.h"
4
5 EAPI const char ELM_TOOLBAR_SMART_NAME[] = "elm_toolbar";
6
7 #define ELM_TOOLBAR_ITEM_FROM_INLIST(item) \
8   ((item) ? EINA_INLIST_CONTAINER_GET(item, Elm_Toolbar_Item) : NULL)
9
10 static const char SIG_CLICKED[] = "clicked";
11 static const char SIG_LONGPRESSED[] = "longpressed";
12 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
13 static const char SIG_LANG_CHANGED[] = "language,changed";
14 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
15    {SIG_CLICKED, ""},
16    {SIG_LONGPRESSED, ""},
17    {SIG_CLICKED_DOUBLE, ""},
18    {SIG_LANG_CHANGED, ""},
19    {NULL, NULL}
20 };
21
22 static const Evas_Smart_Interface *_smart_interfaces[] =
23 {
24    (Evas_Smart_Interface *)&ELM_SCROLLABLE_IFACE, NULL
25 };
26
27 EVAS_SMART_SUBCLASS_IFACE_NEW
28   (ELM_TOOLBAR_SMART_NAME, _elm_toolbar, Elm_Toolbar_Smart_Class,
29   Elm_Widget_Smart_Class, elm_widget_smart_class_get, _smart_callbacks,
30   _smart_interfaces);
31
32 static int
33 _toolbar_item_prio_compare_cb(const void *i1,
34                               const void *i2)
35 {
36    const Elm_Toolbar_Item *eti1 = i1;
37    const Elm_Toolbar_Item *eti2 = i2;
38
39    if (!eti2) return 1;
40    if (!eti1) return -1;
41
42    if (eti2->prio.priority == eti1->prio.priority)
43      return -1;
44
45    return eti2->prio.priority - eti1->prio.priority;
46 }
47
48 static void
49 _items_visibility_fix(Elm_Toolbar_Smart_Data *sd,
50                       Evas_Coord *iw,
51                       Evas_Coord vw,
52                       Eina_Bool *more)
53 {
54    Elm_Toolbar_Item *it, *prev;
55    Evas_Coord ciw = 0, cih = 0;
56    Eina_List *sorted = NULL;
57    int count = 0, i = 0;
58
59    *more = EINA_FALSE;
60
61    EINA_INLIST_FOREACH(sd->items, it)
62      {
63         if (it->separator)
64           {
65              prev = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
66              it->prio.priority = prev->prio.priority;
67           }
68      }
69
70    EINA_INLIST_FOREACH(sd->items, it)
71      {
72         sorted = eina_list_sorted_insert
73             (sorted, _toolbar_item_prio_compare_cb, it);
74      }
75
76    if (sd->more_item)
77      {
78         evas_object_geometry_get(sd->VIEW(more_item), NULL, NULL, &ciw, &cih);
79         if (sd->vertical) *iw += cih;
80         else *iw += ciw;
81      }
82
83    EINA_LIST_FREE(sorted, it)
84      {
85         if (it->prio.priority > sd->standard_priority)
86           {
87              evas_object_geometry_get(VIEW(it), NULL, NULL, &ciw, &cih);
88              if (sd->vertical) *iw += cih;
89              else *iw += ciw;
90              it->prio.visible = (*iw <= vw);
91              it->in_box = sd->bx;
92              if (!it->separator) count++;
93           }
94         else
95           {
96              it->prio.visible = EINA_FALSE;
97              if (!it->separator) i++;
98              if (i <= (count + 1))
99                it->in_box = sd->bx_more;
100              else
101                it->in_box = sd->bx_more2;
102              *more = EINA_TRUE;
103           }
104      }
105 }
106
107 static void
108 _item_menu_destroy(Elm_Toolbar_Item *item)
109 {
110    if (item->o_menu)
111      {
112         evas_object_del(item->o_menu);
113         item->o_menu = NULL;
114      }
115    item->menu = EINA_FALSE;
116 }
117
118 static void
119 _item_unselect(Elm_Toolbar_Item *item)
120 {
121    if ((!item) || (!item->selected)) return;
122
123    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
124
125    item->selected = EINA_FALSE;
126    sd->selected_item = NULL;
127    edje_object_signal_emit(VIEW(item), "elm,state,unselected", "elm");
128    elm_widget_signal_emit(item->icon, "elm,state,unselected", "elm");
129 }
130
131 static void
132 _menu_hide(void *data,
133            Evas *e __UNUSED__,
134            Evas_Object *obj __UNUSED__,
135            void *event_info __UNUSED__)
136 {
137    Elm_Toolbar_Item *selected;
138    Elm_Toolbar_Item *it = data;
139
140    selected = (Elm_Toolbar_Item *)elm_toolbar_selected_item_get(WIDGET(it));
141    _item_unselect(selected);
142 }
143
144 static void
145 _menu_del(void *data,
146           Evas *e __UNUSED__,
147           Evas_Object *obj,
148           void *event_info __UNUSED__)
149 {
150    // avoid hide being emitted during object deletion
151    evas_object_event_callback_del_full
152      (obj, EVAS_CALLBACK_HIDE, _menu_hide, data);
153 }
154
155 static void
156 _item_menu_create(Elm_Toolbar_Smart_Data *sd,
157                   Elm_Toolbar_Item *item)
158 {
159    item->o_menu = elm_menu_add(elm_widget_parent_get(WIDGET(item)));
160    item->menu = EINA_TRUE;
161
162    if (sd->menu_parent)
163      elm_menu_parent_set(item->o_menu, sd->menu_parent);
164
165    evas_object_event_callback_add
166      (item->o_menu, EVAS_CALLBACK_HIDE, _menu_hide, item);
167    evas_object_event_callback_add
168      (item->o_menu, EVAS_CALLBACK_DEL, _menu_del, item);
169 }
170
171 static void
172 _elm_toolbar_item_menu_cb(void *data,
173                           Evas_Object *obj __UNUSED__,
174                           void *event_info __UNUSED__)
175 {
176    Elm_Toolbar_Item *it = data;
177
178    if (it->func) it->func((void *)(it->base.data), WIDGET(it), it);
179 }
180
181 static void
182 _item_show(Elm_Toolbar_Item *it)
183 {
184    Evas_Coord x, y, w, h, bx, by;
185
186    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
187
188    evas_object_geometry_get(sd->bx, &bx, &by, NULL, NULL);
189    evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
190    sd->s_iface->content_region_show
191      (ELM_WIDGET_DATA(sd)->obj, x - bx, y - by, w, h);
192 }
193
194 static void
195 _item_mirrored_set(Evas_Object *obj __UNUSED__,
196                    Elm_Toolbar_Item *it,
197                    Eina_Bool mirrored)
198 {
199    edje_object_mirrored_set(VIEW(it), mirrored);
200    if (it->o_menu) elm_widget_mirrored_set(it->o_menu, mirrored);
201 }
202
203 static void
204 _mirrored_set(Evas_Object *obj,
205               Eina_Bool mirrored)
206 {
207    Elm_Toolbar_Item *it;
208
209    ELM_TOOLBAR_DATA_GET(obj, sd);
210
211    EINA_INLIST_FOREACH(sd->items, it)
212      _item_mirrored_set(obj, it, mirrored);
213    if (sd->more_item)
214      _item_mirrored_set(obj, sd->more_item, mirrored);
215 }
216
217 static void
218 _items_size_fit(Evas_Object *obj, Evas_Coord *bl, Evas_Coord view)
219 {
220    Elm_Toolbar_Item *it, *prev;
221    Eina_Bool full = EINA_FALSE, more = EINA_FALSE;
222    Evas_Coord min, mw, mh;
223    int sumf = 0, sumb = 0, prev_min = 0;
224
225    ELM_TOOLBAR_DATA_GET(obj, sd);
226
227    EINA_INLIST_FOREACH(sd->items, it)
228      {
229         min = mw = mh = -1;
230         if (it->in_box && it->in_box == sd->bx)
231           {
232              if (!it->separator && !it->object)
233                elm_coords_finger_size_adjust(1, &mw, 1, &mh);
234              edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
235              if (!it->separator && !it->object)
236                elm_coords_finger_size_adjust(1, &mw, 1, &mh);
237           }
238         else if (!more)
239           {
240              more = EINA_TRUE;
241              elm_coords_finger_size_adjust(1, &mw, 1, &mh);
242              edje_object_size_min_restricted_calc(sd->VIEW(more_item), &mw, &mh, mw, mh);
243              elm_coords_finger_size_adjust(1, &mw, 1, &mh);
244           }
245
246         if (mw != -1 || mh != -1)
247           {
248              if (sd->vertical) min = mh;
249              else min = mw;
250
251              if ((!full) && ((sumf + min) > view))
252                {
253                   prev = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
254                   if (prev && prev->separator)
255                     {
256                        sumf -= prev_min;
257                        sumb += prev_min;
258                     }
259                   full = EINA_TRUE;
260                }
261
262              if (!full) sumf += min;
263              else sumb += min;
264              prev_min = min;
265           }
266      }
267    if (sumf != 0) *bl = (Evas_Coord)(((sumf + sumb) * view) / sumf);
268 }
269
270 static Eina_Bool
271 _elm_toolbar_item_coordinates_calc(Elm_Object_Item *item,
272                                    Elm_Toolbar_Item_Scrollto_Type type,
273                                    Evas_Coord *x,
274                                    Evas_Coord *y,
275                                    Evas_Coord *w,
276                                    Evas_Coord *h)
277 {
278    Evas_Coord ix, iy, iw, ih, bx, by, vw, vh;
279
280    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
281
282    sd->s_iface->content_viewport_size_get(WIDGET(item), &vw, &vh);
283    evas_object_geometry_get(sd->bx, &bx, &by, NULL, NULL);
284    evas_object_geometry_get(VIEW(item), &ix, &iy, &iw, &ih);
285
286    switch (type)
287      {
288       case ELM_TOOLBAR_ITEM_SCROLLTO_IN:
289          *x = ix - bx;
290          *y = iy - by;
291          *w = iw;
292          *h = ih;
293          break;
294
295       case ELM_TOOLBAR_ITEM_SCROLLTO_FIRST:
296          *x = ix - bx;
297          *y = iy - by;
298          *w = vw;
299          *h = vh;
300          break;
301
302       case ELM_TOOLBAR_ITEM_SCROLLTO_MIDDLE:
303          *x = ix - bx + (iw / 2) - (vw / 2);
304          *y = iy - by + (ih / 2) - (vh / 2);
305          *w = vw;
306          *h = vh;
307          break;
308
309       case ELM_TOOLBAR_ITEM_SCROLLTO_LAST:
310          *x = ix - bx + iw - vw;
311          *y = iy - by + ih - vh;
312          *w = vw;
313          *h = vh;
314          break;
315
316       default:
317          return EINA_FALSE;
318      }
319
320    return EINA_TRUE;
321 }
322
323 static void
324 _resize_job(void *data)
325 {
326    Evas_Object *obj = (Evas_Object *)data;
327    Evas_Coord mw, mh, vw = 0, vh = 0, w = 0, h = 0;
328    Elm_Toolbar_Item *it;
329    Evas_Object *o; // TIZEN ONLY
330    Eina_List *l; // TIZEN ONLY
331    Eina_List *list;
332    Eina_Bool more;
333
334    ELM_TOOLBAR_DATA_GET(obj, sd);
335
336    sd->resize_job = NULL;
337    sd->s_iface->content_viewport_size_get(obj, &vw, &vh);
338    evas_object_size_hint_min_get(sd->bx, &mw, &mh);
339    evas_object_geometry_get(sd->bx, NULL, NULL, &w, &h);
340
341    if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_MENU)
342      {
343         Evas_Coord iw = 0, ih = 0, more_w = 0, more_h = 0;
344
345         if (sd->vertical)
346           {
347              h = vh;
348              _items_visibility_fix(sd, &ih, vh, &more);
349           }
350         else
351           {
352              w = vw;
353              _items_visibility_fix(sd, &iw, vw, &more);
354           }
355         evas_object_geometry_get
356           (sd->VIEW(more_item), NULL, NULL, &more_w, &more_h);
357
358         if (sd->vertical)
359           {
360              if ((ih - more_h) <= vh) ih -= more_h;
361           }
362         else
363           {
364              if ((iw - more_w) <= vw) iw -= more_w;
365           }
366
367         /* All items are removed from the box object, since removing
368          * individual items won't trigger a resize. Items are be
369          * readded below. */
370         evas_object_box_remove_all(sd->bx, EINA_FALSE);
371         if (((sd->vertical) && (ih > vh)) ||
372             ((!sd->vertical) && (iw > vw)) || more)
373           {
374              Evas_Object *menu;
375
376              _item_menu_destroy(sd->more_item);
377              _item_menu_create(sd, sd->more_item);
378              menu =
379                elm_toolbar_item_menu_get((Elm_Object_Item *)sd->more_item);
380              EINA_INLIST_FOREACH(sd->items, it)
381                {
382                   if (!it->prio.visible)
383                     {
384                        if (it->separator)
385                          elm_menu_item_separator_add(menu, NULL);
386                        else
387                          {
388                             Elm_Object_Item *menu_it;
389
390                             menu_it = elm_menu_item_add
391                                 (menu, NULL, it->icon_str, it->label,
392                                 _elm_toolbar_item_menu_cb, it);
393                             elm_object_item_disabled_set
394                               (menu_it, elm_widget_item_disabled_get(it));
395                             if (it->o_menu)
396                               elm_menu_clone(it->o_menu, menu, menu_it);
397                          }
398                        evas_object_hide(VIEW(it));
399                     }
400                   else
401                     {
402                        evas_object_box_append(sd->bx, VIEW(it));
403                        evas_object_show(VIEW(it));
404                     }
405                }
406              evas_object_box_append(sd->bx, sd->VIEW(more_item));
407              evas_object_show(sd->VIEW(more_item));
408           }
409         else
410           {
411              /* All items are visible, show them all (except for the
412               * "More" button, of course). */
413              EINA_INLIST_FOREACH(sd->items, it)
414                {
415                   evas_object_show(VIEW(it));
416                   evas_object_box_append(sd->bx, VIEW(it));
417                }
418              evas_object_hide(sd->VIEW(more_item));
419           }
420      }
421    else if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_HIDE)
422      {
423         Evas_Coord iw = 0, ih = 0;
424
425         if (sd->vertical)
426           {
427              h = vh;
428              _items_visibility_fix(sd, &ih, vh, &more);
429           }
430         else
431           {
432              w = vw;
433              _items_visibility_fix(sd, &iw, vw, &more);
434           }
435         evas_object_box_remove_all(sd->bx, EINA_FALSE);
436         if (((sd->vertical) && (ih > vh)) ||
437             ((!sd->vertical) && (iw > vw)) || more)
438           {
439              EINA_INLIST_FOREACH(sd->items, it)
440                {
441                   if (!it->prio.visible)
442                     evas_object_hide(VIEW(it));
443                   else
444                     {
445                        evas_object_box_append(sd->bx, VIEW(it));
446                        evas_object_show(VIEW(it));
447                     }
448                }
449           }
450         else
451           {
452              /* All items are visible, show them all */
453              EINA_INLIST_FOREACH(sd->items, it)
454                {
455                   evas_object_show(VIEW(it));
456                   evas_object_box_append(sd->bx, VIEW(it));
457                }
458           }
459      }
460    else if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
461      {
462         Evas_Coord iw = 0, ih = 0;
463
464         if (sd->vertical)
465           h = (vh >= mh) ? vh : mh;
466         else
467           w = (vw >= mw) ? vw : mw;
468
469         if (sd->vertical)
470           _items_visibility_fix(sd, &ih, vh, &more);
471         else
472           _items_visibility_fix(sd, &iw, vw, &more);
473
474         evas_object_box_remove_all(sd->bx, EINA_FALSE);
475         evas_object_box_remove_all(sd->bx_more, EINA_FALSE);
476         evas_object_box_remove_all(sd->bx_more2, EINA_FALSE);
477
478         EINA_INLIST_FOREACH(sd->items, it)
479           {
480              if (it->in_box)
481                {
482                   evas_object_box_append(it->in_box, VIEW(it));
483                   evas_object_show(VIEW(it));
484                }
485           }
486         if (more)
487           {
488              evas_object_box_append(sd->bx, sd->VIEW(more_item));
489              evas_object_show(sd->VIEW(more_item));
490           }
491         else
492           evas_object_hide(sd->VIEW(more_item));
493
494         if (sd->vertical)
495           {
496              if (h >= vh) _items_size_fit(obj, &h, vh);
497              if (sd->item_count - sd->separator_count > 0)
498                sd->s_iface->paging_set(obj, 0.0, 0.0, 0, (h / (sd->item_count - sd->separator_count)));
499           }
500         else
501           {
502              if (w >= vw) _items_size_fit(obj, &w, vw);
503              if (sd->item_count - sd->separator_count > 0)
504                sd->s_iface->paging_set(obj, 0.0, 0.0, (w / (sd->item_count - sd->separator_count)), 0);
505           }
506      }
507    else
508      {
509         if (sd->vertical)
510           {
511              if ((vh >= mh) && (h != vh)) h = vh;
512           }
513         else
514           {
515              if ((vw >= mw) && (w != vw)) w = vw;
516           }
517         EINA_INLIST_FOREACH(sd->items, it)
518           {
519              if (it->selected)
520                {
521                   _item_show(it);
522                   break;
523                }
524           }
525      }
526
527    if (sd->transverse_expanded)
528      {
529         if (sd->vertical)
530           w = vw;
531         else
532           h = vh;
533      }
534
535    evas_object_resize(sd->bx, w, h);
536
537 //// TIZEN ONLY
538    list = evas_object_box_children_get(sd->bx);
539    EINA_LIST_FOREACH(list, l, o)
540      {
541         if (o == eina_list_nth(list, 0))
542           edje_object_signal_emit(o, "elm,order,first,item", "elm");
543         else if (o == eina_list_nth(list, eina_list_count(list)-1))
544           edje_object_signal_emit(o, "elm,order,last,item", "elm");
545         else
546           edje_object_signal_emit(o, "elm,order,default,item", "elm");
547      }
548 //
549
550 // Remove the first or last separator since it is not neccessary
551    list = evas_object_box_children_get(sd->bx_more);
552    EINA_INLIST_FOREACH(sd->items, it)
553      {
554         if (it->separator &&
555             ((VIEW(it) == eina_list_data_get(list)) ||
556              (VIEW(it) == eina_list_nth(list, eina_list_count(list) - 1))))
557           {
558              evas_object_box_remove(sd->bx_more, VIEW(it));
559              evas_object_move(VIEW(it), -9999, -9999);
560              evas_object_hide(VIEW(it));
561           }
562      }
563    list = evas_object_box_children_get(sd->bx_more2);
564    EINA_INLIST_FOREACH(sd->items, it)
565      {
566         if (it->separator &&
567             ((VIEW(it) == eina_list_data_get(list)) ||
568              (VIEW(it) == eina_list_nth(list, eina_list_count(list) - 1))))
569           {
570              evas_object_box_remove(sd->bx_more2, VIEW(it));
571              evas_object_move(VIEW(it), -9999, -9999);
572              evas_object_hide(VIEW(it));
573           }
574      }
575
576    _mirrored_set(obj, elm_widget_mirrored_get(obj));
577 }
578
579 static Eina_Bool
580 _elm_toolbar_smart_on_focus(Evas_Object *obj)
581 {
582    ELM_TOOLBAR_DATA_GET(obj, sd);
583
584    if (elm_widget_focus_get(obj))
585      evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE);
586    else
587      evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE);
588
589    return EINA_TRUE;
590 }
591
592 static Eina_Bool
593 _elm_toolbar_smart_event(Evas_Object *obj __UNUSED__,
594                          Evas_Object *src __UNUSED__,
595                          Evas_Callback_Type type __UNUSED__,
596                          void *event_info)
597 {
598    Evas_Event_Key_Down *ev = event_info;
599
600    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
601
602    // Key Down Event precess for toolbar.
603
604    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
605
606    return EINA_TRUE;
607 }
608
609 static void
610 _resize_cb(void *data,
611            Evas *e __UNUSED__,
612            Evas_Object *obj __UNUSED__,
613            void *event_info __UNUSED__)
614 {
615    Evas_Coord x, y, h;
616
617    ELM_TOOLBAR_DATA_GET(data, sd);
618
619    evas_object_geometry_get(data, &x, &y, NULL, &h);
620    evas_object_move(sd->more, x, y + h);
621
622    if (!sd->resize_job)
623      sd->resize_job = ecore_job_add(_resize_job, data);
624 }
625
626 static void
627 _item_disable_hook(Elm_Object_Item *it)
628 {
629    Elm_Toolbar_Item *toolbar_it = (Elm_Toolbar_Item *)it;
630
631    if (elm_widget_item_disabled_get(toolbar_it))
632      {
633         edje_object_signal_emit(VIEW(toolbar_it), "elm,state,disabled", "elm");
634         elm_widget_signal_emit(toolbar_it->icon, "elm,state,disabled", "elm");
635      }
636    else
637      {
638         edje_object_signal_emit(VIEW(toolbar_it), "elm,state,enabled", "elm");
639         elm_widget_signal_emit(toolbar_it->icon, "elm,state,enabled", "elm");
640      }
641
642    _resize_cb(WIDGET(toolbar_it), NULL, NULL, NULL);
643 }
644
645 static Eina_Bool
646 _item_icon_set(Evas_Object *icon_obj,
647                const char *type,
648                const char *icon)
649 {
650    char icon_str[512];
651
652    if ((!type) || (!*type)) goto end;
653    if ((!icon) || (!*icon)) return EINA_FALSE;
654    if ((snprintf(icon_str, sizeof(icon_str), "%s%s", type, icon) > 0)
655        && (elm_icon_standard_set(icon_obj, icon_str)))
656      return EINA_TRUE;
657 end:
658    if (elm_icon_standard_set(icon_obj, icon))
659      return EINA_TRUE;
660
661    WRN("couldn't find icon definition for '%s'", icon);
662    return EINA_FALSE;
663 }
664
665 static int
666 _elm_toolbar_icon_size_get(Elm_Toolbar_Smart_Data *sd)
667 {
668    const char *icon_size = edje_object_data_get
669        (ELM_WIDGET_DATA(sd)->resize_obj, "icon_size");
670
671    if (icon_size) return atoi(icon_size);
672
673    return _elm_config->icon_size;
674 }
675
676 static void
677 _menu_move_resize_cb(void *data,
678                      Evas *e __UNUSED__,
679                      Evas_Object *obj __UNUSED__,
680                      void *event_info __UNUSED__)
681 {
682    Elm_Toolbar_Item *it = data;
683    Evas_Coord x, y, h;
684
685    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
686
687    if (!sd->menu_parent) return;
688    evas_object_geometry_get(VIEW(it), &x, &y, NULL, &h);
689    elm_menu_move(it->o_menu, x, y + h);
690 }
691
692 static void
693 _item_select(Elm_Toolbar_Item *it)
694 {
695    Elm_Toolbar_Item *it2;
696    Evas_Object *obj2;
697    Eina_Bool sel;
698
699    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
700
701    if (elm_widget_item_disabled_get(it) || (it->separator) || (it->object))
702      return;
703    sel = it->selected;
704
705    if (sd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
706      {
707         if (sel)
708           {
709              if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
710                {
711                   if (sd->more_item == it)
712                     {
713                        elm_layout_signal_emit
714                          (sd->more, "elm,state,close", "elm");
715                        _item_unselect(it);
716                     }
717                }
718              if (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS)
719                _item_unselect(it);
720           }
721         else
722           {
723              it2 = (Elm_Toolbar_Item *)
724                elm_toolbar_selected_item_get(WIDGET(it));
725              _item_unselect(it2);
726
727              it->selected = EINA_TRUE;
728              sd->selected_item = it;
729              if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
730                {
731                   if (sd->more_item == it)
732                     {
733                        if (!evas_object_box_children_get(sd->bx_more2))
734                          elm_layout_signal_emit
735                            (sd->more, "elm,state,open", "elm");
736                        else
737                          elm_layout_signal_emit
738                            (sd->more, "elm,state,open2", "elm");
739                     }
740                   else
741                     {
742                        if (it->in_box != sd->bx)
743                          {
744                             edje_object_signal_emit
745                               (sd->VIEW(more_item), "elm,state,selected",
746                               "elm");
747                             elm_widget_signal_emit
748                               (sd->more_item->icon, "elm,state,selected",
749                               "elm");
750                          }
751                        else
752                          {
753                             edje_object_signal_emit
754                               (sd->VIEW(more_item), "elm,state,unselected",
755                               "elm");
756                             elm_widget_signal_emit
757                               (sd->more_item->icon, "elm,state,unselected",
758                               "elm");
759                          }
760                        elm_layout_signal_emit
761                          (sd->more, "elm,state,close", "elm");
762                     }
763                }
764              edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
765              elm_widget_signal_emit(it->icon, "elm,state,selected", "elm");
766              _item_show(it);
767           }
768      }
769
770    obj2 = WIDGET(it);
771    if (it->menu && (!sel))
772      {
773         evas_object_show(it->o_menu);
774         evas_object_event_callback_add
775           (VIEW(it), EVAS_CALLBACK_RESIZE, _menu_move_resize_cb, it);
776         evas_object_event_callback_add
777           (VIEW(it), EVAS_CALLBACK_MOVE, _menu_move_resize_cb, it);
778
779         _menu_move_resize_cb(it, NULL, NULL, NULL);
780      }
781
782    if ((!sel) || (sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
783      {
784         if (it->func) it->func((void *)(it->base.data), WIDGET(it), it);
785      }
786    evas_object_smart_callback_call(obj2, SIG_CLICKED, it);
787 }
788
789 static void
790 _item_del(Elm_Toolbar_Item *it)
791 {
792    Elm_Toolbar_Item_State *it_state;
793
794    _item_unselect(it);
795
796    EINA_LIST_FREE(it->states, it_state)
797      {
798         if (it->icon == it_state->icon)
799           it->icon = NULL;
800         eina_stringshare_del(it_state->label);
801         eina_stringshare_del(it_state->icon_str);
802         if (it_state->icon) evas_object_del(it_state->icon);
803         free(it_state);
804      }
805
806    eina_stringshare_del(it->label);
807    if (it->label)
808      edje_object_signal_emit(VIEW(it), "elm,state,text,hidden", "elm");
809    eina_stringshare_del(it->icon_str);
810
811    if (it->icon)
812      {
813         edje_object_signal_emit(VIEW(it), "elm,state,icon,hidden", "elm");
814         evas_object_del(it->icon);
815      }
816
817    if (it->object) evas_object_del(it->object);
818    //TODO: See if checking for sd->menu_parent is necessary before
819    //deleting menu
820    if (it->o_menu) evas_object_del(it->o_menu);
821 }
822
823 static void
824 _item_theme_hook(Evas_Object *obj,
825                  Elm_Toolbar_Item *it,
826                  double scale,
827                  int icon_size)
828 {
829    Evas_Coord mw, mh, minw, minh;
830    Evas_Object *view = VIEW(it);
831    const char *style;
832
833    ELM_TOOLBAR_DATA_GET(obj, sd);
834
835    style = elm_widget_style_get(obj);
836
837    _item_mirrored_set(obj, it, elm_widget_mirrored_get(obj));
838    edje_object_scale_set(view, scale);
839
840    if (!it->separator && !it->object)
841      {
842         elm_widget_theme_object_set(obj, view, "toolbar", "item", style);
843         if (it->selected)
844           {
845              edje_object_signal_emit(view, "elm,state,selected", "elm");
846              elm_widget_signal_emit(it->icon, "elm,state,selected", "elm");
847           }
848         if (elm_widget_item_disabled_get(it))
849           {
850              edje_object_signal_emit(view, "elm,state,disabled", "elm");
851              elm_widget_signal_emit(it->icon, "elm,state,disabled", "elm");
852           }
853         if (it->icon)
854           {
855              int ms = 0;
856
857              ms = ((double)icon_size * scale);
858              evas_object_size_hint_min_set(it->icon, ms, ms);
859              evas_object_size_hint_max_set(it->icon, ms, ms);
860              edje_object_part_swallow(view, "elm.swallow.icon", it->icon);
861              edje_object_signal_emit
862                (VIEW(it), "elm,state,icon,visible", "elm");
863           }
864         if (it->label)
865           {
866              edje_object_part_text_escaped_set(view, "elm.text", it->label);
867              edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm");
868           }
869      }
870    else
871      {
872         if (!it->object)
873           {
874              elm_widget_theme_object_set
875                (obj, view, "toolbar", "separator", style);
876              if (sd->vertical)
877                {
878                   evas_object_size_hint_weight_set
879                     (view, EVAS_HINT_EXPAND, -1.0);
880                   evas_object_size_hint_align_set
881                     (view, EVAS_HINT_FILL, EVAS_HINT_FILL);
882                }
883              else
884                {
885                   evas_object_size_hint_weight_set
886                     (view, -1.0, EVAS_HINT_EXPAND);
887                   evas_object_size_hint_align_set
888                     (view, EVAS_HINT_FILL, EVAS_HINT_FILL);
889                }
890           }
891         else
892           {
893              elm_widget_theme_object_set
894                (obj, view, "toolbar", "object", style);
895              edje_object_part_swallow(view, "elm.swallow.object", it->object);
896           }
897      }
898
899    mw = mh = minw = minh = -1;
900    if (!it->separator && !it->object)
901      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
902
903    edje_object_size_min_restricted_calc(view, &mw, &mh, mw, mh);
904    if (!it->separator && !it->object)
905      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
906    evas_object_size_hint_min_set(view, mw, mh);
907 }
908
909 static void
910 _inform_item_number(Evas_Object *obj)
911 {
912    ELM_TOOLBAR_DATA_GET(obj, sd);
913    Elm_Toolbar_Item *it;
914    char buf[sizeof("elm,action,click,") + 3];
915    static int scount = 0;
916    int count = 0;
917
918    EINA_INLIST_FOREACH(sd->items, it)
919      {
920         if (!it->separator) count++;
921      }
922    if (scount != count)
923      {
924         scount = count;
925         sprintf(buf, "elm,number,item,%d", count);
926
927         EINA_INLIST_FOREACH(sd->items, it)
928           {
929              if (!it->separator && !it->object)
930                edje_object_signal_emit(VIEW(it), buf, "elm");
931           }
932      }
933 }
934
935 static void
936 _sizing_eval(Evas_Object *obj)
937 {
938    Evas_Coord minw = -1, minh = -1, minw_bx = -1, minh_bx = -1;
939    Evas_Coord vw = 0, vh = 0;
940    Evas_Coord w, h;
941
942    ELM_TOOLBAR_DATA_GET(obj, sd);
943
944    evas_object_smart_need_recalculate_set(sd->bx, EINA_TRUE);
945    evas_object_smart_calculate(sd->bx);
946    edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
947    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
948
949    if (w < minw) w = minw;
950    if (h < minh) h = minh;
951
952    evas_object_resize(ELM_WIDGET_DATA(sd)->resize_obj, w, h);
953
954    evas_object_size_hint_min_get(sd->bx, &minw_bx, &minh_bx);
955    sd->s_iface->content_viewport_size_get(obj, &vw, &vh);
956
957    if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_NONE)
958    {
959            minw = minw_bx + (w - vw);
960            minh = minh_bx + (h - vh);
961    }
962    else if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
963    {
964            if (sd->vertical)
965            {
966                    minw = minw_bx + (w - vw);
967                    if (minh_bx < vh) minh_bx = vh;
968                    else _items_size_fit(obj, &minh_bx, vh);
969            }
970            else
971            {
972                    minh = minh_bx + (h - vh);
973                    if (minw_bx < vw) minw_bx = vw;
974                    else _items_size_fit(obj, &minw_bx, vw);
975            }
976    }
977    else
978      {
979         if (sd->vertical)
980           {
981              minw = minw_bx + (w - vw);
982              minh = h - vh;
983           }
984         else
985           {
986              minw = w - vw;
987              minh = minh_bx + (h - vh);
988           }
989      }
990
991    if (sd->transverse_expanded)
992      {
993         if (sd->vertical)
994           minw_bx = vw;
995         else
996           minh_bx = vh;
997      }
998
999    evas_object_resize(sd->bx, minw_bx, minh_bx);
1000    evas_object_resize(sd->more, minw_bx, minh_bx);
1001    evas_object_size_hint_min_set(obj, minw, minh);
1002    evas_object_size_hint_max_set(obj, -1, -1);
1003
1004    _inform_item_number(obj);
1005 }
1006
1007 static Eina_Bool
1008 _elm_toolbar_smart_theme(Evas_Object *obj)
1009 {
1010    Elm_Toolbar_Item *it;
1011    double scale = 0;
1012
1013    ELM_TOOLBAR_DATA_GET(obj, sd);
1014
1015    if (sd->on_deletion)
1016      return EINA_TRUE;
1017
1018    if (!ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->theme(obj))
1019      return EINA_FALSE;
1020
1021    elm_widget_theme_object_set
1022      (obj, ELM_WIDGET_DATA(sd)->resize_obj, "toolbar", "base",
1023      elm_widget_style_get(obj));
1024
1025    elm_layout_theme_set
1026      (sd->more, "toolbar", "more", elm_widget_style_get(obj));
1027
1028    _mirrored_set(obj, elm_widget_mirrored_get(obj));
1029
1030    sd->theme_icon_size = _elm_toolbar_icon_size_get(sd);
1031    if (sd->priv_icon_size) sd->icon_size = sd->priv_icon_size;
1032    else sd->icon_size = sd->theme_icon_size;
1033
1034    EINA_INLIST_FOREACH(sd->items, it)
1035      _item_theme_hook(obj, it, scale, sd->icon_size);
1036
1037    if (sd->more_item)
1038      _item_theme_hook(obj, sd->more_item, scale, sd->icon_size);
1039
1040    _sizing_eval(obj);
1041
1042    return EINA_TRUE;
1043 }
1044
1045 static void
1046 _elm_toolbar_item_label_update(Elm_Toolbar_Item *item)
1047 {
1048    Evas_Coord mw = -1, mh = -1, minw = -1, minh = -1;
1049
1050    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
1051
1052    edje_object_part_text_escaped_set(VIEW(item), "elm.text", item->label);
1053    if (item->label)
1054      edje_object_signal_emit(VIEW(item), "elm,state,text,visible", "elm");
1055    else
1056      edje_object_signal_emit(VIEW(item), "elm,state,text,hidden", "elm");
1057
1058    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1059    edje_object_size_min_restricted_calc(VIEW(item), &mw, &mh, mw, mh);
1060    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1061    if (sd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
1062      {
1063         if (sd->vertical)
1064           {
1065              evas_object_size_hint_weight_set
1066                (VIEW(item), EVAS_HINT_EXPAND, -1.0);
1067              evas_object_size_hint_align_set
1068                (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1069           }
1070         else
1071           {
1072              evas_object_size_hint_weight_set
1073                (VIEW(item), -1.0, EVAS_HINT_EXPAND);
1074              evas_object_size_hint_align_set
1075                (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1076           }
1077      }
1078    else
1079      {
1080         evas_object_size_hint_weight_set
1081           (VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1082         evas_object_size_hint_align_set
1083           (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1084      }
1085
1086    evas_object_size_hint_min_get(VIEW(item), &minw, &minh);
1087    if ((minw < mw) && (minh < mh))
1088      evas_object_size_hint_min_set(VIEW(item), mw, mh);
1089    else if ((minw < mw) && (minh > mh))
1090      evas_object_size_hint_min_set(VIEW(item), mw, minh);
1091    else if ((minw > mw) && (minh < mh))
1092      evas_object_size_hint_min_set(VIEW(item), minw, mh);
1093 }
1094
1095 static void
1096 _elm_toolbar_item_label_set_cb(void *data,
1097                                Evas_Object *obj,
1098                                const char *emission,
1099                                const char *source)
1100 {
1101    Elm_Toolbar_Item *item = data;
1102
1103    _elm_toolbar_item_label_update(item);
1104    edje_object_signal_callback_del
1105      (obj, emission, source, _elm_toolbar_item_label_set_cb);
1106    edje_object_signal_emit(VIEW(item), "elm,state,label,reset", "elm");
1107 }
1108
1109 static void
1110 _item_label_set(Elm_Toolbar_Item *item,
1111                 const char *label,
1112                 const char *sig)
1113 {
1114    const char *s;
1115
1116    if ((label) && (item->label) && (!strcmp(label, item->label))) return;
1117
1118    eina_stringshare_replace(&item->label, label);
1119    s = edje_object_data_get(VIEW(item), "transition_animation_on");
1120    if ((s) && (atoi(s)))
1121      {
1122         edje_object_part_text_escaped_set
1123           (VIEW(item), "elm.text_new", item->label);
1124         edje_object_signal_emit(VIEW(item), sig, "elm");
1125         edje_object_signal_callback_add
1126           (VIEW(item), "elm,state,label_set,done", "elm",
1127           _elm_toolbar_item_label_set_cb, item);
1128      }
1129    else
1130      _elm_toolbar_item_label_update(item);
1131
1132    _resize_cb(WIDGET(item), NULL, NULL, NULL);
1133 }
1134
1135 static void
1136 _item_text_set_hook(Elm_Object_Item *it,
1137                     const char *part,
1138                     const char *label)
1139 {
1140    Elm_Toolbar_Item *item;
1141    char buf[256];
1142    item = (Elm_Toolbar_Item *)it;
1143
1144    if ((!part) || (!strcmp(part, "default")) ||
1145        (!strcmp(part, "elm.text")))
1146      {
1147         _item_label_set(((Elm_Toolbar_Item *)it), label, "elm,state,label_set");
1148      }
1149    else
1150      {
1151         if (label)
1152           {
1153              snprintf(buf, sizeof(buf), "elm,state,%s,visible", part);
1154              edje_object_signal_emit(VIEW(item), buf, "elm");
1155           }
1156         else
1157           {
1158              snprintf(buf, sizeof(buf), "elm,state,%s,hidden", part);
1159              edje_object_signal_emit(VIEW(item), buf, "elm");
1160           }
1161         edje_object_part_text_escaped_set(VIEW(item), part, label);
1162      }
1163 }
1164
1165 static const char *
1166 _item_text_get_hook(const Elm_Object_Item *it,
1167                     const char *part)
1168 {
1169    char buf[256];
1170
1171    if (!part || !strcmp(part, "default"))
1172      snprintf(buf, sizeof(buf), "elm.text");
1173    else
1174      snprintf(buf, sizeof(buf), "%s", part);
1175
1176    return edje_object_part_text_get(VIEW(it), buf);
1177 }
1178
1179 static void
1180 _item_content_set_hook(Elm_Object_Item *it,
1181                        const char *part,
1182                        Evas_Object *content)
1183 {
1184    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
1185    Evas_Object *obj = WIDGET(item);
1186    double scale;
1187
1188    ELM_TOOLBAR_DATA_GET(obj, sd);
1189
1190    if (part && strcmp(part, "object")) return;
1191    if (item->object == content) return;
1192
1193    if (item->object) evas_object_del(item->object);
1194
1195    item->object = content;
1196    if (item->object)
1197      elm_widget_sub_object_add(obj, item->object);
1198
1199    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
1200    _item_theme_hook(obj, item, scale, sd->icon_size);
1201 }
1202
1203 static Evas_Object *
1204 _item_content_get_hook(const Elm_Object_Item *it,
1205                        const char *part)
1206 {
1207    if (part && strcmp(part, "object")) return NULL;
1208    return ((Elm_Toolbar_Item *)it)->object;
1209 }
1210
1211 static Evas_Object *
1212 _item_content_unset_hook(Elm_Object_Item *it,
1213                          const char *part)
1214 {
1215    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
1216    Evas_Object *obj = WIDGET(item);
1217    Evas_Object *o;
1218    double scale;
1219
1220    ELM_TOOLBAR_DATA_GET(obj, sd);
1221
1222    if (part && strcmp(part, "object")) return NULL;
1223
1224    edje_object_part_unswallow(VIEW(it), item->object);
1225    elm_widget_sub_object_del(obj, item->object);
1226    o = item->object;
1227    item->object = NULL;
1228    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
1229    _item_theme_hook(obj, item, scale, sd->icon_size);
1230
1231    return o;
1232 }
1233
1234 static Eina_Bool
1235 _elm_toolbar_smart_translate(Evas_Object *obj)
1236 {
1237    evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
1238
1239    return EINA_TRUE;
1240 }
1241
1242 static void
1243 _item_resize(void *data,
1244              Evas *e __UNUSED__,
1245              Evas_Object *obj __UNUSED__,
1246              void *event_info __UNUSED__)
1247 {
1248    _sizing_eval(data);
1249    _resize_cb(data, NULL, NULL, NULL);
1250 }
1251
1252 static void
1253 _move_cb(void *data,
1254          Evas *e __UNUSED__,
1255          Evas_Object *obj __UNUSED__,
1256          void *event_info __UNUSED__)
1257 {
1258    Evas_Coord x, y, h;
1259
1260    ELM_TOOLBAR_DATA_GET(data, sd);
1261    evas_object_geometry_get(data, &x, &y, NULL, &h);
1262    evas_object_move(sd->more, x, y + h);
1263 }
1264
1265 static void
1266 _select_filter_cb(Elm_Toolbar_Item *it,
1267                   Evas_Object *obj __UNUSED__,
1268                   const char *emission,
1269                   const char *source __UNUSED__)
1270 {
1271    int button;
1272    char buf[sizeof("elm,action,click,") + 1];
1273
1274    button = atoi(emission + sizeof("mouse,clicked,") - 1);
1275    if (button == 1) return;  /* regular left click event */
1276    snprintf(buf, sizeof(buf), "elm,action,click,%d", button);
1277    edje_object_signal_emit(VIEW(it), buf, "elm");
1278 }
1279
1280 static void
1281 _select_cb(void *data,
1282            Evas_Object *obj __UNUSED__,
1283            const char *emission __UNUSED__,
1284            const char *source __UNUSED__)
1285 {
1286    Elm_Toolbar_Item *it = data;
1287
1288    if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) ||
1289        (_elm_access_2nd_click_timeout(VIEW(it))))
1290      {
1291         if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
1292           _elm_access_say(E_("Selected"));
1293         _item_select(it);
1294      }
1295 }
1296
1297 static void
1298 _items_change(Evas_Object *obj)
1299 {
1300    Elm_Toolbar_Item *prev = NULL, *next = NULL;
1301    int tmp;
1302
1303    ELM_TOOLBAR_DATA_GET(obj, sd);
1304
1305    if ((sd->reorder_from) && (sd->reorder_to) &&
1306        (!sd->reorder_from->separator) && (!sd->reorder_to->separator))
1307      {
1308         prev = ELM_TOOLBAR_ITEM_FROM_INLIST
1309             (EINA_INLIST_GET(sd->reorder_from)->prev);
1310         if (prev == sd->reorder_to)
1311           prev = sd->reorder_from;
1312         if (!prev)
1313           next = ELM_TOOLBAR_ITEM_FROM_INLIST
1314               (EINA_INLIST_GET(sd->reorder_from)->next);
1315         if (next == sd->reorder_to)
1316           next = NULL;
1317
1318         sd->items = eina_inlist_remove
1319             (sd->items, EINA_INLIST_GET(sd->reorder_from));
1320         sd->items = eina_inlist_append_relative
1321             (sd->items, EINA_INLIST_GET(sd->reorder_from),
1322             EINA_INLIST_GET(sd->reorder_to));
1323
1324         sd->items = eina_inlist_remove
1325             (sd->items, EINA_INLIST_GET(sd->reorder_to));
1326         if (prev)
1327           sd->items = eina_inlist_append_relative
1328               (sd->items, EINA_INLIST_GET(sd->reorder_to),
1329               EINA_INLIST_GET(prev));
1330         else if (next)
1331           sd->items = eina_inlist_prepend_relative
1332               (sd->items, EINA_INLIST_GET(sd->reorder_to),
1333               EINA_INLIST_GET(next));
1334         else
1335           sd->items = eina_inlist_prepend
1336              (sd->items, EINA_INLIST_GET(sd->reorder_to));
1337
1338         if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_NONE ||
1339             sd->shrink_mode == ELM_TOOLBAR_SHRINK_SCROLL)
1340           {
1341              evas_object_box_remove(sd->bx, VIEW(sd->reorder_from));
1342              evas_object_box_insert_after(sd->bx, VIEW(sd->reorder_from),
1343                                           VIEW(sd->reorder_to));
1344              evas_object_box_remove(sd->bx, VIEW(sd->reorder_to));
1345              if (prev)
1346                evas_object_box_insert_after(sd->bx, VIEW(sd->reorder_to),
1347                                             VIEW(prev));
1348              else if (next)
1349                evas_object_box_insert_before(sd->bx, VIEW(sd->reorder_to),
1350                                              VIEW(next));
1351              else
1352                evas_object_box_prepend(sd->bx, VIEW(sd->reorder_to));
1353           }
1354
1355         tmp = sd->reorder_from->prio.priority;
1356         sd->reorder_from->prio.priority = sd->reorder_to->prio.priority;
1357         sd->reorder_to->prio.priority = tmp;
1358      }
1359
1360    _resize_cb(obj, NULL, NULL, NULL);
1361 }
1362
1363 static void
1364 _mouse_move_reorder(Elm_Toolbar_Item *it,
1365                     Evas *evas __UNUSED__,
1366                     Evas_Object *obj __UNUSED__,
1367                     Evas_Event_Mouse_Move *ev)
1368 {
1369    Evas_Coord w, h;
1370
1371    evas_object_geometry_get(VIEW(it), NULL, NULL, &w, &h);
1372    evas_object_move
1373      (VIEW(it), ev->cur.canvas.x - (w / 2), ev->cur.canvas.y - (h / 2));
1374    evas_object_show(VIEW(it));
1375 }
1376
1377 static void
1378 _mouse_up_reorder(Elm_Toolbar_Item *it,
1379                   Evas *evas __UNUSED__,
1380                   Evas_Object *obj,
1381                   Evas_Event_Mouse_Up *ev)
1382 {
1383    Evas_Coord x, y, w, h;
1384
1385    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1386
1387    evas_object_event_callback_del_full
1388      (obj, EVAS_CALLBACK_MOUSE_MOVE,
1389      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1390    evas_object_event_callback_del_full
1391      (sd->more, EVAS_CALLBACK_MOUSE_MOVE,
1392      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1393    evas_object_event_callback_del_full
1394      (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1395      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1396    evas_object_event_callback_del_full
1397      (obj, EVAS_CALLBACK_MOUSE_UP,
1398      (Evas_Object_Event_Cb)_mouse_up_reorder, it);
1399    evas_object_event_callback_del_full
1400      (sd->more, EVAS_CALLBACK_MOUSE_UP,
1401      (Evas_Object_Event_Cb)_mouse_up_reorder, it);
1402    elm_widget_item_del(it);
1403
1404    EINA_INLIST_FOREACH(sd->items, it)
1405      {
1406         evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
1407         if ((x < ev->canvas.x) && (ev->canvas.x < x + w) &&
1408             (y < ev->canvas.y) && (ev->canvas.y < y + h))
1409           {
1410              sd->reorder_to = it;
1411              _items_change(WIDGET(it));
1412           }
1413      }
1414
1415    sd->s_iface->hold_set(obj, EINA_FALSE);
1416 }
1417
1418 static void
1419 _item_reorder_start(Elm_Toolbar_Item *item)
1420 {
1421    Evas_Object *obj = WIDGET(item);
1422    Evas_Object *icon_obj;
1423    Evas_Coord x, y, w, h;
1424    Elm_Toolbar_Item *it;
1425
1426    ELM_TOOLBAR_DATA_GET(obj, sd);
1427
1428    sd->reorder_from = item;
1429
1430    icon_obj = elm_icon_add(obj);
1431    elm_icon_order_lookup_set(icon_obj, sd->lookup_order);
1432
1433    if (!icon_obj) return;
1434    it = elm_widget_item_new(obj, Elm_Toolbar_Item);
1435    if (!it)
1436      {
1437         evas_object_del(icon_obj);
1438         return;
1439      }
1440
1441    it->label = eina_stringshare_add(item->label);
1442    VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1443
1444    if (_item_icon_set(icon_obj, "toolbar/", item->icon_str))
1445      {
1446         it->icon = icon_obj;
1447         it->icon_str = eina_stringshare_add(item->icon_str);
1448      }
1449    else
1450      {
1451         it->icon = NULL;
1452         it->icon_str = NULL;
1453         evas_object_del(icon_obj);
1454      }
1455
1456    elm_widget_theme_object_set(obj, VIEW(it), "toolbar", "item",
1457                                elm_widget_style_get(obj));
1458    if (it->icon)
1459      {
1460         int ms = 0;
1461
1462         ms = ((double)sd->icon_size * elm_config_scale_get());
1463         evas_object_size_hint_min_set(it->icon, ms, ms);
1464         evas_object_size_hint_max_set(it->icon, ms, ms);
1465         edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon);
1466         edje_object_signal_emit(VIEW(it), "elm,state,icon,visible", "elm");
1467         evas_object_show(it->icon);
1468         elm_widget_sub_object_add(obj, it->icon);
1469      }
1470    if (it->label)
1471      {
1472         edje_object_part_text_escaped_set(VIEW(it), "elm.text", it->label);
1473         edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm");
1474      }
1475
1476    edje_object_signal_emit(VIEW(it), "elm,state,moving", "elm");
1477
1478    evas_object_event_callback_add
1479      (obj, EVAS_CALLBACK_MOUSE_MOVE,
1480      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1481
1482    evas_object_event_callback_add
1483      (sd->more, EVAS_CALLBACK_MOUSE_MOVE,
1484      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1485
1486    evas_object_event_callback_add
1487      (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1488      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1489
1490    evas_object_event_callback_add
1491      (obj, EVAS_CALLBACK_MOUSE_UP,
1492      (Evas_Object_Event_Cb)_mouse_up_reorder, it);
1493
1494    evas_object_event_callback_add
1495      (sd->more, EVAS_CALLBACK_MOUSE_UP,
1496      (Evas_Object_Event_Cb)_mouse_up_reorder, it);
1497
1498    evas_object_geometry_get(VIEW(item), &x, &y, &w, &h);
1499    evas_object_resize(VIEW(it), w, h);
1500    evas_object_move(VIEW(it), x, y);
1501    evas_object_show(VIEW(it));
1502
1503    sd->s_iface->hold_set(WIDGET(it), EINA_TRUE);
1504 }
1505
1506 static Eina_Bool
1507 _long_press(Elm_Toolbar_Item *it)
1508 {
1509    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1510
1511    sd->long_timer = NULL;
1512    sd->long_press = EINA_TRUE;
1513
1514    if (sd->reorder_mode)
1515      _item_reorder_start(it);
1516
1517    evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1518
1519    return ECORE_CALLBACK_CANCEL;
1520 }
1521
1522 static void
1523 _drag_start_cb(Evas_Object *obj, void *data __UNUSED__)
1524 {
1525    ELM_TOOLBAR_DATA_GET(obj, sd);
1526
1527    if (sd->long_timer)
1528      {
1529         ecore_timer_del(sd->long_timer);
1530         sd->long_timer = NULL;
1531      }
1532 }
1533
1534 static void
1535 _mouse_move_cb(Elm_Toolbar_Item *it,
1536                Evas *evas __UNUSED__,
1537                Evas_Object *obj __UNUSED__,
1538                Evas_Event_Mouse_Move *ev)
1539 {
1540    Evas_Coord x, y, w, h;
1541
1542    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1543    evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
1544
1545    if ((sd->long_timer) &&
1546        ((x > ev->cur.canvas.x) || (ev->cur.canvas.x > x + w) ||
1547         (y > ev->cur.canvas.y) || (ev->cur.canvas.y > y + h)))
1548      {
1549         ecore_timer_del(sd->long_timer);
1550         sd->long_timer = NULL;
1551      }
1552 }
1553
1554 static void
1555 _mouse_down_cb(Elm_Toolbar_Item *it,
1556                Evas *evas __UNUSED__,
1557                Evas_Object *obj __UNUSED__,
1558                Evas_Event_Mouse_Down *ev)
1559 {
1560    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1561
1562    if (ev->button != 1) return;
1563    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1564      evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1565    sd->long_press = EINA_FALSE;
1566    if (sd->long_timer)
1567      ecore_timer_interval_set
1568        (sd->long_timer, _elm_config->longpress_timeout);
1569    else
1570      sd->long_timer = ecore_timer_add
1571          (_elm_config->longpress_timeout, (Ecore_Task_Cb)_long_press, it);
1572
1573    evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1574                                   (Evas_Object_Event_Cb)_mouse_move_cb, it);
1575 }
1576
1577 static void
1578 _mouse_up_cb(Elm_Toolbar_Item *it,
1579              Evas *evas __UNUSED__,
1580              Evas_Object *obj __UNUSED__,
1581              Evas_Event_Mouse_Up *ev)
1582 {
1583    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1584
1585    if (ev->button != 1) return;
1586    if (sd->long_timer)
1587      {
1588         ecore_timer_del(sd->long_timer);
1589         sd->long_timer = NULL;
1590      }
1591    evas_object_event_callback_del_full
1592      (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1593      (Evas_Object_Event_Cb)_mouse_move_cb, it);
1594 }
1595
1596 static void
1597 _mouse_in_cb(void *data,
1598              Evas_Object *obj __UNUSED__,
1599              const char *emission __UNUSED__,
1600              const char *source __UNUSED__)
1601 {
1602    Elm_Toolbar_Item *it = data;
1603
1604    edje_object_signal_emit(VIEW(it), "elm,state,highlighted", "elm");
1605    elm_widget_signal_emit(it->icon, "elm,state,highlighted", "elm");
1606 }
1607
1608 static void
1609 _mouse_out_cb(void *data,
1610               Evas_Object *obj __UNUSED__,
1611               const char *emission __UNUSED__,
1612               const char *source __UNUSED__)
1613 {
1614    Elm_Toolbar_Item *it = data;
1615
1616    edje_object_signal_emit(VIEW(it), "elm,state,unhighlighted", "elm");
1617    elm_widget_signal_emit(it->icon, "elm,state,unhighlighted", "elm");
1618 }
1619
1620 static void
1621 _layout(Evas_Object *o,
1622         Evas_Object_Box_Data *priv,
1623         void *data)
1624 {
1625    Evas_Object *obj = (Evas_Object *)data;
1626
1627    ELM_TOOLBAR_DATA_GET(obj, sd);
1628    _els_box_layout
1629      (o, priv, !sd->vertical, sd->homogeneous, elm_widget_mirrored_get(obj));
1630 }
1631
1632 static char *
1633 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
1634 {
1635    Elm_Toolbar_Item *it = (Elm_Toolbar_Item *)data;
1636    const char *txt = ((Elm_Widget_Item *)it)->access_info;
1637
1638    if (!txt) txt = it->label;
1639    if (txt) return strdup(txt);
1640
1641    return NULL;
1642 }
1643
1644 static char *
1645 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
1646 {
1647    Elm_Toolbar_Item *it = (Elm_Toolbar_Item *)data;
1648
1649    if (it->separator)
1650      return strdup(E_("Separator"));
1651    else if (elm_widget_item_disabled_get(it))
1652      return strdup(E_("State: Disabled"));
1653    else if (it->selected)
1654      return strdup(E_("State: Selected"));
1655    else if (it->menu)
1656      return strdup(E_("Has menu"));
1657
1658    return NULL;
1659 }
1660
1661 static Eina_Bool
1662 _item_del_pre_hook(Elm_Object_Item *it)
1663 {
1664    Elm_Toolbar_Item *item, *next;
1665    Evas_Object *obj;
1666
1667    item = (Elm_Toolbar_Item *)it;
1668
1669    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
1670
1671    obj = WIDGET(item);
1672
1673    if (item != sd->more_item) /* more item does not get in the list */
1674      {
1675         if (!sd->on_deletion)
1676           next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(item)->next);
1677         sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(item));
1678         sd->item_count--;
1679         if (!sd->on_deletion)
1680           {
1681              if (!next) next = ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items);
1682              if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) &&
1683                  item->selected && next) _item_select(next);
1684           }
1685      }
1686
1687    _item_del(item);
1688
1689    if (item != sd->more_item)
1690      _elm_toolbar_smart_theme(obj);
1691
1692    return EINA_TRUE;
1693 }
1694
1695 static void
1696 _access_activate_cb(void *data __UNUSED__,
1697                     Evas_Object *part_obj __UNUSED__,
1698                     Elm_Object_Item *item)
1699 {
1700    Elm_Toolbar_Item *it;
1701    it = (Elm_Toolbar_Item *)item;
1702
1703    if (elm_widget_item_disabled_get(it)) return;
1704
1705    if (it->selected)
1706      {
1707         _elm_access_say(E_("Unselected"));
1708         _item_unselect(it);
1709      }
1710    else
1711      {
1712         _elm_access_say(E_("Selected"));
1713         _item_select(it);
1714      }
1715 }
1716
1717 static void
1718 _access_widget_item_register(Elm_Toolbar_Item *it)
1719 {
1720    Elm_Access_Info *ai;
1721    _elm_access_widget_item_register((Elm_Widget_Item *)it);
1722    ai = _elm_access_object_get(it->base.access_obj);
1723
1724    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Toolbar Item"));
1725    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1726    _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1727    _elm_access_activate_callback_set(ai, _access_activate_cb, NULL);
1728 }
1729
1730 static Elm_Toolbar_Item *
1731 _item_new(Evas_Object *obj,
1732           const char *icon,
1733           const char *label,
1734           Evas_Smart_Cb func,
1735           const void *data)
1736 {
1737    Evas_Object *icon_obj;
1738    Elm_Toolbar_Item *it;
1739    Evas_Coord mw, mh;
1740
1741    ELM_TOOLBAR_DATA_GET(obj, sd);
1742
1743    icon_obj = elm_icon_add(obj);
1744    elm_icon_order_lookup_set(icon_obj, sd->lookup_order);
1745    if (!icon_obj) return NULL;
1746
1747    it = elm_widget_item_new(obj, Elm_Toolbar_Item);
1748    if (!it)
1749      {
1750         evas_object_del(icon_obj);
1751         return NULL;
1752      }
1753
1754    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1755    elm_widget_item_disable_hook_set(it, _item_disable_hook);
1756    elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1757    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1758    elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1759    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1760    elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1761
1762    it->label = eina_stringshare_add(label);
1763    it->prio.visible = 1;
1764    it->prio.priority = 0;
1765    it->func = func;
1766    it->separator = EINA_FALSE;
1767    it->object = NULL;
1768    it->base.data = data;
1769
1770    VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1771
1772    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1773      _access_widget_item_register(it);
1774
1775    if (_item_icon_set(icon_obj, "toolbar/", icon))
1776      {
1777         it->icon = icon_obj;
1778         it->icon_str = eina_stringshare_add(icon);
1779      }
1780    else
1781      {
1782         it->icon = NULL;
1783         it->icon_str = NULL;
1784         evas_object_del(icon_obj);
1785      }
1786
1787    elm_widget_theme_object_set
1788      (obj, VIEW(it), "toolbar", "item", elm_widget_style_get(obj));
1789    edje_object_signal_callback_add
1790      (VIEW(it), "elm,action,click", "elm", _select_cb, it);
1791    edje_object_signal_callback_add
1792      (VIEW(it), "mouse,clicked,*", "*", (Edje_Signal_Cb)_select_filter_cb, it);
1793    edje_object_signal_callback_add
1794      (VIEW(it), "elm,mouse,in", "elm", _mouse_in_cb, it);
1795    edje_object_signal_callback_add
1796      (VIEW(it), "elm,mouse,out", "elm", _mouse_out_cb, it);
1797    evas_object_event_callback_add
1798      (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, (Evas_Object_Event_Cb)_mouse_down_cb,
1799      it);
1800    evas_object_event_callback_add
1801      (VIEW(it), EVAS_CALLBACK_MOUSE_UP, (Evas_Object_Event_Cb)_mouse_up_cb, it);
1802    elm_widget_sub_object_add(obj, VIEW(it));
1803
1804    if (it->icon)
1805      {
1806         int ms = 0;
1807
1808         ms = ((double)sd->icon_size * elm_config_scale_get());
1809         evas_object_size_hint_min_set(it->icon, ms, ms);
1810         evas_object_size_hint_max_set(it->icon, ms, ms);
1811         edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon);
1812         edje_object_signal_emit(VIEW(it), "elm,state,icon,visible", "elm");
1813         evas_object_show(it->icon);
1814         elm_widget_sub_object_add(obj, it->icon);
1815      }
1816    if (it->label)
1817      {
1818         edje_object_part_text_escaped_set(VIEW(it), "elm.text", it->label);
1819         edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm");
1820      }
1821
1822    mw = mh = -1;
1823    if (!it->separator && !it->object)
1824      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1825    edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
1826    if (!it->separator && !it->object)
1827      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1828    if (sd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
1829      {
1830         if (sd->vertical)
1831           {
1832              evas_object_size_hint_weight_set(VIEW(it), EVAS_HINT_EXPAND, -1.0);
1833              evas_object_size_hint_align_set
1834                (VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL);
1835           }
1836         else
1837           {
1838              evas_object_size_hint_weight_set(VIEW(it), -1.0, EVAS_HINT_EXPAND);
1839              evas_object_size_hint_align_set
1840                (VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL);
1841           }
1842      }
1843    else
1844      {
1845         evas_object_size_hint_weight_set
1846           (VIEW(it), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1847         evas_object_size_hint_align_set
1848           (VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL);
1849      }
1850
1851    evas_object_size_hint_min_set(VIEW(it), mw, mh);
1852    evas_object_size_hint_max_set(VIEW(it), -1, -1);
1853    evas_object_event_callback_add
1854      (VIEW(it), EVAS_CALLBACK_RESIZE, _item_resize, obj);
1855
1856    if ((!sd->items) && (sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
1857      _item_select(it);
1858    return it;
1859 }
1860
1861 static void
1862 _elm_toolbar_item_icon_update(Elm_Toolbar_Item *item)
1863 {
1864    Evas_Coord mw = -1, mh = -1, minw = -1, minh = -1;
1865    Elm_Toolbar_Item_State *it_state;
1866    Evas_Object *old_icon =
1867      edje_object_part_swallow_get(VIEW(item), "elm.swallow.icon");
1868    Eina_List *l;
1869
1870    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
1871
1872    elm_widget_sub_object_del(VIEW(item), old_icon);
1873    edje_object_part_swallow(VIEW(item), "elm.swallow.icon", item->icon);
1874    if (item->icon)
1875        edje_object_signal_emit(VIEW(item), "elm,state,icon,visible", "elm");
1876    else
1877        edje_object_signal_emit(VIEW(item), "elm,state,icon,hidden", "elm");
1878    evas_object_hide(old_icon);
1879    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1880    edje_object_size_min_restricted_calc(VIEW(item), &mw, &mh, mw, mh);
1881    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1882    if (sd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
1883      {
1884         if (sd->vertical)
1885           {
1886              evas_object_size_hint_weight_set
1887                (VIEW(item), EVAS_HINT_EXPAND, -1.0);
1888              evas_object_size_hint_align_set
1889                (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1890           }
1891         else
1892           {
1893              evas_object_size_hint_weight_set
1894                (VIEW(item), -1.0, EVAS_HINT_EXPAND);
1895              evas_object_size_hint_align_set
1896                (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1897           }
1898      }
1899    else
1900      {
1901         evas_object_size_hint_weight_set
1902           (VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1903         evas_object_size_hint_align_set
1904           (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1905      }
1906
1907    evas_object_size_hint_min_get(VIEW(item), &minw, &minh);
1908    if ((minw < mw) && (minh < mh))
1909      evas_object_size_hint_min_set(VIEW(item), mw, mh);
1910    else if ((minw < mw) && (minh > mh))
1911      evas_object_size_hint_min_set(VIEW(item), mw, minh);
1912    else if ((minw > mw) && (minh < mh))
1913      evas_object_size_hint_min_set(VIEW(item), minw, mh);
1914
1915    EINA_LIST_FOREACH(item->states, l, it_state)
1916      {
1917         if (it_state->icon == old_icon) return;
1918      }
1919    evas_object_del(old_icon);
1920 }
1921
1922 static void
1923 _elm_toolbar_item_icon_set_cb(void *data,
1924                               Evas_Object *obj,
1925                               const char *emission,
1926                               const char *source)
1927 {
1928    Elm_Toolbar_Item *item = data;
1929
1930    edje_object_part_unswallow(VIEW(item), item->icon);
1931    _elm_toolbar_item_icon_update(item);
1932    edje_object_signal_callback_del
1933      (obj, emission, source, _elm_toolbar_item_icon_set_cb);
1934    edje_object_signal_emit(VIEW(item), "elm,state,icon,reset", "elm");
1935 }
1936
1937 static void
1938 _elm_toolbar_item_icon_obj_set(Evas_Object *obj,
1939                                Elm_Toolbar_Item *item,
1940                                Evas_Object *icon_obj,
1941                                const char *icon_str,
1942                                double icon_size,
1943                                const char *sig)
1944 {
1945    Evas_Object *old_icon;
1946    const char *s;
1947    int ms = 0;
1948
1949    if (icon_str)
1950      eina_stringshare_replace(&item->icon_str, icon_str);
1951    else
1952      {
1953         eina_stringshare_del(item->icon_str);
1954         item->icon_str = NULL;
1955      }
1956    item->icon = icon_obj;
1957    if (icon_obj)
1958      {
1959         ms = (icon_size * elm_config_scale_get());
1960         evas_object_size_hint_min_set(item->icon, ms, ms);
1961         evas_object_size_hint_max_set(item->icon, ms, ms);
1962         evas_object_show(item->icon);
1963         elm_widget_sub_object_add(obj, item->icon);
1964      }
1965    s = edje_object_data_get(VIEW(item), "transition_animation_on");
1966    if ((s) && (atoi(s)))
1967      {
1968         old_icon = edje_object_part_swallow_get
1969             (VIEW(item), "elm.swallow.icon_new");
1970         if (old_icon)
1971           {
1972              elm_widget_sub_object_del(VIEW(item), old_icon);
1973              evas_object_hide(old_icon);
1974           }
1975         edje_object_part_swallow
1976           (VIEW(item), "elm.swallow.icon_new", item->icon);
1977         edje_object_signal_emit(VIEW(item), sig, "elm");
1978         edje_object_signal_callback_add
1979           (VIEW(item), "elm,state,icon_set,done", "elm",
1980           _elm_toolbar_item_icon_set_cb, item);
1981      }
1982    else
1983      _elm_toolbar_item_icon_update(item);
1984
1985    _resize_cb(obj, NULL, NULL, NULL);
1986 }
1987
1988 static void
1989 _elm_toolbar_item_state_cb(void *data __UNUSED__,
1990                            Evas_Object *obj __UNUSED__,
1991                            void *event_info)
1992 {
1993    Elm_Toolbar_Item *it = event_info;
1994    Elm_Toolbar_Item_State *it_state;
1995
1996    it_state = eina_list_data_get(it->current_state);
1997    if (it_state->func)
1998      it_state->func((void *)it_state->data, obj, event_info);
1999 }
2000
2001 static Elm_Toolbar_Item_State *
2002 _item_state_new(const char *label,
2003                 const char *icon_str,
2004                 Evas_Object *icon,
2005                 Evas_Smart_Cb func,
2006                 const void *data)
2007 {
2008    Elm_Toolbar_Item_State *it_state;
2009
2010    it_state = ELM_NEW(Elm_Toolbar_Item_State);
2011    it_state->label = eina_stringshare_add(label);
2012    it_state->icon_str = eina_stringshare_add(icon_str);
2013    it_state->icon = icon;
2014    it_state->func = func;
2015    it_state->data = data;
2016
2017    return it_state;
2018 }
2019
2020 static void
2021 _elm_toolbar_action_left_cb(void *data,
2022                             Evas_Object *o __UNUSED__,
2023                             const char *sig __UNUSED__,
2024                             const char *src __UNUSED__)
2025 {
2026    Evas_Object *obj = data;
2027    Elm_Toolbar_Item *it, *it2;
2028    Eina_Bool done = EINA_FALSE;
2029
2030    ELM_TOOLBAR_DATA_GET(obj, sd);
2031
2032    EINA_INLIST_FOREACH(sd->items, it)
2033      {
2034         if (it->selected)
2035           {
2036              Eina_Bool found = EINA_FALSE;
2037
2038              EINA_INLIST_REVERSE_FOREACH(sd->items, it2)
2039                {
2040                   if (elm_object_item_disabled_get((Elm_Object_Item *)it2))
2041                     continue;
2042                   if (it2 == it)
2043                     {
2044                        found = EINA_TRUE;
2045                        continue;
2046                     }
2047                   if (!found) continue;
2048                   if (it2->separator) continue;
2049                   _item_unselect(it);
2050                   _item_select(it2);
2051                   break;
2052                }
2053              done = EINA_TRUE;
2054              break;
2055           }
2056      }
2057    if (!done)
2058      {
2059         EINA_INLIST_FOREACH(sd->items, it)
2060           {
2061              if (elm_object_item_disabled_get((Elm_Object_Item *)it)) continue;
2062              if (it->separator) continue;
2063              _item_select(it);
2064              break;
2065           }
2066      }
2067 }
2068
2069 static void
2070 _elm_toolbar_action_right_cb(void *data,
2071                              Evas_Object *o __UNUSED__,
2072                              const char *sig __UNUSED__,
2073                              const char *src __UNUSED__)
2074 {
2075    Evas_Object *obj = data;
2076    Elm_Toolbar_Item *it, *it2;
2077    Eina_Bool done = EINA_FALSE;
2078
2079    ELM_TOOLBAR_DATA_GET(obj, sd);
2080
2081    EINA_INLIST_FOREACH(sd->items, it)
2082      {
2083         if (it->selected)
2084           {
2085              Eina_Bool found = EINA_FALSE;
2086
2087              EINA_INLIST_FOREACH(sd->items, it2)
2088                {
2089                   if (elm_object_item_disabled_get((Elm_Object_Item *)it2))
2090                     continue;
2091                   if (it2 == it)
2092                     {
2093                        found = EINA_TRUE;
2094                        continue;
2095                     }
2096                   if (!found) continue;
2097                   if (it2->separator) continue;
2098                   _item_unselect(it);
2099                   _item_select(it2);
2100                   break;
2101                }
2102              done = EINA_TRUE;
2103              break;
2104           }
2105      }
2106    if (!done)
2107      {
2108         EINA_INLIST_REVERSE_FOREACH(sd->items, it)
2109           {
2110              if (elm_object_item_disabled_get((Elm_Object_Item *)it)) continue;
2111              if (it->separator) continue;
2112              _item_select(it);
2113              break;
2114           }
2115      }
2116 }
2117
2118 static void
2119 _elm_toolbar_action_up_cb(void *data,
2120                           Evas_Object *o,
2121                           const char *sig,
2122                           const char *src)
2123 {
2124    _elm_toolbar_action_left_cb(data, o, sig, src);
2125 }
2126
2127 static void
2128 _elm_toolbar_action_down_cb(void *data,
2129                             Evas_Object *o,
2130                             const char *sig,
2131                             const char *src)
2132 {
2133    _elm_toolbar_action_right_cb(data, o, sig, src);
2134 }
2135
2136 static void
2137 _elm_toolbar_smart_add(Evas_Object *obj)
2138 {
2139    EVAS_SMART_DATA_ALLOC(obj, Elm_Toolbar_Smart_Data);
2140
2141    ELM_WIDGET_DATA(priv)->resize_obj =
2142      edje_object_add(evas_object_evas_get(obj));
2143
2144    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.add(obj);
2145
2146    elm_widget_theme_object_set
2147      (obj, ELM_WIDGET_DATA(priv)->resize_obj, "toolbar", "base",
2148      elm_widget_style_get(obj));
2149
2150    priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
2151    evas_object_smart_member_add(priv->hit_rect, obj);
2152    elm_widget_sub_object_add(obj, priv->hit_rect);
2153
2154    /* common scroller hit rectangle setup */
2155    evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
2156    evas_object_show(priv->hit_rect);
2157    evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
2158
2159    elm_widget_can_focus_set(obj, EINA_TRUE);
2160
2161    priv->s_iface = evas_object_smart_interface_get
2162        (obj, ELM_SCROLLABLE_IFACE_NAME);
2163
2164    priv->s_iface->objects_set
2165      (obj, ELM_WIDGET_DATA(priv)->resize_obj, priv->hit_rect);
2166
2167    priv->more_item = NULL;
2168    priv->selected_item = NULL;
2169    priv->standard_priority = -99999;
2170
2171    priv->s_iface->bounce_allow_set
2172      (obj, _elm_config->thumbscroll_bounce_enable, EINA_FALSE);
2173    priv->s_iface->policy_set
2174      (obj, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
2175    priv->s_iface->drag_start_cb_set(obj, _drag_start_cb);
2176
2177    edje_object_signal_callback_add
2178      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,left", "elm",
2179      _elm_toolbar_action_left_cb, obj);
2180    edje_object_signal_callback_add
2181      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,right", "elm",
2182      _elm_toolbar_action_right_cb, obj);
2183    edje_object_signal_callback_add
2184      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,up", "elm",
2185      _elm_toolbar_action_up_cb, obj);
2186    edje_object_signal_callback_add
2187      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,down", "elm",
2188      _elm_toolbar_action_down_cb, obj);
2189
2190    priv->shrink_mode = ELM_TOOLBAR_SHRINK_NONE;
2191    priv->priv_icon_size = 0; // unset
2192    priv->theme_icon_size = _elm_toolbar_icon_size_get(priv);
2193    if (priv->priv_icon_size) priv->icon_size = priv->priv_icon_size;
2194    else priv->icon_size = priv->theme_icon_size;
2195
2196    priv->homogeneous = EINA_TRUE;
2197    priv->align = 0.5;
2198
2199    priv->bx = evas_object_box_add(evas_object_evas_get(obj));
2200    evas_object_size_hint_align_set(priv->bx, priv->align, 0.5);
2201    evas_object_box_layout_set(priv->bx, _layout, obj, NULL);
2202    elm_widget_sub_object_add(obj, priv->bx);
2203    priv->s_iface->content_set(obj, priv->bx);
2204    evas_object_show(priv->bx);
2205
2206    priv->more = elm_layout_add(obj);
2207    elm_layout_theme_set(priv->more, "toolbar", "more", "default");
2208    elm_widget_sub_object_add(obj, priv->more);
2209    evas_object_show(priv->more);
2210
2211    priv->bx_more = evas_object_box_add(evas_object_evas_get(obj));
2212    evas_object_size_hint_align_set(priv->bx_more, priv->align, 0.5);
2213    evas_object_box_layout_set(priv->bx_more, _layout, obj, NULL);
2214    elm_widget_sub_object_add(obj, priv->bx_more);
2215    elm_layout_content_set
2216      (priv->more, "elm.swallow.content", priv->bx_more);
2217    evas_object_show(priv->bx_more);
2218
2219    priv->bx_more2 = evas_object_box_add(evas_object_evas_get(obj));
2220    evas_object_size_hint_align_set(priv->bx_more2, priv->align, 0.5);
2221    evas_object_box_layout_set(priv->bx_more2, _layout, obj, NULL);
2222    elm_widget_sub_object_add(obj, priv->bx_more2);
2223    elm_layout_content_set
2224      (priv->more, "elm.swallow.content2", priv->bx_more2);
2225    evas_object_show(priv->bx_more2);
2226
2227    elm_toolbar_shrink_mode_set(obj, _elm_config->toolbar_shrink_mode);
2228    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
2229    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move_cb, obj);
2230    evas_object_event_callback_add
2231      (priv->bx, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
2232    elm_toolbar_icon_order_lookup_set(obj, ELM_ICON_LOOKUP_THEME_FDO);
2233
2234    _sizing_eval(obj);
2235 }
2236
2237 static void
2238 _elm_toolbar_smart_del(Evas_Object *obj)
2239 {
2240    Elm_Toolbar_Item *it, *next;
2241
2242    ELM_TOOLBAR_DATA_GET(obj, sd);
2243
2244    sd->on_deletion = EINA_TRUE;
2245
2246    if (sd->resize_job)
2247      ecore_job_del(sd->resize_job);
2248
2249    sd->resize_job = NULL;
2250
2251    it = ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items);
2252    while (it)
2253      {
2254         next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
2255         elm_widget_item_del(it);
2256         it = next;
2257      }
2258    if (sd->more_item)
2259      {
2260         elm_widget_item_del(sd->more_item);
2261         sd->more_item = NULL;
2262      }
2263    if (sd->long_timer)
2264      {
2265         ecore_timer_del(sd->long_timer);
2266         sd->long_timer = NULL;
2267      }
2268
2269    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.del(obj);
2270 }
2271
2272 static void
2273 _elm_toolbar_smart_move(Evas_Object *obj,
2274                         Evas_Coord x,
2275                         Evas_Coord y)
2276 {
2277    ELM_TOOLBAR_DATA_GET(obj, sd);
2278
2279    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.move(obj, x, y);
2280
2281    evas_object_move(sd->hit_rect, x, y);
2282 }
2283
2284 static void
2285 _elm_toolbar_smart_resize(Evas_Object *obj,
2286                           Evas_Coord w,
2287                           Evas_Coord h)
2288 {
2289    ELM_TOOLBAR_DATA_GET(obj, sd);
2290
2291    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.resize(obj, w, h);
2292
2293    evas_object_resize(sd->hit_rect, w, h);
2294 }
2295
2296 static void
2297 _elm_toolbar_smart_member_add(Evas_Object *obj,
2298                               Evas_Object *member)
2299 {
2300    ELM_TOOLBAR_DATA_GET(obj, sd);
2301
2302    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.member_add(obj, member);
2303
2304    if (sd->hit_rect)
2305      evas_object_raise(sd->hit_rect);
2306 }
2307
2308 static Eina_List *
2309 _access_item_find_append(const Evas_Object *obj,
2310                          Evas_Object *bx,
2311                          Eina_List *items)
2312 {
2313    Elm_Toolbar_Item *it;
2314    Eina_List *list;
2315
2316    ELM_TOOLBAR_DATA_GET(obj, sd);
2317
2318    list = evas_object_box_children_get(bx);
2319    if (!list) return items;
2320
2321    EINA_INLIST_FOREACH (sd->items, it)
2322      {
2323         if (it->separator) continue;
2324         if (eina_list_data_find(list, it->base.view))
2325           items = eina_list_append(items, it->base.access_obj);
2326      }
2327
2328    return items;
2329 }
2330
2331 static Eina_Bool
2332 _elm_toolbar_smart_focus_next(const Evas_Object *obj,
2333                               Elm_Focus_Direction dir,
2334                               Evas_Object **next)
2335 {
2336    Eina_List *items = NULL;
2337
2338    ELM_TOOLBAR_DATA_GET(obj, sd);
2339
2340    if (sd->more_item && sd->more_item->selected)
2341      {
2342         items = _access_item_find_append(obj, sd->bx_more, items);
2343         items = _access_item_find_append(obj, sd->bx_more2, items);
2344         items = eina_list_append(items, sd->more_item->base.access_obj);
2345      }
2346    else
2347      {
2348         items = _access_item_find_append(obj, sd->bx, items);
2349         if (sd->more_item &&
2350             eina_list_data_find(evas_object_box_children_get(sd->bx),
2351                                             sd->more_item->base.view))
2352           items = eina_list_append(items, sd->more_item->base.access_obj);
2353      }
2354
2355    return elm_widget_focus_list_next_get
2356             (obj, items, eina_list_data_get, dir, next);
2357 }
2358
2359 static void
2360 _access_obj_process(Elm_Toolbar_Smart_Data * sd, Eina_Bool is_access)
2361 {
2362    Elm_Toolbar_Item *it;
2363
2364    EINA_INLIST_FOREACH (sd->items, it)
2365      {
2366         if (is_access) _access_widget_item_register(it);
2367         else _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
2368      }
2369 }
2370
2371 static void
2372 _elm_toolbar_smart_access(Evas_Object *obj, Eina_Bool is_access)
2373 {
2374    ELM_TOOLBAR_CHECK(obj);
2375    ELM_TOOLBAR_DATA_GET(obj, sd);
2376
2377    if (is_access)
2378      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
2379        _elm_toolbar_smart_focus_next;
2380    else
2381      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
2382    _access_obj_process(sd, is_access);
2383 }
2384
2385 static void
2386 _elm_toolbar_smart_set_user(Elm_Toolbar_Smart_Class *sc)
2387 {
2388    ELM_WIDGET_CLASS(sc)->base.add = _elm_toolbar_smart_add;
2389    ELM_WIDGET_CLASS(sc)->base.del = _elm_toolbar_smart_del;
2390    ELM_WIDGET_CLASS(sc)->base.move = _elm_toolbar_smart_move;
2391    ELM_WIDGET_CLASS(sc)->base.resize = _elm_toolbar_smart_resize;
2392    ELM_WIDGET_CLASS(sc)->base.member_add = _elm_toolbar_smart_member_add;
2393
2394    ELM_WIDGET_CLASS(sc)->on_focus = _elm_toolbar_smart_on_focus;
2395    ELM_WIDGET_CLASS(sc)->event = _elm_toolbar_smart_event;
2396    ELM_WIDGET_CLASS(sc)->theme = _elm_toolbar_smart_theme;
2397    ELM_WIDGET_CLASS(sc)->translate = _elm_toolbar_smart_translate;
2398
2399    if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
2400      ELM_WIDGET_CLASS(sc)->focus_next = _elm_toolbar_smart_focus_next;
2401
2402    ELM_WIDGET_CLASS(sc)->access = _elm_toolbar_smart_access;
2403 }
2404
2405 EAPI const Elm_Toolbar_Smart_Class *
2406 elm_toolbar_smart_class_get(void)
2407 {
2408    static Elm_Toolbar_Smart_Class _sc =
2409      ELM_TOOLBAR_SMART_CLASS_INIT_NAME_VERSION(ELM_TOOLBAR_SMART_NAME);
2410    static const Elm_Toolbar_Smart_Class *class = NULL;
2411    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
2412
2413    if (class)
2414      return class;
2415
2416    _elm_toolbar_smart_set(&_sc);
2417    esc->callbacks = _smart_callbacks;
2418    class = &_sc;
2419
2420    return class;
2421 }
2422
2423 EAPI Evas_Object *
2424 elm_toolbar_add(Evas_Object *parent)
2425 {
2426    Evas_Object *obj;
2427
2428    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
2429
2430    obj = elm_widget_add(_elm_toolbar_smart_class_new(), parent);
2431    if (!obj) return NULL;
2432
2433    if (!elm_widget_sub_object_add(parent, obj))
2434      ERR("could not add %p as sub object of %p", obj, parent);
2435
2436    return obj;
2437 }
2438
2439 EAPI void
2440 elm_toolbar_icon_size_set(Evas_Object *obj,
2441                           int icon_size)
2442 {
2443    ELM_TOOLBAR_CHECK(obj);
2444    ELM_TOOLBAR_DATA_GET(obj, sd);
2445
2446    if (sd->priv_icon_size == icon_size) return;
2447    sd->priv_icon_size = icon_size;
2448
2449    if (sd->priv_icon_size) sd->icon_size = sd->priv_icon_size;
2450    else sd->icon_size = sd->theme_icon_size;
2451
2452    _elm_toolbar_smart_theme(obj);
2453 }
2454
2455 EAPI int
2456 elm_toolbar_icon_size_get(const Evas_Object *obj)
2457 {
2458    ELM_TOOLBAR_CHECK(obj) 0;
2459    ELM_TOOLBAR_DATA_GET(obj, sd);
2460
2461    return sd->priv_icon_size;
2462 }
2463
2464 EAPI Elm_Object_Item *
2465 elm_toolbar_item_append(Evas_Object *obj,
2466                         const char *icon,
2467                         const char *label,
2468                         Evas_Smart_Cb func,
2469                         const void *data)
2470 {
2471    Elm_Toolbar_Item *it;
2472    double scale;
2473
2474    ELM_TOOLBAR_CHECK(obj) NULL;
2475    ELM_TOOLBAR_DATA_GET(obj, sd);
2476
2477    it = _item_new(obj, icon, label, func, data);
2478    if (!it) return NULL;
2479    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2480
2481    sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
2482    evas_object_box_append(sd->bx, VIEW(it));
2483    evas_object_show(VIEW(it));
2484
2485    _item_theme_hook(obj, it, scale, sd->icon_size);
2486    _sizing_eval(obj);
2487    sd->item_count++;
2488
2489    return (Elm_Object_Item *)it;
2490 }
2491
2492 EAPI Elm_Object_Item *
2493 elm_toolbar_item_prepend(Evas_Object *obj,
2494                          const char *icon,
2495                          const char *label,
2496                          Evas_Smart_Cb func,
2497                          const void *data)
2498 {
2499    Elm_Toolbar_Item *it;
2500    double scale;
2501
2502    ELM_TOOLBAR_CHECK(obj) NULL;
2503    ELM_TOOLBAR_DATA_GET(obj, sd);
2504
2505    it = _item_new(obj, icon, label, func, data);
2506    if (!it) return NULL;
2507    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2508
2509    sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
2510    evas_object_box_prepend(sd->bx, VIEW(it));
2511    evas_object_show(VIEW(it));
2512    _item_theme_hook(obj, it, scale, sd->icon_size);
2513    _sizing_eval(obj);
2514    sd->item_count++;
2515
2516    return (Elm_Object_Item *)it;
2517 }
2518
2519 EAPI Elm_Object_Item *
2520 elm_toolbar_item_insert_before(Evas_Object *obj,
2521                                Elm_Object_Item *before,
2522                                const char *icon,
2523                                const char *label,
2524                                Evas_Smart_Cb func,
2525                                const void *data)
2526 {
2527    Elm_Toolbar_Item *it, *_before;
2528    double scale;
2529
2530    ELM_TOOLBAR_CHECK(obj) NULL;
2531    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(before, NULL);
2532    ELM_TOOLBAR_DATA_GET(obj, sd);
2533
2534    _before = (Elm_Toolbar_Item *)before;
2535    it = _item_new(obj, icon, label, func, data);
2536    if (!it) return NULL;
2537    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2538
2539    sd->items = eina_inlist_prepend_relative
2540        (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(_before));
2541    evas_object_box_insert_before(sd->bx, VIEW(it), VIEW(_before));
2542    evas_object_show(VIEW(it));
2543    _item_theme_hook(obj, it, scale, sd->icon_size);
2544    _sizing_eval(obj);
2545    sd->item_count++;
2546
2547    return (Elm_Object_Item *)it;
2548 }
2549
2550 EAPI Elm_Object_Item *
2551 elm_toolbar_item_insert_after(Evas_Object *obj,
2552                               Elm_Object_Item *after,
2553                               const char *icon,
2554                               const char *label,
2555                               Evas_Smart_Cb func,
2556                               const void *data)
2557 {
2558    Elm_Toolbar_Item *it, *_after;
2559    double scale;
2560
2561    ELM_TOOLBAR_CHECK(obj) NULL;
2562    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(after, NULL);
2563
2564    ELM_TOOLBAR_DATA_GET(obj, sd);
2565    _after = (Elm_Toolbar_Item *)after;
2566    it = _item_new(obj, icon, label, func, data);
2567    if (!it) return NULL;
2568    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2569
2570    sd->items = eina_inlist_append_relative
2571        (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(_after));
2572    evas_object_box_insert_after(sd->bx, VIEW(it), VIEW(_after));
2573    evas_object_show(VIEW(it));
2574    _item_theme_hook(obj, it, scale, sd->icon_size);
2575    _sizing_eval(obj);
2576    sd->item_count++;
2577
2578    return (Elm_Object_Item *)it;
2579 }
2580
2581 EAPI Elm_Object_Item *
2582 elm_toolbar_first_item_get(const Evas_Object *obj)
2583 {
2584    ELM_TOOLBAR_CHECK(obj) NULL;
2585    ELM_TOOLBAR_DATA_GET(obj, sd);
2586
2587    if (!sd->items) return NULL;
2588    return (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items);
2589 }
2590
2591 EAPI Elm_Object_Item *
2592 elm_toolbar_last_item_get(const Evas_Object *obj)
2593 {
2594    ELM_TOOLBAR_CHECK(obj) NULL;
2595    ELM_TOOLBAR_DATA_GET(obj, sd);
2596
2597    if (!sd->items) return NULL;
2598
2599    return (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items->last);
2600 }
2601
2602 EAPI Elm_Object_Item *
2603 elm_toolbar_item_next_get(const Elm_Object_Item *it)
2604 {
2605    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2606
2607    return (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(
2608             EINA_INLIST_GET(((Elm_Toolbar_Item *)it))->next);
2609 }
2610
2611 EAPI Elm_Object_Item *
2612 elm_toolbar_item_prev_get(const Elm_Object_Item *it)
2613 {
2614    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2615
2616    return (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(
2617             EINA_INLIST_GET(((Elm_Toolbar_Item *)it))->prev);
2618 }
2619
2620 EAPI void
2621 elm_toolbar_item_priority_set(Elm_Object_Item *it,
2622                               int priority)
2623 {
2624    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2625
2626    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
2627
2628    if (item->prio.priority == priority) return;
2629    item->prio.priority = priority;
2630    _resize_cb(WIDGET(item), NULL, NULL, NULL);
2631 }
2632
2633 EAPI int
2634 elm_toolbar_item_priority_get(const Elm_Object_Item *it)
2635 {
2636    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, 0);
2637
2638    return ((Elm_Toolbar_Item *)it)->prio.priority;
2639 }
2640
2641 EAPI Elm_Object_Item *
2642 elm_toolbar_item_find_by_label(const Evas_Object *obj,
2643                                const char *label)
2644 {
2645    Elm_Toolbar_Item *it;
2646
2647    ELM_TOOLBAR_CHECK(obj) NULL;
2648    ELM_TOOLBAR_DATA_GET(obj, sd);
2649
2650    EINA_INLIST_FOREACH(sd->items, it)
2651      {
2652         if (!strcmp(it->label, label))
2653           return (Elm_Object_Item *)it;
2654      }
2655
2656    return NULL;
2657 }
2658
2659 EAPI void
2660 elm_toolbar_item_selected_set(Elm_Object_Item *it,
2661                               Eina_Bool selected)
2662 {
2663    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2664
2665    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
2666
2667    if (item->selected == selected) return;
2668    if (selected) _item_select(item);
2669    else _item_unselect(item);
2670 }
2671
2672 EAPI Eina_Bool
2673 elm_toolbar_item_selected_get(const Elm_Object_Item *it)
2674 {
2675    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2676
2677    return ((Elm_Toolbar_Item *)it)->selected;
2678 }
2679
2680 EAPI Elm_Object_Item *
2681 elm_toolbar_selected_item_get(const Evas_Object *obj)
2682 {
2683    ELM_TOOLBAR_CHECK(obj) NULL;
2684    ELM_TOOLBAR_DATA_GET(obj, sd);
2685
2686    return (Elm_Object_Item *)sd->selected_item;
2687 }
2688
2689 EAPI Elm_Object_Item *
2690 elm_toolbar_more_item_get(const Evas_Object *obj)
2691 {
2692    ELM_TOOLBAR_CHECK(obj) NULL;
2693    ELM_TOOLBAR_DATA_GET(obj, sd);
2694
2695    return (Elm_Object_Item *)sd->more_item;
2696 }
2697
2698 EAPI void
2699 elm_toolbar_item_icon_set(Elm_Object_Item *it,
2700                           const char *icon)
2701 {
2702    Evas_Object *obj;
2703    Evas_Object *icon_obj;
2704    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2705
2706    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
2707
2708    obj = WIDGET(item);
2709    ELM_TOOLBAR_DATA_GET(obj, sd);
2710    if ((icon) && (item->icon_str) && (!strcmp(icon, item->icon_str))) return;
2711
2712    icon_obj = elm_icon_add(obj);
2713    if (!icon_obj) return;
2714    if (_item_icon_set(icon_obj, "toolbar/", icon))
2715      _elm_toolbar_item_icon_obj_set
2716        (obj, item, icon_obj, icon, sd->icon_size, "elm,state,icon_set");
2717    else
2718      {
2719         _elm_toolbar_item_icon_obj_set
2720           (obj, item, NULL, NULL, 0, "elm,state,icon_set");
2721         evas_object_del(icon_obj);
2722      }
2723 }
2724
2725 EAPI const char *
2726 elm_toolbar_item_icon_get(const Elm_Object_Item *it)
2727 {
2728    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2729
2730    return ((Elm_Toolbar_Item *)it)->icon_str;
2731 }
2732
2733 EAPI Evas_Object *
2734 elm_toolbar_item_object_get(const Elm_Object_Item *it)
2735 {
2736    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2737
2738    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2739
2740    return VIEW(item);
2741 }
2742
2743 EAPI Evas_Object *
2744 elm_toolbar_item_icon_object_get(Elm_Object_Item *it)
2745 {
2746    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2747
2748    return ((Elm_Toolbar_Item *)it)->icon;
2749 }
2750
2751 EAPI Eina_Bool
2752 elm_toolbar_item_icon_memfile_set(Elm_Object_Item *it,
2753                                   const void *img,
2754                                   size_t size,
2755                                   const char *format,
2756                                   const char *key)
2757 {
2758    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2759    Evas_Object *icon_obj;
2760    Evas_Object *obj;
2761    Eina_Bool ret;
2762
2763    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2764
2765    obj = WIDGET(item);
2766    ELM_TOOLBAR_DATA_GET(obj, sd);
2767
2768    if (img && size)
2769      {
2770         icon_obj = elm_icon_add(obj);
2771         evas_object_repeat_events_set(icon_obj, EINA_TRUE);
2772         ret = elm_image_memfile_set(icon_obj, img, size, format, key);
2773         if (!ret)
2774           {
2775              evas_object_del(icon_obj);
2776              return EINA_FALSE;
2777           }
2778         _elm_toolbar_item_icon_obj_set
2779           (obj, item, icon_obj, NULL, sd->icon_size, "elm,state,icon_set");
2780      }
2781    else
2782      _elm_toolbar_item_icon_obj_set
2783        (obj, item, NULL, NULL, 0, "elm,state,icon_set");
2784    return EINA_TRUE;
2785 }
2786
2787 EAPI Eina_Bool
2788 elm_toolbar_item_icon_file_set(Elm_Object_Item *it,
2789                                const char *file,
2790                                const char *key)
2791 {
2792    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2793    Evas_Object *icon_obj;
2794    Evas_Object *obj;
2795    Eina_Bool ret;
2796
2797    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2798
2799    obj = WIDGET(item);
2800    ELM_TOOLBAR_DATA_GET(obj, sd);
2801
2802    if (file)
2803      {
2804         icon_obj = elm_icon_add(obj);
2805         evas_object_repeat_events_set(icon_obj, EINA_TRUE);
2806         ret = elm_image_file_set(icon_obj, file, key);
2807         if (!ret)
2808           {
2809              evas_object_del(icon_obj);
2810              return EINA_FALSE;
2811           }
2812         _elm_toolbar_item_icon_obj_set
2813           (obj, item, icon_obj, NULL, sd->icon_size, "elm,state,icon_set");
2814      }
2815    else
2816      _elm_toolbar_item_icon_obj_set
2817        (obj, item, NULL, NULL, 0, "elm,state,icon_set");
2818    return EINA_TRUE;
2819 }
2820
2821 EAPI void
2822 elm_toolbar_item_separator_set(Elm_Object_Item *it,
2823                                Eina_Bool separator)
2824 {
2825    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2826    Evas_Object *obj = WIDGET(item);
2827    double scale;
2828
2829    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
2830    ELM_TOOLBAR_DATA_GET(obj, sd);
2831
2832    if (item->separator == separator) return;
2833    item->separator = separator;
2834    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2835    _item_theme_hook(obj, item, scale, sd->icon_size);
2836    evas_object_size_hint_min_set(VIEW(item), -1, -1);
2837    if (separator) sd->separator_count++;
2838    else sd->separator_count--;
2839 }
2840
2841 EAPI Eina_Bool
2842 elm_toolbar_item_separator_get(const Elm_Object_Item *it)
2843 {
2844    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2845
2846    return ((Elm_Toolbar_Item *)it)->separator;
2847 }
2848
2849 EAPI void
2850 elm_toolbar_shrink_mode_set(Evas_Object *obj,
2851                             Elm_Toolbar_Shrink_Mode shrink_mode)
2852 {
2853    Eina_Bool bounce;
2854
2855    ELM_TOOLBAR_CHECK(obj);
2856    ELM_TOOLBAR_DATA_GET(obj, sd);
2857
2858    if (sd->shrink_mode == shrink_mode) return;
2859    sd->shrink_mode = shrink_mode;
2860    bounce = (_elm_config->thumbscroll_bounce_enable) &&
2861      (shrink_mode == ELM_TOOLBAR_SHRINK_SCROLL);
2862    sd->s_iface->bounce_allow_set(obj, bounce, EINA_FALSE);
2863
2864    if (sd->more_item)
2865      {
2866         elm_widget_item_del(sd->more_item);
2867         sd->more_item = NULL;
2868      }
2869
2870    if (shrink_mode == ELM_TOOLBAR_SHRINK_MENU)
2871      {
2872         elm_toolbar_homogeneous_set(obj, EINA_FALSE);
2873         sd->s_iface->policy_set
2874           (obj, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
2875         sd->more_item = _item_new(obj, "more_menu", "More", NULL, NULL);
2876      }
2877    else if (shrink_mode == ELM_TOOLBAR_SHRINK_HIDE)
2878      {
2879         elm_toolbar_homogeneous_set(obj, EINA_FALSE);
2880         sd->s_iface->policy_set
2881           (obj, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
2882      }
2883    else if (shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
2884      {
2885         elm_toolbar_homogeneous_set(obj, EINA_FALSE);
2886         sd->s_iface->policy_set
2887           (obj, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
2888         sd->more_item = _item_new(obj, "more_menu", "More", NULL, NULL);
2889      }
2890    else
2891      sd->s_iface->policy_set
2892        (obj, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
2893
2894    _sizing_eval(obj);
2895 }
2896
2897 EAPI Elm_Toolbar_Shrink_Mode
2898 elm_toolbar_shrink_mode_get(const Evas_Object *obj)
2899 {
2900    ELM_TOOLBAR_CHECK(obj) ELM_TOOLBAR_SHRINK_NONE;
2901    ELM_TOOLBAR_DATA_GET(obj, sd);
2902
2903    return sd->shrink_mode;
2904 }
2905
2906 EAPI void
2907 elm_toolbar_transverse_expanded_set(Evas_Object *obj, Eina_Bool transverse_expanded)
2908 {
2909    ELM_TOOLBAR_CHECK(obj);
2910    ELM_TOOLBAR_DATA_GET(obj, sd);
2911
2912    if (sd->transverse_expanded == transverse_expanded) return;
2913    sd->transverse_expanded = transverse_expanded;
2914
2915    _sizing_eval(obj);
2916 }
2917
2918 EAPI Eina_Bool
2919 elm_toolbar_transverse_expanded_get(const Evas_Object *obj)
2920 {
2921    ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
2922    ELM_TOOLBAR_DATA_GET(obj, sd);
2923
2924    return sd->transverse_expanded;
2925 }
2926
2927 EAPI void
2928 elm_toolbar_homogeneous_set(Evas_Object *obj,
2929                             Eina_Bool homogeneous)
2930 {
2931    ELM_TOOLBAR_CHECK(obj);
2932    ELM_TOOLBAR_DATA_GET(obj, sd);
2933
2934    homogeneous = !!homogeneous;
2935    if (homogeneous == sd->homogeneous) return;
2936    sd->homogeneous = homogeneous;
2937    if (homogeneous) elm_toolbar_shrink_mode_set(obj, ELM_TOOLBAR_SHRINK_NONE);
2938    evas_object_smart_calculate(sd->bx);
2939 }
2940
2941 EAPI Eina_Bool
2942 elm_toolbar_homogeneous_get(const Evas_Object *obj)
2943 {
2944    ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
2945    ELM_TOOLBAR_DATA_GET(obj, sd);
2946
2947    return sd->homogeneous;
2948 }
2949
2950 EAPI void
2951 elm_toolbar_menu_parent_set(Evas_Object *obj,
2952                             Evas_Object *parent)
2953 {
2954    Elm_Toolbar_Item *it;
2955
2956    ELM_TOOLBAR_CHECK(obj);
2957    ELM_TOOLBAR_DATA_GET(obj, sd);
2958    EINA_SAFETY_ON_NULL_RETURN(parent);
2959
2960    sd->menu_parent = parent;
2961    EINA_INLIST_FOREACH(sd->items, it)
2962      {
2963         if (it->o_menu)
2964           elm_menu_parent_set(it->o_menu, sd->menu_parent);
2965      }
2966    if ((sd->more_item) && (sd->more_item->o_menu))
2967      elm_menu_parent_set(sd->more_item->o_menu, sd->menu_parent);
2968 }
2969
2970 EAPI Evas_Object *
2971 elm_toolbar_menu_parent_get(const Evas_Object *obj)
2972 {
2973    ELM_TOOLBAR_CHECK(obj) NULL;
2974    ELM_TOOLBAR_DATA_GET(obj, sd);
2975
2976    return sd->menu_parent;
2977 }
2978
2979 EAPI void
2980 elm_toolbar_align_set(Evas_Object *obj,
2981                       double align)
2982 {
2983    ELM_TOOLBAR_CHECK(obj);
2984    ELM_TOOLBAR_DATA_GET(obj, sd);
2985
2986    if (sd->vertical)
2987      {
2988         if (sd->align != align)
2989           evas_object_size_hint_align_set(sd->bx, 0.5, align);
2990      }
2991    else
2992      {
2993         if (sd->align != align)
2994           evas_object_size_hint_align_set(sd->bx, align, 0.5);
2995      }
2996    sd->align = align;
2997 }
2998
2999 EAPI double
3000 elm_toolbar_align_get(const Evas_Object *obj)
3001 {
3002    ELM_TOOLBAR_CHECK(obj) 0.0;
3003    ELM_TOOLBAR_DATA_GET(obj, sd);
3004
3005    return sd->align;
3006 }
3007
3008 EAPI void
3009 elm_toolbar_item_menu_set(Elm_Object_Item *it,
3010                           Eina_Bool menu)
3011 {
3012    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3013
3014    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
3015    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
3016
3017    if (item->menu == menu) return;
3018    if (menu) _item_menu_create(sd, item);
3019    else _item_menu_destroy(item);
3020 }
3021
3022 EAPI Evas_Object *
3023 elm_toolbar_item_menu_get(const Elm_Object_Item *it)
3024 {
3025    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3026
3027    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3028
3029    if (!item->menu) return NULL;
3030    return item->o_menu;
3031 }
3032
3033 EAPI Elm_Toolbar_Item_State *
3034 elm_toolbar_item_state_add(Elm_Object_Item *it,
3035                            const char *icon,
3036                            const char *label,
3037                            Evas_Smart_Cb func,
3038                            const void *data)
3039 {
3040    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3041    Elm_Toolbar_Item_State *it_state;
3042    Evas_Object *icon_obj;
3043    Evas_Object *obj;
3044
3045    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3046
3047    obj = WIDGET(item);
3048    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
3049
3050    if (!item->states)
3051      {
3052         it_state = _item_state_new
3053             (item->label, item->icon_str, item->icon, item->func,
3054             item->base.data);
3055         item->states = eina_list_append(item->states, it_state);
3056         item->current_state = item->states;
3057      }
3058
3059    icon_obj = elm_icon_add(obj);
3060    elm_icon_order_lookup_set(icon_obj, sd->lookup_order);
3061    if (!icon_obj) goto error_state_add;
3062
3063    if (!_item_icon_set(icon_obj, "toolbar/", icon))
3064      {
3065         evas_object_del(icon_obj);
3066         icon_obj = NULL;
3067         icon = NULL;
3068      }
3069
3070    it_state = _item_state_new(label, icon, icon_obj, func, data);
3071    item->states = eina_list_append(item->states, it_state);
3072    item->func = _elm_toolbar_item_state_cb;
3073    item->base.data = NULL;
3074
3075    return it_state;
3076
3077 error_state_add:
3078    if (item->states && !eina_list_next(item->states))
3079      {
3080         eina_stringshare_del(item->label);
3081         eina_stringshare_del(item->icon_str);
3082         free(eina_list_data_get(item->states));
3083         eina_list_free(item->states);
3084         item->states = NULL;
3085      }
3086    return NULL;
3087 }
3088
3089 EAPI Eina_Bool
3090 elm_toolbar_item_state_del(Elm_Object_Item *it,
3091                            Elm_Toolbar_Item_State *state)
3092 {
3093    Elm_Toolbar_Item_State *it_state;
3094    Elm_Toolbar_Item *item;
3095    Eina_List *del_state;
3096
3097    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
3098
3099    if (!state) return EINA_FALSE;
3100
3101    item = (Elm_Toolbar_Item *)it;
3102    if (!item->states) return EINA_FALSE;
3103
3104    del_state = eina_list_data_find_list(item->states, state);
3105    if (del_state == item->states) return EINA_FALSE;
3106    if (del_state == item->current_state)
3107      elm_toolbar_item_state_unset(it);
3108
3109    eina_stringshare_del(state->label);
3110    eina_stringshare_del(state->icon_str);
3111    if (state->icon) evas_object_del(state->icon);
3112    free(state);
3113
3114    item->states = eina_list_remove_list(item->states, del_state);
3115    if (item->states && !eina_list_next(item->states))
3116      {
3117         it_state = eina_list_data_get(item->states);
3118         item->base.data = it_state->data;
3119         item->func = it_state->func;
3120         eina_stringshare_del(it_state->label);
3121         eina_stringshare_del(it_state->icon_str);
3122         free(eina_list_data_get(item->states));
3123         eina_list_free(item->states);
3124         item->states = NULL;
3125      }
3126
3127    return EINA_TRUE;
3128 }
3129
3130 EAPI Eina_Bool
3131 elm_toolbar_item_state_set(Elm_Object_Item *it,
3132                            Elm_Toolbar_Item_State *state)
3133 {
3134    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3135    Elm_Toolbar_Item_State *it_state;
3136    Eina_List *next_state;
3137    Evas_Object *obj;
3138
3139    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
3140
3141    obj = WIDGET(item);
3142    ELM_TOOLBAR_DATA_GET(obj, sd);
3143    if (!item->states) return EINA_FALSE;
3144
3145    if (state)
3146      {
3147         next_state = eina_list_data_find_list(item->states, state);
3148         if (!next_state) return EINA_FALSE;
3149      }
3150    else
3151      next_state = item->states;
3152
3153    if (next_state == item->current_state) return EINA_TRUE;
3154
3155    it_state = eina_list_data_get(next_state);
3156    if (eina_list_data_find(item->current_state, state))
3157      {
3158         _item_label_set(item, it_state->label, "elm,state,label_set,forward");
3159         _elm_toolbar_item_icon_obj_set
3160           (obj, item, it_state->icon, it_state->icon_str,
3161           sd->icon_size, "elm,state,icon_set,forward");
3162      }
3163    else
3164      {
3165         _item_label_set(item, it_state->label, "elm,state,label_set,backward");
3166         _elm_toolbar_item_icon_obj_set
3167           (obj, item, it_state->icon, it_state->icon_str,
3168           sd->icon_size, "elm,state,icon_set,backward");
3169      }
3170    if (elm_widget_item_disabled_get(item))
3171      elm_widget_signal_emit(item->icon, "elm,state,disabled", "elm");
3172    else
3173      elm_widget_signal_emit(item->icon, "elm,state,enabled", "elm");
3174
3175    item->current_state = next_state;
3176
3177    return EINA_TRUE;
3178 }
3179
3180 EAPI void
3181 elm_toolbar_item_state_unset(Elm_Object_Item *it)
3182 {
3183    elm_toolbar_item_state_set(it, NULL);
3184 }
3185
3186 EAPI Elm_Toolbar_Item_State *
3187 elm_toolbar_item_state_get(const Elm_Object_Item *it)
3188 {
3189    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3190
3191    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3192
3193    if ((!item->states) || (!item->current_state)) return NULL;
3194    if (item->current_state == item->states) return NULL;
3195
3196    return eina_list_data_get(item->current_state);
3197 }
3198
3199 EAPI Elm_Toolbar_Item_State *
3200 elm_toolbar_item_state_next(Elm_Object_Item *it)
3201 {
3202    Eina_List *next_state;
3203    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3204
3205    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3206
3207    if (!item->states) return NULL;
3208
3209    next_state = eina_list_next(item->current_state);
3210    if (!next_state)
3211      next_state = eina_list_next(item->states);
3212    return eina_list_data_get(next_state);
3213 }
3214
3215 EAPI Elm_Toolbar_Item_State *
3216 elm_toolbar_item_state_prev(Elm_Object_Item *it)
3217 {
3218    Eina_List *prev_state;
3219    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3220
3221    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3222
3223    if (!item->states) return NULL;
3224
3225    prev_state = eina_list_prev(item->current_state);
3226    if ((!prev_state) || (prev_state == item->states))
3227      prev_state = eina_list_last(item->states);
3228    return eina_list_data_get(prev_state);
3229 }
3230
3231 EAPI void
3232 elm_toolbar_icon_order_lookup_set(Evas_Object *obj,
3233                                   Elm_Icon_Lookup_Order order)
3234 {
3235    Elm_Toolbar_Item *it;
3236
3237    ELM_TOOLBAR_CHECK(obj);
3238    ELM_TOOLBAR_DATA_GET(obj, sd);
3239
3240    if (sd->lookup_order == order) return;
3241    sd->lookup_order = order;
3242    EINA_INLIST_FOREACH(sd->items, it)
3243      elm_icon_order_lookup_set(it->icon, order);
3244    if (sd->more_item)
3245      elm_icon_order_lookup_set(sd->more_item->icon, order);
3246 }
3247
3248 EAPI Elm_Icon_Lookup_Order
3249 elm_toolbar_icon_order_lookup_get(const Evas_Object *obj)
3250 {
3251    ELM_TOOLBAR_CHECK(obj) ELM_ICON_LOOKUP_THEME_FDO;
3252    ELM_TOOLBAR_DATA_GET(obj, sd);
3253
3254    return sd->lookup_order;
3255 }
3256
3257 EAPI void
3258 elm_toolbar_horizontal_set(Evas_Object *obj,
3259                            Eina_Bool horizontal)
3260 {
3261    ELM_TOOLBAR_CHECK(obj);
3262    ELM_TOOLBAR_DATA_GET(obj, sd);
3263
3264    horizontal = !!horizontal;
3265    if (!horizontal == sd->vertical) return;
3266    sd->vertical = !horizontal;
3267    if (sd->vertical)
3268      evas_object_size_hint_align_set(sd->bx, 0.5, sd->align);
3269    else
3270      evas_object_size_hint_align_set(sd->bx, sd->align, 0.5);
3271
3272    _sizing_eval(obj);
3273 }
3274
3275 EAPI Eina_Bool
3276 elm_toolbar_horizontal_get(const Evas_Object *obj)
3277 {
3278    ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
3279    ELM_TOOLBAR_DATA_GET(obj, sd);
3280
3281    return !sd->vertical;
3282 }
3283
3284 EAPI unsigned int
3285 elm_toolbar_items_count(const Evas_Object *obj)
3286 {
3287    ELM_TOOLBAR_CHECK(obj) 0;
3288    ELM_TOOLBAR_DATA_GET(obj, sd);
3289
3290    return sd->item_count;
3291 }
3292
3293 EAPI void
3294 elm_toolbar_standard_priority_set(Evas_Object *obj,
3295                                   int priority)
3296 {
3297    ELM_TOOLBAR_CHECK(obj);
3298    ELM_TOOLBAR_DATA_GET(obj, sd);
3299
3300    if (sd->standard_priority == priority) return;
3301    sd->standard_priority = priority;
3302    _resize_cb(obj, NULL, NULL, NULL);
3303 }
3304
3305 EAPI int
3306 elm_toolbar_standard_priority_get(const Evas_Object *obj)
3307 {
3308    ELM_TOOLBAR_CHECK(obj) 0;
3309    ELM_TOOLBAR_DATA_GET(obj, sd);
3310
3311    return sd->standard_priority;
3312 }
3313
3314 EAPI void
3315 elm_toolbar_select_mode_set(Evas_Object *obj,
3316                             Elm_Object_Select_Mode mode)
3317 {
3318    ELM_TOOLBAR_CHECK(obj);
3319    ELM_TOOLBAR_DATA_GET(obj, sd);
3320
3321    if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
3322      return;
3323
3324    if (sd->select_mode == mode) return;
3325
3326    if ((mode == ELM_OBJECT_SELECT_MODE_ALWAYS) &&
3327        (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) &&
3328        sd->items)
3329      _item_select(ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items));
3330
3331    if (sd->select_mode != mode)
3332      sd->select_mode = mode;
3333 }
3334
3335 EAPI Elm_Object_Select_Mode
3336 elm_toolbar_select_mode_get(const Evas_Object *obj)
3337 {
3338    ELM_TOOLBAR_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
3339    ELM_TOOLBAR_DATA_GET(obj, sd);
3340
3341    return sd->select_mode;
3342 }
3343
3344 EAPI void
3345 elm_toolbar_reorder_mode_set(Evas_Object *obj,
3346                              Eina_Bool    reorder_mode)
3347 {
3348    ELM_TOOLBAR_CHECK(obj);
3349    ELM_TOOLBAR_DATA_GET(obj, sd);
3350
3351    sd->reorder_mode = !!reorder_mode;
3352 }
3353
3354 EAPI Eina_Bool
3355 elm_toolbar_reorder_mode_get(const Evas_Object *obj)
3356 {
3357    ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
3358    ELM_TOOLBAR_DATA_GET(obj, sd);
3359
3360    return sd->reorder_mode;
3361 }
3362
3363 EAPI void
3364 elm_toolbar_item_show(Elm_Object_Item *it, Elm_Toolbar_Item_Scrollto_Type type)
3365 {
3366    Evas_Coord x, y, w, h;
3367    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3368
3369    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
3370    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
3371
3372    if (_elm_toolbar_item_coordinates_calc(it, type, &x, &y, &w, &h))
3373      sd->s_iface->content_region_show(WIDGET(item), x, y, w, h);
3374 }
3375
3376 EAPI void
3377 elm_toolbar_item_bring_in(Elm_Object_Item *it, Elm_Toolbar_Item_Scrollto_Type type)
3378 {
3379    Evas_Coord x, y, w, h;
3380    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3381
3382    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
3383    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
3384
3385    if (_elm_toolbar_item_coordinates_calc(it, type, &x, &y, &w, &h))
3386      sd->s_iface->region_bring_in(WIDGET(item), x, y, w, h);
3387 }