[Scroller] Fix the calculation double type number. Round off to the nearest whole...
[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              if (prev) 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    // If the min size is changed by edje signal in edc,
904    //the below function should be called before the calculation.
905    edje_object_message_signal_process(view);
906    edje_object_size_min_restricted_calc(view, &mw, &mh, mw, mh);
907    if (!it->separator && !it->object)
908      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
909    evas_object_size_hint_min_set(view, mw, mh);
910 }
911
912 static void
913 _inform_item_number(Evas_Object *obj)
914 {
915    ELM_TOOLBAR_DATA_GET(obj, sd);
916    Elm_Toolbar_Item *it;
917    char buf[sizeof("elm,action,click,") + 3];
918    static int scount = 0;
919    int count = 0;
920
921    EINA_INLIST_FOREACH(sd->items, it)
922      {
923         if (!it->separator) count++;
924      }
925    if (scount != count)
926      {
927         scount = count;
928         sprintf(buf, "elm,number,item,%d", count);
929
930         EINA_INLIST_FOREACH(sd->items, it)
931           {
932              if (!it->separator && !it->object)
933                edje_object_signal_emit(VIEW(it), buf, "elm");
934           }
935      }
936 }
937
938 static void
939 _sizing_eval(Evas_Object *obj)
940 {
941    Evas_Coord minw = -1, minh = -1, minw_bx = -1, minh_bx = -1;
942    Evas_Coord vw = 0, vh = 0;
943    Evas_Coord w, h;
944
945    ELM_TOOLBAR_DATA_GET(obj, sd);
946
947    evas_object_smart_need_recalculate_set(sd->bx, EINA_TRUE);
948    evas_object_smart_calculate(sd->bx);
949    edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
950    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
951
952    if (w < minw) w = minw;
953    if (h < minh) h = minh;
954
955    evas_object_resize(ELM_WIDGET_DATA(sd)->resize_obj, w, h);
956
957    evas_object_size_hint_min_get(sd->bx, &minw_bx, &minh_bx);
958    sd->s_iface->content_viewport_size_get(obj, &vw, &vh);
959
960    if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_NONE)
961      {
962         minw = minw_bx + (w - vw);
963         minh = minh_bx + (h - vh);
964      }
965    else if (sd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
966      {
967         if (sd->vertical)
968           {
969              minw = minw_bx + (w - vw);
970              if (minh_bx <= vh) minh_bx = vh;
971              else _items_size_fit(obj, &minh_bx, vh);
972           }
973         else
974           {
975              minh = minh_bx + (h - vh);
976              if (minw_bx <= vw) minw_bx = vw;
977              else _items_size_fit(obj, &minw_bx, vw);
978           }
979      }
980    else
981      {
982         if (sd->vertical)
983           {
984              minw = minw_bx + (w - vw);
985              minh = h - vh;
986           }
987         else
988           {
989              minw = w - vw;
990              minh = minh_bx + (h - vh);
991           }
992      }
993
994    if (sd->transverse_expanded)
995      {
996         if (sd->vertical)
997           minw_bx = vw;
998         else
999           minh_bx = vh;
1000      }
1001
1002    evas_object_resize(sd->bx, minw_bx, minh_bx);
1003    evas_object_resize(sd->more, minw_bx, minh_bx);
1004    evas_object_size_hint_min_set(obj, minw, minh);
1005    evas_object_size_hint_max_set(obj, -1, -1);
1006
1007    _inform_item_number(obj);
1008 }
1009
1010 static Eina_Bool
1011 _elm_toolbar_smart_theme(Evas_Object *obj)
1012 {
1013    Elm_Toolbar_Item *it;
1014    double scale = 0;
1015
1016    ELM_TOOLBAR_DATA_GET(obj, sd);
1017
1018    if (sd->on_deletion)
1019      return EINA_TRUE;
1020
1021    if (!ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->theme(obj))
1022      return EINA_FALSE;
1023
1024    elm_widget_theme_object_set
1025      (obj, ELM_WIDGET_DATA(sd)->resize_obj, "toolbar", "base",
1026      elm_widget_style_get(obj));
1027
1028    elm_layout_theme_set
1029      (sd->more, "toolbar", "more", elm_widget_style_get(obj));
1030
1031    _mirrored_set(obj, elm_widget_mirrored_get(obj));
1032
1033    sd->theme_icon_size = _elm_toolbar_icon_size_get(sd);
1034    if (sd->priv_icon_size) sd->icon_size = sd->priv_icon_size;
1035    else sd->icon_size = sd->theme_icon_size;
1036
1037    EINA_INLIST_FOREACH(sd->items, it)
1038      _item_theme_hook(obj, it, scale, sd->icon_size);
1039
1040    if (sd->more_item)
1041      _item_theme_hook(obj, sd->more_item, scale, sd->icon_size);
1042
1043    _sizing_eval(obj);
1044
1045    return EINA_TRUE;
1046 }
1047
1048 static void
1049 _elm_toolbar_item_label_update(Elm_Toolbar_Item *item)
1050 {
1051    Evas_Coord mw = -1, mh = -1, minw = -1, minh = -1;
1052
1053    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
1054
1055    edje_object_part_text_escaped_set(VIEW(item), "elm.text", item->label);
1056    if (item->label)
1057      edje_object_signal_emit(VIEW(item), "elm,state,text,visible", "elm");
1058    else
1059      edje_object_signal_emit(VIEW(item), "elm,state,text,hidden", "elm");
1060
1061    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1062    // If the min size is changed by edje signal in edc,
1063    //the below function should be called before the calculation.
1064    edje_object_message_signal_process(VIEW(item));
1065    edje_object_size_min_restricted_calc(VIEW(item), &mw, &mh, mw, mh);
1066    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1067    if (sd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
1068      {
1069         if (sd->vertical)
1070           {
1071              evas_object_size_hint_weight_set
1072                (VIEW(item), EVAS_HINT_EXPAND, -1.0);
1073              evas_object_size_hint_align_set
1074                (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1075           }
1076         else
1077           {
1078              evas_object_size_hint_weight_set
1079                (VIEW(item), -1.0, EVAS_HINT_EXPAND);
1080              evas_object_size_hint_align_set
1081                (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1082           }
1083      }
1084    else
1085      {
1086         evas_object_size_hint_weight_set
1087           (VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1088         evas_object_size_hint_align_set
1089           (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1090      }
1091
1092    evas_object_size_hint_min_get(VIEW(item), &minw, &minh);
1093    if ((minw < mw) && (minh < mh))
1094      evas_object_size_hint_min_set(VIEW(item), mw, mh);
1095    else if ((minw < mw) && (minh > mh))
1096      evas_object_size_hint_min_set(VIEW(item), mw, minh);
1097    else if ((minw > mw) && (minh < mh))
1098      evas_object_size_hint_min_set(VIEW(item), minw, mh);
1099 }
1100
1101 static void
1102 _elm_toolbar_item_label_set_cb(void *data,
1103                                Evas_Object *obj,
1104                                const char *emission,
1105                                const char *source)
1106 {
1107    Elm_Toolbar_Item *item = data;
1108
1109    _elm_toolbar_item_label_update(item);
1110    edje_object_signal_callback_del
1111      (obj, emission, source, _elm_toolbar_item_label_set_cb);
1112    edje_object_signal_emit(VIEW(item), "elm,state,label,reset", "elm");
1113 }
1114
1115 static void
1116 _item_label_set(Elm_Toolbar_Item *item,
1117                 const char *label,
1118                 const char *sig)
1119 {
1120    const char *s;
1121
1122    if ((label) && (item->label) && (!strcmp(label, item->label))) return;
1123
1124    eina_stringshare_replace(&item->label, label);
1125    s = edje_object_data_get(VIEW(item), "transition_animation_on");
1126    if ((s) && (atoi(s)))
1127      {
1128         edje_object_part_text_escaped_set
1129           (VIEW(item), "elm.text_new", item->label);
1130         edje_object_signal_emit(VIEW(item), sig, "elm");
1131         edje_object_signal_callback_add
1132           (VIEW(item), "elm,state,label_set,done", "elm",
1133           _elm_toolbar_item_label_set_cb, item);
1134      }
1135    else
1136      _elm_toolbar_item_label_update(item);
1137
1138    _resize_cb(WIDGET(item), NULL, NULL, NULL);
1139 }
1140
1141 static void
1142 _item_text_set_hook(Elm_Object_Item *it,
1143                     const char *part,
1144                     const char *label)
1145 {
1146    Elm_Toolbar_Item *item;
1147    char buf[256];
1148    item = (Elm_Toolbar_Item *)it;
1149
1150    if ((!part) || (!strcmp(part, "default")) ||
1151        (!strcmp(part, "elm.text")))
1152      {
1153         _item_label_set(((Elm_Toolbar_Item *)it), label, "elm,state,label_set");
1154      }
1155    else
1156      {
1157         if (label)
1158           {
1159              snprintf(buf, sizeof(buf), "elm,state,%s,visible", part);
1160              edje_object_signal_emit(VIEW(item), buf, "elm");
1161           }
1162         else
1163           {
1164              snprintf(buf, sizeof(buf), "elm,state,%s,hidden", part);
1165              edje_object_signal_emit(VIEW(item), buf, "elm");
1166           }
1167         edje_object_part_text_escaped_set(VIEW(item), part, label);
1168      }
1169 }
1170
1171 static const char *
1172 _item_text_get_hook(const Elm_Object_Item *it,
1173                     const char *part)
1174 {
1175    char buf[256];
1176
1177    if (!part || !strcmp(part, "default"))
1178      snprintf(buf, sizeof(buf), "elm.text");
1179    else
1180      snprintf(buf, sizeof(buf), "%s", part);
1181
1182    return edje_object_part_text_get(VIEW(it), buf);
1183 }
1184
1185 static void
1186 _item_content_set_hook(Elm_Object_Item *it,
1187                        const char *part,
1188                        Evas_Object *content)
1189 {
1190    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
1191    Evas_Object *obj = WIDGET(item);
1192    double scale;
1193
1194    ELM_TOOLBAR_DATA_GET(obj, sd);
1195
1196    if (part && strcmp(part, "object")) return;
1197    if (item->object == content) return;
1198
1199    if (item->object) evas_object_del(item->object);
1200
1201    item->object = content;
1202    if (item->object)
1203      elm_widget_sub_object_add(obj, item->object);
1204
1205    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
1206    _item_theme_hook(obj, item, scale, sd->icon_size);
1207 }
1208
1209 static Evas_Object *
1210 _item_content_get_hook(const Elm_Object_Item *it,
1211                        const char *part)
1212 {
1213    if (part && strcmp(part, "object")) return NULL;
1214    return ((Elm_Toolbar_Item *)it)->object;
1215 }
1216
1217 static Evas_Object *
1218 _item_content_unset_hook(Elm_Object_Item *it,
1219                          const char *part)
1220 {
1221    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
1222    Evas_Object *obj = WIDGET(item);
1223    Evas_Object *o;
1224    double scale;
1225
1226    ELM_TOOLBAR_DATA_GET(obj, sd);
1227
1228    if (part && strcmp(part, "object")) return NULL;
1229
1230    edje_object_part_unswallow(VIEW(it), item->object);
1231    elm_widget_sub_object_del(obj, item->object);
1232    o = item->object;
1233    item->object = NULL;
1234    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
1235    _item_theme_hook(obj, item, scale, sd->icon_size);
1236
1237    return o;
1238 }
1239
1240 static Eina_Bool
1241 _elm_toolbar_smart_translate(Evas_Object *obj)
1242 {
1243    evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
1244
1245    return EINA_TRUE;
1246 }
1247
1248 static void
1249 _item_resize(void *data,
1250              Evas *e __UNUSED__,
1251              Evas_Object *obj __UNUSED__,
1252              void *event_info __UNUSED__)
1253 {
1254    _sizing_eval(data);
1255    _resize_cb(data, NULL, NULL, NULL);
1256 }
1257
1258 static void
1259 _move_cb(void *data,
1260          Evas *e __UNUSED__,
1261          Evas_Object *obj __UNUSED__,
1262          void *event_info __UNUSED__)
1263 {
1264    Evas_Coord x, y, h;
1265
1266    ELM_TOOLBAR_DATA_GET(data, sd);
1267    evas_object_geometry_get(data, &x, &y, NULL, &h);
1268    evas_object_move(sd->more, x, y + h);
1269 }
1270
1271 static void
1272 _select_filter_cb(Elm_Toolbar_Item *it,
1273                   Evas_Object *obj __UNUSED__,
1274                   const char *emission,
1275                   const char *source __UNUSED__)
1276 {
1277    int button;
1278    char buf[sizeof("elm,action,click,") + 1];
1279
1280    button = atoi(emission + sizeof("mouse,clicked,") - 1);
1281    if (button == 1) return;  /* regular left click event */
1282    snprintf(buf, sizeof(buf), "elm,action,click,%d", button);
1283    edje_object_signal_emit(VIEW(it), buf, "elm");
1284 }
1285
1286 static void
1287 _select_cb(void *data,
1288            Evas_Object *obj __UNUSED__,
1289            const char *emission __UNUSED__,
1290            const char *source __UNUSED__)
1291 {
1292    Elm_Toolbar_Item *it = data;
1293
1294    if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) ||
1295        (_elm_access_2nd_click_timeout(VIEW(it))))
1296      {
1297         if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
1298           _elm_access_say(E_("Selected"));
1299         _item_select(it);
1300      }
1301 }
1302
1303 static void
1304 _item_move_cb(void *data,
1305          Evas *e __UNUSED__,
1306          Evas_Object *obj __UNUSED__,
1307          void *event_info __UNUSED__)
1308 {
1309    Elm_Toolbar_Item *item = data;
1310
1311    item->on_move = EINA_FALSE;
1312
1313    evas_object_event_callback_del_full
1314      (VIEW(item), EVAS_CALLBACK_MOVE, _item_move_cb, data);
1315 }
1316
1317 static void
1318 _items_change(Elm_Toolbar_Item *reorder_from, Elm_Toolbar_Item *reorder_to)
1319 {
1320    Elm_Toolbar_Item *prev = NULL, *next = NULL;
1321    int tmp;
1322
1323    if (!reorder_from || !reorder_to) return;
1324
1325    ELM_TOOLBAR_DATA_GET(WIDGET(reorder_from), sd);
1326    if (reorder_from == reorder_to) return;
1327
1328    if ((!reorder_from->separator) && (!reorder_to->separator))
1329      {
1330         prev = ELM_TOOLBAR_ITEM_FROM_INLIST
1331             (EINA_INLIST_GET(reorder_from)->prev);
1332         if (prev == reorder_to)
1333           prev = reorder_from;
1334         if (!prev)
1335           next = ELM_TOOLBAR_ITEM_FROM_INLIST
1336               (EINA_INLIST_GET(reorder_from)->next);
1337         if (next == reorder_to)
1338           next = NULL;
1339
1340         sd->items = eina_inlist_remove
1341             (sd->items, EINA_INLIST_GET(reorder_from));
1342         sd->items = eina_inlist_append_relative
1343             (sd->items, EINA_INLIST_GET(reorder_from),
1344             EINA_INLIST_GET(reorder_to));
1345
1346         sd->items = eina_inlist_remove
1347             (sd->items, EINA_INLIST_GET(reorder_to));
1348         if (prev)
1349           sd->items = eina_inlist_append_relative
1350               (sd->items, EINA_INLIST_GET(reorder_to),
1351               EINA_INLIST_GET(prev));
1352         else if (next)
1353           sd->items = eina_inlist_prepend_relative
1354               (sd->items, EINA_INLIST_GET(reorder_to),
1355               EINA_INLIST_GET(next));
1356         else
1357           sd->items = eina_inlist_prepend
1358              (sd->items, EINA_INLIST_GET(reorder_to));
1359
1360         evas_object_box_remove(sd->bx, VIEW(reorder_from));
1361         evas_object_box_insert_after(sd->bx, VIEW(reorder_from),
1362                                      VIEW(reorder_to));
1363         evas_object_box_remove(sd->bx, VIEW(reorder_to));
1364         if (prev)
1365           evas_object_box_insert_after(sd->bx, VIEW(reorder_to),
1366                                        VIEW(prev));
1367         else if (next)
1368           evas_object_box_insert_before(sd->bx, VIEW(reorder_to),
1369                                         VIEW(next));
1370         else
1371           evas_object_box_prepend(sd->bx, VIEW(reorder_to));
1372
1373         tmp = reorder_from->prio.priority;
1374         reorder_from->prio.priority = reorder_to->prio.priority;
1375         reorder_to->prio.priority = tmp;
1376
1377         reorder_from->on_move = EINA_TRUE;
1378         reorder_to->on_move = EINA_TRUE;
1379
1380         evas_object_event_callback_add
1381            (VIEW(reorder_from), EVAS_CALLBACK_MOVE,
1382            _item_move_cb, reorder_from);
1383         evas_object_event_callback_add
1384            (VIEW(reorder_to), EVAS_CALLBACK_MOVE,
1385            _item_move_cb, reorder_to);
1386      }
1387
1388    _resize_cb(WIDGET(reorder_from), NULL, NULL, NULL);
1389 }
1390
1391 static void
1392 _transit_del_cb(void *data, Elm_Transit *transit __UNUSED__)
1393 {
1394    Elm_Toolbar_Item *it, *item = data;
1395    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
1396
1397    if (item->reorder_to)
1398      {
1399         if (item->reorder_to == sd->reorder_empty)
1400           sd->reorder_empty = item;
1401         else if (item == sd->reorder_empty)
1402           sd->reorder_empty = item->reorder_to;
1403
1404         _items_change(item->reorder_to, item);
1405
1406         EINA_INLIST_FOREACH(sd->items, it)
1407           {
1408              if (it != item)
1409                {
1410                   if (it->reorder_to == item)
1411                     it->reorder_to = item->reorder_to;
1412                   else if (it->reorder_to == item->reorder_to)
1413                     it->reorder_to = item;
1414                }
1415           }
1416      }
1417    if (item->proxy)
1418      {
1419         evas_object_image_source_visible_set(elm_image_object_get(item->proxy), EINA_TRUE);
1420         evas_object_del(item->proxy);
1421         item->proxy = NULL;
1422      }
1423    item->trans = NULL;
1424
1425    if (item->reorder_to)
1426      {
1427         EINA_INLIST_FOREACH(sd->items, it)
1428            if (it->trans) break;
1429
1430         if (!it) sd->reorder_empty = sd->reorder_item;
1431      }
1432    item->reorder_to = NULL;
1433 }
1434
1435 static void
1436 _item_transition_start
1437 (Elm_Toolbar_Item *it, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
1438 {
1439    Evas_Coord tx, ty;
1440    Evas_Object *obj = WIDGET(it);
1441    ELM_TOOLBAR_DATA_GET(obj, sd);
1442
1443    it->proxy = elm_image_add(obj);
1444    elm_image_aspect_fixed_set(it->proxy, EINA_FALSE);
1445    evas_object_image_source_set(elm_image_object_get(it->proxy), VIEW(it));
1446    evas_object_image_source_visible_set(elm_image_object_get(it->proxy), EINA_FALSE);
1447
1448    it->trans = elm_transit_add();
1449    elm_transit_object_add(it->trans, it->proxy);
1450    evas_object_geometry_get(VIEW(sd->reorder_empty), &tx, &ty, NULL, NULL);
1451    evas_object_move(it->proxy, x, y);
1452    evas_object_resize(it->proxy, w, h);
1453    evas_object_show(it->proxy);
1454
1455    elm_transit_effect_translation_add(it->trans, 0, 0, tx - x, 0);
1456    elm_transit_duration_set(it->trans, 0.3);
1457    elm_transit_del_cb_set(it->trans, _transit_del_cb, it);
1458    elm_transit_go(it->trans);
1459
1460    it->reorder_to = sd->reorder_empty;
1461 }
1462
1463 static void
1464 _animate_missed_items(Elm_Toolbar_Item *prev, Elm_Toolbar_Item *next)
1465 {
1466    ELM_TOOLBAR_DATA_GET(WIDGET(prev), sd);
1467    Elm_Toolbar_Item *it, *it2;
1468    Eina_List *list, *l;
1469    Evas_Object *o;
1470    Eina_Bool reverse = EINA_FALSE;
1471    Evas_Coord fx, fy, fw, fh;
1472
1473    list = evas_object_box_children_get(sd->bx);
1474
1475    EINA_LIST_FOREACH(list, l, o)
1476      {
1477         if (o == VIEW(prev))
1478           break;
1479         else if (o == VIEW(next))
1480           reverse = EINA_TRUE;
1481      }
1482
1483    if (!reverse)
1484      l = eina_list_next(l);
1485    else
1486      l = eina_list_prev(l);
1487
1488    while (VIEW(next) != eina_list_data_get(l))
1489      {
1490         EINA_INLIST_FOREACH(sd->items, it)
1491           {
1492              if (VIEW(it) == eina_list_data_get(l))
1493                {
1494                   if (!it->trans && it != sd->reorder_item)
1495                     {
1496                        evas_object_geometry_get(VIEW(sd->reorder_empty), &fx, &fy, &fw, &fh);
1497                        _item_transition_start(it, fx, fy, fw, fh);
1498                        sd->reorder_empty = it;
1499                     }
1500                   EINA_INLIST_FOREACH(sd->items, it2)
1501                     {
1502                        if (it == it2->reorder_to) break;
1503                     }
1504                   if (it2)
1505                     {
1506                        it2->reorder_to = NULL;
1507                        evas_object_geometry_get(it2->proxy, &fx, &fy, &fw, &fh);
1508                        if (it2->trans) elm_transit_del(it2->trans);
1509                        _item_transition_start(it2, fx, fy, fw, fh);
1510                        sd->reorder_empty = it;
1511                     }
1512                }
1513           }
1514         if (!reverse)
1515           l = eina_list_next(l);
1516         else
1517           l = eina_list_prev(l);
1518      }
1519 }
1520
1521 static void
1522 _mouse_move_reorder(Elm_Toolbar_Item *item,
1523                     Evas *evas __UNUSED__,
1524                     Evas_Object *obj __UNUSED__,
1525                     Evas_Event_Mouse_Move *ev)
1526 {
1527    Evas_Coord x, y, w, h;
1528    Evas_Coord fx, fy, fw, fh;
1529    Elm_Toolbar_Item *it, *it2;
1530
1531    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
1532
1533    evas_object_geometry_get(VIEW(item), &x, &y, &w, &h);
1534    if (sd->vertical)
1535      evas_object_move(item->proxy, x, ev->cur.canvas.y - (h / 2));
1536    else
1537      evas_object_move(item->proxy, ev->cur.canvas.x - (w / 2), y);
1538    evas_object_show(item->proxy);
1539
1540    if (sd->reorder_empty->on_move) return;
1541
1542    evas_object_geometry_get(sd->VIEW(reorder_empty), &x, &y, &w, &h);
1543    if (ev->cur.canvas.x < x || ev->cur.canvas.x > x + w)
1544      {
1545         EINA_INLIST_FOREACH(sd->items, it)
1546           {
1547              if (it->on_move) continue;
1548              evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
1549              if (ev->cur.canvas.x > x && ev->cur.canvas.x < x + w) break;
1550           }
1551         if (it && (it != sd->reorder_empty))
1552           {
1553              _animate_missed_items(sd->reorder_empty, it);
1554              if (!it->trans && it != item)
1555                {
1556                   evas_object_geometry_get(VIEW(it), &fx, &fy, &fw, &fh);
1557                   _item_transition_start(it, fx, fy, fw, fh);
1558                   sd->reorder_empty = it;
1559                }
1560              EINA_INLIST_FOREACH(sd->items, it2)
1561                {
1562                   if (it == it2->reorder_to) break;
1563                }
1564              if (it2)
1565                {
1566                   it2->reorder_to = NULL;
1567                   evas_object_geometry_get(it2->proxy, &fx, &fy, &fw, &fh);
1568                   if (it2->trans) elm_transit_del(it2->trans);
1569                   _item_transition_start(it2, fx, fy, fw, fh);
1570                   sd->reorder_empty = it;
1571                }
1572           }
1573      }
1574 }
1575
1576 static void
1577 _mouse_up_reorder(Elm_Toolbar_Item *it,
1578                   Evas *evas __UNUSED__,
1579                   Evas_Object *obj,
1580                   Evas_Event_Mouse_Up *ev __UNUSED__)
1581 {
1582    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1583
1584    evas_object_event_callback_del_full
1585      (obj, EVAS_CALLBACK_MOUSE_MOVE,
1586      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1587    evas_object_event_callback_del_full
1588      (sd->more, EVAS_CALLBACK_MOUSE_MOVE,
1589      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1590    evas_object_event_callback_del_full
1591      (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1592      (Evas_Object_Event_Cb)_mouse_move_reorder, it);
1593    evas_object_event_callback_del_full
1594      (obj, EVAS_CALLBACK_MOUSE_UP,
1595      (Evas_Object_Event_Cb)_mouse_up_reorder, it);
1596    evas_object_event_callback_del_full
1597      (sd->more, EVAS_CALLBACK_MOUSE_UP,
1598      (Evas_Object_Event_Cb)_mouse_up_reorder, it);
1599
1600    if (it->proxy)
1601      {
1602         evas_object_image_source_visible_set(elm_image_object_get(it->proxy), EINA_TRUE);
1603         evas_object_del(it->proxy);
1604         it->proxy = NULL;
1605      }
1606    sd->s_iface->hold_set(obj, EINA_FALSE);
1607 }
1608
1609 static void
1610 _item_reorder_start(Elm_Toolbar_Item *item)
1611 {
1612    Evas_Object *obj = WIDGET(item);
1613    Evas_Coord x, y, w, h;
1614
1615    ELM_TOOLBAR_DATA_GET(obj, sd);
1616
1617    sd->reorder_empty = sd->reorder_item = item;
1618
1619    item->proxy = elm_image_add(obj);
1620    elm_image_aspect_fixed_set(item->proxy, EINA_FALSE);
1621    evas_object_image_source_set(elm_image_object_get(item->proxy), VIEW(item));
1622    evas_object_image_source_visible_set(elm_image_object_get(item->proxy), EINA_FALSE);
1623    evas_object_layer_set(item->proxy, 100);
1624    edje_object_signal_emit(VIEW(item), "elm,state,moving", "elm");
1625
1626    evas_object_event_callback_add
1627      (obj, EVAS_CALLBACK_MOUSE_MOVE,
1628      (Evas_Object_Event_Cb)_mouse_move_reorder, item);
1629
1630    evas_object_event_callback_add
1631      (sd->more, EVAS_CALLBACK_MOUSE_MOVE,
1632      (Evas_Object_Event_Cb)_mouse_move_reorder, item);
1633
1634    evas_object_event_callback_add
1635      (item->proxy, EVAS_CALLBACK_MOUSE_MOVE,
1636      (Evas_Object_Event_Cb)_mouse_move_reorder, item);
1637
1638    evas_object_event_callback_add
1639      (obj, EVAS_CALLBACK_MOUSE_UP,
1640      (Evas_Object_Event_Cb)_mouse_up_reorder, item);
1641
1642    evas_object_event_callback_add
1643      (sd->more, EVAS_CALLBACK_MOUSE_UP,
1644      (Evas_Object_Event_Cb)_mouse_up_reorder, item);
1645
1646    evas_object_geometry_get(VIEW(item), &x, &y, &w, &h);
1647    evas_object_resize(item->proxy, w, h);
1648    evas_object_move(item->proxy, x, y);
1649    evas_object_show(item->proxy);
1650
1651    sd->s_iface->hold_set(WIDGET(item), EINA_TRUE);
1652 }
1653
1654 static Eina_Bool
1655 _long_press_cb(void *data)
1656 {
1657    Elm_Toolbar_Item *it = data;
1658    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1659
1660    sd->long_timer = NULL;
1661    sd->long_press = EINA_TRUE;
1662
1663    if (sd->reorder_mode)
1664      _item_reorder_start(it);
1665
1666    evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
1667
1668    return ECORE_CALLBACK_CANCEL;
1669 }
1670
1671 static void
1672 _drag_start_cb(Evas_Object *obj, void *data __UNUSED__)
1673 {
1674    ELM_TOOLBAR_DATA_GET(obj, sd);
1675
1676    if (sd->long_timer)
1677      {
1678         ecore_timer_del(sd->long_timer);
1679         sd->long_timer = NULL;
1680      }
1681 }
1682
1683 static void
1684 _mouse_move_cb(Elm_Toolbar_Item *it,
1685                Evas *evas __UNUSED__,
1686                Evas_Object *obj __UNUSED__,
1687                Evas_Event_Mouse_Move *ev)
1688 {
1689    Evas_Coord x, y, w, h;
1690
1691    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1692    evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
1693
1694    if ((sd->long_timer) &&
1695        ((x > ev->cur.canvas.x) || (ev->cur.canvas.x > x + w) ||
1696         (y > ev->cur.canvas.y) || (ev->cur.canvas.y > y + h)))
1697      {
1698         ecore_timer_del(sd->long_timer);
1699         sd->long_timer = NULL;
1700      }
1701 }
1702
1703 static void
1704 _mouse_down_cb(Elm_Toolbar_Item *it,
1705                Evas *evas __UNUSED__,
1706                Evas_Object *obj __UNUSED__,
1707                Evas_Event_Mouse_Down *ev)
1708 {
1709    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1710
1711    if (ev->button != 1) return;
1712    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1713      evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
1714    sd->long_press = EINA_FALSE;
1715    if (sd->long_timer)
1716      ecore_timer_interval_set
1717        (sd->long_timer, _elm_config->longpress_timeout);
1718    else
1719      sd->long_timer = ecore_timer_add
1720          (_elm_config->longpress_timeout, _long_press_cb, it);
1721
1722    evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1723                                   (Evas_Object_Event_Cb)_mouse_move_cb, it);
1724 }
1725
1726 static void
1727 _mouse_up_cb(Elm_Toolbar_Item *it,
1728              Evas *evas __UNUSED__,
1729              Evas_Object *obj __UNUSED__,
1730              Evas_Event_Mouse_Up *ev)
1731 {
1732    ELM_TOOLBAR_DATA_GET(WIDGET(it), sd);
1733
1734    if (ev->button != 1) return;
1735    if (sd->long_timer)
1736      {
1737         ecore_timer_del(sd->long_timer);
1738         sd->long_timer = NULL;
1739      }
1740    evas_object_event_callback_del_full
1741      (VIEW(it), EVAS_CALLBACK_MOUSE_MOVE,
1742      (Evas_Object_Event_Cb)_mouse_move_cb, it);
1743 }
1744
1745 static void
1746 _mouse_in_cb(void *data,
1747              Evas_Object *obj __UNUSED__,
1748              const char *emission __UNUSED__,
1749              const char *source __UNUSED__)
1750 {
1751    Elm_Toolbar_Item *it = data;
1752
1753    edje_object_signal_emit(VIEW(it), "elm,state,highlighted", "elm");
1754    elm_widget_signal_emit(it->icon, "elm,state,highlighted", "elm");
1755 }
1756
1757 static void
1758 _mouse_out_cb(void *data,
1759               Evas_Object *obj __UNUSED__,
1760               const char *emission __UNUSED__,
1761               const char *source __UNUSED__)
1762 {
1763    Elm_Toolbar_Item *it = data;
1764
1765    edje_object_signal_emit(VIEW(it), "elm,state,unhighlighted", "elm");
1766    elm_widget_signal_emit(it->icon, "elm,state,unhighlighted", "elm");
1767 }
1768
1769 static void
1770 _layout(Evas_Object *o,
1771         Evas_Object_Box_Data *priv,
1772         void *data)
1773 {
1774    Evas_Object *obj = (Evas_Object *)data;
1775
1776    ELM_TOOLBAR_DATA_GET(obj, sd);
1777    _els_box_layout
1778      (o, priv, !sd->vertical, sd->homogeneous, elm_widget_mirrored_get(obj));
1779 }
1780
1781 static char *
1782 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
1783 {
1784    Elm_Toolbar_Item *it = (Elm_Toolbar_Item *)data;
1785    const char *txt = ((Elm_Widget_Item *)it)->access_info;
1786
1787    if (!txt) txt = it->label;
1788    if (txt) return strdup(txt);
1789
1790    return NULL;
1791 }
1792
1793 static char *
1794 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
1795 {
1796    Elm_Toolbar_Item *it = (Elm_Toolbar_Item *)data;
1797
1798    if (it->separator)
1799      return strdup(E_("Separator"));
1800    else if (elm_widget_item_disabled_get(it))
1801      return strdup(E_("State: Disabled"));
1802    else if (it->selected)
1803      return strdup(E_("State: Selected"));
1804    else if (it->menu)
1805      return strdup(E_("Has menu"));
1806
1807    return NULL;
1808 }
1809
1810 static Eina_Bool
1811 _item_del_pre_hook(Elm_Object_Item *it)
1812 {
1813    Elm_Toolbar_Item *item, *next = NULL;
1814    Evas_Object *obj;
1815
1816    item = (Elm_Toolbar_Item *)it;
1817
1818    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
1819
1820    obj = WIDGET(item);
1821
1822    if (item != sd->more_item) /* more item does not get in the list */
1823      {
1824         if (!sd->on_deletion)
1825           next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(item)->next);
1826         sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(item));
1827         sd->item_count--;
1828         if (!sd->on_deletion)
1829           {
1830              if (!next) next = ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items);
1831              if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS) &&
1832                  item->selected && next) _item_select(next);
1833           }
1834      }
1835
1836    _item_del(item);
1837
1838    if (item != sd->more_item)
1839      _elm_toolbar_smart_theme(obj);
1840
1841    return EINA_TRUE;
1842 }
1843
1844 static void
1845 _access_activate_cb(void *data __UNUSED__,
1846                     Evas_Object *part_obj __UNUSED__,
1847                     Elm_Object_Item *item)
1848 {
1849    Elm_Toolbar_Item *it;
1850    it = (Elm_Toolbar_Item *)item;
1851
1852    if (elm_widget_item_disabled_get(it)) return;
1853
1854    if (!it->selected)
1855      {
1856         _elm_access_say(E_("Selected"));
1857         _item_select(it);
1858      }
1859 }
1860
1861 static void
1862 _access_widget_item_register(Elm_Toolbar_Item *it)
1863 {
1864    Elm_Access_Info *ai;
1865    _elm_access_widget_item_register((Elm_Widget_Item *)it);
1866    ai = _elm_access_object_get(it->base.access_obj);
1867
1868    _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Toolbar Item"));
1869    _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
1870    _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
1871    _elm_access_activate_callback_set(ai, _access_activate_cb, NULL);
1872 }
1873
1874 static Elm_Toolbar_Item *
1875 _item_new(Evas_Object *obj,
1876           const char *icon,
1877           const char *label,
1878           Evas_Smart_Cb func,
1879           const void *data)
1880 {
1881    Evas_Object *icon_obj;
1882    Elm_Toolbar_Item *it;
1883    Evas_Coord mw, mh;
1884
1885    ELM_TOOLBAR_DATA_GET(obj, sd);
1886
1887    icon_obj = elm_icon_add(obj);
1888    elm_icon_order_lookup_set(icon_obj, sd->lookup_order);
1889    if (!icon_obj) return NULL;
1890
1891    it = elm_widget_item_new(obj, Elm_Toolbar_Item);
1892    if (!it)
1893      {
1894         evas_object_del(icon_obj);
1895         return NULL;
1896      }
1897
1898    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1899    elm_widget_item_disable_hook_set(it, _item_disable_hook);
1900    elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1901    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1902    elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1903    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1904    elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1905
1906    it->label = eina_stringshare_add(label);
1907    it->prio.visible = 1;
1908    it->prio.priority = 0;
1909    it->func = func;
1910    it->separator = EINA_FALSE;
1911    it->object = NULL;
1912    it->base.data = data;
1913
1914    VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1915
1916    if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1917      _access_widget_item_register(it);
1918
1919    if (_item_icon_set(icon_obj, "toolbar/", icon))
1920      {
1921         it->icon = icon_obj;
1922         it->icon_str = eina_stringshare_add(icon);
1923      }
1924    else
1925      {
1926         it->icon = NULL;
1927         it->icon_str = NULL;
1928         evas_object_del(icon_obj);
1929      }
1930
1931    elm_widget_theme_object_set
1932      (obj, VIEW(it), "toolbar", "item", elm_widget_style_get(obj));
1933    edje_object_signal_callback_add
1934      (VIEW(it), "elm,action,click", "elm", _select_cb, it);
1935    edje_object_signal_callback_add
1936      (VIEW(it), "mouse,clicked,*", "*", (Edje_Signal_Cb)_select_filter_cb, it);
1937    edje_object_signal_callback_add
1938      (VIEW(it), "elm,mouse,in", "elm", _mouse_in_cb, it);
1939    edje_object_signal_callback_add
1940      (VIEW(it), "elm,mouse,out", "elm", _mouse_out_cb, it);
1941    evas_object_event_callback_add
1942      (VIEW(it), EVAS_CALLBACK_MOUSE_DOWN, (Evas_Object_Event_Cb)_mouse_down_cb,
1943      it);
1944    evas_object_event_callback_add
1945      (VIEW(it), EVAS_CALLBACK_MOUSE_UP, (Evas_Object_Event_Cb)_mouse_up_cb, it);
1946    elm_widget_sub_object_add(obj, VIEW(it));
1947
1948    if (it->icon)
1949      {
1950         int ms = 0;
1951
1952         ms = ((double)sd->icon_size * elm_config_scale_get());
1953         evas_object_size_hint_min_set(it->icon, ms, ms);
1954         evas_object_size_hint_max_set(it->icon, ms, ms);
1955         edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon);
1956         edje_object_signal_emit(VIEW(it), "elm,state,icon,visible", "elm");
1957         evas_object_show(it->icon);
1958         elm_widget_sub_object_add(obj, it->icon);
1959      }
1960    if (it->label)
1961      {
1962         edje_object_part_text_escaped_set(VIEW(it), "elm.text", it->label);
1963         edje_object_signal_emit(VIEW(it), "elm,state,text,visible", "elm");
1964      }
1965
1966    mw = mh = -1;
1967    if (!it->separator && !it->object)
1968      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1969    // If the min size is changed by edje signal in edc,
1970    //the below function should be called before the calculation.
1971    edje_object_message_signal_process(VIEW(it));
1972    edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
1973    if (!it->separator && !it->object)
1974      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1975    if (sd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
1976      {
1977         if (sd->vertical)
1978           {
1979              evas_object_size_hint_weight_set(VIEW(it), EVAS_HINT_EXPAND, -1.0);
1980              evas_object_size_hint_align_set
1981                (VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL);
1982           }
1983         else
1984           {
1985              evas_object_size_hint_weight_set(VIEW(it), -1.0, EVAS_HINT_EXPAND);
1986              evas_object_size_hint_align_set
1987                (VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL);
1988           }
1989      }
1990    else
1991      {
1992         evas_object_size_hint_weight_set
1993           (VIEW(it), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1994         evas_object_size_hint_align_set
1995           (VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL);
1996      }
1997
1998    evas_object_size_hint_min_set(VIEW(it), mw, mh);
1999    evas_object_size_hint_max_set(VIEW(it), -1, -1);
2000    evas_object_event_callback_add
2001      (VIEW(it), EVAS_CALLBACK_RESIZE, _item_resize, obj);
2002
2003    if ((!sd->items) && (sd->select_mode == ELM_OBJECT_SELECT_MODE_ALWAYS))
2004      _item_select(it);
2005    return it;
2006 }
2007
2008 static void
2009 _elm_toolbar_item_icon_update(Elm_Toolbar_Item *item)
2010 {
2011    Evas_Coord mw = -1, mh = -1, minw = -1, minh = -1;
2012    Elm_Toolbar_Item_State *it_state;
2013    Evas_Object *old_icon =
2014      edje_object_part_swallow_get(VIEW(item), "elm.swallow.icon");
2015    Eina_List *l;
2016
2017    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
2018
2019    elm_widget_sub_object_del(VIEW(item), old_icon);
2020    edje_object_part_swallow(VIEW(item), "elm.swallow.icon", item->icon);
2021    if (item->icon)
2022        edje_object_signal_emit(VIEW(item), "elm,state,icon,visible", "elm");
2023    else
2024        edje_object_signal_emit(VIEW(item), "elm,state,icon,hidden", "elm");
2025    evas_object_hide(old_icon);
2026    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2027    // If the min size is changed by edje signal in edc,
2028    //the below function should be called before the calculation.
2029    edje_object_message_signal_process(VIEW(item));
2030    edje_object_size_min_restricted_calc(VIEW(item), &mw, &mh, mw, mh);
2031    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
2032    if (sd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
2033      {
2034         if (sd->vertical)
2035           {
2036              evas_object_size_hint_weight_set
2037                (VIEW(item), EVAS_HINT_EXPAND, -1.0);
2038              evas_object_size_hint_align_set
2039                (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
2040           }
2041         else
2042           {
2043              evas_object_size_hint_weight_set
2044                (VIEW(item), -1.0, EVAS_HINT_EXPAND);
2045              evas_object_size_hint_align_set
2046                (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
2047           }
2048      }
2049    else
2050      {
2051         evas_object_size_hint_weight_set
2052           (VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2053         evas_object_size_hint_align_set
2054           (VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
2055      }
2056
2057    evas_object_size_hint_min_get(VIEW(item), &minw, &minh);
2058    if ((minw < mw) && (minh < mh))
2059      evas_object_size_hint_min_set(VIEW(item), mw, mh);
2060    else if ((minw < mw) && (minh > mh))
2061      evas_object_size_hint_min_set(VIEW(item), mw, minh);
2062    else if ((minw > mw) && (minh < mh))
2063      evas_object_size_hint_min_set(VIEW(item), minw, mh);
2064
2065    EINA_LIST_FOREACH(item->states, l, it_state)
2066      {
2067         if (it_state->icon == old_icon) return;
2068      }
2069    evas_object_del(old_icon);
2070 }
2071
2072 static void
2073 _elm_toolbar_item_icon_set_cb(void *data,
2074                               Evas_Object *obj,
2075                               const char *emission,
2076                               const char *source)
2077 {
2078    Elm_Toolbar_Item *item = data;
2079
2080    edje_object_part_unswallow(VIEW(item), item->icon);
2081    _elm_toolbar_item_icon_update(item);
2082    edje_object_signal_callback_del
2083      (obj, emission, source, _elm_toolbar_item_icon_set_cb);
2084    edje_object_signal_emit(VIEW(item), "elm,state,icon,reset", "elm");
2085 }
2086
2087 static void
2088 _elm_toolbar_item_icon_obj_set(Evas_Object *obj,
2089                                Elm_Toolbar_Item *item,
2090                                Evas_Object *icon_obj,
2091                                const char *icon_str,
2092                                double icon_size,
2093                                const char *sig)
2094 {
2095    Evas_Object *old_icon;
2096    const char *s;
2097    int ms = 0;
2098
2099    if (icon_str)
2100      eina_stringshare_replace(&item->icon_str, icon_str);
2101    else
2102      {
2103         eina_stringshare_del(item->icon_str);
2104         item->icon_str = NULL;
2105      }
2106    item->icon = icon_obj;
2107    if (icon_obj)
2108      {
2109         ms = (icon_size * elm_config_scale_get());
2110         evas_object_size_hint_min_set(item->icon, ms, ms);
2111         evas_object_size_hint_max_set(item->icon, ms, ms);
2112         evas_object_show(item->icon);
2113         elm_widget_sub_object_add(obj, item->icon);
2114      }
2115    s = edje_object_data_get(VIEW(item), "transition_animation_on");
2116    if ((s) && (atoi(s)))
2117      {
2118         old_icon = edje_object_part_swallow_get
2119             (VIEW(item), "elm.swallow.icon_new");
2120         if (old_icon)
2121           {
2122              elm_widget_sub_object_del(VIEW(item), old_icon);
2123              evas_object_hide(old_icon);
2124           }
2125         edje_object_part_swallow
2126           (VIEW(item), "elm.swallow.icon_new", item->icon);
2127         edje_object_signal_emit(VIEW(item), sig, "elm");
2128         edje_object_signal_callback_add
2129           (VIEW(item), "elm,state,icon_set,done", "elm",
2130           _elm_toolbar_item_icon_set_cb, item);
2131      }
2132    else
2133      _elm_toolbar_item_icon_update(item);
2134
2135    _resize_cb(obj, NULL, NULL, NULL);
2136 }
2137
2138 static void
2139 _elm_toolbar_item_state_cb(void *data __UNUSED__,
2140                            Evas_Object *obj __UNUSED__,
2141                            void *event_info)
2142 {
2143    Elm_Toolbar_Item *it = event_info;
2144    Elm_Toolbar_Item_State *it_state;
2145
2146    it_state = eina_list_data_get(it->current_state);
2147    if (it_state->func)
2148      it_state->func((void *)it_state->data, obj, event_info);
2149 }
2150
2151 static Elm_Toolbar_Item_State *
2152 _item_state_new(const char *label,
2153                 const char *icon_str,
2154                 Evas_Object *icon,
2155                 Evas_Smart_Cb func,
2156                 const void *data)
2157 {
2158    Elm_Toolbar_Item_State *it_state;
2159
2160    it_state = ELM_NEW(Elm_Toolbar_Item_State);
2161    it_state->label = eina_stringshare_add(label);
2162    it_state->icon_str = eina_stringshare_add(icon_str);
2163    it_state->icon = icon;
2164    it_state->func = func;
2165    it_state->data = data;
2166
2167    return it_state;
2168 }
2169
2170 static void
2171 _elm_toolbar_action_left_cb(void *data,
2172                             Evas_Object *o __UNUSED__,
2173                             const char *sig __UNUSED__,
2174                             const char *src __UNUSED__)
2175 {
2176    Evas_Object *obj = data;
2177    Elm_Toolbar_Item *it, *it2;
2178    Eina_Bool done = EINA_FALSE;
2179
2180    ELM_TOOLBAR_DATA_GET(obj, sd);
2181
2182    EINA_INLIST_FOREACH(sd->items, it)
2183      {
2184         if (it->selected)
2185           {
2186              Eina_Bool found = EINA_FALSE;
2187
2188              EINA_INLIST_REVERSE_FOREACH(sd->items, it2)
2189                {
2190                   if (elm_object_item_disabled_get((Elm_Object_Item *)it2))
2191                     continue;
2192                   if (it2 == it)
2193                     {
2194                        found = EINA_TRUE;
2195                        continue;
2196                     }
2197                   if (!found) continue;
2198                   if (it2->separator) continue;
2199                   _item_unselect(it);
2200                   _item_select(it2);
2201                   break;
2202                }
2203              done = EINA_TRUE;
2204              break;
2205           }
2206      }
2207    if (!done)
2208      {
2209         EINA_INLIST_FOREACH(sd->items, it)
2210           {
2211              if (elm_object_item_disabled_get((Elm_Object_Item *)it)) continue;
2212              if (it->separator) continue;
2213              _item_select(it);
2214              break;
2215           }
2216      }
2217 }
2218
2219 static void
2220 _elm_toolbar_action_right_cb(void *data,
2221                              Evas_Object *o __UNUSED__,
2222                              const char *sig __UNUSED__,
2223                              const char *src __UNUSED__)
2224 {
2225    Evas_Object *obj = data;
2226    Elm_Toolbar_Item *it, *it2;
2227    Eina_Bool done = EINA_FALSE;
2228
2229    ELM_TOOLBAR_DATA_GET(obj, sd);
2230
2231    EINA_INLIST_FOREACH(sd->items, it)
2232      {
2233         if (it->selected)
2234           {
2235              Eina_Bool found = EINA_FALSE;
2236
2237              EINA_INLIST_FOREACH(sd->items, it2)
2238                {
2239                   if (elm_object_item_disabled_get((Elm_Object_Item *)it2))
2240                     continue;
2241                   if (it2 == it)
2242                     {
2243                        found = EINA_TRUE;
2244                        continue;
2245                     }
2246                   if (!found) continue;
2247                   if (it2->separator) continue;
2248                   _item_unselect(it);
2249                   _item_select(it2);
2250                   break;
2251                }
2252              done = EINA_TRUE;
2253              break;
2254           }
2255      }
2256    if (!done)
2257      {
2258         EINA_INLIST_REVERSE_FOREACH(sd->items, it)
2259           {
2260              if (elm_object_item_disabled_get((Elm_Object_Item *)it)) continue;
2261              if (it->separator) continue;
2262              _item_select(it);
2263              break;
2264           }
2265      }
2266 }
2267
2268 static void
2269 _elm_toolbar_action_up_cb(void *data,
2270                           Evas_Object *o,
2271                           const char *sig,
2272                           const char *src)
2273 {
2274    _elm_toolbar_action_left_cb(data, o, sig, src);
2275 }
2276
2277 static void
2278 _elm_toolbar_action_down_cb(void *data,
2279                             Evas_Object *o,
2280                             const char *sig,
2281                             const char *src)
2282 {
2283    _elm_toolbar_action_right_cb(data, o, sig, src);
2284 }
2285
2286 static void
2287 _elm_toolbar_smart_add(Evas_Object *obj)
2288 {
2289    EVAS_SMART_DATA_ALLOC(obj, Elm_Toolbar_Smart_Data);
2290
2291    ELM_WIDGET_DATA(priv)->resize_obj =
2292      edje_object_add(evas_object_evas_get(obj));
2293
2294    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.add(obj);
2295
2296    elm_widget_theme_object_set
2297      (obj, ELM_WIDGET_DATA(priv)->resize_obj, "toolbar", "base",
2298      elm_widget_style_get(obj));
2299
2300    priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
2301    evas_object_smart_member_add(priv->hit_rect, obj);
2302    elm_widget_sub_object_add(obj, priv->hit_rect);
2303
2304    /* common scroller hit rectangle setup */
2305    evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
2306    evas_object_show(priv->hit_rect);
2307    evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
2308
2309    elm_widget_can_focus_set(obj, EINA_TRUE);
2310
2311    priv->s_iface = evas_object_smart_interface_get
2312        (obj, ELM_SCROLLABLE_IFACE_NAME);
2313
2314    priv->s_iface->objects_set
2315      (obj, ELM_WIDGET_DATA(priv)->resize_obj, priv->hit_rect);
2316
2317    priv->more_item = NULL;
2318    priv->selected_item = NULL;
2319    priv->standard_priority = -99999;
2320
2321    priv->s_iface->bounce_allow_set
2322      (obj, _elm_config->thumbscroll_bounce_enable, EINA_FALSE);
2323    priv->s_iface->policy_set
2324      (obj, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
2325    priv->s_iface->drag_start_cb_set(obj, _drag_start_cb);
2326
2327    edje_object_signal_callback_add
2328      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,left", "elm",
2329      _elm_toolbar_action_left_cb, obj);
2330    edje_object_signal_callback_add
2331      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,right", "elm",
2332      _elm_toolbar_action_right_cb, obj);
2333    edje_object_signal_callback_add
2334      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,up", "elm",
2335      _elm_toolbar_action_up_cb, obj);
2336    edje_object_signal_callback_add
2337      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,down", "elm",
2338      _elm_toolbar_action_down_cb, obj);
2339
2340    priv->shrink_mode = ELM_TOOLBAR_SHRINK_NONE;
2341    priv->priv_icon_size = 0; // unset
2342    priv->theme_icon_size = _elm_toolbar_icon_size_get(priv);
2343    if (priv->priv_icon_size) priv->icon_size = priv->priv_icon_size;
2344    else priv->icon_size = priv->theme_icon_size;
2345
2346    priv->homogeneous = EINA_TRUE;
2347    priv->align = 0.5;
2348
2349    priv->bx = evas_object_box_add(evas_object_evas_get(obj));
2350    evas_object_size_hint_align_set(priv->bx, priv->align, 0.5);
2351    evas_object_box_layout_set(priv->bx, _layout, obj, NULL);
2352    elm_widget_sub_object_add(obj, priv->bx);
2353    priv->s_iface->content_set(obj, priv->bx);
2354    evas_object_show(priv->bx);
2355
2356    priv->more = elm_layout_add(obj);
2357    elm_layout_theme_set(priv->more, "toolbar", "more", "default");
2358    elm_widget_sub_object_add(obj, priv->more);
2359    evas_object_show(priv->more);
2360
2361    priv->bx_more = evas_object_box_add(evas_object_evas_get(obj));
2362    evas_object_size_hint_align_set(priv->bx_more, priv->align, 0.5);
2363    evas_object_box_layout_set(priv->bx_more, _layout, obj, NULL);
2364    elm_widget_sub_object_add(obj, priv->bx_more);
2365    elm_layout_content_set
2366      (priv->more, "elm.swallow.content", priv->bx_more);
2367    evas_object_show(priv->bx_more);
2368
2369    priv->bx_more2 = evas_object_box_add(evas_object_evas_get(obj));
2370    evas_object_size_hint_align_set(priv->bx_more2, priv->align, 0.5);
2371    evas_object_box_layout_set(priv->bx_more2, _layout, obj, NULL);
2372    elm_widget_sub_object_add(obj, priv->bx_more2);
2373    elm_layout_content_set
2374      (priv->more, "elm.swallow.content2", priv->bx_more2);
2375    evas_object_show(priv->bx_more2);
2376
2377    elm_toolbar_shrink_mode_set(obj, _elm_config->toolbar_shrink_mode);
2378    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
2379    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move_cb, obj);
2380    evas_object_event_callback_add
2381      (priv->bx, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
2382    elm_toolbar_icon_order_lookup_set(obj, ELM_ICON_LOOKUP_THEME_FDO);
2383
2384    _sizing_eval(obj);
2385 }
2386
2387 static void
2388 _elm_toolbar_smart_del(Evas_Object *obj)
2389 {
2390    Elm_Toolbar_Item *it, *next;
2391
2392    ELM_TOOLBAR_DATA_GET(obj, sd);
2393
2394    sd->on_deletion = EINA_TRUE;
2395
2396    if (sd->resize_job)
2397      ecore_job_del(sd->resize_job);
2398
2399    sd->resize_job = NULL;
2400
2401    it = ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items);
2402    while (it)
2403      {
2404         next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
2405         elm_widget_item_del(it);
2406         it = next;
2407      }
2408    if (sd->more_item)
2409      {
2410         elm_widget_item_del(sd->more_item);
2411         sd->more_item = NULL;
2412      }
2413    if (sd->long_timer)
2414      {
2415         ecore_timer_del(sd->long_timer);
2416         sd->long_timer = NULL;
2417      }
2418
2419    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.del(obj);
2420 }
2421
2422 static void
2423 _elm_toolbar_smart_move(Evas_Object *obj,
2424                         Evas_Coord x,
2425                         Evas_Coord y)
2426 {
2427    ELM_TOOLBAR_DATA_GET(obj, sd);
2428
2429    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.move(obj, x, y);
2430
2431    evas_object_move(sd->hit_rect, x, y);
2432 }
2433
2434 static void
2435 _elm_toolbar_smart_resize(Evas_Object *obj,
2436                           Evas_Coord w,
2437                           Evas_Coord h)
2438 {
2439    ELM_TOOLBAR_DATA_GET(obj, sd);
2440
2441    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.resize(obj, w, h);
2442
2443    evas_object_resize(sd->hit_rect, w, h);
2444 }
2445
2446 static void
2447 _elm_toolbar_smart_member_add(Evas_Object *obj,
2448                               Evas_Object *member)
2449 {
2450    ELM_TOOLBAR_DATA_GET(obj, sd);
2451
2452    ELM_WIDGET_CLASS(_elm_toolbar_parent_sc)->base.member_add(obj, member);
2453
2454    if (sd->hit_rect)
2455      evas_object_raise(sd->hit_rect);
2456 }
2457
2458 static Eina_List *
2459 _access_item_find_append(const Evas_Object *obj,
2460                          Evas_Object *bx,
2461                          Eina_List *items)
2462 {
2463    Elm_Toolbar_Item *it;
2464    Eina_List *list;
2465
2466    ELM_TOOLBAR_DATA_GET(obj, sd);
2467
2468    list = evas_object_box_children_get(bx);
2469    if (!list) return items;
2470
2471    EINA_INLIST_FOREACH (sd->items, it)
2472      {
2473         if (it->separator) continue;
2474         if (eina_list_data_find(list, it->base.view))
2475           items = eina_list_append(items, it->base.access_obj);
2476      }
2477
2478    return items;
2479 }
2480
2481 static Eina_Bool
2482 _elm_toolbar_smart_focus_next(const Evas_Object *obj,
2483                               Elm_Focus_Direction dir,
2484                               Evas_Object **next)
2485 {
2486    Eina_List *items = NULL;
2487
2488    ELM_TOOLBAR_DATA_GET(obj, sd);
2489
2490    if (sd->more_item && sd->more_item->selected)
2491      {
2492         items = _access_item_find_append(obj, sd->bx_more, items);
2493         items = _access_item_find_append(obj, sd->bx_more2, items);
2494         items = eina_list_append(items, sd->more_item->base.access_obj);
2495      }
2496    else
2497      {
2498         items = _access_item_find_append(obj, sd->bx, items);
2499         if (sd->more_item &&
2500             eina_list_data_find(evas_object_box_children_get(sd->bx),
2501                                             sd->more_item->base.view))
2502           items = eina_list_append(items, sd->more_item->base.access_obj);
2503      }
2504
2505    return elm_widget_focus_list_next_get
2506             (obj, items, eina_list_data_get, dir, next);
2507 }
2508
2509 static void
2510 _access_obj_process(Elm_Toolbar_Smart_Data * sd, Eina_Bool is_access)
2511 {
2512    Elm_Toolbar_Item *it;
2513
2514    EINA_INLIST_FOREACH (sd->items, it)
2515      {
2516         if (is_access) _access_widget_item_register(it);
2517         else _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
2518      }
2519 }
2520
2521 static void
2522 _elm_toolbar_smart_access(Evas_Object *obj, Eina_Bool is_access)
2523 {
2524    ELM_TOOLBAR_CHECK(obj);
2525    ELM_TOOLBAR_DATA_GET(obj, sd);
2526
2527    if (is_access)
2528      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
2529        _elm_toolbar_smart_focus_next;
2530    else
2531      ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
2532    _access_obj_process(sd, is_access);
2533 }
2534
2535 static void
2536 _elm_toolbar_smart_set_user(Elm_Toolbar_Smart_Class *sc)
2537 {
2538    ELM_WIDGET_CLASS(sc)->base.add = _elm_toolbar_smart_add;
2539    ELM_WIDGET_CLASS(sc)->base.del = _elm_toolbar_smart_del;
2540    ELM_WIDGET_CLASS(sc)->base.move = _elm_toolbar_smart_move;
2541    ELM_WIDGET_CLASS(sc)->base.resize = _elm_toolbar_smart_resize;
2542    ELM_WIDGET_CLASS(sc)->base.member_add = _elm_toolbar_smart_member_add;
2543
2544    ELM_WIDGET_CLASS(sc)->on_focus = _elm_toolbar_smart_on_focus;
2545    ELM_WIDGET_CLASS(sc)->event = _elm_toolbar_smart_event;
2546    ELM_WIDGET_CLASS(sc)->theme = _elm_toolbar_smart_theme;
2547    ELM_WIDGET_CLASS(sc)->translate = _elm_toolbar_smart_translate;
2548
2549    if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
2550      ELM_WIDGET_CLASS(sc)->focus_next = _elm_toolbar_smart_focus_next;
2551
2552    ELM_WIDGET_CLASS(sc)->access = _elm_toolbar_smart_access;
2553 }
2554
2555 EAPI const Elm_Toolbar_Smart_Class *
2556 elm_toolbar_smart_class_get(void)
2557 {
2558    static Elm_Toolbar_Smart_Class _sc =
2559      ELM_TOOLBAR_SMART_CLASS_INIT_NAME_VERSION(ELM_TOOLBAR_SMART_NAME);
2560    static const Elm_Toolbar_Smart_Class *class = NULL;
2561    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
2562
2563    if (class)
2564      return class;
2565
2566    _elm_toolbar_smart_set(&_sc);
2567    esc->callbacks = _smart_callbacks;
2568    class = &_sc;
2569
2570    return class;
2571 }
2572
2573 EAPI Evas_Object *
2574 elm_toolbar_add(Evas_Object *parent)
2575 {
2576    Evas_Object *obj;
2577
2578    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
2579
2580    obj = elm_widget_add(_elm_toolbar_smart_class_new(), parent);
2581    if (!obj) return NULL;
2582
2583    if (!elm_widget_sub_object_add(parent, obj))
2584      ERR("could not add %p as sub object of %p", obj, parent);
2585
2586    return obj;
2587 }
2588
2589 EAPI void
2590 elm_toolbar_icon_size_set(Evas_Object *obj,
2591                           int icon_size)
2592 {
2593    ELM_TOOLBAR_CHECK(obj);
2594    ELM_TOOLBAR_DATA_GET(obj, sd);
2595
2596    if (sd->priv_icon_size == icon_size) return;
2597    sd->priv_icon_size = icon_size;
2598
2599    if (sd->priv_icon_size) sd->icon_size = sd->priv_icon_size;
2600    else sd->icon_size = sd->theme_icon_size;
2601
2602    _elm_toolbar_smart_theme(obj);
2603 }
2604
2605 EAPI int
2606 elm_toolbar_icon_size_get(const Evas_Object *obj)
2607 {
2608    ELM_TOOLBAR_CHECK(obj) 0;
2609    ELM_TOOLBAR_DATA_GET(obj, sd);
2610
2611    return sd->priv_icon_size;
2612 }
2613
2614 EAPI Elm_Object_Item *
2615 elm_toolbar_item_append(Evas_Object *obj,
2616                         const char *icon,
2617                         const char *label,
2618                         Evas_Smart_Cb func,
2619                         const void *data)
2620 {
2621    Elm_Toolbar_Item *it;
2622    double scale;
2623
2624    ELM_TOOLBAR_CHECK(obj) NULL;
2625    ELM_TOOLBAR_DATA_GET(obj, sd);
2626
2627    it = _item_new(obj, icon, label, func, data);
2628    if (!it) return NULL;
2629    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2630
2631    sd->items = eina_inlist_append(sd->items, EINA_INLIST_GET(it));
2632    evas_object_box_append(sd->bx, VIEW(it));
2633    evas_object_show(VIEW(it));
2634
2635    _item_theme_hook(obj, it, scale, sd->icon_size);
2636    _sizing_eval(obj);
2637    sd->item_count++;
2638
2639    return (Elm_Object_Item *)it;
2640 }
2641
2642 EAPI Elm_Object_Item *
2643 elm_toolbar_item_prepend(Evas_Object *obj,
2644                          const char *icon,
2645                          const char *label,
2646                          Evas_Smart_Cb func,
2647                          const void *data)
2648 {
2649    Elm_Toolbar_Item *it;
2650    double scale;
2651
2652    ELM_TOOLBAR_CHECK(obj) NULL;
2653    ELM_TOOLBAR_DATA_GET(obj, sd);
2654
2655    it = _item_new(obj, icon, label, func, data);
2656    if (!it) return NULL;
2657    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2658
2659    sd->items = eina_inlist_prepend(sd->items, EINA_INLIST_GET(it));
2660    evas_object_box_prepend(sd->bx, VIEW(it));
2661    evas_object_show(VIEW(it));
2662    _item_theme_hook(obj, it, scale, sd->icon_size);
2663    _sizing_eval(obj);
2664    sd->item_count++;
2665
2666    return (Elm_Object_Item *)it;
2667 }
2668
2669 EAPI Elm_Object_Item *
2670 elm_toolbar_item_insert_before(Evas_Object *obj,
2671                                Elm_Object_Item *before,
2672                                const char *icon,
2673                                const char *label,
2674                                Evas_Smart_Cb func,
2675                                const void *data)
2676 {
2677    Elm_Toolbar_Item *it, *_before;
2678    double scale;
2679
2680    ELM_TOOLBAR_CHECK(obj) NULL;
2681    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(before, NULL);
2682    ELM_TOOLBAR_DATA_GET(obj, sd);
2683
2684    _before = (Elm_Toolbar_Item *)before;
2685    it = _item_new(obj, icon, label, func, data);
2686    if (!it) return NULL;
2687    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2688
2689    sd->items = eina_inlist_prepend_relative
2690        (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(_before));
2691    evas_object_box_insert_before(sd->bx, VIEW(it), VIEW(_before));
2692    evas_object_show(VIEW(it));
2693    _item_theme_hook(obj, it, scale, sd->icon_size);
2694    _sizing_eval(obj);
2695    sd->item_count++;
2696
2697    return (Elm_Object_Item *)it;
2698 }
2699
2700 EAPI Elm_Object_Item *
2701 elm_toolbar_item_insert_after(Evas_Object *obj,
2702                               Elm_Object_Item *after,
2703                               const char *icon,
2704                               const char *label,
2705                               Evas_Smart_Cb func,
2706                               const void *data)
2707 {
2708    Elm_Toolbar_Item *it, *_after;
2709    double scale;
2710
2711    ELM_TOOLBAR_CHECK(obj) NULL;
2712    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(after, NULL);
2713
2714    ELM_TOOLBAR_DATA_GET(obj, sd);
2715    _after = (Elm_Toolbar_Item *)after;
2716    it = _item_new(obj, icon, label, func, data);
2717    if (!it) return NULL;
2718    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2719
2720    sd->items = eina_inlist_append_relative
2721        (sd->items, EINA_INLIST_GET(it), EINA_INLIST_GET(_after));
2722    evas_object_box_insert_after(sd->bx, VIEW(it), VIEW(_after));
2723    evas_object_show(VIEW(it));
2724    _item_theme_hook(obj, it, scale, sd->icon_size);
2725    _sizing_eval(obj);
2726    sd->item_count++;
2727
2728    return (Elm_Object_Item *)it;
2729 }
2730
2731 EAPI Elm_Object_Item *
2732 elm_toolbar_first_item_get(const Evas_Object *obj)
2733 {
2734    ELM_TOOLBAR_CHECK(obj) NULL;
2735    ELM_TOOLBAR_DATA_GET(obj, sd);
2736
2737    if (!sd->items) return NULL;
2738    return (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items);
2739 }
2740
2741 EAPI Elm_Object_Item *
2742 elm_toolbar_last_item_get(const Evas_Object *obj)
2743 {
2744    ELM_TOOLBAR_CHECK(obj) NULL;
2745    ELM_TOOLBAR_DATA_GET(obj, sd);
2746
2747    if (!sd->items) return NULL;
2748
2749    return (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items->last);
2750 }
2751
2752 EAPI Elm_Object_Item *
2753 elm_toolbar_item_next_get(const Elm_Object_Item *it)
2754 {
2755    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2756
2757    return (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(
2758             EINA_INLIST_GET(((Elm_Toolbar_Item *)it))->next);
2759 }
2760
2761 EAPI Elm_Object_Item *
2762 elm_toolbar_item_prev_get(const Elm_Object_Item *it)
2763 {
2764    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2765
2766    return (Elm_Object_Item *)ELM_TOOLBAR_ITEM_FROM_INLIST(
2767             EINA_INLIST_GET(((Elm_Toolbar_Item *)it))->prev);
2768 }
2769
2770 EAPI void
2771 elm_toolbar_item_priority_set(Elm_Object_Item *it,
2772                               int priority)
2773 {
2774    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2775
2776    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
2777
2778    if (item->prio.priority == priority) return;
2779    item->prio.priority = priority;
2780    _resize_cb(WIDGET(item), NULL, NULL, NULL);
2781 }
2782
2783 EAPI int
2784 elm_toolbar_item_priority_get(const Elm_Object_Item *it)
2785 {
2786    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, 0);
2787
2788    return ((Elm_Toolbar_Item *)it)->prio.priority;
2789 }
2790
2791 EAPI Elm_Object_Item *
2792 elm_toolbar_item_find_by_label(const Evas_Object *obj,
2793                                const char *label)
2794 {
2795    Elm_Toolbar_Item *it;
2796
2797    ELM_TOOLBAR_CHECK(obj) NULL;
2798    ELM_TOOLBAR_DATA_GET(obj, sd);
2799
2800    EINA_INLIST_FOREACH(sd->items, it)
2801      {
2802         if (!strcmp(it->label, label))
2803           return (Elm_Object_Item *)it;
2804      }
2805
2806    return NULL;
2807 }
2808
2809 EAPI void
2810 elm_toolbar_item_selected_set(Elm_Object_Item *it,
2811                               Eina_Bool selected)
2812 {
2813    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2814
2815    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
2816
2817    if (item->selected == selected) return;
2818    if (selected) _item_select(item);
2819    else _item_unselect(item);
2820 }
2821
2822 EAPI Eina_Bool
2823 elm_toolbar_item_selected_get(const Elm_Object_Item *it)
2824 {
2825    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2826
2827    return ((Elm_Toolbar_Item *)it)->selected;
2828 }
2829
2830 EAPI Elm_Object_Item *
2831 elm_toolbar_selected_item_get(const Evas_Object *obj)
2832 {
2833    ELM_TOOLBAR_CHECK(obj) NULL;
2834    ELM_TOOLBAR_DATA_GET(obj, sd);
2835
2836    return (Elm_Object_Item *)sd->selected_item;
2837 }
2838
2839 EAPI Elm_Object_Item *
2840 elm_toolbar_more_item_get(const Evas_Object *obj)
2841 {
2842    ELM_TOOLBAR_CHECK(obj) NULL;
2843    ELM_TOOLBAR_DATA_GET(obj, sd);
2844
2845    return (Elm_Object_Item *)sd->more_item;
2846 }
2847
2848 EAPI void
2849 elm_toolbar_item_icon_set(Elm_Object_Item *it,
2850                           const char *icon)
2851 {
2852    Evas_Object *obj;
2853    Evas_Object *icon_obj;
2854    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2855
2856    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
2857
2858    obj = WIDGET(item);
2859    ELM_TOOLBAR_DATA_GET(obj, sd);
2860    if ((icon) && (item->icon_str) && (!strcmp(icon, item->icon_str))) return;
2861
2862    icon_obj = elm_icon_add(obj);
2863    if (!icon_obj) return;
2864    if (_item_icon_set(icon_obj, "toolbar/", icon))
2865      _elm_toolbar_item_icon_obj_set
2866        (obj, item, icon_obj, icon, sd->icon_size, "elm,state,icon_set");
2867    else
2868      {
2869         _elm_toolbar_item_icon_obj_set
2870           (obj, item, NULL, NULL, 0, "elm,state,icon_set");
2871         evas_object_del(icon_obj);
2872      }
2873 }
2874
2875 EAPI const char *
2876 elm_toolbar_item_icon_get(const Elm_Object_Item *it)
2877 {
2878    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2879
2880    return ((Elm_Toolbar_Item *)it)->icon_str;
2881 }
2882
2883 EAPI Evas_Object *
2884 elm_toolbar_item_object_get(const Elm_Object_Item *it)
2885 {
2886    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2887
2888    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2889
2890    return VIEW(item);
2891 }
2892
2893 EAPI Evas_Object *
2894 elm_toolbar_item_icon_object_get(Elm_Object_Item *it)
2895 {
2896    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
2897
2898    return ((Elm_Toolbar_Item *)it)->icon;
2899 }
2900
2901 EAPI Eina_Bool
2902 elm_toolbar_item_icon_memfile_set(Elm_Object_Item *it,
2903                                   const void *img,
2904                                   size_t size,
2905                                   const char *format,
2906                                   const char *key)
2907 {
2908    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2909    Evas_Object *icon_obj;
2910    Evas_Object *obj;
2911    Eina_Bool ret;
2912
2913    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2914
2915    obj = WIDGET(item);
2916    ELM_TOOLBAR_DATA_GET(obj, sd);
2917
2918    if (img && size)
2919      {
2920         icon_obj = elm_icon_add(obj);
2921         evas_object_repeat_events_set(icon_obj, EINA_TRUE);
2922         ret = elm_image_memfile_set(icon_obj, img, size, format, key);
2923         if (!ret)
2924           {
2925              evas_object_del(icon_obj);
2926              return EINA_FALSE;
2927           }
2928         _elm_toolbar_item_icon_obj_set
2929           (obj, item, icon_obj, NULL, sd->icon_size, "elm,state,icon_set");
2930      }
2931    else
2932      _elm_toolbar_item_icon_obj_set
2933        (obj, item, NULL, NULL, 0, "elm,state,icon_set");
2934    return EINA_TRUE;
2935 }
2936
2937 EAPI Eina_Bool
2938 elm_toolbar_item_icon_file_set(Elm_Object_Item *it,
2939                                const char *file,
2940                                const char *key)
2941 {
2942    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2943    Evas_Object *icon_obj;
2944    Evas_Object *obj;
2945    Eina_Bool ret;
2946
2947    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2948
2949    obj = WIDGET(item);
2950    ELM_TOOLBAR_DATA_GET(obj, sd);
2951
2952    if (file)
2953      {
2954         icon_obj = elm_icon_add(obj);
2955         evas_object_repeat_events_set(icon_obj, EINA_TRUE);
2956         ret = elm_image_file_set(icon_obj, file, key);
2957         if (!ret)
2958           {
2959              evas_object_del(icon_obj);
2960              return EINA_FALSE;
2961           }
2962         _elm_toolbar_item_icon_obj_set
2963           (obj, item, icon_obj, NULL, sd->icon_size, "elm,state,icon_set");
2964      }
2965    else
2966      _elm_toolbar_item_icon_obj_set
2967        (obj, item, NULL, NULL, 0, "elm,state,icon_set");
2968    return EINA_TRUE;
2969 }
2970
2971 EAPI void
2972 elm_toolbar_item_separator_set(Elm_Object_Item *it,
2973                                Eina_Bool separator)
2974 {
2975    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
2976    Evas_Object *obj = WIDGET(item);
2977    double scale;
2978
2979    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
2980    ELM_TOOLBAR_DATA_GET(obj, sd);
2981
2982    if (item->separator == separator) return;
2983    item->separator = separator;
2984    scale = (elm_widget_scale_get(obj) * elm_config_scale_get());
2985    _item_theme_hook(obj, item, scale, sd->icon_size);
2986    evas_object_size_hint_min_set(VIEW(item), -1, -1);
2987    if (separator) sd->separator_count++;
2988    else sd->separator_count--;
2989 }
2990
2991 EAPI Eina_Bool
2992 elm_toolbar_item_separator_get(const Elm_Object_Item *it)
2993 {
2994    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2995
2996    return ((Elm_Toolbar_Item *)it)->separator;
2997 }
2998
2999 EAPI void
3000 elm_toolbar_shrink_mode_set(Evas_Object *obj,
3001                             Elm_Toolbar_Shrink_Mode shrink_mode)
3002 {
3003    Eina_Bool bounce;
3004
3005    ELM_TOOLBAR_CHECK(obj);
3006    ELM_TOOLBAR_DATA_GET(obj, sd);
3007
3008    if (sd->shrink_mode == shrink_mode) return;
3009    sd->shrink_mode = shrink_mode;
3010    bounce = (_elm_config->thumbscroll_bounce_enable) &&
3011      (shrink_mode == ELM_TOOLBAR_SHRINK_SCROLL);
3012    sd->s_iface->bounce_allow_set(obj, bounce, EINA_FALSE);
3013
3014    if (sd->more_item)
3015      {
3016         elm_widget_item_del(sd->more_item);
3017         sd->more_item = NULL;
3018      }
3019
3020    if (shrink_mode == ELM_TOOLBAR_SHRINK_MENU)
3021      {
3022         elm_toolbar_homogeneous_set(obj, EINA_FALSE);
3023         sd->s_iface->policy_set
3024           (obj, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
3025         sd->more_item = _item_new(obj, "more_menu", "More", NULL, NULL);
3026      }
3027    else if (shrink_mode == ELM_TOOLBAR_SHRINK_HIDE)
3028      {
3029         elm_toolbar_homogeneous_set(obj, EINA_FALSE);
3030         sd->s_iface->policy_set
3031           (obj, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
3032      }
3033    else if (shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
3034      {
3035         elm_toolbar_homogeneous_set(obj, EINA_FALSE);
3036         sd->s_iface->policy_set
3037           (obj, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
3038         sd->more_item = _item_new(obj, "more_menu", "More", NULL, NULL);
3039      }
3040    else
3041      sd->s_iface->policy_set
3042        (obj, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
3043
3044    _sizing_eval(obj);
3045 }
3046
3047 EAPI Elm_Toolbar_Shrink_Mode
3048 elm_toolbar_shrink_mode_get(const Evas_Object *obj)
3049 {
3050    ELM_TOOLBAR_CHECK(obj) ELM_TOOLBAR_SHRINK_NONE;
3051    ELM_TOOLBAR_DATA_GET(obj, sd);
3052
3053    return sd->shrink_mode;
3054 }
3055
3056 EAPI void
3057 elm_toolbar_transverse_expanded_set(Evas_Object *obj, Eina_Bool transverse_expanded)
3058 {
3059    ELM_TOOLBAR_CHECK(obj);
3060    ELM_TOOLBAR_DATA_GET(obj, sd);
3061
3062    if (sd->transverse_expanded == transverse_expanded) return;
3063    sd->transverse_expanded = transverse_expanded;
3064
3065    _sizing_eval(obj);
3066 }
3067
3068 EAPI Eina_Bool
3069 elm_toolbar_transverse_expanded_get(const Evas_Object *obj)
3070 {
3071    ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
3072    ELM_TOOLBAR_DATA_GET(obj, sd);
3073
3074    return sd->transverse_expanded;
3075 }
3076
3077 EAPI void
3078 elm_toolbar_homogeneous_set(Evas_Object *obj,
3079                             Eina_Bool homogeneous)
3080 {
3081    ELM_TOOLBAR_CHECK(obj);
3082    ELM_TOOLBAR_DATA_GET(obj, sd);
3083
3084    homogeneous = !!homogeneous;
3085    if (homogeneous == sd->homogeneous) return;
3086    sd->homogeneous = homogeneous;
3087    if (homogeneous) elm_toolbar_shrink_mode_set(obj, ELM_TOOLBAR_SHRINK_NONE);
3088    evas_object_smart_calculate(sd->bx);
3089 }
3090
3091 EAPI Eina_Bool
3092 elm_toolbar_homogeneous_get(const Evas_Object *obj)
3093 {
3094    ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
3095    ELM_TOOLBAR_DATA_GET(obj, sd);
3096
3097    return sd->homogeneous;
3098 }
3099
3100 EAPI void
3101 elm_toolbar_menu_parent_set(Evas_Object *obj,
3102                             Evas_Object *parent)
3103 {
3104    Elm_Toolbar_Item *it;
3105
3106    ELM_TOOLBAR_CHECK(obj);
3107    ELM_TOOLBAR_DATA_GET(obj, sd);
3108    EINA_SAFETY_ON_NULL_RETURN(parent);
3109
3110    sd->menu_parent = parent;
3111    EINA_INLIST_FOREACH(sd->items, it)
3112      {
3113         if (it->o_menu)
3114           elm_menu_parent_set(it->o_menu, sd->menu_parent);
3115      }
3116    if ((sd->more_item) && (sd->more_item->o_menu))
3117      elm_menu_parent_set(sd->more_item->o_menu, sd->menu_parent);
3118 }
3119
3120 EAPI Evas_Object *
3121 elm_toolbar_menu_parent_get(const Evas_Object *obj)
3122 {
3123    ELM_TOOLBAR_CHECK(obj) NULL;
3124    ELM_TOOLBAR_DATA_GET(obj, sd);
3125
3126    return sd->menu_parent;
3127 }
3128
3129 EAPI void
3130 elm_toolbar_align_set(Evas_Object *obj,
3131                       double align)
3132 {
3133    ELM_TOOLBAR_CHECK(obj);
3134    ELM_TOOLBAR_DATA_GET(obj, sd);
3135
3136    if (sd->vertical)
3137      {
3138         if (sd->align != align)
3139           evas_object_size_hint_align_set(sd->bx, 0.5, align);
3140      }
3141    else
3142      {
3143         if (sd->align != align)
3144           evas_object_size_hint_align_set(sd->bx, align, 0.5);
3145      }
3146    sd->align = align;
3147 }
3148
3149 EAPI double
3150 elm_toolbar_align_get(const Evas_Object *obj)
3151 {
3152    ELM_TOOLBAR_CHECK(obj) 0.0;
3153    ELM_TOOLBAR_DATA_GET(obj, sd);
3154
3155    return sd->align;
3156 }
3157
3158 EAPI void
3159 elm_toolbar_item_menu_set(Elm_Object_Item *it,
3160                           Eina_Bool menu)
3161 {
3162    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3163
3164    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
3165    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
3166
3167    if (item->menu == menu) return;
3168    if (menu) _item_menu_create(sd, item);
3169    else _item_menu_destroy(item);
3170 }
3171
3172 EAPI Evas_Object *
3173 elm_toolbar_item_menu_get(const Elm_Object_Item *it)
3174 {
3175    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3176
3177    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3178
3179    if (!item->menu) return NULL;
3180    return item->o_menu;
3181 }
3182
3183 EAPI Elm_Toolbar_Item_State *
3184 elm_toolbar_item_state_add(Elm_Object_Item *it,
3185                            const char *icon,
3186                            const char *label,
3187                            Evas_Smart_Cb func,
3188                            const void *data)
3189 {
3190    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3191    Elm_Toolbar_Item_State *it_state;
3192    Evas_Object *icon_obj;
3193    Evas_Object *obj;
3194
3195    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3196
3197    obj = WIDGET(item);
3198    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
3199
3200    if (!item->states)
3201      {
3202         it_state = _item_state_new
3203             (item->label, item->icon_str, item->icon, item->func,
3204             item->base.data);
3205         item->states = eina_list_append(item->states, it_state);
3206         item->current_state = item->states;
3207      }
3208
3209    icon_obj = elm_icon_add(obj);
3210    elm_icon_order_lookup_set(icon_obj, sd->lookup_order);
3211    if (!icon_obj) goto error_state_add;
3212
3213    if (!_item_icon_set(icon_obj, "toolbar/", icon))
3214      {
3215         evas_object_del(icon_obj);
3216         icon_obj = NULL;
3217         icon = NULL;
3218      }
3219
3220    it_state = _item_state_new(label, icon, icon_obj, func, data);
3221    item->states = eina_list_append(item->states, it_state);
3222    item->func = _elm_toolbar_item_state_cb;
3223    item->base.data = NULL;
3224
3225    return it_state;
3226
3227 error_state_add:
3228    if (item->states && !eina_list_next(item->states))
3229      {
3230         eina_stringshare_del(item->label);
3231         eina_stringshare_del(item->icon_str);
3232         free(eina_list_data_get(item->states));
3233         eina_list_free(item->states);
3234         item->states = NULL;
3235      }
3236    return NULL;
3237 }
3238
3239 EAPI Eina_Bool
3240 elm_toolbar_item_state_del(Elm_Object_Item *it,
3241                            Elm_Toolbar_Item_State *state)
3242 {
3243    Elm_Toolbar_Item_State *it_state;
3244    Elm_Toolbar_Item *item;
3245    Eina_List *del_state;
3246
3247    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
3248
3249    if (!state) return EINA_FALSE;
3250
3251    item = (Elm_Toolbar_Item *)it;
3252    if (!item->states) return EINA_FALSE;
3253
3254    del_state = eina_list_data_find_list(item->states, state);
3255    if (del_state == item->states) return EINA_FALSE;
3256    if (del_state == item->current_state)
3257      elm_toolbar_item_state_unset(it);
3258
3259    eina_stringshare_del(state->label);
3260    eina_stringshare_del(state->icon_str);
3261    if (state->icon) evas_object_del(state->icon);
3262    free(state);
3263
3264    item->states = eina_list_remove_list(item->states, del_state);
3265    if (item->states && !eina_list_next(item->states))
3266      {
3267         it_state = eina_list_data_get(item->states);
3268         item->base.data = it_state->data;
3269         item->func = it_state->func;
3270         eina_stringshare_del(it_state->label);
3271         eina_stringshare_del(it_state->icon_str);
3272         free(eina_list_data_get(item->states));
3273         eina_list_free(item->states);
3274         item->states = NULL;
3275      }
3276
3277    return EINA_TRUE;
3278 }
3279
3280 EAPI Eina_Bool
3281 elm_toolbar_item_state_set(Elm_Object_Item *it,
3282                            Elm_Toolbar_Item_State *state)
3283 {
3284    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3285    Elm_Toolbar_Item_State *it_state;
3286    Eina_List *next_state;
3287    Evas_Object *obj;
3288
3289    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
3290
3291    obj = WIDGET(item);
3292    ELM_TOOLBAR_DATA_GET(obj, sd);
3293    if (!item->states) return EINA_FALSE;
3294
3295    if (state)
3296      {
3297         next_state = eina_list_data_find_list(item->states, state);
3298         if (!next_state) return EINA_FALSE;
3299      }
3300    else
3301      next_state = item->states;
3302
3303    if (next_state == item->current_state) return EINA_TRUE;
3304
3305    it_state = eina_list_data_get(next_state);
3306    if (eina_list_data_find(item->current_state, state))
3307      {
3308         _item_label_set(item, it_state->label, "elm,state,label_set,forward");
3309         _elm_toolbar_item_icon_obj_set
3310           (obj, item, it_state->icon, it_state->icon_str,
3311           sd->icon_size, "elm,state,icon_set,forward");
3312      }
3313    else
3314      {
3315         _item_label_set(item, it_state->label, "elm,state,label_set,backward");
3316         _elm_toolbar_item_icon_obj_set
3317           (obj, item, it_state->icon, it_state->icon_str,
3318           sd->icon_size, "elm,state,icon_set,backward");
3319      }
3320    if (elm_widget_item_disabled_get(item))
3321      elm_widget_signal_emit(item->icon, "elm,state,disabled", "elm");
3322    else
3323      elm_widget_signal_emit(item->icon, "elm,state,enabled", "elm");
3324
3325    item->current_state = next_state;
3326
3327    return EINA_TRUE;
3328 }
3329
3330 EAPI void
3331 elm_toolbar_item_state_unset(Elm_Object_Item *it)
3332 {
3333    elm_toolbar_item_state_set(it, NULL);
3334 }
3335
3336 EAPI Elm_Toolbar_Item_State *
3337 elm_toolbar_item_state_get(const Elm_Object_Item *it)
3338 {
3339    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3340
3341    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3342
3343    if ((!item->states) || (!item->current_state)) return NULL;
3344    if (item->current_state == item->states) return NULL;
3345
3346    return eina_list_data_get(item->current_state);
3347 }
3348
3349 EAPI Elm_Toolbar_Item_State *
3350 elm_toolbar_item_state_next(Elm_Object_Item *it)
3351 {
3352    Eina_List *next_state;
3353    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3354
3355    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3356
3357    if (!item->states) return NULL;
3358
3359    next_state = eina_list_next(item->current_state);
3360    if (!next_state)
3361      next_state = eina_list_next(item->states);
3362    return eina_list_data_get(next_state);
3363 }
3364
3365 EAPI Elm_Toolbar_Item_State *
3366 elm_toolbar_item_state_prev(Elm_Object_Item *it)
3367 {
3368    Eina_List *prev_state;
3369    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3370
3371    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it, NULL);
3372
3373    if (!item->states) return NULL;
3374
3375    prev_state = eina_list_prev(item->current_state);
3376    if ((!prev_state) || (prev_state == item->states))
3377      prev_state = eina_list_last(item->states);
3378    return eina_list_data_get(prev_state);
3379 }
3380
3381 EAPI void
3382 elm_toolbar_icon_order_lookup_set(Evas_Object *obj,
3383                                   Elm_Icon_Lookup_Order order)
3384 {
3385    Elm_Toolbar_Item *it;
3386
3387    ELM_TOOLBAR_CHECK(obj);
3388    ELM_TOOLBAR_DATA_GET(obj, sd);
3389
3390    if (sd->lookup_order == order) return;
3391    sd->lookup_order = order;
3392    EINA_INLIST_FOREACH(sd->items, it)
3393      elm_icon_order_lookup_set(it->icon, order);
3394    if (sd->more_item)
3395      elm_icon_order_lookup_set(sd->more_item->icon, order);
3396 }
3397
3398 EAPI Elm_Icon_Lookup_Order
3399 elm_toolbar_icon_order_lookup_get(const Evas_Object *obj)
3400 {
3401    ELM_TOOLBAR_CHECK(obj) ELM_ICON_LOOKUP_THEME_FDO;
3402    ELM_TOOLBAR_DATA_GET(obj, sd);
3403
3404    return sd->lookup_order;
3405 }
3406
3407 EAPI void
3408 elm_toolbar_horizontal_set(Evas_Object *obj,
3409                            Eina_Bool horizontal)
3410 {
3411    ELM_TOOLBAR_CHECK(obj);
3412    ELM_TOOLBAR_DATA_GET(obj, sd);
3413
3414    horizontal = !!horizontal;
3415    if (!horizontal == sd->vertical) return;
3416    sd->vertical = !horizontal;
3417    if (sd->vertical)
3418      evas_object_size_hint_align_set(sd->bx, 0.5, sd->align);
3419    else
3420      evas_object_size_hint_align_set(sd->bx, sd->align, 0.5);
3421
3422    _sizing_eval(obj);
3423 }
3424
3425 EAPI Eina_Bool
3426 elm_toolbar_horizontal_get(const Evas_Object *obj)
3427 {
3428    ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
3429    ELM_TOOLBAR_DATA_GET(obj, sd);
3430
3431    return !sd->vertical;
3432 }
3433
3434 EAPI unsigned int
3435 elm_toolbar_items_count(const Evas_Object *obj)
3436 {
3437    ELM_TOOLBAR_CHECK(obj) 0;
3438    ELM_TOOLBAR_DATA_GET(obj, sd);
3439
3440    return sd->item_count;
3441 }
3442
3443 EAPI void
3444 elm_toolbar_standard_priority_set(Evas_Object *obj,
3445                                   int priority)
3446 {
3447    ELM_TOOLBAR_CHECK(obj);
3448    ELM_TOOLBAR_DATA_GET(obj, sd);
3449
3450    if (sd->standard_priority == priority) return;
3451    sd->standard_priority = priority;
3452    _resize_cb(obj, NULL, NULL, NULL);
3453 }
3454
3455 EAPI int
3456 elm_toolbar_standard_priority_get(const Evas_Object *obj)
3457 {
3458    ELM_TOOLBAR_CHECK(obj) 0;
3459    ELM_TOOLBAR_DATA_GET(obj, sd);
3460
3461    return sd->standard_priority;
3462 }
3463
3464 EAPI void
3465 elm_toolbar_select_mode_set(Evas_Object *obj,
3466                             Elm_Object_Select_Mode mode)
3467 {
3468    ELM_TOOLBAR_CHECK(obj);
3469    ELM_TOOLBAR_DATA_GET(obj, sd);
3470
3471    if (mode >= ELM_OBJECT_SELECT_MODE_MAX)
3472      return;
3473
3474    if (sd->select_mode == mode) return;
3475
3476    if ((mode == ELM_OBJECT_SELECT_MODE_ALWAYS) &&
3477        (sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) &&
3478        sd->items)
3479      _item_select(ELM_TOOLBAR_ITEM_FROM_INLIST(sd->items));
3480
3481    if (sd->select_mode != mode)
3482      sd->select_mode = mode;
3483 }
3484
3485 EAPI Elm_Object_Select_Mode
3486 elm_toolbar_select_mode_get(const Evas_Object *obj)
3487 {
3488    ELM_TOOLBAR_CHECK(obj) ELM_OBJECT_SELECT_MODE_MAX;
3489    ELM_TOOLBAR_DATA_GET(obj, sd);
3490
3491    return sd->select_mode;
3492 }
3493
3494 EAPI void
3495 elm_toolbar_reorder_mode_set(Evas_Object *obj,
3496                              Eina_Bool    reorder_mode)
3497 {
3498    ELM_TOOLBAR_CHECK(obj);
3499    ELM_TOOLBAR_DATA_GET(obj, sd);
3500
3501    sd->reorder_mode = !!reorder_mode;
3502 }
3503
3504 EAPI Eina_Bool
3505 elm_toolbar_reorder_mode_get(const Evas_Object *obj)
3506 {
3507    ELM_TOOLBAR_CHECK(obj) EINA_FALSE;
3508    ELM_TOOLBAR_DATA_GET(obj, sd);
3509
3510    return sd->reorder_mode;
3511 }
3512
3513 EAPI void
3514 elm_toolbar_item_show(Elm_Object_Item *it, Elm_Toolbar_Item_Scrollto_Type type)
3515 {
3516    Evas_Coord x, y, w, h;
3517    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3518
3519    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
3520    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
3521
3522    if (_elm_toolbar_item_coordinates_calc(it, type, &x, &y, &w, &h))
3523      sd->s_iface->content_region_show(WIDGET(item), x, y, w, h);
3524 }
3525
3526 EAPI void
3527 elm_toolbar_item_bring_in(Elm_Object_Item *it, Elm_Toolbar_Item_Scrollto_Type type)
3528 {
3529    Evas_Coord x, y, w, h;
3530    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *)it;
3531
3532    ELM_TOOLBAR_ITEM_CHECK_OR_RETURN(it);
3533    ELM_TOOLBAR_DATA_GET(WIDGET(item), sd);
3534
3535    if (_elm_toolbar_item_coordinates_calc(it, type, &x, &y, &w, &h))
3536      sd->s_iface->region_bring_in(WIDGET(item), x, y, w, h);
3537 }