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