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