Add the ELM_TOOLBAR_SHRINK_EXPAND mode. The items be expanded according the size...
[framework/uifw/elementary.git] / src / lib / elm_toolbar.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "els_scroller.h"
4 #include "els_box.h"
5 #include "els_icon.h"
6
7 typedef struct _Widget_Data Widget_Data;
8 typedef struct _Elm_Toolbar_Item Elm_Toolbar_Item;
9
10 struct _Widget_Data
11 {
12    Evas_Object *scr, *bx;
13    Evas_Object *menu_parent;
14    Eina_Inlist *items;
15    Elm_Toolbar_Item *more_item, *selected_item;
16    Elm_Toolbar_Shrink_Mode shrink_mode;
17    Elm_Icon_Lookup_Order lookup_order;
18    int icon_size;
19    unsigned int item_count;
20    double align;
21    Eina_Bool homogeneous : 1;
22    Eina_Bool no_select : 1;
23    Eina_Bool always_select : 1;
24    Eina_Bool vertical : 1;
25    Eina_Bool long_press : 1;
26    Ecore_Timer *long_timer;
27    Ecore_Job *resize_job;
28 };
29
30 struct _Elm_Toolbar_Item
31 {
32    ELM_WIDGET_ITEM;
33    EINA_INLIST;
34    const char *label;
35    const char *icon_str;
36    Evas_Object *icon;
37    Evas_Object *o_menu;
38    Evas_Smart_Cb func;
39    struct {
40       int priority;
41       Eina_Bool visible : 1;
42    } prio;
43    Eina_Bool selected : 1;
44    Eina_Bool separator : 1;
45    Eina_Bool menu : 1;
46    Eina_List *states;
47    Eina_List *current_state;
48 };
49
50 #define ELM_TOOLBAR_ITEM_FROM_INLIST(item)      \
51   ((item) ? EINA_INLIST_CONTAINER_GET(item, Elm_Toolbar_Item) : NULL)
52
53 struct _Elm_Toolbar_Item_State
54 {
55    const char *label;
56    const char *icon_str;
57    Evas_Object *icon;
58    Evas_Smart_Cb func;
59    const void *data;
60 };
61
62 static const char *widtype = NULL;
63 static void _item_show(Elm_Toolbar_Item *it);
64 static void _item_select(Elm_Toolbar_Item *it);
65 static void _item_unselect(Elm_Toolbar_Item *it);
66 static void _del_pre_hook(Evas_Object *obj);
67 static void _del_hook(Evas_Object *obj);
68 static void _mirrored_set(Evas_Object *obj, Eina_Bool mirrored);
69 static void _mirrored_set_item(Evas_Object *obj, Elm_Toolbar_Item *it, Eina_Bool mirrored);
70 static void _theme_hook(Evas_Object *obj);
71 static void _sizing_eval(Evas_Object *obj);
72 static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
73 static void _menu_move_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
74 static void _menu_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
75 static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data);
76 static void _elm_toolbar_item_icon_obj_set(Evas_Object *obj, Elm_Toolbar_Item *item, Evas_Object *icon_obj, const char *icon_str, double icon_size, const char *signal);
77 static void _item_label_set(Elm_Toolbar_Item *item, const char *label, const char *signal);
78
79 static const char SIG_CLICKED[] = "clicked";
80 static const char SIG_LONGPRESSED[] = "longpressed";
81 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
82
83 static const Evas_Smart_Cb_Description _signals[] = {
84    {SIG_CLICKED, ""},
85    {SIG_LONGPRESSED, ""},
86    {SIG_CLICKED_DOUBLE, ""},
87    {NULL, NULL}
88 };
89
90 static void
91 _item_disable_hook(Elm_Object_Item *it)
92 {
93    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
94
95    Widget_Data *wd;
96    Elm_Toolbar_Item *toolbar_it = (Elm_Toolbar_Item *) it;
97
98    wd = elm_widget_data_get(WIDGET(toolbar_it));
99    if (!wd) return;
100
101    if (elm_widget_item_disabled_get(toolbar_it))
102      {
103         edje_object_signal_emit(VIEW(toolbar_it), "elm,state,disabled", "elm");
104         elm_widget_signal_emit(toolbar_it->icon, "elm,state,disabled", "elm");
105      }
106    else
107      {
108         edje_object_signal_emit(VIEW(toolbar_it), "elm,state,enabled", "elm");
109         elm_widget_signal_emit(toolbar_it->icon, "elm,state,enabled", "elm");
110      }
111    _resize(WIDGET(toolbar_it), NULL, NULL, NULL);
112 }
113
114 static Eina_Bool
115 _item_icon_set(Evas_Object *icon_obj, const char *type, const char *icon)
116 {
117    char icon_str[512];
118
119    if ((!type) || (!*type)) goto end;
120    if ((!icon) || (!*icon)) return EINA_FALSE;
121    if ((snprintf(icon_str, sizeof(icon_str), "%s%s", type, icon) > 0)
122        && (elm_icon_standard_set(icon_obj, icon_str)))
123      return EINA_TRUE;
124 end:
125    if (elm_icon_standard_set(icon_obj, icon))
126      return EINA_TRUE;
127    WRN("couldn't find icon definition for '%s'", icon);
128    return EINA_FALSE;
129 }
130
131 static int
132 _elm_toolbar_icon_size_get(Widget_Data *wd)
133 {
134    const char *icon_size = edje_object_data_get(
135       elm_smart_scroller_edje_object_get(wd->scr), "icon_size");
136    if (icon_size)
137      return atoi(icon_size);
138    return _elm_config->icon_size;
139 }
140
141 static void
142 _item_show(Elm_Toolbar_Item *it)
143 {
144    Widget_Data *wd = elm_widget_data_get(WIDGET(it));
145    Evas_Coord x, y, w, h, bx, by;
146
147    if (!wd) return;
148    evas_object_geometry_get(wd->bx, &bx, &by, NULL, NULL);
149    evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
150    elm_smart_scroller_child_region_show(wd->scr, x - bx, y - by, w, h);
151 }
152
153 static void
154 _item_unselect(Elm_Toolbar_Item *item)
155 {
156    Widget_Data *wd;
157    if ((!item) || (!item->selected)) return;
158    wd = elm_widget_data_get(WIDGET(item));
159    if (!wd) return;
160    item->selected = EINA_FALSE;
161    wd->selected_item = NULL;
162    edje_object_signal_emit(VIEW(item), "elm,state,unselected", "elm");
163    elm_widget_signal_emit(item->icon, "elm,state,unselected", "elm");
164 }
165
166 static void
167 _item_select(Elm_Toolbar_Item *it)
168 {
169    Elm_Toolbar_Item *it2;
170    Widget_Data *wd = elm_widget_data_get(WIDGET(it));
171    Evas_Object *obj2;
172    Eina_Bool sel;
173
174    if (!wd) return;
175    if (elm_widget_item_disabled_get(it) || (it->separator)) return;
176    sel = it->selected;
177
178    if (!wd->no_select)
179      {
180         if (sel)
181           {
182              if (wd->always_select) return;
183              _item_unselect(it);
184           }
185         else
186           {
187              it2 = (Elm_Toolbar_Item *)
188                 elm_toolbar_selected_item_get(WIDGET(it));
189              _item_unselect(it2);
190
191              it->selected = EINA_TRUE;
192              wd->selected_item = it;
193              edje_object_signal_emit(VIEW(it), "elm,state,selected", "elm");
194              elm_widget_signal_emit(it->icon, "elm,state,selected", "elm");
195              _item_show(it);
196           }
197      }
198    obj2 = WIDGET(it);
199    if (it->menu && (!sel))
200      {
201         evas_object_show(it->o_menu);
202         evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_RESIZE,
203                                        _menu_move_resize, it);
204         evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOVE,
205                                        _menu_move_resize, it);
206
207         _menu_move_resize(it, NULL, NULL, NULL);
208      }
209    if (it->func) it->func((void *)(it->base.data), WIDGET(it), it);
210    evas_object_smart_callback_call(obj2, SIG_CLICKED, it);
211 }
212
213 static void
214 _menu_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
215 {
216    Elm_Toolbar_Item *selected;
217    Elm_Toolbar_Item *it = data;
218    selected = (Elm_Toolbar_Item *) elm_toolbar_selected_item_get(WIDGET(it));
219    _item_unselect(selected);
220 }
221
222 static void
223 _menu_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
224 {
225    // avoid hide being emitted during object deletion
226    evas_object_event_callback_del_full
227       (obj, EVAS_CALLBACK_HIDE, _menu_hide, data);
228 }
229
230 static void
231 _menu_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
232 {
233    Elm_Toolbar_Item *it = data;
234    Evas_Coord x,y,w,h;
235    Widget_Data *wd = elm_widget_data_get(WIDGET(it));
236
237    if ((!wd) || (!wd->menu_parent)) return;
238    evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
239    elm_menu_move(it->o_menu, x, y+h);
240 }
241
242 static void
243 _item_del(Elm_Toolbar_Item *it)
244 {
245    Elm_Toolbar_Item_State *it_state;
246    _item_unselect(it);
247    EINA_LIST_FREE(it->states, it_state)
248      {
249         if (it->icon == it_state->icon)
250           it->icon = NULL;
251         eina_stringshare_del(it_state->label);
252         eina_stringshare_del(it_state->icon_str);
253         if (it_state->icon) evas_object_del(it_state->icon);
254         free(it_state);
255      }
256    eina_stringshare_del(it->label);
257    eina_stringshare_del(it->icon_str);
258    if (it->icon) evas_object_del(it->icon);
259    //TODO: See if checking for wd->menu_parent is necessary before deleting menu
260    if (it->o_menu) evas_object_del(it->o_menu);
261 }
262
263 static void
264 _del_pre_hook(Evas_Object *obj)
265 {
266    Widget_Data *wd = elm_widget_data_get(obj);
267    Elm_Toolbar_Item *it, *next;
268
269    if (!wd) return;
270    it = ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items);
271    while(it)
272      {
273         next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
274         _item_del(it);
275         elm_widget_item_free(it);
276         it = next;
277      }
278    if (wd->more_item)
279      {
280         _item_del(wd->more_item);
281         elm_widget_item_free(wd->more_item);
282      }
283    if (wd->long_timer)
284      {
285         ecore_timer_del(wd->long_timer);
286         wd->long_timer = NULL;
287      }
288 }
289
290 static void
291 _del_hook(Evas_Object *obj)
292 {
293    Widget_Data *wd = elm_widget_data_get(obj);
294
295    if (!wd) return;
296    free(wd);
297 }
298
299
300 static void
301 _mirrored_set_item(Evas_Object *obj __UNUSED__, Elm_Toolbar_Item *it, Eina_Bool mirrored)
302 {
303    edje_object_mirrored_set(VIEW(it), mirrored);
304    elm_widget_mirrored_set(it->o_menu, mirrored);
305 }
306
307 static void
308 _theme_hook_item(Evas_Object *obj, Elm_Toolbar_Item *it, double scale, int icon_size)
309 {
310    Widget_Data *wd = elm_widget_data_get(obj);
311    Evas_Object *view = VIEW(it);
312    Evas_Coord mw, mh;
313    const char *style = elm_widget_style_get(obj);
314
315    _mirrored_set_item(obj, it, elm_widget_mirrored_get(obj));
316    edje_object_scale_set(view, scale);
317    if (!it->separator)
318      {
319         _elm_theme_object_set(obj, view, "toolbar", "item", style);
320         if (it->selected)
321           {
322              edje_object_signal_emit(view, "elm,state,selected", "elm");
323              elm_widget_signal_emit(it->icon, "elm,state,selected", "elm");
324           }
325         if (elm_widget_item_disabled_get(it))
326           {
327              edje_object_signal_emit(view, "elm,state,disabled", "elm");
328              elm_widget_signal_emit(it->icon, "elm,state,disabled", "elm");
329           }
330         if (it->icon)
331           {
332              int ms = 0;
333
334              ms = ((double)icon_size * scale);
335              evas_object_size_hint_min_set(it->icon, ms, ms);
336              evas_object_size_hint_max_set(it->icon, ms, ms);
337              edje_object_part_swallow(view, "elm.swallow.icon", it->icon);
338           }
339         edje_object_part_text_set(view, "elm.text", it->label);
340      }
341    else
342      {
343         _elm_theme_object_set(obj, view, "toolbar", "separator", style);
344         if (wd->vertical)
345           {
346              evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, -1.0);
347              evas_object_size_hint_align_set(view, EVAS_HINT_FILL, 0.5);
348           }
349         else
350           {
351              evas_object_size_hint_weight_set(view, -1.0, EVAS_HINT_EXPAND);
352              evas_object_size_hint_align_set(view, 0.5, EVAS_HINT_FILL);
353           }
354      }
355
356    mw = mh = -1;
357    if (!it->separator)
358      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
359    edje_object_size_min_restricted_calc(view, &mw, &mh, mw, mh);
360    if (!it->separator)
361      elm_coords_finger_size_adjust(1, &mw, 1, &mh);
362    evas_object_size_hint_min_set(view, mw, mh);
363 }
364
365 static void
366 _mirrored_set(Evas_Object *obj, Eina_Bool mirrored)
367 {
368    Widget_Data *wd = elm_widget_data_get(obj);
369    Elm_Toolbar_Item *it;
370
371    EINA_INLIST_FOREACH(wd->items, it)
372       _mirrored_set_item(obj, it, mirrored);
373    if (wd->more_item)
374      _mirrored_set_item(obj, wd->more_item, mirrored);
375 }
376
377 static void
378 _theme_hook(Evas_Object *obj)
379 {
380    Widget_Data *wd = elm_widget_data_get(obj);
381    Elm_Toolbar_Item *it;
382    double scale = 0;
383
384    if (!wd) return;
385    _elm_widget_mirrored_reload(obj);
386    elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", elm_widget_style_get(obj));
387    _mirrored_set(obj, elm_widget_mirrored_get(obj));
388    scale = (elm_widget_scale_get(obj) * _elm_config->scale);
389    edje_object_scale_set(wd->scr, scale);
390    wd->icon_size = _elm_toolbar_icon_size_get(wd);
391    EINA_INLIST_FOREACH(wd->items, it)
392       _theme_hook_item(obj, it, scale, wd->icon_size);
393    if (wd->more_item)
394      _theme_hook_item(obj, wd->more_item, scale, wd->icon_size);
395    _sizing_eval(obj);
396 }
397
398 static void
399 _item_text_set_hook(Elm_Object_Item *it,
400                     const char *part,
401                     const char *label)
402 {
403    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
404    if (part && strcmp(part, "default")) return;
405    _item_label_set(((Elm_Toolbar_Item *) it), label, "elm,state,label_set");
406 }
407
408 static const char *
409 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
410 {
411    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
412    if (part && strcmp(part, "default")) return NULL;
413    return ((Elm_Toolbar_Item *) it)->label;
414 }
415
416 static void
417 _translate_hook(Evas_Object *obj)
418 {
419    evas_object_smart_callback_call(obj, "language,changed", NULL);
420 }
421
422 static void
423 _sizing_eval(Evas_Object *obj)
424 {
425    Widget_Data *wd = elm_widget_data_get(obj);
426    Evas_Coord minw = -1, minh = -1, minw_bx = -1, minh_bx = -1;
427    Evas_Coord vw = 0, vh = 0;
428    Evas_Coord w, h;
429
430    if (!wd) return;
431    evas_object_smart_need_recalculate_set(wd->bx, EINA_TRUE);
432    evas_object_smart_calculate(wd->bx);
433    edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
434                              &minw, &minh);
435    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
436    if (w < minw) w = minw;
437    if (h < minh) h = minh;
438    evas_object_resize(wd->scr, w, h);
439
440    evas_object_size_hint_min_get(wd->bx, &minw_bx, &minh_bx);
441 //   if (wd->vertical && (h > minh)) minh = h;
442 //   if ((!wd->vertical) && (w > minw)) minw = w;
443    elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
444    if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_NONE)
445      {
446         if (wd->vertical)
447           {
448              minw = minw_bx + (w - vw);
449              minh = minh_bx + (h - vh);
450           }
451         else
452           {
453              minw = minw_bx + (w - vw);
454              minh = minh_bx + (h - vh);
455           }
456      }
457    else if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
458      {
459         minw = minw_bx + (w - vw);
460         minh = minh_bx + (h - vh);
461         if (minw_bx < vw) minw_bx = vw;
462         if (minh_bx < vh) minh_bx = vh;
463      }
464    else
465      {
466         if (wd->vertical)
467           {
468              minw = minw_bx + (w - vw);
469              minh = h - vh;
470           }
471         else
472           {
473              minw = w - vw;
474              minh = minh_bx + (h - vh);
475           }
476 //        if (wd->vertical) minh = h - vh;
477 //        else minw = w - vw;
478 //        minh = minh + (h - vh);
479      }
480    evas_object_resize(wd->bx, minw_bx, minh_bx);
481    evas_object_size_hint_min_set(obj, minw, minh);
482    evas_object_size_hint_max_set(obj, -1, -1);
483 }
484
485 static void
486 _item_menu_create(Widget_Data *wd, Elm_Toolbar_Item *item)
487 {
488    item->o_menu = elm_menu_add(VIEW(item));
489    item->menu = EINA_TRUE;
490    if (wd->menu_parent)
491      elm_menu_parent_set(item->o_menu, wd->menu_parent);
492    evas_object_event_callback_add(item->o_menu, EVAS_CALLBACK_HIDE,
493                                   _menu_hide, item);
494    evas_object_event_callback_add(item->o_menu, EVAS_CALLBACK_DEL,
495                                   _menu_del, item);
496 }
497
498 static void
499 _item_menu_destroy(Elm_Toolbar_Item *item)
500 {
501    if (item->o_menu)
502      {
503         evas_object_del(item->o_menu);
504         item->o_menu = NULL;
505      }
506    item->menu = EINA_FALSE;
507 }
508
509 static int
510 _toolbar_item_prio_compare_cb(const void *i1, const void *i2)
511 {
512    const Elm_Toolbar_Item *eti1 = i1;
513    const Elm_Toolbar_Item *eti2 = i2;
514
515    if (!eti2) return 1;
516    if (!eti1) return -1;
517
518    return eti2->prio.priority - eti1->prio.priority;
519 }
520
521 static void
522 _fix_items_visibility(Widget_Data *wd, Evas_Coord *iw, Evas_Coord vw)
523 {
524    Elm_Toolbar_Item *it;
525    Eina_List *sorted = NULL;
526    Evas_Coord ciw = 0, cih = 0;
527
528    EINA_INLIST_FOREACH(wd->items, it)
529      {
530         sorted = eina_list_sorted_insert(sorted,
531                                          _toolbar_item_prio_compare_cb, it);
532      }
533
534    if (wd->more_item)
535      {
536         evas_object_geometry_get(wd->VIEW(more_item), NULL, NULL, &ciw, &cih);
537         if (wd->vertical) *iw += cih;
538         else              *iw += ciw;
539      }
540    EINA_LIST_FREE(sorted, it)
541      {
542         evas_object_geometry_get(VIEW(it), NULL, NULL, &ciw, &cih);
543         if (wd->vertical) *iw += cih;
544         else              *iw += ciw;
545         it->prio.visible = (*iw <= vw);
546      }
547 }
548
549 static void
550 _elm_toolbar_item_menu_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
551 {
552    Elm_Toolbar_Item *it = data;
553    if (it->func) it->func((void *)(it->base.data), WIDGET(it), it);
554 }
555
556 static void
557 _resize_job(void *data)
558 {
559    Evas_Object *obj = (Evas_Object *)data;
560    Widget_Data *wd = elm_widget_data_get(obj);
561    Evas_Coord mw, mh, vw = 0, vh = 0, w = 0, h = 0;
562    Elm_Toolbar_Item *it;
563
564    if (!wd) return;
565    wd->resize_job = NULL;
566    elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
567    evas_object_size_hint_min_get(wd->bx, &mw, &mh);
568    evas_object_geometry_get(wd->bx, NULL, NULL, &w, &h);
569    if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_MENU)
570      {
571         Evas_Coord iw = 0, ih = 0, more_w = 0, more_h = 0;
572
573         if (wd->vertical)
574           {
575              evas_object_resize(wd->bx, w, vh);
576              _fix_items_visibility(wd, &ih, vh);
577           }
578         else
579           {
580              evas_object_resize(wd->bx, vw, h);
581              _fix_items_visibility(wd, &iw, vw);
582           }
583         evas_object_geometry_get(wd->VIEW(more_item), NULL, NULL,
584                                  &more_w, &more_h);
585         if (wd->vertical)
586           {
587              if ((ih - more_h) <= vh) ih -= more_h;
588           }
589         else
590           {
591              if ((iw - more_w) <= vw) iw -= more_w;
592           }
593
594         /* All items are removed from the box object, since removing individual
595          * items won't trigger a resize. Items are be readded below. */
596         evas_object_box_remove_all(wd->bx, EINA_FALSE);
597         if (((wd->vertical)  && (ih > vh)) || 
598             ((!wd->vertical) && (iw > vw)))
599           {
600              Evas_Object *menu;
601
602              _item_menu_destroy(wd->more_item);
603              _item_menu_create(wd, wd->more_item);
604              menu = elm_toolbar_item_menu_get((Elm_Object_Item *)wd->more_item);
605              EINA_INLIST_FOREACH(wd->items, it)
606                {
607                   if (!it->prio.visible)
608                     {
609                        if (it->separator)
610                          elm_menu_item_separator_add(menu, NULL);
611                        else
612                          {
613                             Elm_Object_Item *menu_it;
614                             menu_it = elm_menu_item_add
615                               (menu, NULL, it->icon_str, it->label,
616                                   _elm_toolbar_item_menu_cb, it);
617                             elm_object_item_disabled_set
618                               (menu_it, elm_widget_item_disabled_get(it));
619                             if (it->o_menu)
620                               elm_menu_clone(it->o_menu, menu, menu_it);
621                          }
622                        evas_object_hide(VIEW(it));
623                     }
624                   else
625                     {
626                        evas_object_box_append(wd->bx, VIEW(it));
627                        evas_object_show(VIEW(it));
628                     }
629                }
630              evas_object_box_append(wd->bx, wd->VIEW(more_item));
631              evas_object_show(wd->VIEW(more_item));
632           }
633         else
634           {
635              /* All items are visible, show them all (except for the "More"
636               * button, of course). */
637              EINA_INLIST_FOREACH(wd->items, it)
638                {
639                   evas_object_show(VIEW(it));
640                   evas_object_box_append(wd->bx, VIEW(it));
641                }
642              evas_object_hide(wd->VIEW(more_item));
643           }
644      }
645    else if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_HIDE)
646      {
647         Evas_Coord iw = 0, ih = 0;
648
649         if (wd->vertical)
650           {
651              evas_object_resize(wd->bx, w, vh);
652              _fix_items_visibility(wd, &ih, vh);
653           }
654         else
655           {
656              evas_object_resize(wd->bx, vw, h);
657              _fix_items_visibility(wd, &iw, vw);
658           }
659         evas_object_box_remove_all(wd->bx, EINA_FALSE);
660         if (((wd->vertical)  && (ih > vh)) || 
661             ((!wd->vertical) && (iw > vw)))
662           {
663              EINA_INLIST_FOREACH(wd->items, it)
664                {
665                   if (!it->prio.visible)
666                     evas_object_hide(VIEW(it));
667                   else
668                     {
669                        evas_object_box_append(wd->bx, VIEW(it));
670                        evas_object_show(VIEW(it));
671                     }
672                }
673           }
674         else
675           {
676              /* All items are visible, show them all */
677              EINA_INLIST_FOREACH(wd->items, it)
678                {
679                   evas_object_show(VIEW(it));
680                   evas_object_box_append(wd->bx, VIEW(it));
681                }
682           }
683      }
684    else if (wd->shrink_mode == ELM_TOOLBAR_SHRINK_EXPAND)
685      {
686         if ((vw >= mw) && (vh >= mh))
687           evas_object_resize(wd->bx, vw, vh);
688         else if (vw < mw)
689           evas_object_resize(wd->bx, mw, vh);
690         else if (vh < mh)
691           evas_object_resize(wd->bx, vw, mh);
692      }
693    else
694      {
695         if (wd->vertical)
696           {
697              if ((vh >= mh) && (h != vh)) evas_object_resize(wd->bx, w, vh);
698           }
699         else
700           {
701              if ((vw >= mw) && (w != vw)) evas_object_resize(wd->bx, vw, h);
702           }
703         EINA_INLIST_FOREACH(wd->items, it)
704           {
705              if (it->selected)
706                {
707                   _item_show(it);
708                   break;
709                }
710           }
711      }
712
713    _mirrored_set(obj, elm_widget_mirrored_get(obj));
714 }
715
716 static void
717 _resize_item(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
718 {
719    _sizing_eval(data);
720    _resize(data, NULL, NULL, NULL);
721 }
722
723 static void
724 _resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
725 {
726    Widget_Data *wd = elm_widget_data_get(data);
727    if (!wd->resize_job)
728      wd->resize_job = ecore_job_add(_resize_job, data);
729 }
730
731 static void
732 _select_filter(Elm_Toolbar_Item *it, Evas_Object *obj __UNUSED__, const char *emission, const char *source __UNUSED__)
733 {
734    int button;
735    char buf[sizeof("elm,action,click,") + 1];
736
737    button = atoi(emission + sizeof("mouse,clicked,") - 1);
738    if (button == 1) return; /* regular left click event */
739    snprintf(buf, sizeof(buf), "elm,action,click,%d", button);
740    edje_object_signal_emit(VIEW(it), buf, "elm");
741 }
742
743 static void
744 _select(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
745 {
746    Elm_Toolbar_Item *it = data;
747
748    if ((_elm_config->access_mode == ELM_ACCESS_MODE_OFF) ||
749        (_elm_access_2nd_click_timeout(VIEW(it))))
750      {
751         if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
752            _elm_access_say(E_("Selected"));
753         _item_select(it);
754      }
755 }
756
757 static Eina_Bool
758 _long_press(Elm_Toolbar_Item *it)
759 {
760    Widget_Data *wd = elm_widget_data_get(WIDGET(it));
761    wd->long_timer = NULL;
762    wd->long_press = EINA_TRUE;
763    evas_object_smart_callback_call(WIDGET(it), SIG_LONGPRESSED, it);
764    return ECORE_CALLBACK_CANCEL;
765 }
766
767 static void
768 _mouse_down(Elm_Toolbar_Item *it, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, Evas_Event_Mouse_Down *ev)
769 {
770    Widget_Data *wd = elm_widget_data_get(WIDGET(it));
771    if (!wd) return;
772    if (ev->button != 1) return;
773    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
774      evas_object_smart_callback_call(WIDGET(it), SIG_CLICKED_DOUBLE, it);
775    wd->long_press = EINA_FALSE;
776    if (wd->long_timer) ecore_timer_interval_set(wd->long_timer, _elm_config->longpress_timeout);
777    else wd->long_timer = ecore_timer_add(_elm_config->longpress_timeout, (Ecore_Task_Cb)_long_press, it);
778 }
779
780 static void
781 _mouse_up(Elm_Toolbar_Item *it, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, Evas_Event_Mouse_Up *ev)
782 {
783    Widget_Data *wd = elm_widget_data_get(WIDGET(it));
784    if (!wd) return;
785    if (ev->button != 1) return;
786    if (wd->long_timer)
787      {
788         ecore_timer_del(wd->long_timer);
789         wd->long_timer = NULL;
790      }
791 }
792
793 static void
794 _mouse_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
795 {
796    Elm_Toolbar_Item *it = data;
797    edje_object_signal_emit(VIEW(it), "elm,state,highlighted", "elm");
798    elm_widget_signal_emit(it->icon, "elm,state,highlighted", "elm");
799 }
800
801 static void
802 _mouse_out(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
803 {
804    Elm_Toolbar_Item *it = data;
805    edje_object_signal_emit(VIEW(it), "elm,state,unhighlighted", "elm");
806    elm_widget_signal_emit(it->icon, "elm,state,unhighlighted", "elm");
807 }
808
809 static void
810 _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
811 {
812    Evas_Object *obj = (Evas_Object *) data;
813    Widget_Data *wd = elm_widget_data_get(obj);
814    if (!wd) return;
815    _els_box_layout(o, priv, !wd->vertical, wd->homogeneous, 
816                    elm_widget_mirrored_get(obj));
817 }
818
819 static char *
820 _access_info_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, Elm_Widget_Item *item)
821 {
822    Elm_Toolbar_Item *it = (Elm_Toolbar_Item *)item;
823    const char *txt = item->access_info;
824    if (!txt) txt = it->label;
825    if (txt) return strdup(txt);
826    return NULL;
827 }
828
829 static char *
830 _access_state_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, Elm_Widget_Item *item __UNUSED__)
831 {
832    Elm_Toolbar_Item *it = (Elm_Toolbar_Item *)item;
833    if (it->separator)
834       return strdup(E_("Separator"));
835    else if (elm_widget_item_disabled_get(it))
836       return strdup(E_("State: Disabled"));
837    else if (it->selected)
838       return strdup(E_("State: Selected"));
839    else if (it->menu)
840       return strdup(E_("Has menu"));
841    return NULL;
842 }
843
844 static Eina_Bool
845 _item_del_pre_hook(Elm_Object_Item *it)
846 {
847    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
848
849    Widget_Data *wd;
850    Evas_Object *obj2;
851    Elm_Toolbar_Item *item, *next;
852    item = (Elm_Toolbar_Item *) it;
853
854    wd = elm_widget_data_get(WIDGET(item));
855    if (!wd) return EINA_FALSE;
856
857    obj2 = WIDGET(item);
858    next = ELM_TOOLBAR_ITEM_FROM_INLIST(EINA_INLIST_GET(item)->next);
859    wd->items = eina_inlist_remove(wd->items, EINA_INLIST_GET(item));
860    wd->item_count--;
861    if (!next) next = ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items);
862    if (wd->always_select && item->selected && next) _item_select(next);
863    _item_del(item);
864    _theme_hook(obj2);
865
866    return EINA_TRUE;
867 }
868
869 static Elm_Toolbar_Item *
870 _item_new(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
871 {
872    Widget_Data *wd = elm_widget_data_get(obj);
873    Evas_Object *icon_obj;
874    Evas_Coord mw, mh;
875    Elm_Toolbar_Item *it;
876
877    icon_obj = elm_icon_add(obj);
878    elm_icon_order_lookup_set(icon_obj, wd->lookup_order);
879    if (!icon_obj) return NULL;
880    it = elm_widget_item_new(obj, Elm_Toolbar_Item);
881    if (!it)
882      {
883         evas_object_del(icon_obj);
884         return NULL;
885      }
886
887    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
888    elm_widget_item_disable_hook_set(it, _item_disable_hook);
889    elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
890    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
891
892    it->label = eina_stringshare_add(label);
893    it->prio.visible = 1;
894    it->prio.priority = 0;
895    it->func = func;
896    it->separator = EINA_FALSE;
897    it->base.data = data;
898    VIEW(it) = edje_object_add(evas_object_evas_get(obj));
899    _elm_access_item_register(&it->base, VIEW(it));
900    _elm_access_text_set(_elm_access_item_get(&it->base),
901                         ELM_ACCESS_TYPE, E_("Tool Item"));
902    _elm_access_callback_set(_elm_access_item_get(&it->base),
903                             ELM_ACCESS_INFO, _access_info_cb, it);
904    _elm_access_callback_set(_elm_access_item_get(&it->base),
905                             ELM_ACCESS_STATE, _access_state_cb, it);
906
907    if (_item_icon_set(icon_obj, "toolbar/", icon))
908      {
909         it->icon = icon_obj;
910         it->icon_str = eina_stringshare_add(icon);
911      }
912    else
913      {
914         it->icon = NULL;
915         it->icon_str = NULL;
916         evas_object_del(icon_obj);
917      }
918
919    _elm_theme_object_set(obj, VIEW(it), "toolbar", "item",
920                          elm_widget_style_get(obj));
921    edje_object_signal_callback_add(VIEW(it), "elm,action,click", "elm",
922                                    _select, it);
923    edje_object_signal_callback_add(VIEW(it), "mouse,clicked,*", "*",
924                                    (Edje_Signal_Cb)_select_filter, it);
925    edje_object_signal_callback_add(VIEW(it), "elm,mouse,in", "elm",
926                                    _mouse_in, it);
927    edje_object_signal_callback_add(VIEW(it), "elm,mouse,out", "elm",
928                                    _mouse_out, it);
929    evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_DOWN,
930                                   (Evas_Object_Event_Cb)_mouse_down, it);
931    evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_MOUSE_UP,
932                                   (Evas_Object_Event_Cb)_mouse_up, it);
933    elm_widget_sub_object_add(obj, VIEW(it));
934    if (it->icon)
935      {
936         int ms = 0;
937
938         ms = ((double)wd->icon_size * _elm_config->scale);
939         evas_object_size_hint_min_set(it->icon, ms, ms);
940         evas_object_size_hint_max_set(it->icon, ms, ms);
941         edje_object_part_swallow(VIEW(it), "elm.swallow.icon", it->icon);
942         evas_object_show(it->icon);
943         elm_widget_sub_object_add(obj, it->icon);
944      }
945    edje_object_part_text_set(VIEW(it), "elm.text", it->label);
946    mw = mh = -1;
947    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
948    edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh);
949    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
950     if (wd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
951      {
952         if (wd->vertical)
953           {
954              evas_object_size_hint_weight_set(VIEW(it), EVAS_HINT_EXPAND, -1.0);
955              evas_object_size_hint_align_set(VIEW(it), EVAS_HINT_FILL, 0.5);
956           }
957         else
958           {
959              evas_object_size_hint_weight_set(VIEW(it), -1.0, EVAS_HINT_EXPAND);
960              evas_object_size_hint_align_set(VIEW(it), 0.5, EVAS_HINT_FILL);
961           }
962      }
963    else
964      {
965         evas_object_size_hint_weight_set(VIEW(it), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
966         evas_object_size_hint_align_set(VIEW(it), EVAS_HINT_FILL, EVAS_HINT_FILL);
967      }
968    evas_object_size_hint_min_set(VIEW(it), mw, mh);
969    evas_object_size_hint_max_set(VIEW(it), -1, -1);
970    evas_object_event_callback_add(VIEW(it), EVAS_CALLBACK_RESIZE,
971                                   _resize_item, obj);
972    if ((!wd->items) && wd->always_select) _item_select(it);
973    wd->item_count++;
974    return it;
975 }
976
977 static void
978 _elm_toolbar_item_label_update(Elm_Toolbar_Item *item)
979 {
980    Evas_Coord mw = -1, mh = -1;
981    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
982    edje_object_part_text_set(VIEW(item), "elm.text", item->label);
983
984    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
985    edje_object_size_min_restricted_calc(VIEW(item), &mw, &mh, mw, mh);
986    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
987    if (wd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
988      {
989         if (wd->vertical)
990           {
991              evas_object_size_hint_weight_set(VIEW(item), EVAS_HINT_EXPAND, -1.0);
992              evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, 0.5);
993           }
994         else
995           {
996              evas_object_size_hint_weight_set(VIEW(item), -1.0, EVAS_HINT_EXPAND);
997              evas_object_size_hint_align_set(VIEW(item), 0.5, EVAS_HINT_FILL);
998           }
999      }
1000    else
1001      {
1002         evas_object_size_hint_weight_set(VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1003         evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1004      }
1005    evas_object_size_hint_min_set(VIEW(item), mw, mh);
1006 }
1007
1008 static void
1009 _elm_toolbar_item_label_set_cb (void *data, Evas_Object *obj, const char *emission, const char *source)
1010 {
1011    Elm_Toolbar_Item *item = data;
1012    _elm_toolbar_item_label_update(item);
1013    edje_object_signal_callback_del(obj, emission, source,
1014                                    _elm_toolbar_item_label_set_cb);
1015    edje_object_signal_emit (VIEW(item), "elm,state,label,reset", "elm");
1016 }
1017
1018 static void
1019 _item_label_set(Elm_Toolbar_Item *item, const char *label, const char *signal)
1020 {
1021    const char *s;
1022
1023    if ((label) && (item->label) && (!strcmp(label, item->label))) return;
1024
1025    eina_stringshare_replace(&item->label, label);
1026    s = edje_object_data_get(VIEW(item), "transition_animation_on");
1027    if ((s) && (atoi(s)))
1028      {
1029         edje_object_part_text_set(VIEW(item), "elm.text_new", item->label);
1030         edje_object_signal_emit (VIEW(item), signal, "elm");
1031         edje_object_signal_callback_add(VIEW(item),
1032                                         "elm,state,label_set,done", "elm",
1033                                         _elm_toolbar_item_label_set_cb, item);
1034      }
1035    else
1036      _elm_toolbar_item_label_update(item);
1037    _resize(WIDGET(item), NULL, NULL, NULL);
1038 }
1039
1040 static void
1041 _elm_toolbar_item_icon_update(Elm_Toolbar_Item *item)
1042 {
1043    Elm_Toolbar_Item_State *it_state;
1044    Eina_List *l;
1045    Evas_Coord mw = -1, mh = -1;
1046    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
1047    Evas_Object *old_icon = edje_object_part_swallow_get(VIEW(item),
1048                                                         "elm.swallow.icon");
1049    elm_widget_sub_object_del(VIEW(item), old_icon);
1050    evas_object_hide(old_icon);
1051    edje_object_part_swallow(VIEW(item), "elm.swallow.icon", item->icon);
1052    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1053    edje_object_size_min_restricted_calc(VIEW(item), &mw, &mh, mw, mh);
1054    elm_coords_finger_size_adjust(1, &mw, 1, &mh);
1055    if (wd->shrink_mode != ELM_TOOLBAR_SHRINK_EXPAND)
1056      {
1057         if (wd->vertical)
1058           {
1059              evas_object_size_hint_weight_set(VIEW(item), EVAS_HINT_EXPAND, -1.0);
1060              evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, 0.5);
1061           }
1062         else
1063           {
1064              evas_object_size_hint_weight_set(VIEW(item), -1.0, EVAS_HINT_EXPAND);
1065              evas_object_size_hint_align_set(VIEW(item), 0.5, EVAS_HINT_FILL);
1066           }
1067      }
1068    else
1069      {
1070         evas_object_size_hint_weight_set(VIEW(item), EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1071         evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
1072      }
1073    evas_object_size_hint_min_set(VIEW(item), mw, mh);
1074
1075    EINA_LIST_FOREACH(item->states, l, it_state)
1076      {
1077         if (it_state->icon == old_icon) return;
1078      }
1079    evas_object_del(old_icon);
1080 }
1081
1082 static void
1083 _elm_toolbar_item_icon_set_cb (void *data, Evas_Object *obj, const char *emission, const char *source)
1084 {
1085    Elm_Toolbar_Item *item = data;
1086    edje_object_part_unswallow(VIEW(item), item->icon);
1087    _elm_toolbar_item_icon_update(item);
1088    edje_object_signal_callback_del(obj, emission, source,
1089                                    _elm_toolbar_item_icon_set_cb);
1090    edje_object_signal_emit (VIEW(item), "elm,state,icon,reset", "elm");
1091 }
1092
1093 static void
1094 _elm_toolbar_item_icon_obj_set(Evas_Object *obj, Elm_Toolbar_Item *item, Evas_Object *icon_obj, const char *icon_str, double icon_size, const char *signal)
1095 {
1096    Evas_Object *old_icon;
1097    int ms = 0;
1098    const char *s;
1099
1100    if (icon_str)
1101      eina_stringshare_replace(&item->icon_str, icon_str);
1102    else
1103      {
1104         eina_stringshare_del(item->icon_str);
1105         item->icon_str = NULL;
1106      }
1107    item->icon = icon_obj;
1108    if (icon_obj)
1109      {
1110         ms = (icon_size * _elm_config->scale);
1111         evas_object_size_hint_min_set(item->icon, ms, ms);
1112         evas_object_size_hint_max_set(item->icon, ms, ms);
1113         evas_object_show(item->icon);
1114         elm_widget_sub_object_add(obj, item->icon);
1115      }
1116    s = edje_object_data_get(VIEW(item), "transition_animation_on");
1117    if ((s) && (atoi(s)))
1118      {
1119         old_icon = edje_object_part_swallow_get(VIEW(item),
1120                                                 "elm.swallow.icon_new");
1121         if (old_icon)
1122           {
1123              elm_widget_sub_object_del(VIEW(item), old_icon);
1124              evas_object_hide(old_icon);
1125           }
1126         edje_object_part_swallow(VIEW(item), "elm.swallow.icon_new",
1127                                  item->icon);
1128         edje_object_signal_emit (VIEW(item), signal, "elm");
1129         edje_object_signal_callback_add(VIEW(item),
1130                                         "elm,state,icon_set,done", "elm",
1131                                         _elm_toolbar_item_icon_set_cb, item);
1132      }
1133    else
1134      _elm_toolbar_item_icon_update(item);
1135    _resize(obj, NULL, NULL, NULL);
1136 }
1137
1138 static void
1139 _elm_toolbar_item_state_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1140 {
1141    Elm_Toolbar_Item *it = event_info;
1142    Elm_Toolbar_Item_State *it_state;
1143
1144    it_state = eina_list_data_get(it->current_state);
1145    if (it_state->func)
1146      it_state->func((void *)it_state->data, obj, event_info);
1147 }
1148
1149 static Elm_Toolbar_Item_State *
1150 _item_state_new(const char *label, const char *icon_str, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
1151 {
1152    Elm_Toolbar_Item_State *it_state;
1153    it_state = ELM_NEW(Elm_Toolbar_Item_State);
1154    it_state->label = eina_stringshare_add(label);
1155    it_state->icon_str = eina_stringshare_add(icon_str);
1156    it_state->icon = icon;
1157    it_state->func = func;
1158    it_state->data = data;
1159    return it_state;
1160 }
1161
1162 EAPI Evas_Object *
1163 elm_toolbar_add(Evas_Object *parent)
1164 {
1165    Evas_Object *obj;
1166    Evas *e;
1167    Widget_Data *wd;
1168
1169    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1170
1171    ELM_SET_WIDTYPE(widtype, "toolbar");
1172    elm_widget_type_set(obj, "toolbar");
1173    elm_widget_sub_object_add(parent, obj);
1174    elm_widget_data_set(obj, wd);
1175    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
1176    elm_widget_del_hook_set(obj, _del_hook);
1177    elm_widget_theme_hook_set(obj, _theme_hook);
1178    elm_widget_translate_hook_set(obj, _translate_hook);
1179    elm_widget_can_focus_set(obj, EINA_FALSE);
1180
1181    wd->more_item = NULL;
1182    wd->selected_item = NULL;
1183    wd->scr = elm_smart_scroller_add(e);
1184    elm_smart_scroller_widget_set(wd->scr, obj);
1185    elm_smart_scroller_object_theme_set(obj, wd->scr, "toolbar", "base", "default");
1186    elm_smart_scroller_bounce_allow_set(wd->scr,
1187                                        _elm_config->thumbscroll_bounce_enable,
1188                                        EINA_FALSE);
1189    elm_widget_resize_object_set(obj, wd->scr);
1190    elm_smart_scroller_policy_set(wd->scr,
1191                                  ELM_SMART_SCROLLER_POLICY_AUTO,
1192                                  ELM_SMART_SCROLLER_POLICY_OFF);
1193
1194
1195    wd->icon_size = _elm_toolbar_icon_size_get(wd);
1196
1197
1198    wd->homogeneous = EINA_TRUE;
1199    wd->align = 0.5;
1200
1201    wd->bx = evas_object_box_add(e);
1202    evas_object_size_hint_align_set(wd->bx, wd->align, 0.5);
1203    evas_object_box_layout_set(wd->bx, _layout, obj, NULL);
1204    elm_widget_sub_object_add(obj, wd->bx);
1205    elm_smart_scroller_child_set(wd->scr, wd->bx);
1206    evas_object_show(wd->bx);
1207
1208    elm_toolbar_shrink_mode_set(obj, _elm_config->toolbar_shrink_mode);
1209    evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE, _resize, obj);
1210    evas_object_event_callback_add(wd->bx, EVAS_CALLBACK_RESIZE, _resize, obj);
1211    elm_toolbar_icon_order_lookup_set(obj, ELM_ICON_LOOKUP_THEME_FDO);
1212
1213    evas_object_smart_callbacks_descriptions_set(obj, _signals);
1214
1215    _sizing_eval(obj);
1216    return obj;
1217 }
1218
1219 EAPI void
1220 elm_toolbar_icon_size_set(Evas_Object *obj, int icon_size)
1221 {
1222    ELM_CHECK_WIDTYPE(obj, widtype);
1223    Widget_Data *wd = elm_widget_data_get(obj);
1224    if (!wd) return;
1225    if (wd->icon_size == icon_size) return;
1226    wd->icon_size = icon_size;
1227    _theme_hook(obj);
1228 }
1229
1230 EAPI int
1231 elm_toolbar_icon_size_get(const Evas_Object *obj)
1232 {
1233    ELM_CHECK_WIDTYPE(obj, widtype) 0;
1234    Widget_Data *wd = elm_widget_data_get(obj);
1235    if (!wd) return 0;
1236    return wd->icon_size;
1237 }
1238
1239 EAPI Elm_Object_Item *
1240 elm_toolbar_item_append(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1241 {
1242    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1243    Widget_Data *wd = elm_widget_data_get(obj);
1244    if (!wd) return NULL;
1245
1246    Elm_Toolbar_Item *it = _item_new(obj, icon, label, func, data);
1247    if (!it) return NULL;
1248    double scale = (elm_widget_scale_get(obj) * _elm_config->scale);
1249
1250    wd->items = eina_inlist_append(wd->items, EINA_INLIST_GET(it));
1251    evas_object_box_append(wd->bx, VIEW(it));
1252    evas_object_show(VIEW(it));
1253
1254    _theme_hook_item(obj, it, scale, wd->icon_size);
1255    _sizing_eval(obj);
1256
1257    return (Elm_Object_Item *) it;
1258 }
1259
1260 EAPI Elm_Object_Item *
1261 elm_toolbar_item_prepend(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1262 {
1263    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1264    Widget_Data *wd = elm_widget_data_get(obj);
1265    if (!wd) return NULL;
1266
1267    Elm_Toolbar_Item *it = _item_new(obj, icon, label, func, data);
1268    if (!it) return NULL;
1269    double scale = (elm_widget_scale_get(obj) * _elm_config->scale);
1270
1271    wd->items = eina_inlist_prepend(wd->items, EINA_INLIST_GET(it));
1272    evas_object_box_prepend(wd->bx, VIEW(it));
1273    evas_object_show(VIEW(it));
1274    _theme_hook_item(obj, it, scale, wd->icon_size);
1275    _sizing_eval(obj);
1276
1277    return (Elm_Object_Item *) it;
1278 }
1279
1280 EAPI Elm_Object_Item *
1281 elm_toolbar_item_insert_before(Evas_Object *obj, Elm_Object_Item *before, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1282 {
1283    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1284    ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1285    Widget_Data *wd;
1286    Elm_Toolbar_Item *it, *_before;
1287
1288    wd = elm_widget_data_get(obj);
1289    if (!wd) return NULL;
1290    _before = (Elm_Toolbar_Item *) before;
1291    it = _item_new(obj, icon, label, func, data);
1292    if (!it) return NULL;
1293    double scale = (elm_widget_scale_get(obj) * _elm_config->scale);
1294
1295    wd->items = eina_inlist_prepend_relative(wd->items, EINA_INLIST_GET(it),
1296                                             EINA_INLIST_GET(_before));
1297    evas_object_box_insert_before(wd->bx, VIEW(it), VIEW(_before));
1298    evas_object_show(VIEW(it));
1299    _theme_hook_item(obj, it, scale, wd->icon_size);
1300    _sizing_eval(obj);
1301
1302    return (Elm_Object_Item *) it;
1303 }
1304
1305 EAPI Elm_Object_Item *
1306 elm_toolbar_item_insert_after(Evas_Object *obj, Elm_Object_Item *after, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1307 {
1308    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1309    ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1310    Widget_Data *wd;
1311    Elm_Toolbar_Item *it, *_after;
1312
1313    wd = elm_widget_data_get(obj);
1314    if (!wd) return NULL;
1315    _after = (Elm_Toolbar_Item *) after;
1316    it = _item_new(obj, icon, label, func, data);
1317    if (!it) return NULL;
1318    double scale = (elm_widget_scale_get(obj) * _elm_config->scale);
1319
1320    wd->items = eina_inlist_append_relative(wd->items, EINA_INLIST_GET(it),
1321                                            EINA_INLIST_GET(_after));
1322    evas_object_box_insert_after(wd->bx, VIEW(it), VIEW(_after));
1323    evas_object_show(VIEW(it));
1324    _theme_hook_item(obj, it, scale, wd->icon_size);
1325    _sizing_eval(obj);
1326
1327    return (Elm_Object_Item *) it;
1328 }
1329
1330 EAPI Elm_Object_Item *
1331 elm_toolbar_first_item_get(const Evas_Object *obj)
1332 {
1333    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1334    Widget_Data *wd = elm_widget_data_get(obj);
1335    if (!wd || !wd->items) return NULL;
1336    return (Elm_Object_Item *) ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items);
1337 }
1338
1339 EAPI Elm_Object_Item *
1340 elm_toolbar_last_item_get(const Evas_Object *obj)
1341 {
1342    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1343    Widget_Data *wd = elm_widget_data_get(obj);
1344    if (!wd || !wd->items) return NULL;
1345    return (Elm_Object_Item *) ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items->last);
1346 }
1347
1348 EAPI Elm_Object_Item *
1349 elm_toolbar_item_next_get(const Elm_Object_Item *it)
1350 {
1351    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1352    return (Elm_Object_Item *) ELM_TOOLBAR_ITEM_FROM_INLIST(
1353       EINA_INLIST_GET(((Elm_Toolbar_Item *) it))->next);
1354 }
1355
1356 EAPI Elm_Object_Item *
1357 elm_toolbar_item_prev_get(const Elm_Object_Item *it)
1358 {
1359    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1360    return (Elm_Object_Item *) ELM_TOOLBAR_ITEM_FROM_INLIST(
1361       EINA_INLIST_GET(((Elm_Toolbar_Item *) it))->prev);
1362 }
1363
1364 EAPI Evas_Object *
1365 elm_toolbar_item_toolbar_get(const Elm_Object_Item *it)
1366 {
1367    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1368    return elm_object_item_widget_get(it);
1369 }
1370
1371 EAPI void
1372 elm_toolbar_item_priority_set(Elm_Object_Item *it, int priority)
1373 {
1374    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1375    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1376    if (item->prio.priority == priority) return;
1377    item->prio.priority = priority;
1378    _resize(WIDGET(item), NULL, NULL, NULL);
1379 }
1380
1381 EAPI int
1382 elm_toolbar_item_priority_get(const Elm_Object_Item *it)
1383 {
1384    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, 0);
1385    return ((Elm_Toolbar_Item *) it)->prio.priority;
1386 }
1387
1388 EAPI const char *
1389 elm_toolbar_item_label_get(const Elm_Object_Item *it)
1390 {
1391    return _item_text_get_hook(it, NULL);
1392 }
1393
1394 EAPI void
1395 elm_toolbar_item_label_set(Elm_Object_Item *it, const char *label)
1396 {
1397    _item_text_set_hook(it, NULL, label);
1398 }
1399
1400 EAPI void *
1401 elm_toolbar_item_data_get(const Elm_Object_Item *it)
1402 {
1403    return elm_object_item_data_get(it);
1404 }
1405
1406 EAPI void
1407 elm_toolbar_item_data_set(Elm_Object_Item *it, const void *data)
1408 {
1409    elm_object_item_data_set(it, (void *) data);
1410 }
1411
1412 EAPI Elm_Object_Item *
1413 elm_toolbar_item_find_by_label(const Evas_Object *obj, const char *label)
1414 {
1415    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1416    Elm_Toolbar_Item *it;
1417    Widget_Data *wd = elm_widget_data_get(obj);
1418    if (!wd) return NULL;
1419
1420    EINA_INLIST_FOREACH(wd->items, it)
1421      {
1422         if (!strcmp(it->label, label))
1423           return (Elm_Object_Item *) it;
1424      }
1425    return NULL;
1426 }
1427
1428 EAPI void
1429 elm_toolbar_item_selected_set(Elm_Object_Item *it, Eina_Bool selected)
1430 {
1431    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1432    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1433    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
1434    if (!wd) return;
1435
1436    if (item->selected == selected) return;
1437    if (selected) _item_select(item);
1438    else _item_unselect(item);
1439 }
1440
1441 EAPI Eina_Bool
1442 elm_toolbar_item_selected_get(const Elm_Object_Item *it)
1443 {
1444    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1445    return ((Elm_Toolbar_Item *) it)->selected;
1446 }
1447
1448 EAPI Elm_Object_Item *
1449 elm_toolbar_selected_item_get(const Evas_Object *obj)
1450 {
1451    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1452    Widget_Data *wd = elm_widget_data_get(obj);
1453    if (!wd) return NULL;
1454    return (Elm_Object_Item *) wd->selected_item;
1455 }
1456
1457 EAPI void
1458 elm_toolbar_item_icon_set(Elm_Object_Item *it, const char *icon)
1459 {
1460    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1461
1462    Evas_Object *icon_obj;
1463    Widget_Data *wd;
1464    Evas_Object *obj;
1465    Elm_Toolbar_Item * item = (Elm_Toolbar_Item *) it;
1466
1467    obj = WIDGET(item);
1468    wd = elm_widget_data_get(obj);
1469    if (!wd) return;
1470    if ((icon) && (item->icon_str) && (!strcmp(icon, item->icon_str))) return;
1471
1472    icon_obj = elm_icon_add(obj);
1473    if (!icon_obj) return;
1474    if (_item_icon_set(icon_obj, "toolbar/", icon))
1475      _elm_toolbar_item_icon_obj_set(obj, item, icon_obj, icon, wd->icon_size,
1476                                     "elm,state,icon_set");
1477    else
1478      {
1479         _elm_toolbar_item_icon_obj_set(obj, item, NULL, NULL, 0,
1480                                        "elm,state,icon_set");
1481         evas_object_del(icon_obj);
1482      }
1483 }
1484
1485 EAPI const char *
1486 elm_toolbar_item_icon_get(const Elm_Object_Item *it)
1487 {
1488    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1489    return ((Elm_Toolbar_Item *) it)->icon_str;
1490 }
1491
1492 EAPI Evas_Object *
1493 elm_toolbar_item_object_get(const Elm_Object_Item *it)
1494 {
1495    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1496
1497    Widget_Data *wd;
1498    Evas_Object *obj;
1499    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1500
1501    obj = WIDGET(item);
1502    wd = elm_widget_data_get(obj);
1503    if (!wd) return NULL;
1504
1505    return VIEW(item);
1506 }
1507
1508 EAPI Evas_Object *
1509 elm_toolbar_item_icon_object_get(Elm_Object_Item *it)
1510 {
1511    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1512    return ((Elm_Toolbar_Item *) it)->icon;
1513 }
1514
1515 EAPI Eina_Bool
1516 elm_toolbar_item_icon_memfile_set(Elm_Object_Item *it, const void *img, size_t size, const char *format, const char *key)
1517 {
1518    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1519
1520    Evas_Object *icon_obj;
1521    Widget_Data *wd;
1522    Evas_Object *obj;
1523    Eina_Bool ret;
1524    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1525
1526    obj = WIDGET(item);
1527    wd = elm_widget_data_get(obj);
1528    if (!wd) return EINA_FALSE;
1529
1530    if (img && size)
1531      {
1532         icon_obj = _els_smart_icon_add(evas_object_evas_get(obj));
1533         evas_object_repeat_events_set(icon_obj, EINA_TRUE);
1534         ret = _els_smart_icon_memfile_set(icon_obj, img, size, format, key);
1535         if (!ret)
1536           {
1537              evas_object_del(icon_obj);
1538              return EINA_FALSE;
1539           }
1540         _elm_toolbar_item_icon_obj_set(obj, item, icon_obj, NULL, wd->icon_size,
1541                                          "elm,state,icon_set");
1542      }
1543    else
1544      _elm_toolbar_item_icon_obj_set(obj, item, NULL, NULL, 0, "elm,state,icon_set");
1545    return EINA_TRUE;
1546 }
1547
1548 EAPI Eina_Bool
1549 elm_toolbar_item_icon_file_set(Elm_Object_Item *it, const char *file, const char *key)
1550 {
1551    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1552
1553    Evas_Object *icon_obj;
1554    Widget_Data *wd;
1555    Evas_Object *obj;
1556    Eina_Bool ret;
1557    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1558
1559    obj = WIDGET(item);
1560    wd = elm_widget_data_get(obj);
1561    if (!wd) return EINA_FALSE;
1562
1563    if (file)
1564      {
1565         icon_obj = _els_smart_icon_add(evas_object_evas_get(obj));
1566         evas_object_repeat_events_set(icon_obj, EINA_TRUE);
1567         ret = _els_smart_icon_file_key_set(icon_obj, file, key);
1568         if (!ret)
1569           {
1570              evas_object_del(icon_obj);
1571              return EINA_FALSE;
1572           }
1573         _elm_toolbar_item_icon_obj_set(obj, item, icon_obj, NULL, wd->icon_size,
1574                                          "elm,state,icon_set");
1575      }
1576    else
1577      _elm_toolbar_item_icon_obj_set(obj, item, NULL, NULL, 0, "elm,state,icon_set");
1578    return EINA_TRUE;
1579 }
1580
1581 EAPI void
1582 elm_toolbar_item_del(Elm_Object_Item *it)
1583 {
1584    elm_object_item_del(it);
1585 }
1586
1587 EAPI void
1588 elm_toolbar_item_del_cb_set(Elm_Object_Item *it, Evas_Smart_Cb func)
1589 {
1590    elm_object_item_del_cb_set(it, func);
1591 }
1592
1593 EAPI Eina_Bool
1594 elm_toolbar_item_disabled_get(const Elm_Object_Item *it)
1595 {
1596    return elm_object_item_disabled_get(it);
1597 }
1598
1599 EAPI void
1600 elm_toolbar_item_disabled_set(Elm_Object_Item *it, Eina_Bool disabled)
1601 {
1602    elm_object_item_disabled_set(it, disabled);
1603 }
1604
1605 EAPI void
1606 elm_toolbar_item_separator_set(Elm_Object_Item *it, Eina_Bool separator)
1607 {
1608    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1609    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1610    Evas_Object *obj = WIDGET(item);
1611    Widget_Data *wd = elm_widget_data_get(obj);
1612    double scale;
1613    if (item->separator == separator) return;
1614    item->separator = separator;
1615    scale = (elm_widget_scale_get(obj) * _elm_config->scale);
1616    _theme_hook_item(obj, item, scale, wd->icon_size);
1617 }
1618
1619 EAPI Eina_Bool
1620 elm_toolbar_item_separator_get(const Elm_Object_Item *it)
1621 {
1622    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1623    return ((Elm_Toolbar_Item *) it)->separator;
1624 }
1625
1626 EAPI void
1627 elm_toolbar_shrink_mode_set(Evas_Object *obj, Elm_Toolbar_Shrink_Mode shrink_mode)
1628 {
1629    ELM_CHECK_WIDTYPE(obj, widtype);
1630    Widget_Data *wd = elm_widget_data_get(obj);
1631    Eina_Bool bounce;
1632
1633    if (!wd) return;
1634    wd->shrink_mode = shrink_mode;
1635    bounce = (_elm_config->thumbscroll_bounce_enable) &&
1636       (shrink_mode == ELM_TOOLBAR_SHRINK_SCROLL);
1637    elm_smart_scroller_bounce_allow_set(wd->scr, bounce, EINA_FALSE);
1638
1639    if (wd->more_item)
1640      {
1641         _item_del(wd->more_item);
1642         elm_widget_item_free(wd->more_item);
1643         wd->more_item = NULL;
1644      }
1645
1646    if (shrink_mode == ELM_TOOLBAR_SHRINK_MENU)
1647      {
1648         elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_OFF, 
1649                                       ELM_SMART_SCROLLER_POLICY_OFF);
1650         wd->more_item = _item_new(obj, "more_menu", "More", NULL, NULL);
1651      }
1652    else if (shrink_mode == ELM_TOOLBAR_SHRINK_HIDE)
1653      elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_OFF,
1654                                    ELM_SMART_SCROLLER_POLICY_OFF);
1655    else
1656      elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_AUTO,
1657                                    ELM_SMART_SCROLLER_POLICY_OFF);
1658    _sizing_eval(obj);
1659 }
1660
1661 EAPI Elm_Toolbar_Shrink_Mode
1662 elm_toolbar_shrink_mode_get(const Evas_Object *obj)
1663 {
1664    ELM_CHECK_WIDTYPE(obj, widtype) ELM_TOOLBAR_SHRINK_NONE;
1665    Widget_Data *wd = elm_widget_data_get(obj);
1666
1667    if (!wd) return ELM_TOOLBAR_SHRINK_NONE;
1668    return wd->shrink_mode;
1669 }
1670
1671 EAPI void
1672 elm_toolbar_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous)
1673 {
1674    ELM_CHECK_WIDTYPE(obj, widtype);
1675    Widget_Data *wd = elm_widget_data_get(obj);
1676
1677    if (!wd) return;
1678    wd->homogeneous = !!homogeneous;
1679    evas_object_smart_calculate(wd->bx);
1680 }
1681
1682 EAPI Eina_Bool
1683 elm_toolbar_homogeneous_get(const Evas_Object *obj)
1684 {
1685    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1686    Widget_Data *wd = elm_widget_data_get(obj);
1687
1688    if (!wd) return EINA_FALSE;
1689    return wd->homogeneous;
1690 }
1691
1692 EAPI void
1693 elm_toolbar_menu_parent_set(Evas_Object *obj, Evas_Object *parent)
1694 {
1695    Elm_Toolbar_Item *it;
1696    ELM_CHECK_WIDTYPE(obj, widtype);
1697    Widget_Data *wd = elm_widget_data_get(obj);
1698
1699    if (!wd) return;
1700    EINA_SAFETY_ON_NULL_RETURN(parent);
1701    wd->menu_parent = parent;
1702    EINA_INLIST_FOREACH(wd->items, it)
1703      {
1704         if (it->o_menu)
1705           elm_menu_parent_set(it->o_menu, wd->menu_parent);
1706      }
1707    if ((wd->more_item) && (wd->more_item->o_menu))
1708      elm_menu_parent_set(wd->more_item->o_menu, wd->menu_parent);
1709 }
1710
1711 EAPI Evas_Object *
1712 elm_toolbar_menu_parent_get(const Evas_Object *obj)
1713 {
1714    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1715    Widget_Data *wd = elm_widget_data_get(obj);
1716
1717    if (!wd) return NULL;
1718    return wd->menu_parent;
1719 }
1720
1721 EAPI void
1722 elm_toolbar_align_set(Evas_Object *obj, double align)
1723 {
1724    ELM_CHECK_WIDTYPE(obj, widtype);
1725    Widget_Data *wd = elm_widget_data_get(obj);
1726
1727    if (!wd) return;
1728    if (wd->vertical)
1729      {
1730         if (wd->align != align)
1731           evas_object_size_hint_align_set(wd->bx, 0.5, align);
1732      }
1733    else
1734      {
1735         if (wd->align != align)
1736           evas_object_size_hint_align_set(wd->bx, align, 0.5);
1737      }
1738    wd->align = align;
1739 }
1740
1741 EAPI double
1742 elm_toolbar_align_get(const Evas_Object *obj)
1743 {
1744    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
1745    Widget_Data *wd = elm_widget_data_get(obj);
1746
1747    if (!wd) return 0.0;
1748    return wd->align;
1749 }
1750
1751 EAPI void
1752 elm_toolbar_item_menu_set(Elm_Object_Item *it, Eina_Bool menu)
1753 {
1754    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1755    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1756    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
1757    if (!wd) return;
1758
1759    if (item->menu == menu) return;
1760    if (menu) _item_menu_create(wd, item);
1761    else _item_menu_destroy(item);
1762 }
1763
1764 EAPI Evas_Object *
1765 elm_toolbar_item_menu_get(const Elm_Object_Item *it)
1766 {
1767    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1768    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1769    if (!item->menu) return NULL;
1770    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
1771    if (!wd) return NULL;
1772    return item->o_menu;
1773 }
1774
1775 EAPI Elm_Toolbar_Item_State *
1776 elm_toolbar_item_state_add(Elm_Object_Item *it, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
1777 {
1778    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1779
1780    Elm_Toolbar_Item_State *it_state;
1781    Evas_Object *icon_obj;
1782    Evas_Object *obj;
1783    Widget_Data *wd;
1784    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1785    obj = WIDGET(item);
1786    wd = elm_widget_data_get(WIDGET(item));
1787    if (!wd) return NULL;
1788
1789    if (!item->states)
1790      {
1791         it_state = _item_state_new(item->label, item->icon_str, item->icon,
1792                                    item->func, item->base.data);
1793         item->states = eina_list_append(item->states, it_state);
1794         item->current_state = item->states;
1795      }
1796
1797    icon_obj = elm_icon_add(obj);
1798    elm_icon_order_lookup_set(icon_obj, wd->lookup_order);
1799    if (!icon_obj) goto error_state_add;
1800
1801    if (!_item_icon_set(icon_obj, "toolbar/", icon))
1802      {
1803         evas_object_del(icon_obj);
1804         icon_obj = NULL;
1805         icon = NULL;
1806      }
1807
1808    it_state = _item_state_new(label, icon, icon_obj, func, data);
1809    item->states = eina_list_append(item->states, it_state);
1810    item->func = _elm_toolbar_item_state_cb;
1811    item->base.data = NULL;
1812
1813    return it_state;
1814
1815 error_state_add:
1816    if (item->states && !eina_list_next(item->states))
1817      {
1818         eina_stringshare_del(item->label);
1819         eina_stringshare_del(item->icon_str);
1820         free(eina_list_data_get(item->states));
1821         eina_list_free(item->states);
1822         item->states = NULL;
1823      }
1824    return NULL;
1825 }
1826
1827 EAPI Eina_Bool
1828 elm_toolbar_item_state_del(Elm_Object_Item *it, Elm_Toolbar_Item_State *state)
1829 {
1830    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1831
1832    Eina_List *del_state;
1833    Elm_Toolbar_Item_State *it_state;
1834    Elm_Toolbar_Item *item;
1835
1836    if (!state) return EINA_FALSE;
1837
1838    item = (Elm_Toolbar_Item *) it;
1839    if (!item->states) return EINA_FALSE;
1840
1841    del_state = eina_list_data_find_list(item->states, state);
1842    if (del_state == item->states) return EINA_FALSE;
1843    if (del_state == item->current_state)
1844      elm_toolbar_item_state_unset(it);
1845
1846    eina_stringshare_del(state->label);
1847    eina_stringshare_del(state->icon_str);
1848    if (state->icon) evas_object_del(state->icon);
1849    free(state);
1850    item->states = eina_list_remove_list(item->states, del_state);
1851    if (item->states && !eina_list_next(item->states))
1852      {
1853         it_state = eina_list_data_get(item->states);
1854         item->base.data = it_state->data;
1855         item->func = it_state->func;
1856         eina_stringshare_del(it_state->label);
1857         eina_stringshare_del(it_state->icon_str);
1858         free(eina_list_data_get(item->states));
1859         eina_list_free(item->states);
1860         item->states = NULL;
1861      }
1862    return EINA_TRUE;
1863 }
1864
1865 EAPI Eina_Bool
1866 elm_toolbar_item_state_set(Elm_Object_Item *it, Elm_Toolbar_Item_State *state)
1867 {
1868    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1869
1870    Widget_Data *wd;
1871    Eina_List *next_state;
1872    Elm_Toolbar_Item_State *it_state;
1873    Evas_Object *obj;
1874    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1875
1876    obj = WIDGET(item);
1877    wd = elm_widget_data_get(obj);
1878    if (!wd) return EINA_FALSE;
1879    if (!item->states) return EINA_FALSE;
1880
1881    if (state)
1882      {
1883         next_state = eina_list_data_find_list(item->states, state);
1884         if (!next_state) return EINA_FALSE;
1885      }
1886    else
1887      next_state = item->states;
1888
1889    if (next_state == item->current_state) return EINA_TRUE;
1890
1891    it_state = eina_list_data_get(next_state);
1892    if (eina_list_data_find(item->current_state, state))
1893      {
1894         _item_label_set(item, it_state->label, "elm,state,label_set,forward");
1895         _elm_toolbar_item_icon_obj_set(obj, item, it_state->icon, it_state->icon_str,
1896                                        wd->icon_size, "elm,state,icon_set,forward");
1897      }
1898    else
1899      {
1900         _item_label_set(item, it_state->label, "elm,state,label_set,backward");
1901         _elm_toolbar_item_icon_obj_set(obj,
1902                                        item,
1903                                        it_state->icon,
1904                                        it_state->icon_str,
1905                                        wd->icon_size,
1906                                        "elm,state,icon_set,backward");
1907      }
1908    if (elm_widget_item_disabled_get(item))
1909      elm_widget_signal_emit(item->icon, "elm,state,disabled", "elm");
1910    else
1911      elm_widget_signal_emit(item->icon, "elm,state,enabled", "elm");
1912
1913    item->current_state = next_state;
1914    return EINA_TRUE;
1915 }
1916
1917 EAPI void
1918 elm_toolbar_item_state_unset(Elm_Object_Item *it)
1919 {
1920    elm_toolbar_item_state_set(it, NULL);
1921 }
1922
1923 EAPI Elm_Toolbar_Item_State *
1924 elm_toolbar_item_state_get(const Elm_Object_Item *it)
1925 {
1926    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1927    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1928
1929    if ((!item->states) || (!item->current_state)) return NULL;
1930    if (item->current_state == item->states) return NULL;
1931
1932    return eina_list_data_get(item->current_state);
1933 }
1934
1935 EAPI Elm_Toolbar_Item_State *
1936 elm_toolbar_item_state_next(Elm_Object_Item *it)
1937 {
1938    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1939
1940    Widget_Data *wd;
1941    Evas_Object *obj;
1942    Eina_List *next_state;
1943    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1944
1945    obj = WIDGET(item);
1946    wd = elm_widget_data_get(obj);
1947    if (!wd) return NULL;
1948    if (!item->states) return NULL;
1949
1950    next_state = eina_list_next(item->current_state);
1951    if (!next_state)
1952      next_state = eina_list_next(item->states);
1953    return eina_list_data_get(next_state);
1954 }
1955
1956 EAPI Elm_Toolbar_Item_State *
1957 elm_toolbar_item_state_prev(Elm_Object_Item *it)
1958 {
1959    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1960
1961    Widget_Data *wd;
1962    Evas_Object *obj;
1963    Eina_List *prev_state;
1964    Elm_Toolbar_Item *item = (Elm_Toolbar_Item *) it;
1965
1966    obj = WIDGET(item);
1967    wd = elm_widget_data_get(obj);
1968    if (!wd) return NULL;
1969    if (!item->states) return NULL;
1970
1971    prev_state = eina_list_prev(item->current_state);
1972    if ((!prev_state) || (prev_state == item->states))
1973      prev_state = eina_list_last(item->states);
1974    return eina_list_data_get(prev_state);
1975 }
1976
1977 EAPI void
1978 elm_toolbar_item_tooltip_text_set(Elm_Object_Item *it, const char *text)
1979 {
1980    elm_object_item_tooltip_text_set(it, text);
1981 }
1982
1983 EAPI void
1984 elm_toolbar_item_tooltip_content_cb_set(Elm_Object_Item *it, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
1985 {
1986    elm_object_item_tooltip_content_cb_set(it, func, data, del_cb);
1987 }
1988
1989 EAPI void
1990 elm_toolbar_item_tooltip_unset(Elm_Object_Item *it)
1991 {
1992    elm_object_item_tooltip_unset(it);
1993 }
1994
1995 EAPI void
1996 elm_toolbar_item_tooltip_style_set(Elm_Object_Item *it, const char *style)
1997 {
1998    elm_object_item_tooltip_style_set(it, style);
1999 }
2000
2001 EAPI const char *
2002 elm_toolbar_item_tooltip_style_get(const Elm_Object_Item *it)
2003 {
2004    return elm_object_item_tooltip_style_get(it);
2005 }
2006
2007 EAPI void
2008 elm_toolbar_item_cursor_set(Elm_Object_Item *it, const char *cursor)
2009 {
2010    elm_object_item_cursor_set(it, cursor);
2011 }
2012
2013 EAPI const char *
2014 elm_toolbar_item_cursor_get(const Elm_Object_Item *it)
2015 {
2016    return elm_object_item_cursor_get(it);
2017 }
2018
2019 EAPI void
2020 elm_toolbar_item_cursor_unset(Elm_Object_Item *it)
2021 {
2022    elm_object_item_cursor_unset(it);
2023 }
2024
2025 EAPI void
2026 elm_toolbar_item_cursor_style_set(Elm_Object_Item *it, const char *style)
2027 {
2028    elm_object_item_cursor_style_set(it, style);
2029 }
2030
2031 EAPI const char *
2032 elm_toolbar_item_cursor_style_get(const Elm_Object_Item *it)
2033 {
2034    return elm_object_item_cursor_style_get(it);
2035 }
2036
2037 EAPI void
2038 elm_toolbar_item_cursor_engine_only_set(Elm_Object_Item *it, Eina_Bool engine_only)
2039 {
2040    elm_object_item_cursor_engine_only_set(it, engine_only);
2041 }
2042
2043 EAPI Eina_Bool
2044 elm_toolbar_item_cursor_engine_only_get(const Elm_Object_Item *it)
2045 {
2046    return elm_object_item_cursor_engine_only_get(it);
2047 }
2048
2049 EAPI void
2050 elm_toolbar_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select)
2051 {
2052    ELM_CHECK_WIDTYPE(obj, widtype);
2053    Widget_Data *wd = elm_widget_data_get(obj);
2054    if (!wd) return;
2055    if (always_select && (!wd->always_select) && wd->items)
2056      _item_select(ELM_TOOLBAR_ITEM_FROM_INLIST(wd->items));
2057    wd->always_select = always_select;
2058 }
2059
2060 EAPI Eina_Bool
2061 elm_toolbar_always_select_mode_get(const Evas_Object *obj)
2062 {
2063    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2064    Widget_Data *wd = elm_widget_data_get(obj);
2065    if (!wd) return EINA_FALSE;
2066    return wd->always_select;
2067 }
2068
2069 EAPI void
2070 elm_toolbar_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select)
2071 {
2072    ELM_CHECK_WIDTYPE(obj, widtype);
2073    Widget_Data *wd = elm_widget_data_get(obj);
2074    if (!wd) return;
2075    wd->no_select = no_select;
2076 }
2077
2078 EAPI Eina_Bool
2079 elm_toolbar_no_select_mode_get(const Evas_Object *obj)
2080 {
2081    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2082    Widget_Data *wd = elm_widget_data_get(obj);
2083    if (!wd) return EINA_FALSE;
2084    return wd->no_select;
2085 }
2086
2087 EAPI void
2088 elm_toolbar_icon_order_lookup_set(Evas_Object *obj, Elm_Icon_Lookup_Order order)
2089 {
2090    ELM_CHECK_WIDTYPE(obj, widtype);
2091    Elm_Toolbar_Item *it;
2092    Widget_Data *wd = elm_widget_data_get(obj);
2093    if (!wd) return;
2094
2095    wd->lookup_order = order;
2096    EINA_INLIST_FOREACH(wd->items, it)
2097       elm_icon_order_lookup_set(it->icon, order);
2098    if (wd->more_item)
2099      elm_icon_order_lookup_set(wd->more_item->icon, order);
2100 }
2101
2102 EAPI Elm_Icon_Lookup_Order
2103 elm_toolbar_icon_order_lookup_get(const Evas_Object *obj)
2104 {
2105    ELM_CHECK_WIDTYPE(obj, widtype) ELM_ICON_LOOKUP_THEME_FDO;
2106    Widget_Data *wd = elm_widget_data_get(obj);
2107    if (!wd) return ELM_ICON_LOOKUP_THEME_FDO;
2108    return wd->lookup_order;
2109 }
2110
2111 EINA_DEPRECATED EAPI void
2112 elm_toolbar_orientation_set(Evas_Object *obj, Eina_Bool vertical)
2113 {
2114    elm_toolbar_horizontal_set(obj, !vertical);
2115 }
2116
2117 EINA_DEPRECATED EAPI Eina_Bool
2118 elm_toolbar_orientation_get(const Evas_Object *obj)
2119 {
2120    return !elm_toolbar_horizontal_get(obj);
2121 }
2122
2123 EAPI void
2124 elm_toolbar_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
2125 {
2126    ELM_CHECK_WIDTYPE(obj, widtype);
2127    Widget_Data *wd = elm_widget_data_get(obj);
2128    if (!wd) return;
2129    wd->vertical = !horizontal;
2130    if (wd->vertical)
2131      evas_object_size_hint_align_set(wd->bx, 0.5, wd->align);
2132    else
2133      evas_object_size_hint_align_set(wd->bx, wd->align, 0.5);
2134    _sizing_eval(obj);
2135 }
2136
2137 EAPI Eina_Bool
2138 elm_toolbar_horizontal_get(const Evas_Object *obj)
2139 {
2140    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2141    Widget_Data *wd = elm_widget_data_get(obj);
2142    if (!wd) return EINA_FALSE;
2143    return !wd->vertical;
2144 }
2145
2146 EAPI unsigned int
2147 elm_toolbar_items_count(const Evas_Object *obj)
2148 {
2149    ELM_CHECK_WIDTYPE(obj, widtype) 0;
2150    Widget_Data *wd = elm_widget_data_get(obj);
2151    if (!wd) return 0;
2152    return wd->item_count;
2153 }
2154
2155 EINA_DEPRECATED EAPI void
2156 elm_toolbar_mode_shrink_set(Evas_Object *obj, Elm_Toolbar_Shrink_Mode shrink_mode)
2157 {
2158    elm_toolbar_shrink_mode_set(obj, shrink_mode);
2159 }
2160
2161 EINA_DEPRECATED EAPI Elm_Toolbar_Shrink_Mode
2162 elm_toolbar_mode_shrink_get(const Evas_Object *obj)
2163 {
2164    return elm_toolbar_shrink_mode_get(obj);
2165 }