2 # include "elementary_config.h"
5 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6 #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
7 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
9 #define ELM_WIDGET_ITEM_PROTECTED
10 #include <Elementary.h>
13 //TIZEN_ONLY(20160412): fix 'more' style size problem
14 #include "elm_interface_scrollable.h"
16 #include "elm_widget_ctxpopup.h"
18 #define MY_CLASS ELM_CTXPOPUP_CLASS
20 #define MY_CLASS_NAME "Elm_Ctxpopup"
21 #define MY_CLASS_NAME_LEGACY "elm_ctxpopup"
23 #define ELM_PRIV_CTXPOPUP_SIGNALS(cmd) \
24 cmd(SIG_DISMISSED, "dismissed", "") \
26 ELM_PRIV_CTXPOPUP_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
28 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
29 ELM_PRIV_CTXPOPUP_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
30 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
31 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
32 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
33 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
36 #undef ELM_PRIV_CTXPOPUP_SIGNALS
38 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
39 static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
41 static const Elm_Action key_actions[] = {
42 {"move", _key_action_move},
43 {"escape", _key_action_escape},
47 EOLIAN static Eina_Bool
48 _elm_ctxpopup_elm_widget_translate(Eo *obj, Elm_Ctxpopup_Data *sd)
53 if (sd->auto_hide) evas_object_hide(obj);
55 EINA_LIST_FOREACH(sd->items, l, it)
56 eo_do(it, elm_wdg_item_translate());
58 eo_do_super(obj, MY_CLASS, elm_obj_widget_translate());
63 EOLIAN static Eina_Bool
64 _elm_ctxpopup_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *_pd EINA_UNUSED)
69 EOLIAN static Eina_Bool
70 _elm_ctxpopup_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *_pd EINA_UNUSED)
75 EOLIAN static Eina_Bool
76 _elm_ctxpopup_elm_widget_focus_next(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
81 if (!elm_widget_focus_next_get(sd->box, dir, next, next_item))
83 elm_widget_focused_object_clear(sd->box);
84 elm_widget_focus_next_get(sd->box, dir, next, next_item);
90 EOLIAN static Eina_Bool
91 _elm_ctxpopup_elm_widget_focus_direction(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd, const Evas_Object *base, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
96 void *(*list_data_get)(const Eina_List *list);
101 list_data_get = eina_list_data_get;
103 l = eina_list_append(l, sd->box);
105 int_ret = elm_widget_focus_list_direction_get
106 (obj, base, l, list_data_get, degree, direction, direction_item, weight);
113 _key_action_move(Evas_Object *obj, const char *params)
115 ELM_CTXPOPUP_DATA_GET(obj, sd);
116 const char *dir = params;
118 if (!sd->box) return EINA_FALSE;
120 _elm_widget_focus_auto_show(obj);
121 if (!strcmp(dir, "previous"))
122 elm_widget_focus_cycle(sd->box, ELM_FOCUS_PREVIOUS);
123 else if (!strcmp(dir, "next"))
124 elm_widget_focus_cycle(sd->box, ELM_FOCUS_NEXT);
125 else if (!strcmp(dir, "left"))
126 elm_widget_focus_cycle(sd->box, ELM_FOCUS_LEFT);
127 else if (!strcmp(dir, "right"))
128 elm_widget_focus_cycle(sd->box, ELM_FOCUS_RIGHT);
129 else if (!strcmp(dir, "up"))
130 elm_widget_focus_cycle(sd->box, ELM_FOCUS_UP);
131 else if (!strcmp(dir, "down"))
132 elm_widget_focus_cycle(sd->box, ELM_FOCUS_DOWN);
133 else return EINA_FALSE;
139 _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
141 elm_ctxpopup_dismiss(obj);
145 EOLIAN static Eina_Bool
146 _elm_ctxpopup_elm_widget_event(Eo *obj, Elm_Ctxpopup_Data *sd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
148 Evas_Event_Key_Down *ev = event_info;
151 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
152 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
154 if (!_elm_config_key_binding_call(obj, ev, key_actions))
157 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
162 _x_pos_adjust(Evas_Coord_Point *pos,
163 Evas_Coord_Point *base_size,
164 Evas_Coord_Rectangle *hover_area)
166 pos->x -= (base_size->x / 2);
168 if (pos->x < hover_area->x)
169 pos->x = hover_area->x;
170 else if ((pos->x + base_size->x) > (hover_area->x + hover_area->w))
171 pos->x = (hover_area->x + hover_area->w) - base_size->x;
173 if (base_size->x > hover_area->w)
174 base_size->x -= (base_size->x - hover_area->w);
176 if (pos->x < hover_area->x)
177 pos->x = hover_area->x;
181 _y_pos_adjust(Evas_Coord_Point *pos,
182 Evas_Coord_Point *base_size,
183 Evas_Coord_Rectangle *hover_area)
185 pos->y -= (base_size->y / 2);
187 if (pos->y < hover_area->y)
188 pos->y = hover_area->y;
189 else if ((pos->y + base_size->y) > (hover_area->y + hover_area->h))
190 pos->y = hover_area->y + hover_area->h - base_size->y;
192 if (base_size->y > hover_area->h)
193 base_size->y -= (base_size->y - hover_area->h);
195 if (pos->y < hover_area->y)
196 pos->y = hover_area->y;
199 static Elm_Ctxpopup_Direction
200 _base_geometry_calc(Evas_Object *obj,
201 Evas_Coord_Rectangle *rect)
203 Elm_Ctxpopup_Direction dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
204 Evas_Coord_Rectangle hover_area;
205 Evas_Coord_Point pos = {0, 0};
206 Evas_Coord_Point arrow_size;
207 Evas_Coord_Point base_size;
208 Evas_Coord_Point max_size;
209 Evas_Coord_Point min_size;
210 Evas_Coord_Point temp;
211 //TIZEN_ONLY(20160412): fix 'more' style size problem
214 const char *str = NULL;
218 ELM_CTXPOPUP_DATA_GET(obj, sd);
219 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, ELM_CTXPOPUP_DIRECTION_DOWN);
221 if (!rect || !sd->parent) return ELM_CTXPOPUP_DIRECTION_DOWN;
223 edje_object_part_geometry_get(sd->arrow, "base", NULL, NULL,
224 &arrow_size.x, &arrow_size.y);
225 evas_object_resize(sd->arrow, arrow_size.x, arrow_size.y);
227 //Initialize Area Rectangle.
228 evas_object_geometry_get
229 (sd->parent, &hover_area.x, &hover_area.y, &hover_area.w,
231 if (sd->parent && eo_isa(sd->parent, ELM_WIN_CLASS))
232 hover_area.x = hover_area.y = 0;
234 evas_object_geometry_get(obj, &pos.x, &pos.y, NULL, NULL);
237 edje_object_size_min_calc
238 (wd->resize_obj, &base_size.x, &base_size.y);
239 evas_object_smart_calculate(wd->resize_obj);
242 evas_object_size_hint_max_get(obj, &max_size.x, &max_size.y);
244 //TIZEN_ONLY(20160412): fix 'more' style size problem
245 if (sd->list && sd->list_visible)
247 eo_do(sd->list, elm_interface_scrollable_content_size_get(NULL, &scrh));
248 if (base_size.y < scrh)
253 if ((max_size.y > 0) && (base_size.y > max_size.y))
254 base_size.y = max_size.y;
256 if ((max_size.x > 0) && (base_size.x > max_size.x))
257 base_size.x = max_size.x;
259 //TIZEN_ONLY(20160412): fix 'more' style size problem
260 if ((wd->orient_mode == 90) || (wd->orient_mode == 270))
261 str = edje_object_data_get(elm_layout_edje_get(obj), "visible_landscape_maxh");
263 if (!str) str = edje_object_data_get(elm_layout_edje_get(obj), "visible_maxh");
265 if (str) maxh = (int)(atoi(str)
266 * elm_config_scale_get() * elm_object_scale_get(obj)
267 / edje_object_base_scale_get(elm_layout_edje_get(obj)));
269 if ((maxh > 0) && (base_size.y > maxh))
274 evas_object_size_hint_min_get(obj, &min_size.x, &min_size.y);
276 //TIZEN_ONLY(20160412): fix 'more' style size problem
277 if ((min_size.y > 0) && (min_size.y > maxh))
281 if ((min_size.y > 0) && (base_size.y < min_size.y))
282 base_size.y = min_size.y;
284 if ((min_size.x > 0) && (base_size.x < min_size.x))
285 base_size.x = min_size.x;
287 //Check available directions. If there is one, it adjusts ctxpopup's position
289 for (idx = 0; idx < 4; idx++)
291 switch (sd->dir_priority[idx])
293 case ELM_CTXPOPUP_DIRECTION_UP:
294 temp.y = (pos.y - base_size.y);
295 if ((temp.y - arrow_size.y) < hover_area.y)
298 _x_pos_adjust(&pos, &base_size, &hover_area);
299 pos.y -= base_size.y;
300 dir = ELM_CTXPOPUP_DIRECTION_UP;
303 case ELM_CTXPOPUP_DIRECTION_LEFT:
304 temp.x = (pos.x - base_size.x);
305 if ((temp.x - arrow_size.x) < hover_area.x)
308 _y_pos_adjust(&pos, &base_size, &hover_area);
309 pos.x -= base_size.x;
310 dir = ELM_CTXPOPUP_DIRECTION_LEFT;
313 case ELM_CTXPOPUP_DIRECTION_RIGHT:
314 temp.x = (pos.x + base_size.x);
315 if ((temp.x + arrow_size.x) >
316 (hover_area.x + hover_area.w))
319 _y_pos_adjust(&pos, &base_size, &hover_area);
320 dir = ELM_CTXPOPUP_DIRECTION_RIGHT;
323 case ELM_CTXPOPUP_DIRECTION_DOWN:
324 temp.y = (pos.y + base_size.y);
325 if ((temp.y + arrow_size.y) >
326 (hover_area.y + hover_area.h))
329 _x_pos_adjust(&pos, &base_size, &hover_area);
330 dir = ELM_CTXPOPUP_DIRECTION_DOWN;
339 //In this case, all directions are invalid because of lack of space.
342 Evas_Coord length[2];
346 length[0] = pos.y - hover_area.y;
347 length[1] = (hover_area.y + hover_area.h) - pos.y;
349 // ELM_CTXPOPUP_DIRECTION_UP
350 if (length[0] > length[1])
352 _x_pos_adjust(&pos, &base_size, &hover_area);
353 pos.y -= base_size.y;
354 dir = ELM_CTXPOPUP_DIRECTION_UP;
355 if (pos.y < (hover_area.y + arrow_size.y))
357 base_size.y -= ((hover_area.y + arrow_size.y) - pos.y);
358 pos.y = hover_area.y + arrow_size.y;
361 //ELM_CTXPOPUP_DIRECTION_DOWN
364 _x_pos_adjust(&pos, &base_size, &hover_area);
365 dir = ELM_CTXPOPUP_DIRECTION_DOWN;
366 if ((pos.y + arrow_size.y + base_size.y) >
367 (hover_area.y + hover_area.h))
369 ((pos.y + arrow_size.y + base_size.y) -
370 (hover_area.y + hover_area.h));
375 length[0] = pos.x - hover_area.x;
376 length[1] = (hover_area.x + hover_area.w) - pos.x;
378 //ELM_CTXPOPUP_DIRECTION_LEFT
379 if (length[0] > length[1])
381 _y_pos_adjust(&pos, &base_size, &hover_area);
382 pos.x -= base_size.x;
383 dir = ELM_CTXPOPUP_DIRECTION_LEFT;
384 if (pos.x < (hover_area.x + arrow_size.x))
386 base_size.x -= ((hover_area.x + arrow_size.x) - pos.x);
387 pos.x = hover_area.x + arrow_size.x;
390 //ELM_CTXPOPUP_DIRECTION_RIGHT
393 _y_pos_adjust(&pos, &base_size, &hover_area);
394 dir = ELM_CTXPOPUP_DIRECTION_RIGHT;
395 if (pos.x + (arrow_size.x + base_size.x) >
396 hover_area.x + hover_area.w)
398 ((pos.x + arrow_size.x + base_size.x) -
399 (hover_area.x + hover_area.w));
404 //Final position and size.
407 rect->w = base_size.x;
408 rect->h = base_size.y;
414 _arrow_update(Evas_Object *obj,
415 Elm_Ctxpopup_Direction dir,
416 Evas_Coord_Rectangle base_size)
418 Evas_Coord_Rectangle arrow_size;
422 ELM_CTXPOPUP_DATA_GET(obj, sd);
423 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
425 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
426 evas_object_geometry_get
427 (sd->arrow, NULL, NULL, &arrow_size.w, &arrow_size.h);
429 /* arrow is not being kept as sub-object on purpose, here. the
430 * design of the widget does not help with the contrary */
434 case ELM_CTXPOPUP_DIRECTION_RIGHT:
435 edje_object_signal_emit(sd->arrow, "elm,state,left", "elm");
436 if (!edje_object_part_swallow(wd->resize_obj,
437 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_right" :
438 "elm.swallow.arrow_left"), sd->arrow))
440 evas_object_hide(sd->arrow);
446 if (y < ((arrow_size.h * 0.5) + base_size.y))
448 else if (y > base_size.y + base_size.h - (arrow_size.h * 0.5))
449 y = base_size.h - arrow_size.h;
451 y = y - base_size.y - (arrow_size.h * 0.5);
452 drag = (double)(y) / (double)(base_size.h - arrow_size.h);
453 edje_object_part_drag_value_set
455 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_right" :
456 "elm.swallow.arrow_left"), 1, drag);
460 case ELM_CTXPOPUP_DIRECTION_LEFT:
461 edje_object_signal_emit(sd->arrow, "elm,state,right", "elm");
462 if (!edje_object_part_swallow(wd->resize_obj,
463 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_left" :
464 "elm.swallow.arrow_right"), sd->arrow))
466 evas_object_hide(sd->arrow);
472 if (y < ((arrow_size.h * 0.5) + base_size.y))
474 else if (y > (base_size.y + base_size.h - (arrow_size.h * 0.5)))
475 y = base_size.h - arrow_size.h;
477 y = y - base_size.y - (arrow_size.h * 0.5);
478 drag = (double)(y) / (double)(base_size.h - arrow_size.h);
479 edje_object_part_drag_value_set
481 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_left" :
482 "elm.swallow.arrow_right"), 0, drag);
486 case ELM_CTXPOPUP_DIRECTION_DOWN:
487 edje_object_signal_emit(sd->arrow, "elm,state,top", "elm");
488 if (!edje_object_part_swallow(wd->resize_obj, "elm.swallow.arrow_up", sd->arrow))
490 evas_object_hide(sd->arrow);
496 if (x < ((arrow_size.w * 0.5) + base_size.x))
498 else if (x > (base_size.x + base_size.w - (arrow_size.w * 0.5)))
499 x = base_size.w - arrow_size.w;
501 x = x - base_size.x - (arrow_size.w * 0.5);
502 drag = (double)(x) / (double)(base_size.w - arrow_size.w);
503 edje_object_part_drag_value_set
504 (wd->resize_obj, "elm.swallow.arrow_up", drag,
509 case ELM_CTXPOPUP_DIRECTION_UP:
510 edje_object_signal_emit(sd->arrow, "elm,state,bottom", "elm");
511 if (!edje_object_part_swallow(wd->resize_obj, "elm.swallow.arrow_down", sd->arrow))
513 evas_object_hide(sd->arrow);
519 if (x < ((arrow_size.w * 0.5) + base_size.x))
521 else if (x > (base_size.x + base_size.w - (arrow_size.w * 0.5)))
522 x = base_size.w - arrow_size.w;
523 else x = x - base_size.x - (arrow_size.w * 0.5);
524 drag = (double)(x) / (double)(base_size.w - arrow_size.w);
525 edje_object_part_drag_value_set
526 (wd->resize_obj, "elm.swallow.arrow_down",
535 //should be here for getting accurate geometry value
536 evas_object_smart_calculate(wd->resize_obj);
540 _show_signals_emit(Evas_Object *obj,
541 Elm_Ctxpopup_Direction dir)
543 ELM_CTXPOPUP_DATA_GET(obj, sd);
545 if (!sd->visible) return;
546 if ((sd->list) && (!sd->list_visible)) return;
547 if (sd->emitted) return;
549 sd->emitted = EINA_TRUE;
552 case ELM_CTXPOPUP_DIRECTION_UP:
553 elm_layout_signal_emit(obj, "elm,state,show,up", "elm");
556 case ELM_CTXPOPUP_DIRECTION_LEFT:
557 elm_layout_signal_emit(obj,
558 (elm_widget_mirrored_get(obj) ? "elm,state,show,right" :
559 "elm,state,show,left"), "elm");
562 case ELM_CTXPOPUP_DIRECTION_RIGHT:
563 elm_layout_signal_emit(obj,
564 (elm_widget_mirrored_get(obj) ? "elm,state,show,left" :
565 "elm,state,show,right"), "elm");
568 case ELM_CTXPOPUP_DIRECTION_DOWN:
569 elm_layout_signal_emit(obj, "elm,state,show,down", "elm");
576 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
577 elm_layout_signal_emit(obj, "elm,state,show", "elm");
581 _hide_signals_emit(Evas_Object *obj,
582 Elm_Ctxpopup_Direction dir)
584 ELM_CTXPOPUP_DATA_GET(obj, sd);
586 if (!sd->visible) return;
590 case ELM_CTXPOPUP_DIRECTION_UP:
591 elm_layout_signal_emit(obj, "elm,state,hide,up", "elm");
594 case ELM_CTXPOPUP_DIRECTION_LEFT:
595 elm_layout_signal_emit(obj,
596 (elm_widget_mirrored_get(obj) ? "elm,state,hide,right" :
597 "elm,state,hide,left"), "elm");
600 case ELM_CTXPOPUP_DIRECTION_RIGHT:
601 elm_layout_signal_emit(obj,
602 (elm_widget_mirrored_get(obj) ? "elm,state,hide,left" :
603 "elm,state,hide,right"), "elm");
606 case ELM_CTXPOPUP_DIRECTION_DOWN:
607 elm_layout_signal_emit(obj, "elm,state,hide,down", "elm");
613 edje_object_signal_emit(sd->bg, "elm,state,hide", "elm");
614 elm_layout_signal_emit(obj, "elm,state,hide", "elm");
618 _base_shift_by_arrow(Evas_Object *arrow,
619 Elm_Ctxpopup_Direction dir,
620 Evas_Coord_Rectangle *rect)
622 Evas_Coord arrow_w, arrow_h;
624 evas_object_geometry_get(arrow, NULL, NULL, &arrow_w, &arrow_h);
627 case ELM_CTXPOPUP_DIRECTION_RIGHT:
631 case ELM_CTXPOPUP_DIRECTION_LEFT:
635 case ELM_CTXPOPUP_DIRECTION_DOWN:
639 case ELM_CTXPOPUP_DIRECTION_UP:
648 EOLIAN static Eina_Bool
649 _elm_ctxpopup_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *_pd EINA_UNUSED)
654 EOLIAN static Eina_Bool
655 _elm_ctxpopup_elm_widget_sub_object_add(Eo *obj, Elm_Ctxpopup_Data *_pd EINA_UNUSED, Evas_Object *sobj)
657 Eina_Bool int_ret = EINA_FALSE;
659 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
665 _elm_ctxpopup_elm_layout_sizing_eval(Eo *obj, Elm_Ctxpopup_Data *sd)
667 Evas_Coord_Rectangle rect = { 0, 0, 1, 1 };
668 Evas_Coord_Point list_size = { 0, 0 }, parent_size = {0, 0};
670 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
672 if (!sd->arrow) return; /* simple way to flag "under deletion" */
673 if (!sd->parent) return; /* do not calculate sizes unless parent is set */
676 sd->dir = _base_geometry_calc(obj, &rect);
678 _arrow_update(obj, sd->dir, rect);
680 _base_shift_by_arrow(sd->arrow, sd->dir, &rect);
682 if ((sd->list) && (sd->list_visible))
684 evas_object_geometry_get(sd->list, 0, 0, &list_size.x, &list_size.y);
685 if ((list_size.x >= rect.w) || (list_size.y >= rect.h))
687 elm_list_mode_set(sd->list, ELM_LIST_COMPRESS);
688 evas_object_size_hint_min_set(obj, list_size.x, list_size.y);
691 Decrease height of main object initiate recalc of size (sizing_eval).
692 At each iteration of calculating size height of the object
693 will be closer to the height of the list.
695 if (list_size.y < rect.h) rect.h--;
697 else if (sd->content)
699 evas_object_geometry_get(sd->content, 0, 0, &list_size.x, &list_size.y);
700 if ((list_size.x >= rect.w) || (list_size.y >= rect.h))
701 evas_object_size_hint_min_set(obj, list_size.x, list_size.y);
704 evas_object_geometry_get(sd->parent, NULL, NULL, &parent_size.x, &parent_size.y);
705 evas_object_resize(sd->bg, parent_size.x, parent_size.y);
707 evas_object_move(wd->resize_obj, rect.x, rect.y);
708 evas_object_resize(wd->resize_obj, rect.w, rect.h);
710 _show_signals_emit(obj, sd->dir);
714 _on_parent_del(void *data,
716 Evas_Object *obj EINA_UNUSED,
717 void *event_info EINA_UNUSED)
719 evas_object_del(data);
723 _on_parent_move(void *data,
725 Evas_Object *obj EINA_UNUSED,
726 void *event_info EINA_UNUSED)
728 ELM_CTXPOPUP_DATA_GET(data, sd);
730 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
732 if (sd->visible) elm_layout_sizing_eval(data);
736 _on_parent_resize(void *data,
738 Evas_Object *obj EINA_UNUSED,
739 void *event_info EINA_UNUSED)
741 ELM_CTXPOPUP_DATA_GET(data, sd);
745 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
747 evas_object_hide(data);
748 eo_do(data, eo_event_callback_call(ELM_CTXPOPUP_EVENT_DISMISSED, NULL));
753 elm_layout_sizing_eval(data);
758 _parent_detach(Evas_Object *obj)
760 ELM_CTXPOPUP_DATA_GET(obj, sd);
762 if (!sd->parent) return;
764 evas_object_event_callback_del_full
765 (sd->parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
766 evas_object_event_callback_del_full
767 (sd->parent, EVAS_CALLBACK_MOVE, _on_parent_move, obj);
768 evas_object_event_callback_del_full
769 (sd->parent, EVAS_CALLBACK_RESIZE, _on_parent_resize, obj);
773 _on_content_resized(void *data,
775 Evas_Object *obj EINA_UNUSED,
776 void *event_info EINA_UNUSED)
778 ELM_CTXPOPUP_DATA_GET(data, sd);
780 elm_box_recalculate(sd->box);
781 elm_layout_sizing_eval(data);
784 //FIXME: lost the content size when theme hook is called.
785 EOLIAN static Elm_Theme_Apply
786 _elm_ctxpopup_elm_widget_theme_apply(Eo *obj, Elm_Ctxpopup_Data *sd)
788 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
790 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
791 if (!int_ret) return ELM_THEME_APPLY_FAILED;
793 elm_widget_theme_object_set
794 (obj, sd->bg, "ctxpopup", "bg", elm_widget_style_get(obj));
795 elm_widget_theme_object_set
796 (obj, sd->arrow, "ctxpopup", "arrow", elm_widget_style_get(obj));
800 if (!strncmp(elm_object_style_get(obj), "default", strlen("default")))
801 elm_object_style_set(sd->list, "ctxpopup");
803 elm_object_style_set(sd->list, elm_object_style_get(obj));
806 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
808 if (sd->visible) elm_layout_sizing_eval(obj);
813 /* kind of a big and tricky override here: an internal box will hold
814 * the actual content. content aliases won't be of much help here */
815 EOLIAN static Eina_Bool
816 _elm_ctxpopup_elm_container_content_set(Eo *obj, Elm_Ctxpopup_Data *sd, const char *part, Evas_Object *content)
818 Eina_Bool int_ret = EINA_TRUE;
820 if ((part) && (strcmp(part, "default")))
822 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_container_content_set(part, content));
826 if (!content) return EINA_FALSE;
828 if (content == sd->content) return EINA_TRUE;
830 evas_object_del(sd->content);
831 if (sd->content == sd->list) sd->list = NULL;
833 evas_object_size_hint_weight_set
834 (content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
835 evas_object_size_hint_fill_set
836 (content, EVAS_HINT_FILL, EVAS_HINT_FILL);
838 elm_box_pack_end(sd->box, content);
839 evas_object_show(content);
841 sd->content = content;
842 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
844 if (sd->visible) elm_layout_sizing_eval(obj);
849 EOLIAN static Evas_Object*
850 _elm_ctxpopup_elm_container_content_get(Eo *obj, Elm_Ctxpopup_Data *sd, const char *part)
853 if ((part) && (strcmp(part, "default")))
855 Evas_Object *ret = NULL;
856 eo_do_super(obj, MY_CLASS, ret = elm_obj_container_content_get(part));
863 EOLIAN static Evas_Object*
864 _elm_ctxpopup_elm_container_content_unset(Eo *obj, Elm_Ctxpopup_Data *sd, const char *part)
866 Evas_Object *content = NULL;
868 if ((part) && (strcmp(part, "default")))
870 eo_do_super(obj, MY_CLASS, content = elm_obj_container_content_unset(part));
874 content = sd->content;
875 if (!content) return content;
877 elm_box_unpack(sd->box, content);
879 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
881 if (sd->visible) elm_layout_sizing_eval(obj);
887 _elm_ctxpopup_item_elm_widget_item_part_text_set(Eo *eo_ctxpopup_it EINA_UNUSED,
888 Elm_Ctxpopup_Item_Data *ctxpopup_it,
892 if ((part) && (strcmp(part, "default"))) return;
894 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
896 elm_object_item_part_text_set(ctxpopup_it->list_item, "default", label);
897 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
899 if (sd->visible) elm_layout_sizing_eval(WIDGET(ctxpopup_it));
902 EOLIAN static const char *
903 _elm_ctxpopup_item_elm_widget_item_part_text_get(Eo *eo_ctxpopup_it EINA_UNUSED,
904 Elm_Ctxpopup_Item_Data *ctxpopup_it,
907 if (part && strcmp(part, "default")) return NULL;
909 return elm_object_item_part_text_get(ctxpopup_it->list_item, "default");
913 _elm_ctxpopup_item_elm_widget_item_part_content_set(Eo *eo_ctxpopup_it EINA_UNUSED,
914 Elm_Ctxpopup_Item_Data *ctxpopup_it,
916 Evas_Object *content)
918 if ((part) && (strcmp(part, "icon"))
919 && (strcmp(part, "start"))
920 && (strcmp(part, "end"))) return;
922 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
924 if ((part) && (!strcmp(part, "end")))
925 elm_object_item_part_content_set(ctxpopup_it->list_item, "end", content);
927 elm_object_item_part_content_set
928 (ctxpopup_it->list_item, "start", content);
930 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
932 if (sd->visible) elm_layout_sizing_eval(WIDGET(ctxpopup_it));
935 EOLIAN static Evas_Object *
936 _elm_ctxpopup_item_elm_widget_item_part_content_get(Eo *eo_ctxpopup_it EINA_UNUSED,
937 Elm_Ctxpopup_Item_Data *ctxpopup_it,
940 if (part && strcmp(part, "icon") && strcmp(part, "start")
941 && strcmp(part, "end")) return NULL;
943 if (part && !strcmp(part, "end"))
944 return elm_object_item_part_content_get(ctxpopup_it->list_item, "end");
946 return elm_object_item_part_content_get(ctxpopup_it->list_item, "start");
950 _elm_ctxpopup_item_elm_widget_item_disable(Eo *eo_ctxpopup_it,
951 Elm_Ctxpopup_Item_Data *ctxpopup_it)
954 elm_object_item_disabled_set
955 (ctxpopup_it->list_item, eo_do_ret(eo_ctxpopup_it, tmp, elm_wdg_item_disabled_get()));
959 _elm_ctxpopup_item_elm_widget_item_signal_emit(Eo *eo_ctxpopup_it EINA_UNUSED,
960 Elm_Ctxpopup_Item_Data *ctxpopup_it EINA_UNUSED,
961 const char *emission EINA_UNUSED,
962 const char *source EINA_UNUSED)
964 elm_object_item_signal_emit(ctxpopup_it->list_item, emission, source);
967 // TIZEN_ONLY(20170116): merge eo & header files for different profiles
969 _elm_ctxpopup_item_elm_widget_item_style_set(Eo *eo_item EINA_UNUSED,
970 Elm_Ctxpopup_Item_Data *item EINA_UNUSED,
971 const char *style EINA_UNUSED)
973 // mobile & wearable only feature
976 EOLIAN static Eina_Bool
977 _elm_ctxpopup_item_elm_widget_item_del_pre(Eo *eo_item EINA_UNUSED, Elm_Ctxpopup_Item_Data *item EINA_UNUSED)
979 // mobile & wearable only feature
983 EOLIAN static Elm_Atspi_State_Set
984 _elm_ctxpopup_item_elm_interface_atspi_accessible_state_set_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Item_Data *it EINA_UNUSED)
986 // mobile & wearable only feature
990 EOLIAN static Eina_Bool
991 _elm_ctxpopup_item_elm_interface_atspi_component_highlight_grab(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Item_Data *sd EINA_UNUSED)
993 // mobile & wearable only feature
997 EOLIAN static Eina_Bool
998 _elm_ctxpopup_item_elm_interface_atspi_component_highlight_clear(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Item_Data *sd EINA_UNUSED)
1000 // mobile & wearable only feature
1006 _elm_ctxpopup_item_elm_widget_item_focus_set(Eo *eo_ctxpopup_it EINA_UNUSED,
1007 Elm_Ctxpopup_Item_Data *ctxpopup_it,
1010 elm_object_item_focus_set(ctxpopup_it->list_item, focused);
1013 EOLIAN static Eina_Bool
1014 _elm_ctxpopup_item_elm_widget_item_focus_get(Eo *eo_ctxpopup_it EINA_UNUSED,
1015 Elm_Ctxpopup_Item_Data *ctxpopup_it)
1017 return elm_object_item_focus_get(ctxpopup_it->list_item);
1021 _bg_clicked_cb(void *data,
1022 Evas_Object *obj EINA_UNUSED,
1023 const char *emission EINA_UNUSED,
1024 const char *source EINA_UNUSED)
1026 ELM_CTXPOPUP_DATA_GET(data, sd);
1029 _hide_signals_emit(data, sd->dir);
1033 _on_show(void *data EINA_UNUSED,
1034 Evas *e EINA_UNUSED,
1036 void *event_info EINA_UNUSED)
1038 ELM_CTXPOPUP_DATA_GET(obj, sd);
1042 elm_list_go(sd->list);
1043 sd->visible = EINA_TRUE;
1045 * XXX: Giving focus to the list when it has nothing selected makes
1046 * it select the first of its items, which makes the popup in
1047 * Terminology never open and instead just trigger the first option.
1048 * I'll let as an exercise to the reader to figure out why that
1049 * is so fucking annoying. Extra points for noting why this is my
1050 * choice of a "fix" instead of fixing the actual focus/select issue
1051 * that seems to be spread all over Elementary.
1053 //elm_object_focus_set(sd->list, EINA_TRUE);
1055 //TIZEN_ONLY(20160412): fix 'more' style size problem
1056 elm_layout_sizing_eval(obj);
1062 if (!sd->content) return;
1064 sd->emitted = EINA_FALSE;
1065 sd->visible = EINA_TRUE;
1067 _show_signals_emit(obj, sd->dir);
1069 elm_layout_sizing_eval(obj);
1071 elm_object_focus_set(obj, EINA_TRUE);
1075 _on_hide(void *data EINA_UNUSED,
1076 Evas *e EINA_UNUSED,
1078 void *event_info EINA_UNUSED)
1080 ELM_CTXPOPUP_DATA_GET(obj, sd);
1082 if (!sd->visible) return;
1084 sd->visible = EINA_FALSE;
1085 sd->list_visible = EINA_FALSE;
1089 _on_move(void *data EINA_UNUSED,
1090 Evas *e EINA_UNUSED,
1092 void *event_info EINA_UNUSED)
1094 elm_layout_sizing_eval(obj);
1098 _hide_finished_cb(void *data,
1099 Evas_Object *obj EINA_UNUSED,
1100 const char *emission EINA_UNUSED,
1101 const char *source EINA_UNUSED)
1103 evas_object_hide(data);
1104 eo_do(data, eo_event_callback_call(ELM_CTXPOPUP_EVENT_DISMISSED, NULL));
1108 _list_resize_cb(void *data,
1109 Evas *e EINA_UNUSED,
1110 Evas_Object *obj EINA_UNUSED,
1111 void *event_info EINA_UNUSED)
1113 ELM_CTXPOPUP_DATA_GET(data, sd);
1115 if (!sd->visible) return;
1116 if (sd->list_visible) return;
1118 sd->list_visible = EINA_TRUE;
1120 elm_layout_sizing_eval(data);
1124 _list_del(Elm_Ctxpopup_Data *sd)
1126 ELM_SAFE_FREE(sd->list, evas_object_del);
1130 _elm_ctxpopup_item_eo_base_destructor(Eo *eo_ctxpopup_it,
1131 Elm_Ctxpopup_Item_Data *ctxpopup_it)
1135 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
1137 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1139 list = elm_object_item_widget_get(ctxpopup_it->list_item);
1141 if (ctxpopup_it->list_item)
1142 eo_unref(ctxpopup_it->list_item);
1143 sd->items = eina_list_remove(sd->items, eo_ctxpopup_it);
1144 if (list && eina_list_count(elm_list_items_get(list)) < 2)
1146 evas_object_hide(WIDGET(ctxpopup_it));
1150 if (sd->list_visible) elm_layout_sizing_eval(WIDGET(ctxpopup_it));
1153 eo_do_super(eo_ctxpopup_it, ELM_CTXPOPUP_ITEM_CLASS, eo_destructor());
1156 EOLIAN static Eina_Bool
1157 _elm_ctxpopup_elm_widget_disable(Eo *obj, Elm_Ctxpopup_Data *sd)
1159 Eina_Bool int_ret = EINA_FALSE;
1161 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_disable());
1162 if (!int_ret) return EINA_FALSE;
1164 elm_object_disabled_set(sd->list, elm_widget_disabled_get(obj));
1165 else if (sd->content)
1166 elm_object_disabled_set(sd->content, elm_widget_disabled_get(obj));
1172 _elm_ctxpopup_evas_object_smart_add(Eo *obj, Elm_Ctxpopup_Data *priv)
1174 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1176 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
1177 elm_widget_sub_object_parent_add(obj);
1179 if (!elm_layout_theme_set
1180 (obj, "ctxpopup", "base", elm_widget_style_get(obj)))
1181 CRI("Failed to set layout!");
1183 elm_layout_signal_callback_add
1184 (obj, "elm,action,hide,finished", "*", _hide_finished_cb, obj);
1187 priv->bg = edje_object_add(evas_object_evas_get(obj));
1188 /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
1189 _elm_widget_color_class_parent_set(priv->bg, obj);
1191 elm_widget_theme_object_set(obj, priv->bg, "ctxpopup", "bg", "default");
1192 edje_object_signal_callback_add
1193 (priv->bg, "elm,action,click", "*", _bg_clicked_cb, obj);
1194 evas_object_smart_member_add(priv->bg, obj);
1195 evas_object_stack_below(priv->bg, wd->resize_obj);
1198 priv->arrow = edje_object_add(evas_object_evas_get(obj));
1199 /* TIZEN_ONLY(20161031): apply color_class parent-child relationship to all widgets */
1200 _elm_widget_color_class_parent_set(priv->arrow, obj);
1202 elm_widget_theme_object_set
1203 (obj, priv->arrow, "ctxpopup", "arrow", "default");
1204 evas_object_smart_member_add(priv->arrow, obj);
1206 priv->dir_priority[0] = ELM_CTXPOPUP_DIRECTION_UP;
1207 priv->dir_priority[1] = ELM_CTXPOPUP_DIRECTION_LEFT;
1208 priv->dir_priority[2] = ELM_CTXPOPUP_DIRECTION_RIGHT;
1209 priv->dir_priority[3] = ELM_CTXPOPUP_DIRECTION_DOWN;
1210 priv->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1211 priv->auto_hide = EINA_TRUE;
1213 priv->box = elm_box_add(obj);
1214 evas_object_size_hint_weight_set
1215 (priv->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1217 evas_object_event_callback_add
1218 (priv->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1220 /* box will be our content placeholder, thus the parent's version call */
1221 eo_do_super(obj, MY_CLASS, elm_obj_container_content_set("elm.swallow.content", priv->box));
1223 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _on_show, NULL);
1224 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _on_hide, NULL);
1225 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _on_move, NULL);
1227 elm_widget_can_focus_set(obj, EINA_TRUE);
1231 _elm_ctxpopup_evas_object_smart_del(Eo *obj, Elm_Ctxpopup_Data *sd)
1233 Elm_Object_Item *it;
1235 evas_object_event_callback_del_full
1236 (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1237 _parent_detach(obj);
1239 elm_ctxpopup_clear(obj);
1240 ELM_SAFE_FREE(sd->arrow, evas_object_del); /* stops _sizing_eval() from going on on deletion */
1241 ELM_SAFE_FREE(sd->bg, evas_object_del);
1243 EINA_LIST_FREE(sd->items, it)
1246 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
1250 _elm_ctxpopup_elm_widget_parent_set(Eo *obj, Elm_Ctxpopup_Data *_pd EINA_UNUSED, Evas_Object *parent)
1252 //default parent is to be hover parent
1253 elm_ctxpopup_hover_parent_set(obj, parent);
1257 elm_ctxpopup_add(Evas_Object *parent)
1259 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1260 Evas_Object *obj = eo_add(MY_CLASS, parent);
1262 /* access: parent could be any object such as elm_list which does
1263 not know elc_ctxpopup as its child object in the focus_next(); */
1264 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1265 wd->highlight_root = EINA_TRUE;
1271 _elm_ctxpopup_eo_base_constructor(Eo *obj, Elm_Ctxpopup_Data *_pd EINA_UNUSED)
1273 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
1275 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
1276 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
1277 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_POPUP_MENU));
1283 _elm_ctxpopup_hover_parent_set(Eo *obj, Elm_Ctxpopup_Data *sd, Evas_Object *parent)
1285 Evas_Coord x, y, w, h;
1287 if (!parent) return;
1289 _parent_detach(obj);
1291 evas_object_event_callback_add
1292 (parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
1293 evas_object_event_callback_add
1294 (parent, EVAS_CALLBACK_MOVE, _on_parent_move, obj);
1295 evas_object_event_callback_add
1296 (parent, EVAS_CALLBACK_RESIZE, _on_parent_resize, obj);
1298 sd->parent = parent;
1301 evas_object_geometry_get(parent, &x, &y, &w, &h);
1302 if (parent && eo_isa(parent, ELM_WIN_CLASS))
1304 evas_object_move(sd->bg, x, y);
1305 evas_object_resize(sd->bg, w, h);
1307 if (sd->visible) elm_layout_sizing_eval(obj);
1310 EOLIAN static Evas_Object*
1311 _elm_ctxpopup_hover_parent_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1317 _elm_ctxpopup_clear(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1320 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1324 _elm_ctxpopup_horizontal_set(Eo *obj, Elm_Ctxpopup_Data *sd, Eina_Bool horizontal)
1326 sd->horizontal = !!horizontal;
1328 if (!sd->list) return;
1330 elm_list_horizontal_set(sd->list, sd->horizontal);
1332 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1334 if (sd->visible) elm_layout_sizing_eval(obj);
1337 EOLIAN static Eina_Bool
1338 _elm_ctxpopup_horizontal_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1340 return sd->horizontal;
1344 _item_wrap_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1346 Elm_Ctxpopup_Item_Data *item = data;
1347 if (!item->wcb.org_func_cb) return;
1348 item->wcb.org_func_cb((void *)item->wcb.org_data, item->wcb.cobj, EO_OBJ(item));
1352 _elm_ctxpopup_item_eo_base_constructor(Eo *obj, Elm_Ctxpopup_Item_Data *it)
1354 obj = eo_do_super_ret(obj, ELM_CTXPOPUP_ITEM_CLASS, obj, eo_constructor());
1355 it->base = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
1356 //TIZEN ONLY(20150710)ctxpopup: Accessible methods for children_get, extents_get and item name_get
1357 eo_do(obj, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
1362 EOLIAN static Elm_Object_Item*
1363 _elm_ctxpopup_item_append(Eo *obj, Elm_Ctxpopup_Data *sd, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
1367 eo_item = eo_add(ELM_CTXPOPUP_ITEM_CLASS, obj, elm_obj_ctxpopup_item_init(func, data));
1368 if (!eo_item) return NULL;
1370 ELM_CTXPOPUP_ITEM_DATA_GET(eo_item, item);
1373 elm_list_item_append(sd->list, label, icon, NULL, _item_wrap_cb, item);
1374 eo_ref(item->list_item);
1375 sd->items = eina_list_append(sd->items, eo_item);
1377 if (sd->visible) elm_layout_sizing_eval(obj);
1383 _elm_ctxpopup_direction_priority_set(Eo *obj, Elm_Ctxpopup_Data *sd, Elm_Ctxpopup_Direction first, Elm_Ctxpopup_Direction second, Elm_Ctxpopup_Direction third, Elm_Ctxpopup_Direction fourth)
1385 sd->dir_priority[0] = first;
1386 sd->dir_priority[1] = second;
1387 sd->dir_priority[2] = third;
1388 sd->dir_priority[3] = fourth;
1390 if (sd->visible) elm_layout_sizing_eval(obj);
1394 _elm_ctxpopup_direction_priority_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd, Elm_Ctxpopup_Direction *first, Elm_Ctxpopup_Direction *second, Elm_Ctxpopup_Direction *third, Elm_Ctxpopup_Direction *fourth)
1396 if (first) *first = sd->dir_priority[0];
1397 if (second) *second = sd->dir_priority[1];
1398 if (third) *third = sd->dir_priority[2];
1399 if (fourth) *fourth = sd->dir_priority[3];
1402 EOLIAN static Elm_Ctxpopup_Direction
1403 _elm_ctxpopup_direction_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1408 // TIZEN_ONLY(20160126): add direction available get function, it will be deprecated soon
1409 EINA_DEPRECATED EAPI Eina_Bool
1410 elm_ctxpopup_direction_available_get(Evas_Object *obj, Elm_Ctxpopup_Direction direction)
1412 ELM_CTXPOPUP_CHECK(obj) EINA_FALSE;
1413 ELM_CTXPOPUP_DATA_GET(obj, sd);
1415 elm_layout_sizing_eval(obj);
1417 if (sd->dir == direction) return EINA_TRUE;
1423 _elm_ctxpopup_dismiss(Eo *obj, Elm_Ctxpopup_Data *sd)
1425 _hide_signals_emit(obj, sd->dir);
1429 _elm_ctxpopup_auto_hide_disabled_set(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd, Eina_Bool disabled)
1431 disabled = !!disabled;
1432 if (sd->auto_hide == !disabled) return;
1433 sd->auto_hide = !disabled;
1436 EOLIAN static Eina_Bool
1437 _elm_ctxpopup_auto_hide_disabled_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1439 return !sd->auto_hide;
1443 _elm_ctxpopup_class_constructor(Eo_Class *klass)
1445 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
1448 EOLIAN static const Eina_List*
1449 _elm_ctxpopup_items_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1454 EOLIAN static Elm_Object_Item*
1455 _elm_ctxpopup_first_item_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1457 if (!sd->items) return NULL;
1459 return eina_list_data_get(sd->items);
1462 EOLIAN static Elm_Object_Item*
1463 _elm_ctxpopup_last_item_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1465 if (!sd->items) return NULL;
1467 return eina_list_data_get(eina_list_last(sd->items));
1470 EOLIAN static Elm_Object_Item*
1471 _elm_ctxpopup_item_prepend(Eo *obj, Elm_Ctxpopup_Data *sd, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
1475 eo_item = eo_add(ELM_CTXPOPUP_ITEM_CLASS, obj, elm_obj_ctxpopup_item_init(func, data));
1476 if (!eo_item) return NULL;
1478 ELM_CTXPOPUP_ITEM_DATA_GET(eo_item, item);
1481 elm_list_item_prepend(sd->list, label, icon, NULL, _item_wrap_cb, item);
1482 eo_ref(item->list_item);
1483 sd->items = eina_list_prepend(sd->items, eo_item);
1485 if (sd->visible) elm_layout_sizing_eval(obj);
1490 EOLIAN static Elm_Object_Item *
1491 _elm_ctxpopup_item_prev_get(Eo *eo_item EINA_UNUSED, Elm_Ctxpopup_Item_Data *item)
1495 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
1497 if (!sd->items) return NULL;
1499 l = eina_list_data_find_list(sd->items, eo_item);
1500 if (l && l->prev) return eina_list_data_get(l->prev);
1505 EOLIAN static Elm_Object_Item *
1506 _elm_ctxpopup_item_next_get(Eo *eo_item EINA_UNUSED, Elm_Ctxpopup_Item_Data *item)
1510 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
1512 if (!sd->items) return NULL;
1514 l = eina_list_data_find_list(sd->items, eo_item);
1515 if (l && l->next) return eina_list_data_get(l->next);
1521 _elm_ctxpopup_item_init(Eo *eo_item,
1522 Elm_Ctxpopup_Item_Data *item,
1527 eo_do(eo_item, obj = eo_parent_get());
1528 Elm_Ctxpopup_Data *sd = eo_data_scope_get(obj, ELM_CTXPOPUP_CLASS);
1531 sd->list = elm_list_add(obj);
1532 if (!strncmp(elm_object_style_get(obj), "default", strlen("default")))
1533 elm_object_style_set(sd->list, "ctxpopup");
1534 else elm_object_style_set(sd->list, elm_object_style_get(obj));
1535 elm_list_mode_set(sd->list, ELM_LIST_EXPAND);
1536 elm_list_horizontal_set(sd->list, sd->horizontal);
1537 evas_object_event_callback_add
1538 (sd->list, EVAS_CALLBACK_RESIZE, _list_resize_cb, obj);
1539 elm_layout_content_set(obj, "default", sd->list);
1542 item->wcb.org_func_cb = func;
1543 item->wcb.org_data = data;
1544 item->wcb.cobj = obj;
1546 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1549 EOLIAN static const Elm_Atspi_Action*
1550 _elm_ctxpopup_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd EINA_UNUSED)
1552 static Elm_Atspi_Action atspi_actions[] = {
1553 { "escape", "escape", NULL, _key_action_escape},
1554 { "move,previous", "move", "previous", _key_action_move},
1555 { "move,next", "move", "next", _key_action_move},
1556 { "move,left", "move", "left", _key_action_move},
1557 { "move,right", "move", "right", _key_action_move},
1558 { "move,up", "move", "up", _key_action_move},
1559 { "move,down", "move", "down", _key_action_move},
1560 { NULL, NULL, NULL, NULL }
1562 return &atspi_actions[0];
1565 EOLIAN static Elm_Atspi_State_Set
1566 _elm_ctxpopup_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Ctxpopup_Data *sd EINA_UNUSED)
1568 Elm_Atspi_State_Set ret;
1569 eo_do_super(obj, MY_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
1571 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MODAL);
1576 // TIZEN_ONLY(20170116): merge eo & header files for different profiles
1577 EOLIAN static Eina_List *
1578 _elm_ctxpopup_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd EINA_UNUSED)
1580 // mobile & wearable only feature
1584 EOLIAN static const char*
1585 _elm_ctxpopup_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd EINA_UNUSED)
1587 // mobile & wearable only feature
1592 //TIZEN ONLY(20150710): ctxpopup: Accessible methods for children_get, extents_get and item name_get
1594 _elm_ctxpopup_elm_interface_atspi_component_extents_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd, Eina_Bool screen_coords, int *x, int *y, int *w, int *h)
1606 evas_object_geometry_get(sd->box, x, y, w, h);
1610 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->box));
1612 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
1620 _item_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
1622 ELM_CTXPOPUP_ITEM_DATA_GET(obj, item);
1624 if (item->wcb.org_func_cb)
1625 item->wcb.org_func_cb((void*)item->wcb.org_data, WIDGET(item), EO_OBJ(item));
1629 EOLIAN static const Elm_Atspi_Action*
1630 _elm_ctxpopup_item_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Item_Data *sd EINA_UNUSED)
1632 static Elm_Atspi_Action atspi_actions[] = {
1633 { "activate", "activate", NULL, _item_action_activate},
1634 { NULL, NULL, NULL, NULL }
1636 return &atspi_actions[0];
1639 //TIZEN ONLY(20150708): popup and ctxpopup accessibility highlight impementation
1640 EOLIAN static Eina_Bool
1641 _elm_ctxpopup_elm_interface_atspi_component_highlight_grab(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1645 elm_object_accessibility_highlight_set(sd->box, EINA_TRUE);
1651 EOLIAN static Eina_Bool
1652 _elm_ctxpopup_elm_interface_atspi_component_highlight_clear(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
1656 elm_object_accessibility_highlight_set(sd->box, EINA_FALSE);
1663 //TIZEN ONLY(20150710)ctxpopup: Accessible methods for children_get, extents_get and item name_get
1665 _elm_ctxpopup_item_elm_interface_atspi_accessible_name_get(Eo *eo_it EINA_UNUSED, Elm_Ctxpopup_Item_Data *item)
1667 return elm_object_item_text_get(item->list_item);
1671 #include "elm_ctxpopup_item.eo.c"
1672 #include "elm_ctxpopup.eo.c"