Ctxpopup should have been an elC from the beginning.
[platform/upstream/elementary.git] / src / lib / elc_ctxpopup.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Ctxpopup
6  *
7  * A ctxpopup is a widget that, when shown, pops up a list of items.
8  * It automatically chooses an area inside its parent object's view
9  * (set via elm_ctxpopup_add() and elm_ctxpopup_hover_parent_set()) to
10  * optimally fit into it. In the default theme, it will also point an
11  * arrow to the cursor position at the time one shows it. Ctxpopup
12  * items have a label and/or an icon. It is intended for a small
13  * number of items (hence the use of list, not genlist).
14  *
15  * Signals that you can add callbacks for are:
16  *
17  * dismissed - the hover was dismissed
18  */
19
20 typedef struct _Widget_Data Widget_Data;
21
22 struct _Elm_Ctxpopup_Item
23 {
24    Elm_Widget_Item base;
25
26    Elm_List_Item  *lptr;
27
28    const char     *label;
29    Evas_Object    *icon;
30
31    Evas_Smart_Cb   func;
32    const void     *data;
33
34    Eina_Bool       disabled : 1;
35 };
36
37 struct _Widget_Data
38 {
39    Evas_Object *hover_parent;
40    Evas_Object *list;
41    Evas_Object *target;
42    Evas_Object *hover;
43    Evas        *evas;
44
45    Eina_List   *items;
46
47    Eina_Bool    scroller_disabled : 1;
48    Eina_Bool    horizontal : 1;
49 };
50
51 static const char *widtype = NULL;
52 static void _del_hook(Evas_Object *obj);
53 static void _del_pre_hook(Evas_Object *obj);
54 static void _theme_hook(Evas_Object *obj);
55 static void _hover_clicked_cb(void        *data,
56                               Evas_Object *obj,
57                               void        *event_info);
58 static void _parent_resize_cb(void        *data,
59                               Evas        *evas,
60                               Evas_Object *obj,
61                               void        *event_info);
62 static void _ctxpopup_show(void        *data,
63                            Evas        *evas,
64                            Evas_Object *obj,
65                            void        *event_info);
66 static void _ctxpopup_hide(void        *data,
67                            Evas        *evas,
68                            Evas_Object *obj,
69                            void        *event_info);
70
71 static const char SIG_DISMISSED[] = "dismissed";
72 static const Evas_Smart_Cb_Description _signals[] = {
73    {SIG_DISMISSED, ""},
74    {NULL, NULL}
75 };
76
77 #define ELM_CTXPOPUP_ITEM_CHECK_RETURN(it, ...)                        \
78   ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
79   ELM_CHECK_WIDTYPE(item->base.widget, widtype) __VA_ARGS__;
80
81 static Elm_Ctxpopup_Item *
82 _item_new(Evas_Object  *obj,
83           const char   *label,
84           Evas_Object  *icon,
85           Evas_Smart_Cb func,
86           const void   *data)
87 {
88    Elm_Ctxpopup_Item *it;
89
90    it = elm_widget_item_new(obj, Elm_Ctxpopup_Item);
91    if (!it)
92      return NULL;
93
94    it->label = eina_stringshare_add(label);
95    it->icon = icon;
96    it->func = func;
97    it->base.data = data;
98
99    return it;
100 }
101
102 static inline void
103 _item_free(Elm_Ctxpopup_Item *it)
104 {
105    eina_stringshare_del(it->label);
106    elm_widget_item_del(it);
107 }
108
109 static void
110 _del_pre_hook(Evas_Object *obj)
111 {
112    Widget_Data *wd = elm_widget_data_get(obj);
113    if (!wd)
114      return;
115    evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_RESIZE,
116                                        _parent_resize_cb, obj);
117 }
118
119 static void
120 _del_hook(Evas_Object *obj)
121 {
122    Elm_Ctxpopup_Item *it;
123    Widget_Data *wd;
124
125    wd = elm_widget_data_get(obj);
126    if (!wd)
127      return;
128
129    EINA_LIST_FREE(wd->items, it)
130      _item_free(it);
131
132    free(wd);
133 }
134
135 static Eina_Bool
136 _event_hook(Evas_Object       *obj,
137             Evas_Object *src   __UNUSED__,
138             Evas_Callback_Type type,
139             void              *event_info)
140 {
141    if (type != EVAS_CALLBACK_KEY_DOWN)
142      return EINA_FALSE;
143
144    Evas_Event_Key_Down *ev = event_info;
145
146    Widget_Data *wd = elm_widget_data_get(obj);
147    if (!wd)
148      return EINA_FALSE;
149
150    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
151      return EINA_FALSE;
152
153    if (strcmp(ev->keyname, "Escape"))
154      return EINA_FALSE;
155
156    evas_object_hide(obj);
157    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
158    return EINA_TRUE;
159 }
160
161 static void
162 _on_focus_hook(void *data   __UNUSED__,
163                Evas_Object *obj)
164 {
165    Widget_Data *wd = elm_widget_data_get(obj);
166    if (!wd)
167      return;
168
169    if (elm_widget_focus_get(obj))
170      {
171         elm_object_signal_emit(wd->list, "elm,action,focus", "elm");
172         evas_object_focus_set(wd->list, EINA_TRUE);
173      }
174    else
175      {
176         elm_object_signal_emit(wd->list, "elm,action,unfocus", "elm");
177         evas_object_focus_set(wd->list, EINA_FALSE);
178      }
179 }
180
181 static void
182 _theme_hook(Evas_Object *obj)
183 {
184    Widget_Data *wd;
185    char buf[1024];
186
187    wd = elm_widget_data_get(obj);
188    if (!wd)
189      return;
190
191    elm_widget_style_set(wd->list, "ctxpopup");
192
193    snprintf(buf, sizeof(buf), "ctxpopup/%s", elm_widget_style_get(obj));
194    elm_object_style_set(wd->hover, buf);
195 }
196
197 static void
198 _signal_emit_hook(Evas_Object *obj,
199                   const char  *emission,
200                   const char  *source)
201 {
202    Widget_Data *wd = elm_widget_data_get(obj);
203    if (!wd) return;
204    elm_object_signal_emit(wd->list, emission, source);
205    elm_object_signal_emit(wd->hover, emission, source);
206 }
207
208 static void
209 _signal_callback_add_hook(Evas_Object *obj,
210                           const char  *emission,
211                           const char  *source,
212                           void         (*func_cb)(void *data,
213                                                   Evas_Object *o,
214                                                   const char  *emission,
215                                                   const char  *source),
216                           void        *data)
217 {
218    Widget_Data *wd = elm_widget_data_get(obj);
219    if (!wd) return;
220    elm_object_signal_callback_add(wd->list, emission, source, func_cb, data);
221    elm_object_signal_callback_add(wd->hover, emission, source, func_cb, data);
222 }
223
224 static void
225 _signal_callback_del_hook(Evas_Object *obj,
226                           const char  *emission,
227                           const char  *source,
228                           void         (*func_cb)(void *data,
229                                                   Evas_Object *o,
230                                                   const char  *emission,
231                                                   const char  *source),
232                           void   *data __UNUSED__)
233 {
234    Widget_Data *wd = elm_widget_data_get(obj);
235    elm_object_signal_callback_del(wd->list, emission, source, func_cb);
236    elm_object_signal_callback_del(wd->hover, emission, source, func_cb);
237 }
238
239 static void
240 _item_func_cb(void            *data,
241               Evas_Object *obj __UNUSED__,
242               void            *event_info)
243 {
244    Elm_Ctxpopup_Item *it;
245
246    elm_list_item_selected_set(event_info, EINA_FALSE);
247
248    it = data;
249    if (it->func)
250      it->func((void *)it->base.data, it->base.widget, it);
251 }
252
253 static void
254 _hover_clicked_cb(void            *data,
255                   Evas_Object *obj __UNUSED__,
256                   void *event_info __UNUSED__)
257 {
258    evas_object_hide(data);
259 }
260
261 void
262 _content_placement_changed_cb(void            *data,
263                               Evas_Object *obj __UNUSED__,
264                               void            *event_info)
265 {
266    const char *new_slot;
267    Widget_Data *wd;
268    char buf[1024];
269
270    wd = elm_widget_data_get(data);
271    new_slot = event_info;
272
273    snprintf(buf, sizeof(buf), "elm,action,slot,%s,show", new_slot);
274    elm_widget_signal_emit(wd->hover, buf, "elm");
275 }
276
277 static void
278 _ctxpopup_show(void *data       __UNUSED__,
279                Evas *evas       __UNUSED__,
280                Evas_Object     *obj,
281                void *event_info __UNUSED__)
282 {
283    Widget_Data *wd;
284    int px, py;
285    int w, h;
286
287    wd = elm_widget_data_get(obj);
288    if (eina_list_count(wd->items) < 1)
289      return;
290
291    elm_widget_focus_steal(obj);
292
293    evas_pointer_canvas_xy_get(wd->evas, &px, &py);
294    evas_object_geometry_get(wd->target, NULL, NULL, &w, &h);
295    evas_object_move(wd->target, px - (w / 2), py - (h / 2));
296
297    /* reset list */
298    elm_list_item_show(eina_list_data_get(elm_list_items_get(wd->list)));
299
300    evas_object_show(wd->hover);
301 }
302
303 static void
304 _ctxpopup_hide(void *data       __UNUSED__,
305                Evas *evas       __UNUSED__,
306                Evas_Object     *obj,
307                void *event_info __UNUSED__)
308 {
309    Widget_Data *wd = elm_widget_data_get(obj);
310    if (!wd)
311      return;
312
313    evas_object_hide(wd->hover);
314    evas_object_smart_callback_call(obj, SIG_DISMISSED, NULL);
315 }
316
317 static void
318 _parent_del(void            *data,
319             Evas *e          __UNUSED__,
320             Evas_Object *obj __UNUSED__,
321             void *event_info __UNUSED__)
322 {
323    Widget_Data *wd = elm_widget_data_get(data);
324    if (!wd)
325      return;
326
327    wd->hover_parent = NULL;
328 }
329
330 static void
331 _parent_resize_cb(void            *data,
332                   Evas *e          __UNUSED__,
333                   Evas_Object *obj __UNUSED__,
334                   void *event_info __UNUSED__)
335 {
336    Widget_Data *wd;
337    int w, h;
338
339    wd = elm_widget_data_get(data);
340    if (!wd)
341      return;
342
343    evas_object_geometry_get(wd->hover_parent, NULL, NULL, &w, &h);
344    evas_object_size_hint_max_set(wd->list, w * 0.666667, h / 2);
345 }
346
347 /**
348  * Add a new Ctxpopup object to the parent.
349  *
350  * @param parent Parent object
351  * @return New object or @c NULL, if it cannot be created
352  *
353  * @ingroup Ctxpopup
354  */
355 EAPI Evas_Object *
356 elm_ctxpopup_add(Evas_Object *parent)
357 {
358    Evas_Object *obj;
359    Widget_Data *wd;
360    char buf[1024];
361
362    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
363
364    wd = ELM_NEW(Widget_Data);
365    wd->evas = evas_object_evas_get(parent);
366    obj = elm_widget_add(wd->evas);
367    ELM_SET_WIDTYPE(widtype, "ctxpopup");
368    elm_widget_type_set(obj, "ctxpopup");
369    elm_widget_sub_object_add(parent, obj);
370    elm_widget_data_set(obj, wd);
371    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
372    elm_widget_can_focus_set(obj, EINA_TRUE);
373    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
374    elm_widget_del_hook_set(obj, _del_hook);
375    elm_widget_theme_hook_set(obj, _theme_hook);
376    elm_widget_event_hook_set(obj, _event_hook);
377    elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
378    elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
379    elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
380
381    wd->list = elm_list_add(obj);
382    elm_widget_style_set(wd->list, "ctxpopup");
383
384    elm_list_mode_set(wd->list, ELM_LIST_EXPAND);
385    evas_object_show(wd->list);
386
387    wd->target = elm_icon_add(obj); /* has to be an elm_widget (dummy,
388                                       in this case) because we gotta
389                                       make it work with
390                                       elm_widget_hover_object_set() */
391    evas_object_resize(wd->target, elm_finger_size_get(),
392                       elm_finger_size_get());
393    evas_object_show(wd->target);
394    evas_object_layer_set(wd->target, EVAS_LAYER_MIN);
395
396    wd->hover = elm_hover_add(obj);
397
398    snprintf(buf, sizeof(buf), "ctxpopup/%s", elm_widget_style_get(obj));
399    elm_object_style_set(wd->hover, buf);
400
401    evas_object_smart_callback_add(wd->hover, "smart,changed",
402                                   _content_placement_changed_cb, obj);
403
404    elm_ctxpopup_hover_parent_set(obj, parent);
405    elm_hover_target_set(wd->hover, wd->target);
406
407    evas_object_smart_callback_add(wd->hover, "clicked", _hover_clicked_cb, obj);
408    elm_hover_content_set(wd->hover, "smart", wd->list);
409
410    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _ctxpopup_show,
411                                   NULL);
412    evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _ctxpopup_hide,
413                                   NULL);
414
415    elm_widget_sub_object_add(obj, wd->list);
416    elm_widget_sub_object_add(obj, wd->hover);
417    elm_widget_sub_object_add(obj, wd->target);
418    evas_object_smart_callbacks_descriptions_set(obj, _signals);
419    return obj;
420 }
421
422 /**
423  * This ends the Ctxpopup's popup as if the user had clicked
424  * outside the hover.
425  *
426  * @param obj The ctxpopup object
427  *
428  * @ingroup Ctxpopup
429  */
430 EAPI void
431 elm_ctxpopup_hover_end(Evas_Object *obj)
432 {
433    ELM_CHECK_WIDTYPE(obj, widtype);
434
435    Widget_Data *wd = elm_widget_data_get(obj);
436    if (!wd)
437      return;
438
439    if (!wd->hover)
440      return;
441
442    evas_object_hide(wd->hover);
443 }
444
445 /**
446  * Get the icon object for the given ctxpopup item.
447  *
448  * @param item Ctxpopup item
449  * @return icon object or @c NULL, if the item does not have icon or
450  *         an error occurred
451  *
452  * @ingroup Ctxpopup
453  */
454 EAPI Evas_Object *
455 elm_ctxpopup_item_icon_get(const Elm_Ctxpopup_Item *item)
456 {
457    ELM_CTXPOPUP_ITEM_CHECK_RETURN(item, NULL);
458    return item->icon;
459 }
460
461 /**
462  * Sets the side icon associated with the ctxpopup item.
463  *
464  * Once the icon object is set, a previously set one will be deleted.
465  * You probably don't want, then, to have the <b>same</b> icon object
466  * set for more than one item of the list (when replacing one of its
467  * instances).
468  *
469  * @param item Ctxpopup item
470  * @param icon Icon object to be set
471  *
472  * @ingroup Ctxpopup
473  */
474 EAPI void
475 elm_ctxpopup_item_icon_set(Elm_Ctxpopup_Item *item,
476                            Evas_Object       *icon)
477 {
478    ELM_CTXPOPUP_ITEM_CHECK_RETURN(item);
479
480    Widget_Data *wd;
481
482    wd = elm_widget_data_get(item->base.widget);
483    if (!wd)
484      return;
485
486    if (item->icon)
487      {
488         evas_object_del(item->icon);
489         item->icon = NULL;
490      }
491
492    item->icon = icon;
493    elm_list_item_icon_set(item->lptr, icon);
494    elm_list_go(wd->list);
495 }
496
497 /**
498  * Get the label object for the given ctxpopup item.
499  *
500  * @param item Ctxpopup item
501  * @return label object or @c NULL, if the item does not have label or
502  *         an error occur-ed
503  *
504  * @ingroup Ctxpopup
505  */
506 EAPI const char *
507 elm_ctxpopup_item_label_get(const Elm_Ctxpopup_Item *item)
508 {
509    ELM_CTXPOPUP_ITEM_CHECK_RETURN(item, NULL);
510    return item->label;
511 }
512
513 /**
514  * (Re)set the label on the given ctxpopup item.
515  *
516  * @param obj Ctxpopup item
517  * @param label String to set as label
518  *
519  * @ingroup Ctxpopup
520  */
521 EAPI void
522 elm_ctxpopup_item_label_set(Elm_Ctxpopup_Item *item,
523                             const char        *label)
524 {
525    ELM_CTXPOPUP_ITEM_CHECK_RETURN(item);
526
527    Widget_Data *wd;
528
529    wd = elm_widget_data_get(item->base.widget);
530    if (!wd)
531      return;
532
533    if (!eina_stringshare_replace(&item->label, label))
534      return;
535
536    elm_list_item_label_set(item->lptr, label);
537    elm_list_go(wd->list);
538 }
539
540 /**
541  * Set the Ctxpopup's parent.
542  *
543  * Sets the hover's parent object (it would much probably be the
544  * window that the ctxpopup is in). See Hover objects for more
545  * information.
546  *
547  * @param obj The ctxpopup object
548  * @param parent The parent to use
549  *
550  * @note elm_ctxpopup_add() will automatically call this function
551  * with its @c parent argument.
552  *
553  * @ingroup Ctxpopup
554  */
555 EAPI void
556 elm_ctxpopup_hover_parent_set(Evas_Object *obj,
557                               Evas_Object *parent)
558 {
559    ELM_CHECK_WIDTYPE(obj, widtype);
560
561    Widget_Data *wd;
562
563    wd = elm_widget_data_get(obj);
564    if (!wd)
565      return;
566
567    EINA_SAFETY_ON_NULL_RETURN(parent);
568
569    elm_hover_parent_set(wd->hover, parent);
570
571    if (wd->hover_parent)
572      {
573         evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_DEL,
574                                             _parent_del, obj);
575         evas_object_event_callback_del_full(wd->hover_parent,
576                                             EVAS_CALLBACK_RESIZE,
577                                             _parent_resize_cb, obj);
578      }
579
580    wd->hover_parent = parent;
581    evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL,
582                                   _parent_del, obj);
583    evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_RESIZE,
584                                   _parent_resize_cb, obj);
585
586    _parent_resize_cb(obj, NULL, NULL, NULL);
587 }
588
589 /**
590  * Get the Ctxpopup's parent object.
591  *
592  * @param obj The ctxpopup object
593  * @param parent The parent to use
594  *
595  * See elm_ctxpopup_hover_parent_set() for more information.
596  *
597  * @ingroup Ctxpopup
598  */
599 EAPI Evas_Object *
600 elm_ctxpopup_hover_parent_get(const Evas_Object *obj)
601 {
602    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
603
604    Widget_Data *wd;
605
606    wd = elm_widget_data_get(obj);
607    if (!wd)
608      return NULL;
609
610    return wd->hover_parent;
611 }
612
613 /**
614  * Clear all items in the given ctxpopup object.
615  *
616  * @param obj Ctxpopup object
617  *
618  * @ingroup Ctxpopup
619  */
620 EAPI void
621 elm_ctxpopup_clear(Evas_Object *obj)
622 {
623    ELM_CHECK_WIDTYPE(obj, widtype);
624
625    Elm_Ctxpopup_Item *item;
626    Widget_Data *wd;
627
628    wd = elm_widget_data_get(obj);
629    if ((!wd) || (!wd->items))
630      return;
631
632    EINA_LIST_FREE(wd->items, item)
633      {
634         elm_list_item_del(item->lptr);
635         _item_free(item);
636      }
637
638    evas_object_hide(wd->hover);
639 }
640
641 /**
642  * Change the ctxpopup's orientation to horizontal or vertical.
643  *
644  * @param obj Ctxpopup object
645  * @param horizontal @c EINA_TRUE for horizontal mode, @c EINA_FALSE
646  *        for vertical
647  *
648  * @ingroup Ctxpopup
649  */
650 EAPI void
651 elm_ctxpopup_horizontal_set(Evas_Object *obj,
652                             Eina_Bool    horizontal)
653 {
654    ELM_CHECK_WIDTYPE(obj, widtype);
655
656    Widget_Data *wd;
657
658    wd = elm_widget_data_get(obj);
659    if (!wd)
660      return;
661
662    if (wd->horizontal == horizontal)
663      return;
664
665    wd->horizontal = horizontal;
666    elm_list_horizontal_set(wd->list, horizontal);
667 }
668
669 /**
670  * Get the value of current ctxpopup object's orientation.
671  *
672  * @param obj Ctxpopup object
673  * @return @c EINA_TRUE for horizontal mode, @c EINA_FALSE for
674  *            vertical mode (or errors)
675  *
676  * @ingroup Ctxpopup
677  */
678 EAPI Eina_Bool
679 elm_ctxpopup_horizontal_get(const Evas_Object *obj)
680 {
681    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
682
683    Widget_Data *wd;
684
685    wd = elm_widget_data_get(obj);
686    if (!wd)
687      return EINA_FALSE;
688
689    return wd->horizontal;
690 }
691
692 /**
693  * Append a new item to a ctxpopup object.
694  *
695  * @param obj Ctxpopup object
696  * @param label The label of the new item
697  * @param icon Icon to be set on new item
698  * @param func Convenience function called when item selected
699  * @param data Data passed to @p func above
700  * @return A handle to the item added or @c NULL, on errors
701  *
702  * @ingroup Ctxpopup
703  */
704 EAPI Elm_Ctxpopup_Item *
705 elm_ctxpopup_item_append(Evas_Object  *obj,
706                          const char   *label,
707                          Evas_Object  *icon,
708                          Evas_Smart_Cb func,
709                          const void   *data)
710 {
711    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
712
713    Elm_Ctxpopup_Item *item;
714    Widget_Data *wd;
715
716    wd = elm_widget_data_get(obj);
717    if (!wd)
718      return NULL;
719
720    item = _item_new(obj, label, icon, func, data);
721    if (!item)
722      return NULL;
723
724    wd->items = eina_list_append(wd->items, item);
725    item->lptr = elm_list_item_append(wd->list, label, icon, NULL,
726                                      _item_func_cb, item);
727    elm_list_go(wd->list);
728    return item;
729 }
730
731 /**
732  * Delete the given item in a ctxpopup object.
733  *
734  * @param item Ctxpopup item to be deleted
735  *
736  * @ingroup Ctxpopup
737  */
738 EAPI void
739 elm_ctxpopup_item_del(Elm_Ctxpopup_Item *item)
740 {
741    ELM_CTXPOPUP_ITEM_CHECK_RETURN(item);
742
743    Widget_Data *wd;
744
745    wd = elm_widget_data_get(item->base.widget);
746    if (!wd)
747      return;
748
749    wd->items = eina_list_remove(wd->items, item);
750
751    elm_list_item_del(item->lptr);
752    item->lptr = NULL;
753
754    if (eina_list_count(wd->items) < 1)
755      evas_object_hide(wd->hover);
756
757    _item_free(item);
758 }
759
760 /**
761  * Set the ctxpopup item's state as disabled or enabled
762  *
763  * @param item Ctxpopup item to be enabled/disabled
764  * @param disabled @c EINA_TRUE to disable it, @c EINA_FALSE to enable
765  *
766  * @ingroup Ctxpopup
767  */
768 EAPI void
769 elm_ctxpopup_item_disabled_set(Elm_Ctxpopup_Item *item,
770                                Eina_Bool          disabled)
771 {
772    ELM_CTXPOPUP_ITEM_CHECK_RETURN(item);
773
774    Widget_Data *wd;
775
776    wd = elm_widget_data_get(item->base.widget);
777    if (!wd)
778      return;
779
780    if (disabled == item->disabled)
781      return;
782
783    item->disabled = disabled;
784    elm_list_item_disabled_set(item->lptr, disabled);
785 }
786
787 /**
788  * Get the ctxpopup item's disabled/enabled state.
789  *
790  * @param item Ctxpopup item to be enabled/disabled
791  * @return @c EINA_TRUE, if disabled, @c EINA_FALSE otherwise
792  *
793  * @ingroup Ctxpopup
794  */
795 EAPI Eina_Bool
796 elm_ctxpopup_item_disabled_get(const Elm_Ctxpopup_Item *item)
797 {
798    ELM_CTXPOPUP_ITEM_CHECK_RETURN(item, EINA_FALSE);
799
800    return item->disabled;
801 }
802