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