Merge branch 'master' into svn_merge
[framework/uifw/elementary.git] / src / lib / elc_hoversel.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Hoversel Hoversel
6  * @ingroup Elementary
7  *
8  * A hoversel is a button that pops up a list of items (automatically
9  * choosing the direction to display) that have a lable and/or an icon to
10  * select from. It is a convenience widget to avoid the need to do all the
11  * piecing together yourself. It is intended for a small number of items in
12  * the hoversel menu (no more than 8), though is capable of many more.
13  *
14  * Signals that you can add callbacks for are:
15  *
16  * "clicked" - the user clicked the hoversel button and popped up the sel
17  * "selected" - an item in the hoversel list is selected. event_info is the item
18  * "dismissed" - the hover is dismissed
19  */
20 typedef struct _Widget_Data Widget_Data;
21
22 struct _Widget_Data
23 {
24    Evas_Object *btn, *hover;
25    Evas_Object *hover_parent;
26    Eina_List *items;
27    Eina_Bool horizontal : 1;
28    Eina_Bool expanded   : 1;
29 };
30
31 struct _Elm_Hoversel_Item
32 {
33    Elm_Widget_Item base;
34    const char *label;
35    const char *icon_file;
36    const char *icon_group;
37    Elm_Icon_Type icon_type;
38    Evas_Smart_Cb func;
39 };
40
41 static const char *widtype = NULL;
42 static void _del_pre_hook(Evas_Object *obj);
43 static void _del_hook(Evas_Object *obj);
44 static void _activate(Evas_Object *obj);
45 static void _activate_hook(Evas_Object *obj);
46 static void _disable_hook(Evas_Object *obj);
47 static void _sizing_eval(Evas_Object *obj);
48 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
49 static void _parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
50
51 static const char SIG_CLICKED[] = "clicked";
52 static const char SIG_SELECTED[] = "selected";
53 static const char SIG_DISMISSED[] = "dismissed";
54
55 static const Evas_Smart_Cb_Description _signals[] = {
56    {SIG_CLICKED, ""},
57    {SIG_SELECTED, ""},
58    {SIG_DISMISSED, ""},
59    {NULL, NULL}
60 };
61
62 static void
63 _del_pre_hook(Evas_Object *obj)
64 {
65    Elm_Hoversel_Item *item;
66    Widget_Data *wd = elm_widget_data_get(obj);
67    if (!wd) return;
68    elm_hoversel_hover_end(obj);
69    elm_hoversel_hover_parent_set(obj, NULL);
70    EINA_LIST_FREE(wd->items, item)
71      {
72         elm_widget_item_pre_notify_del(item);
73         eina_stringshare_del(item->label);
74         eina_stringshare_del(item->icon_file);
75         eina_stringshare_del(item->icon_group);
76         elm_widget_item_del(item);
77      }
78 }
79
80 static void
81 _del_hook(Evas_Object *obj)
82 {
83    Widget_Data *wd = elm_widget_data_get(obj);
84    if (!wd) return;
85    free(wd);
86 }
87
88 static void
89 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
90 {
91    Widget_Data *wd = elm_widget_data_get(obj);
92    if (!wd) return;
93    elm_widget_mirrored_set(wd->btn, rtl);
94    elm_widget_mirrored_set(wd->hover, rtl);
95 }
96
97 static void
98 _theme_hook(Evas_Object *obj)
99 {
100    Widget_Data *wd = elm_widget_data_get(obj);
101    char buf[4096];
102    if (!wd) return;
103    _elm_widget_mirrored_reload(obj);
104
105    elm_hoversel_hover_end(obj);
106    if (wd->horizontal)
107      snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj));
108    else
109      snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj));
110    elm_object_style_set(wd->btn, buf);
111    elm_object_disabled_set(wd->btn, elm_widget_disabled_get(obj));
112    _mirrored_set(obj, elm_widget_mirrored_get(obj));
113 }
114
115 static void
116 _disable_hook(Evas_Object *obj)
117 {
118    Widget_Data *wd = elm_widget_data_get(obj);
119    if (!wd) return;
120    elm_object_disabled_set(wd->btn, elm_widget_disabled_get(obj));
121 }
122
123 static void
124 _sizing_eval(Evas_Object *obj)
125 {
126    Widget_Data *wd = elm_widget_data_get(obj);
127    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
128    if (!wd) return;
129    evas_object_size_hint_min_get(wd->btn, &minw, &minh);
130    evas_object_size_hint_max_get(wd->btn, &maxw, &maxh);
131    evas_object_size_hint_min_set(obj, minw, minh);
132    evas_object_size_hint_max_set(obj, maxw, maxh);
133 }
134
135 static void
136 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
137 {
138    Widget_Data *wd = elm_widget_data_get(obj);
139    if (!wd) return;
140    if (elm_widget_focus_get(obj))
141      elm_widget_focus_steal(wd->btn);
142 }
143
144 static void
145 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
146 {
147    _sizing_eval(data);
148 }
149
150 static void
151 _hover_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
152 {
153    elm_hoversel_hover_end(data);
154 }
155
156 static void
157 _item_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
158 {
159    Elm_Hoversel_Item *item = data;
160    Evas_Object *obj2 = item->base.widget;
161
162    elm_hoversel_hover_end(obj2);
163    if (item->func) item->func((void *)item->base.data, obj2, item);
164    evas_object_smart_callback_call(obj2, SIG_SELECTED, item);
165 }
166
167 static void
168 _activate(Evas_Object *obj)
169 {
170    Widget_Data *wd = elm_widget_data_get(obj);
171    Evas_Object *bt, *bx, *ic;
172    const Eina_List *l;
173    const Elm_Hoversel_Item *item;
174    char buf[4096];
175
176    if (!wd) return;
177    if (wd->expanded)
178      {
179         elm_hoversel_hover_end(obj);
180         return;
181      }
182    wd->expanded = EINA_TRUE;
183
184    if (elm_widget_disabled_get(obj)) return;
185    wd->hover = elm_hover_add(obj);
186    elm_widget_mirrored_automatic_set(wd->hover, EINA_FALSE);
187    if (wd->horizontal)
188      snprintf(buf, sizeof(buf), "hoversel_horizontal/%s", elm_widget_style_get(obj));
189    else
190      snprintf(buf, sizeof(buf), "hoversel_vertical/%s", elm_widget_style_get(obj));
191    elm_object_style_set(wd->hover, buf);
192    evas_object_smart_callback_add(wd->hover, "clicked", _hover_clicked, obj);
193    elm_hover_parent_set(wd->hover, wd->hover_parent);
194    elm_hover_target_set(wd->hover, wd->btn);
195
196    bx = elm_box_add(wd->hover);
197    elm_widget_mirrored_automatic_set(bx, EINA_FALSE);
198    elm_box_homogeneous_set(bx, 1);
199
200    elm_box_horizontal_set(bx, wd->horizontal);
201
202    if (wd->horizontal)
203      snprintf(buf, sizeof(buf), "hoversel_horizontal_entry/%s",
204               elm_widget_style_get(obj));
205    else
206      snprintf(buf, sizeof(buf), "hoversel_vertical_entry/%s",
207               elm_widget_style_get(obj));
208    EINA_LIST_FOREACH(wd->items, l, item)
209      {
210         bt = elm_button_add(wd->hover);
211         elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
212         elm_widget_mirrored_set(bt, elm_widget_mirrored_get(obj));
213         elm_object_style_set(bt, buf);
214         elm_object_text_set(bt, item->label);
215         if (item->icon_file)
216           {
217              ic = elm_icon_add(obj);
218              elm_icon_scale_set(ic, 0, 1);
219              if (item->icon_type == ELM_ICON_FILE)
220                elm_icon_file_set(ic, item->icon_file, item->icon_group);
221              else if (item->icon_type == ELM_ICON_STANDARD)
222                elm_icon_standard_set(ic, item->icon_file);
223              elm_button_icon_set(bt, ic);
224              evas_object_show(ic);
225           }
226         evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
227         evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
228         elm_box_pack_end(bx, bt);
229         evas_object_smart_callback_add(bt, "clicked", _item_clicked, item);
230         evas_object_show(bt);
231      }
232
233    if (wd->horizontal)
234      elm_hover_content_set(wd->hover,
235                            elm_hover_best_content_location_get(wd->hover,
236                                                                ELM_HOVER_AXIS_HORIZONTAL),
237                            bx);
238    else
239      elm_hover_content_set(wd->hover,
240                            elm_hover_best_content_location_get(wd->hover,
241                                                                ELM_HOVER_AXIS_VERTICAL),
242                            bx);
243    evas_object_show(bx);
244
245    evas_object_show(wd->hover);
246    evas_object_smart_callback_call(obj, SIG_CLICKED, NULL);
247
248    //   if (wd->horizontal) evas_object_hide(wd->btn);
249 }
250
251 static void
252 _activate_hook(Evas_Object *obj)
253 {
254    _activate(obj);
255 }
256
257 static void
258 _button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
259 {
260    _activate(data);
261 }
262
263 static void
264 _parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
265 {
266    Widget_Data *wd = elm_widget_data_get(data);
267    if (!wd) return;
268    wd->hover_parent = NULL;
269 }
270
271 static void
272 _elm_hoversel_label_set(Evas_Object *obj, const char *item, const char *label)
273 {
274    ELM_CHECK_WIDTYPE(obj, widtype);
275    Widget_Data *wd = elm_widget_data_get(obj);
276    if (item && strcmp(item, "default")) return;
277    if (!wd) return;
278    elm_object_text_set(wd->btn, label);
279 }
280
281 static const char *
282 _elm_hoversel_label_get(const Evas_Object *obj, const char *item)
283 {
284    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
285    Widget_Data *wd = elm_widget_data_get(obj);
286    if (item && strcmp(item, "default")) return NULL;
287    if ((!wd) || (!wd->btn)) return NULL;
288    return elm_object_text_get(wd->btn);
289 }
290
291 /**
292  * Add a new Hoversel object
293  *
294  * @param parent The parent object
295  * @return The new object or NULL if it cannot be created
296  *
297  * @ingroup Hoversel
298  */
299 EAPI Evas_Object *
300 elm_hoversel_add(Evas_Object *parent)
301 {
302    Evas_Object *obj;
303    Evas *e;
304    Widget_Data *wd;
305
306    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
307
308    ELM_SET_WIDTYPE(widtype, "hoversel");
309    elm_widget_type_set(obj, "hoversel");
310    elm_widget_sub_object_add(parent, obj);
311    elm_widget_data_set(obj, wd);
312    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
313    elm_widget_del_hook_set(obj, _del_hook);
314    elm_widget_theme_hook_set(obj, _theme_hook);
315    elm_widget_disable_hook_set(obj, _disable_hook);
316    elm_widget_activate_hook_set(obj, _activate_hook);
317    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
318    elm_widget_can_focus_set(obj, EINA_TRUE);
319    elm_widget_text_set_hook_set(obj, _elm_hoversel_label_set);
320    elm_widget_text_get_hook_set(obj, _elm_hoversel_label_get);
321
322    wd->btn = elm_button_add(parent);
323    elm_widget_mirrored_automatic_set(wd->btn, EINA_FALSE);
324    wd->expanded = EINA_FALSE;
325    elm_widget_resize_object_set(obj, wd->btn);
326    evas_object_event_callback_add(wd->btn, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
327                                   _changed_size_hints, obj);
328    evas_object_smart_callback_add(wd->btn, "clicked", _button_clicked, obj);
329    evas_object_smart_callbacks_descriptions_set(obj, _signals);
330
331    elm_widget_sub_object_add(obj, wd->btn);
332
333    elm_hoversel_hover_parent_set(obj, parent);
334    _theme_hook(obj);
335
336    return obj;
337 }
338
339 /**
340  * Set the Hover parent
341  *
342  * Sets the hover parent object. Should probably be the window that the hoversel
343  * is in.  See Hover objects for more information.
344  *
345  * @param obj The hoversel object
346  * @param parent The parent to use
347  *
348  * @ingroup Hoversel
349  */
350 EAPI void
351 elm_hoversel_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
352 {
353    ELM_CHECK_WIDTYPE(obj, widtype);
354    Widget_Data *wd = elm_widget_data_get(obj);
355    if (!wd) return;
356    if (wd->hover_parent)
357      evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_DEL,
358                                          _parent_del, obj);
359    wd->hover_parent = parent;
360    if (wd->hover_parent)
361      evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL,
362                                     _parent_del, obj);
363 }
364
365 /**
366  * Get the Hover parent
367  *
368  * Gets the hover parent object. Should probably be the window that the hoversel
369  * is in.  See Hover objects for more information.
370  *
371  * @param obj The hoversel object
372  * @return The used parent
373  *
374  * @ingroup Hoversel
375  */
376 EAPI Evas_Object *
377 elm_hoversel_hover_parent_get(const Evas_Object *obj)
378 {
379    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
380    Widget_Data *wd = elm_widget_data_get(obj);
381    if (!wd) return NULL;
382    return wd->hover_parent;
383 }
384
385 /**
386  * Set the hoversel button label
387  *
388  * This sets the label of the button that is always visible (before it is
389  * clicked and expanded). Also see elm_object_text_set().
390  *
391  * @param obj The hoversel object
392  * @param label The label text.
393  *
394  * @ingroup Hoversel
395  */
396 EAPI void
397 elm_hoversel_label_set(Evas_Object *obj, const char *label)
398 {
399    _elm_hoversel_label_set(obj, NULL, label);
400 }
401
402 /**
403  * Get the hoversel button label
404  *
405  * @param obj The hoversel object
406  * @return The label text.
407  *
408  * @ingroup Hoversel
409  */
410 EAPI const char *
411 elm_hoversel_label_get(const Evas_Object *obj)
412 {
413    return _elm_hoversel_label_get(obj, NULL);
414 }
415
416 /**
417  * This sets the hoversel to expand horizontally.  The initial button
418  * will display horizontally regardless of this setting.
419  *
420  * @param obj The hoversel object
421  * @param horizontal If true, the hover will expand horizontally to the right.
422  *
423  * @ingroup Hoversel
424  */
425 EAPI void
426 elm_hoversel_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
427 {
428    ELM_CHECK_WIDTYPE(obj, widtype);
429    Widget_Data *wd = elm_widget_data_get(obj);
430    if (!wd) return;
431    wd->horizontal = !!horizontal;
432 }
433
434
435 /**
436  * This returns whether the hoversel is set to expand horizontally.
437  *
438  * @param obj The hoversel object
439  * @return If true, the hover will expand horizontally to the right.
440  *
441  * @ingroup Hoversel
442  */
443 EAPI Eina_Bool
444 elm_hoversel_horizontal_get(const Evas_Object *obj)
445 {
446    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
447    Widget_Data *wd = elm_widget_data_get(obj);
448    if (!wd) return EINA_FALSE;
449    return wd->horizontal;
450 }
451
452 /**
453  * Set the icon of the hoversel button
454  *
455  * Sets the icon of the button that is always visible (before it is clicked
456  * and expanded). Also see elm_button_icon_set().
457  * Once the icon object is set, a previously set one will be deleted
458  * If you want to keep that old content object, use the
459  * elm_hoversel_icon_unset() function.
460  *
461  * @param obj The hoversel object
462  * @param icon The icon object
463  *
464  * @ingroup Hoversel
465  */
466 EAPI void
467 elm_hoversel_icon_set(Evas_Object *obj, Evas_Object *icon)
468 {
469    ELM_CHECK_WIDTYPE(obj, widtype);
470    Widget_Data *wd = elm_widget_data_get(obj);
471    if (!wd) return;
472    elm_button_icon_set(wd->btn, icon);
473 }
474
475 /**
476  * Get the icon of the hoversel button
477  *
478  * Get the icon of the button that is always visible (before it is clicked
479  * and expanded). Also see elm_button_icon_get().
480  *
481  * @param obj The hoversel object
482  * @return The icon object
483  *
484  * @ingroup Hoversel
485  */
486 EAPI Evas_Object *
487 elm_hoversel_icon_get(const Evas_Object *obj)
488 {
489    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
490    Widget_Data *wd = elm_widget_data_get(obj);
491    if ((!wd) || (!wd->btn)) return NULL;
492    return elm_button_icon_get(wd->btn);
493 }
494
495 /**
496  * Get the icon of the hoversel button
497  *
498  * Unparent and return the icon of the button that is always visible
499  * (before it is clicked and expanded). Also see elm_button_icon_unset().
500  *
501  * @param obj The hoversel object
502  * @return The icon object that was being used
503  *
504  * @ingroup Hoversel
505  */
506 EAPI Evas_Object *
507 elm_hoversel_icon_unset(Evas_Object *obj)
508 {
509    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
510    Widget_Data *wd = elm_widget_data_get(obj);
511    if ((!wd) || (!wd->btn)) return NULL;
512    return elm_button_icon_unset(wd->btn);
513 }
514
515 /**
516  * This triggers the hoversel popup from code, the same as though the
517  * user clicked the button.
518  *
519  * @param obj The hoversel object
520  *
521  * @ingroup Hoversel
522  */
523 EAPI void
524 elm_hoversel_hover_begin(Evas_Object *obj)
525 {
526    ELM_CHECK_WIDTYPE(obj, widtype);
527    Widget_Data *wd = elm_widget_data_get(obj);
528    if (!wd) return;
529    if (wd->hover) return;
530    _activate(obj);
531 }
532
533 /**
534  * This ends the hoversel popup as though the user clicked outside the hover.
535  *
536  * @param obj The hoversel object
537  *
538  * @ingroup Hoversel
539  */
540 EAPI void
541 elm_hoversel_hover_end(Evas_Object *obj)
542 {
543    ELM_CHECK_WIDTYPE(obj, widtype);
544    Widget_Data *wd = elm_widget_data_get(obj);
545    if (!wd) return;
546    if (!wd->hover) return;
547    wd->expanded = EINA_FALSE;
548    evas_object_del(wd->hover);
549    wd->hover = NULL;
550    evas_object_smart_callback_call(obj, SIG_DISMISSED, NULL);
551 }
552
553 /**
554  * Returns whether the hoversel is expanded.
555  *
556  * @param obj The hoversel object
557  * @return  This will return EINA_TRUE if the hoversel
558  * is expanded or EINA_FALSE if it is not expanded.
559  *
560  * @ingroup Hoversel
561  */
562 EAPI Eina_Bool
563 elm_hoversel_expanded_get(const Evas_Object *obj)
564 {
565    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
566    Widget_Data *wd = elm_widget_data_get(obj);
567    if (!wd) return EINA_FALSE;
568    return (wd->hover) ? EINA_TRUE : EINA_FALSE;
569 }
570
571 /**
572  * This will remove all the children items from the hoversel. (should not be
573  * called while the hoversel is active; use elm_hoversel_expanded_get()
574  * to check first).
575  *
576  * @param obj The hoversel object
577  *
578  * @ingroup Hoversel
579  */
580 EAPI void
581 elm_hoversel_clear(Evas_Object *obj)
582 {
583    Elm_Hoversel_Item *item;
584    Eina_List *l, *ll;
585    ELM_CHECK_WIDTYPE(obj, widtype);
586    Widget_Data *wd = elm_widget_data_get(obj);
587    if (!wd) return;
588    EINA_LIST_FOREACH_SAFE(wd->items, l, ll, item) elm_hoversel_item_del(item);
589 }
590
591 /**
592  * Get the list of items within the given hoversel.
593  *
594  * @param obj The hoversel object
595  * @return Returns a list of Elm_Hoversel_Item*
596  *
597  * @ingroup Hoversel
598  */
599 EAPI const Eina_List *
600 elm_hoversel_items_get(const Evas_Object *obj)
601 {
602    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
603    Widget_Data *wd = elm_widget_data_get(obj);
604    if (!wd) return NULL;
605    return wd->items;
606 }
607
608 /**
609  * Add an item to the hoversel button
610  *
611  * This adds an item to the hoversel to show when it is clicked. Note: if you
612  * need to use an icon from an edje file then use elm_hoversel_item_icon_set()
613  * right after the this function, and set icon_file to NULL here.
614  *
615  * @param obj The hoversel object
616  * @param label The text label to use for the item (NULL if not desired)
617  * @param icon_file An image file path on disk to use for the icon or standard
618  * icon name (NULL if not desired)
619  * @param icon_type The icon type if relevant
620  * @param func Convenience function to call when this item is selected
621  * @param data Data to pass to item-related functions
622  * @return A handle to the item added.
623  *
624  * @ingroup Hoversel
625  */
626 EAPI Elm_Hoversel_Item *
627 elm_hoversel_item_add(Evas_Object *obj, const char *label, const char *icon_file, Elm_Icon_Type icon_type, Evas_Smart_Cb func, const void *data)
628 {
629    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
630    Widget_Data *wd = elm_widget_data_get(obj);
631    if (!wd) return NULL;
632    Elm_Hoversel_Item *item = elm_widget_item_new(obj, Elm_Hoversel_Item);
633    if (!item) return NULL;
634    wd->items = eina_list_append(wd->items, item);
635    item->label = eina_stringshare_add(label);
636    item->icon_file = eina_stringshare_add(icon_file);
637    item->icon_type = icon_type;
638    item->func = func;
639    item->base.data = data;
640    return item;
641 }
642
643 /**
644  * Delete an item from the hoversel
645  *
646  * This deletes the item from the hoversel (should not be called while the
647  * hoversel is active; use elm_hoversel_expanded_get()
648  * to check first).
649  *
650  * @param item The item to delete
651  *
652  * @ingroup Hoversel
653  */
654 EAPI void
655 elm_hoversel_item_del(Elm_Hoversel_Item *item)
656 {
657    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
658    Widget_Data *wd = elm_widget_data_get(item->base.widget);
659    if (!wd) return;
660    elm_hoversel_hover_end(item->base.widget);
661    wd->items = eina_list_remove(wd->items, item);
662    elm_widget_item_pre_notify_del(item);
663    eina_stringshare_del(item->label);
664    eina_stringshare_del(item->icon_file);
665    eina_stringshare_del(item->icon_group);
666    elm_widget_item_del(item);
667 }
668
669 /**
670  * Set the function called when an item within the hoversel
671  * is freed. That function will receive these parameters:
672  *
673  * void *item_data
674  * Evas_Object *the_item_object
675  * Elm_Hoversel_Item *the_object_struct
676  *
677  * @param item The item to set the callback on
678  * @param func The function called
679  *
680  * @ingroup Hoversel
681  */
682 EAPI void
683 elm_hoversel_item_del_cb_set(Elm_Hoversel_Item *item, Evas_Smart_Cb func)
684 {
685    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
686    elm_widget_item_del_cb_set(item, func);
687 }
688
689 /**
690  * This returns the data pointer supplied with elm_hoversel_item_add() that
691  * will be passed to associated function callbacks.
692  *
693  * @param item The item to get the data from
694  * @return The data pointer set with elm_hoversel_item_add()
695  *
696  * @ingroup Hoversel
697  */
698 EAPI void *
699 elm_hoversel_item_data_get(const Elm_Hoversel_Item *item)
700 {
701    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
702    return elm_widget_item_data_get(item);
703 }
704
705 /**
706  * This returns the label text of the given hoversel item.
707  *
708  * @param item The item to get the label
709  * @return The label text of the hoversel item
710  *
711  * @ingroup Hoversel
712  */
713 EAPI const char *
714 elm_hoversel_item_label_get(const Elm_Hoversel_Item *item)
715 {
716    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
717    return item->label;
718 }
719
720 /**
721  * This sets the icon for the given hoversel item. The icon can be loaded from
722  * the standard set, from an image file, or from an edje file.
723  *
724  * @param item The item to set the icon
725  * @param icon_file An image file path on disk to use for the icon or standard
726  * icon name
727  * @param icon_group The edje group to use if @p icon_file is an edje file. Set this
728  * to NULL if the icon is not an edje file
729  * @param icon_type The icon type
730  *
731  * @ingroup Hoversel
732  */
733 EAPI void
734 elm_hoversel_item_icon_set(Elm_Hoversel_Item *item, const char *icon_file, const char *icon_group, Elm_Icon_Type icon_type)
735 {
736    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
737    eina_stringshare_replace(&item->icon_file, icon_file);
738    eina_stringshare_replace(&item->icon_group, icon_group);
739    item->icon_type = icon_type;
740 }
741
742 /**
743  * Get the icon object of the hoversel item
744  *
745  * @param item The item to get the icon from
746  * @param icon_file The image file path on disk used for the icon or standard
747  * icon name
748  * @param icon_group The edje group used if @p icon_file is an edje file. NULL
749  * if the icon is not an edje file
750  * @param icon_type The icon type
751  *
752  * @ingroup Hoversel
753  */
754 EAPI void
755 elm_hoversel_item_icon_get(const Elm_Hoversel_Item *item, const char **icon_file, const char **icon_group, Elm_Icon_Type *icon_type)
756 {
757    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
758    if (icon_file) *icon_file = item->icon_file;
759    if (icon_group) *icon_group = item->icon_group;
760    if (icon_type) *icon_type = item->icon_type;
761 }
762