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