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
8 #define ELM_WIDGET_ITEM_PROTECTED
10 #include <Elementary.h>
13 #include "elm_widget_ctxpopup.h"
15 #define MY_CLASS ELM_CTXPOPUP_CLASS
17 #define MY_CLASS_NAME "Elm_Ctxpopup"
18 #define MY_CLASS_NAME_LEGACY "elm_ctxpopup"
20 EAPI const char ELM_CTXPOPUP_SMART_NAME[] = "elm_ctxpopup";
22 #define ELM_PRIV_CTXPOPUP_SIGNALS(cmd) \
23 cmd(SIG_DISMISSED, "dismissed", "") \
25 ELM_PRIV_CTXPOPUP_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
27 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
28 ELM_PRIV_CTXPOPUP_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
29 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
30 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
31 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
32 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
35 #undef ELM_PRIV_CTXPOPUP_SIGNALS
37 #define TTS_STR_MENU_POPUP dgettext(PACKAGE, "IDS_SCR_OPT_MENU_POP_UP_TTS")
38 #define TTS_STR_MENU_CLOSE dgettext(PACKAGE, "IDS_ST_BODY_DOUBLE_TAP_TO_CLOSE_THE_MENU_T_TTS")
40 static const char ACCESS_OUTLINE_PART[] = "access.outline";
42 static void _on_move(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED);
43 static void _item_sizing_eval(Elm_Ctxpopup_Item_Data *item);
44 static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED);
45 //TIZEN ONLY(20161014) : Accessibility: scroll the content when highlight frame goes out of view port
46 static void _content_move_down_cb(void *data, Evas_Object *obj, void *ev EINA_UNUSED);
47 static void _content_move_up_cb(void *data, Evas_Object *obj, void *ev EINA_UNUSED);
50 EOLIAN static Eina_Bool
51 _elm_ctxpopup_elm_widget_translate(Eo *obj, Elm_Ctxpopup_Data *sd)
54 Elm_Ctxpopup_Item_Data *it;
58 evas_object_hide(obj);
59 eo_do(obj, eo_event_callback_call(ELM_CTXPOPUP_EVENT_DISMISSED, NULL));
62 EINA_LIST_FOREACH(sd->items, l, it)
63 eo_do(EO_OBJ(it), elm_wdg_item_translate());
65 eo_do_super(obj, MY_CLASS, elm_obj_widget_translate());
71 _access_object_get(const Evas_Object *obj, const char* part)
75 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
77 po = (Evas_Object *)edje_object_part_object_get(wd->resize_obj, part);
78 ao = evas_object_data_get(po, "_part_access_obj");
83 EOLIAN static Eina_Bool
84 _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)
86 Eina_List *items = NULL;
92 if (_elm_config->access_mode)
96 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
97 if (ao) items = eina_list_append(items, ao);
99 /* scroller exists when ctxpopup has an item */
101 items = eina_list_append(items, sd->scr);
103 items = eina_list_append(items, sd->box);
105 _elm_access_auto_highlight_set(EINA_TRUE);
106 ret = elm_widget_focus_list_next_get
107 (obj, items, eina_list_data_get, dir, next, next_item);
108 _elm_access_auto_highlight_set(EINA_FALSE);
113 elm_widget_focus_next_get(sd->box, dir, next, next_item);
114 if (!*next) *next = (Evas_Object *)obj;
119 EOLIAN static Eina_Bool
120 _elm_ctxpopup_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *_pd EINA_UNUSED)
125 EOLIAN static Eina_Bool
126 _elm_ctxpopup_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *_pd EINA_UNUSED)
131 EOLIAN static Eina_Bool
132 _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)
135 void *(*list_data_get)(const Eina_List *list);
140 list_data_get = eina_list_data_get;
142 l = eina_list_append(l, sd->box);
144 elm_widget_focus_list_direction_get
145 (obj, base, l, list_data_get, degree, direction, direction_item, weight);
152 _key_action_move(Evas_Object *obj, const char *params)
154 ELM_CTXPOPUP_DATA_GET(obj, sd);
155 const char *dir = params;
157 if (!sd->box) return EINA_FALSE;
159 if (!strcmp(dir, "previous"))
160 elm_widget_focus_cycle(sd->box, ELM_FOCUS_PREVIOUS);
161 else if (!strcmp(dir, "next"))
162 elm_widget_focus_cycle(sd->box, ELM_FOCUS_NEXT);
163 else if (!strcmp(dir, "left"))
164 elm_widget_focus_cycle(sd->box, ELM_FOCUS_LEFT);
165 else if (!strcmp(dir, "right"))
166 elm_widget_focus_cycle(sd->box, ELM_FOCUS_RIGHT);
167 else if (!strcmp(dir, "up"))
168 elm_widget_focus_cycle(sd->box, ELM_FOCUS_UP);
169 else if (!strcmp(dir, "down"))
170 elm_widget_focus_cycle(sd->box, ELM_FOCUS_DOWN);
171 else return EINA_FALSE;
177 _x_pos_adjust(Evas_Coord_Point *pos,
178 Evas_Coord_Point *base_size,
179 Evas_Coord_Rectangle *hover_area)
181 pos->x -= (base_size->x / 2);
183 if (pos->x < hover_area->x)
184 pos->x = hover_area->x;
185 else if ((pos->x + base_size->x) > (hover_area->x + hover_area->w))
186 pos->x = (hover_area->x + hover_area->w) - base_size->x;
188 if (base_size->x > hover_area->w)
189 base_size->x -= (base_size->x - hover_area->w);
191 if (pos->x < hover_area->x)
192 pos->x = hover_area->x;
196 _y_pos_adjust(Evas_Coord_Point *pos,
197 Evas_Coord_Point *base_size,
198 Evas_Coord_Rectangle *hover_area)
200 pos->y -= (base_size->y / 2);
202 if (pos->y < hover_area->y)
203 pos->y = hover_area->y;
204 else if ((pos->y + base_size->y) > (hover_area->y + hover_area->h))
205 pos->y = hover_area->y + hover_area->h - base_size->y;
207 if (base_size->y > hover_area->h)
208 base_size->y -= (base_size->y - hover_area->h);
210 if (pos->y < hover_area->y)
211 pos->y = hover_area->y;
215 _item_select_cb(void *data,
216 Evas_Object *obj EINA_UNUSED,
217 void *event_info EINA_UNUSED)
219 Elm_Ctxpopup_Item_Data *item = data;
223 if (eo_do_ret(EO_OBJ(item), tmp, elm_wdg_item_disabled_get()))
225 if (_elm_config->access_mode)
226 elm_access_say(E_("Disabled"));
230 if (item->wcb.org_func_cb)
231 item->wcb.org_func_cb((void*)item->wcb.org_data, WIDGET(item), EO_OBJ(item));
235 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
237 Elm_Ctxpopup_Item_Data *it = (Elm_Ctxpopup_Item_Data *)data;
238 const char *txt = NULL;
239 Evas_Object *icon = NULL;
241 if (!it) return NULL;
246 if (txt) return strdup(txt);
247 if (icon) return strdup(E_("icon"));
252 _access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
254 Elm_Ctxpopup_Item_Data *it = (Elm_Ctxpopup_Item_Data *)data;
256 if (!it) return NULL;
258 if (eo_do_ret(EO_OBJ(it), tmp, elm_wdg_item_disabled_get()))
259 return strdup(E_("Disabled"));
265 _access_focusable_button_register(Evas_Object *obj, Elm_Ctxpopup_Item_Data *it)
269 ai = _elm_access_info_get(obj);
271 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
272 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
273 _elm_access_callback_set(ai, ELM_ACCESS_TYPE, NULL, NULL);
275 it->base->access_obj = obj;
279 _mouse_down_cb(Elm_Ctxpopup_Item_Data *it,
280 Evas *evas EINA_UNUSED,
281 Evas_Object *obj EINA_UNUSED,
282 Evas_Event_Mouse_Down *ev)
284 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
286 if (ev->button != 1) return;
288 //If counter is not zero, it means all other multi down is not released.
289 if (sd->multi_down != 0) return;
290 sd->mouse_down = EINA_TRUE;
291 //******************** TIZEN Only
292 sd->pressed = EINA_TRUE;
293 //****************************
296 //******************** TIZEN Only
298 _mouse_move_cb(Elm_Ctxpopup_Item_Data *it,
299 Evas *evas EINA_UNUSED,
303 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
304 Evas_Event_Mouse_Move *ev = event_info;
306 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
310 edje_object_signal_emit(obj,"elm,action,unpressed", "elm");
311 sd->pressed = EINA_FALSE;
316 Evas_Coord x, y, w, h;
317 evas_object_geometry_get(obj, &x, &y, &w, &h);
318 if ((sd->pressed) && (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y)))
320 edje_object_signal_emit(obj,"elm,action,unpressed", "elm");
321 sd->pressed = EINA_FALSE;
325 //****************************
328 _mouse_up_cb(Elm_Ctxpopup_Item_Data *it,
329 Evas *evas EINA_UNUSED,
330 Evas_Object *obj EINA_UNUSED,
331 Evas_Event_Mouse_Up *ev)
333 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
335 if (ev->button != 1) return;
337 if (!sd->mouse_down) return;
338 sd->mouse_down = EINA_FALSE;
339 //******************** TIZEN Only
340 sd->pressed = EINA_FALSE;
341 //****************************
345 _multi_down_cb(void *data,
346 Evas *evas EINA_UNUSED,
347 Evas_Object *obj EINA_UNUSED,
348 void *event_info EINA_UNUSED)
350 Elm_Ctxpopup_Item_Data *it = data;
351 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
353 //Emitting signal to inform edje about multi down event.
354 edje_object_signal_emit(VIEW(it), "elm,action,multi,down", "elm");
359 _multi_up_cb(void *data,
360 Evas *evas EINA_UNUSED,
361 Evas_Object *obj EINA_UNUSED,
362 void *event_info EINA_UNUSED)
364 Elm_Ctxpopup_Item_Data *it = data;
365 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
368 if(sd->multi_down == 0)
370 //Emitting signal to inform edje about last multi up event.
371 edje_object_signal_emit(VIEW(it), "elm,action,multi,up", "elm");
376 _item_theme_set(Elm_Ctxpopup_Item_Data *item,
379 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
382 VIEW(item) = edje_object_add(evas_object_evas_get(sd->box));
383 edje_object_mirrored_set(VIEW(item), elm_widget_mirrored_get(WIDGET(item)));
384 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", group_name,
385 elm_widget_style_get(WIDGET(item)));
386 evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
387 evas_object_show(VIEW(item));
389 evas_object_event_callback_add
390 (VIEW(item), EVAS_CALLBACK_MOUSE_DOWN, (Evas_Object_Event_Cb)_mouse_down_cb,
392 //******************** TIZEN Only
393 evas_object_event_callback_add
394 (VIEW(item), EVAS_CALLBACK_MOUSE_MOVE, (Evas_Object_Event_Cb)_mouse_move_cb,
396 //****************************
397 evas_object_event_callback_add
398 (VIEW(item), EVAS_CALLBACK_MOUSE_UP, (Evas_Object_Event_Cb)_mouse_up_cb, item);
400 /*Registering Multi down/up events to ignore mouse down/up events untill all
401 multi down/up events are released.*/
402 evas_object_event_callback_add
403 (VIEW(item), EVAS_CALLBACK_MULTI_DOWN, (Evas_Object_Event_Cb)_multi_down_cb,
405 evas_object_event_callback_add
406 (VIEW(item), EVAS_CALLBACK_MULTI_UP, (Evas_Object_Event_Cb)_multi_up_cb,
411 _item_in_focusable_button(Elm_Ctxpopup_Item_Data *item)
415 bt = elm_button_add(WIDGET(item));
416 elm_object_style_set(bt, "focus");
417 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
418 elm_object_part_content_set(bt, "elm.swallow.content", VIEW(item));
419 evas_object_smart_callback_add(bt, "clicked", _item_select_cb, item);
420 evas_object_show(bt);
425 EOLIAN static Eina_Bool
426 _elm_ctxpopup_item_elm_widget_item_del_pre(Eo *eo_item EINA_UNUSED, Elm_Ctxpopup_Item_Data *item)
430 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
431 if (!sd) return EINA_FALSE;
434 elm_box_unpack(sd->box, btn);
435 evas_object_smart_callback_del_full(btn, "clicked", _item_select_cb, item);
436 evas_object_del(btn);
438 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
441 evas_object_del(item->icon);
443 evas_object_del(VIEW(item));
445 eina_stringshare_del(item->label);
446 sd->items = eina_list_remove(sd->items, item);
448 if (eina_list_count(sd->items) < 1)
450 evas_object_hide(WIDGET(item));
453 if (sd->visible) elm_layout_sizing_eval(WIDGET(item));
459 _items_remove(Elm_Ctxpopup_Data *sd)
461 Eina_List *l, *l_next;
462 Elm_Ctxpopup_Item_Data *item;
464 if (!sd->items) return;
466 EINA_LIST_FOREACH_SAFE(sd->items, l, l_next, item)
467 eo_do(EO_OBJ(item), elm_wdg_item_del());
473 _items_sizing_eval(Evas_Object *obj,
474 Elm_Ctxpopup_Data *sd)
476 Elm_Ctxpopup_Item_Data *it;
480 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
484 EINA_LIST_FOREACH(sd->items, elist, it)
487 edje_object_signal_emit(VIEW(it), "elm,state,default", "elm");
489 edje_object_signal_emit(VIEW(it), "elm,state,separator", "elm");
491 elm_layout_sizing_eval(obj);
496 _item_sizing_eval(Elm_Ctxpopup_Item_Data *item)
498 Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
502 edje_object_signal_emit(VIEW(item), "elm,state,text,default", "elm");
503 edje_object_message_signal_process(VIEW(item));
504 edje_object_size_min_restricted_calc(VIEW(item), &min_w, &min_h, min_w,
506 evas_object_size_hint_min_set(VIEW(item), min_w, min_h);
507 evas_object_size_hint_max_set(VIEW(item), max_w, max_h);
510 static Elm_Ctxpopup_Direction
511 _base_geometry_calc(Evas_Object *obj,
512 Evas_Coord_Rectangle *rect)
514 Elm_Ctxpopup_Direction dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
515 Evas_Coord_Rectangle hover_area;
516 Evas_Coord_Point pos = {0, 0};
517 Evas_Coord_Point arrow_size;
518 Evas_Coord_Point base_size;
519 Evas_Coord_Point max_size;
520 Evas_Coord_Point min_size;
521 Evas_Coord_Point temp;
525 ELM_CTXPOPUP_DATA_GET(obj, sd);
526 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, ELM_CTXPOPUP_DIRECTION_DOWN);
528 if (!rect) return ELM_CTXPOPUP_DIRECTION_DOWN;
530 edje_object_part_geometry_get
531 (sd->arrow, "ctxpopup_arrow", NULL, NULL, &arrow_size.x, &arrow_size.y);
532 evas_object_resize(sd->arrow, arrow_size.x, arrow_size.y);
534 //Initialize Area Rectangle.
535 evas_object_geometry_get
536 (sd->parent, &hover_area.x, &hover_area.y, &hover_area.w,
539 evas_object_geometry_get(obj, &pos.x, &pos.y, NULL, NULL);
541 /* TIZEN_ONLY(20170524): move position in hover area */
542 if (pos.x < hover_area.x) pos.x = hover_area.x;
543 else if (pos.x > hover_area.x + hover_area.w) pos.x = hover_area.x + hover_area.w;
545 if (pos.y < hover_area.y) pos.y = hover_area.y;
546 else if (pos.y > hover_area.y + hover_area.h) pos.y = hover_area.y + hover_area.h;
550 edje_object_size_min_calc
551 (wd->resize_obj, &base_size.x, &base_size.y);
552 evas_object_smart_calculate(wd->resize_obj);
555 evas_object_size_hint_max_get(obj, &max_size.x, &max_size.y);
556 if ((max_size.x == -1) || (max_size.y == -1))
558 str = edje_object_data_get(sd->layout, "visible_maxw");
560 max_size.x = (int)(atoi(str)
561 * elm_config_scale_get()
562 * elm_object_scale_get(obj)
563 / edje_object_base_scale_get(sd->layout) + 0.5);
564 str = edje_object_data_get(sd->layout, "visible_maxh");
566 max_size.y = (int)(atoi(str)
567 * elm_config_scale_get()
568 * elm_object_scale_get(obj)
569 / edje_object_base_scale_get(sd->layout) + 0.5);
572 if ((max_size.y > 0) && (base_size.y > max_size.y))
573 base_size.y = max_size.y;
575 if ((max_size.x > 0) && (base_size.x > max_size.x))
576 base_size.x = max_size.x;
579 evas_object_size_hint_min_get(obj, &min_size.x, &min_size.y);
580 if ((min_size.x == 0) || (min_size.y == 0))
581 edje_object_size_min_get(sd->layout, &min_size.x, &min_size.y);
583 if ((min_size.y > 0) && (base_size.y < min_size.y))
584 base_size.y = min_size.y;
586 if ((min_size.x > 0) && (base_size.x < min_size.x))
587 base_size.x = min_size.x;
589 //Check the Which direction is available.
590 //If find a avaialble direction, it adjusts position and size.
591 for (idx = 0; idx < 4; idx++)
593 switch (sd->dir_priority[idx])
595 case ELM_CTXPOPUP_DIRECTION_UNKNOWN:
597 case ELM_CTXPOPUP_DIRECTION_UP:
598 temp.y = (pos.y - base_size.y);
599 if ((temp.y - arrow_size.y) < hover_area.y)
602 _x_pos_adjust(&pos, &base_size, &hover_area);
603 pos.y -= base_size.y;
604 dir = ELM_CTXPOPUP_DIRECTION_UP;
607 case ELM_CTXPOPUP_DIRECTION_LEFT:
608 temp.x = (pos.x - base_size.x);
609 if ((temp.x - arrow_size.x) < hover_area.x)
612 _y_pos_adjust(&pos, &base_size, &hover_area);
613 pos.x -= base_size.x;
614 dir = ELM_CTXPOPUP_DIRECTION_LEFT;
617 case ELM_CTXPOPUP_DIRECTION_RIGHT:
618 temp.x = (pos.x + base_size.x);
619 if ((temp.x + arrow_size.x) >
620 (hover_area.x + hover_area.w))
623 _y_pos_adjust(&pos, &base_size, &hover_area);
624 dir = ELM_CTXPOPUP_DIRECTION_RIGHT;
627 case ELM_CTXPOPUP_DIRECTION_DOWN:
628 temp.y = (pos.y + base_size.y);
629 if ((temp.y + arrow_size.y) >
630 (hover_area.y + hover_area.h))
633 _x_pos_adjust(&pos, &base_size, &hover_area);
634 dir = ELM_CTXPOPUP_DIRECTION_DOWN;
643 //In this case, all directions are invalid because of lack of space.
646 Evas_Coord length[2];
650 length[0] = pos.y - hover_area.y;
651 length[1] = (hover_area.y + hover_area.h) - pos.y;
653 // ELM_CTXPOPUP_DIRECTION_UP
654 if (length[0] > length[1])
656 _x_pos_adjust(&pos, &base_size, &hover_area);
657 pos.y -= base_size.y;
658 dir = ELM_CTXPOPUP_DIRECTION_UP;
659 if (pos.y < (hover_area.y + arrow_size.y))
661 base_size.y -= ((hover_area.y + arrow_size.y) - pos.y);
662 pos.y = hover_area.y + arrow_size.y;
665 //ELM_CTXPOPUP_DIRECTION_DOWN
668 _x_pos_adjust(&pos, &base_size, &hover_area);
669 dir = ELM_CTXPOPUP_DIRECTION_DOWN;
670 if ((pos.y + arrow_size.y + base_size.y) >
671 (hover_area.y + hover_area.h))
673 ((pos.y + arrow_size.y + base_size.y) -
674 (hover_area.y + hover_area.h));
679 length[0] = pos.x - hover_area.x;
680 length[1] = (hover_area.x + hover_area.w) - pos.x;
682 //ELM_CTXPOPUP_DIRECTION_LEFT
683 if (length[0] > length[1])
685 _y_pos_adjust(&pos, &base_size, &hover_area);
686 pos.x -= base_size.x;
687 dir = ELM_CTXPOPUP_DIRECTION_LEFT;
688 if (pos.x < (hover_area.x + arrow_size.x))
690 base_size.x -= ((hover_area.x + arrow_size.x) - pos.x);
691 pos.x = hover_area.x + arrow_size.x;
694 //ELM_CTXPOPUP_DIRECTION_RIGHT
697 _y_pos_adjust(&pos, &base_size, &hover_area);
698 dir = ELM_CTXPOPUP_DIRECTION_RIGHT;
699 if (pos.x + (arrow_size.x + base_size.x) >
700 hover_area.x + hover_area.w)
702 ((pos.x + arrow_size.x + base_size.x) -
703 (hover_area.x + hover_area.w));
708 //Final position and size.
711 rect->w = base_size.x;
712 rect->h = base_size.y;
718 _arrow_update(Evas_Object *obj,
719 Elm_Ctxpopup_Direction dir,
720 Evas_Coord_Rectangle base_size)
722 Evas_Coord_Rectangle arrow_size;
725 Evas_Coord_Rectangle shadow_left_top, shadow_right_bottom, arrow_padding;
727 ELM_CTXPOPUP_DATA_GET(obj, sd);
728 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
730 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
731 evas_object_geometry_get
732 (sd->arrow, NULL, NULL, &arrow_size.w, &arrow_size.h);
734 /* tizen only : since ctxpopup of tizen has shadow, start and end padding of arrow, it should be put together when updating arrow
735 * so there are some differences between open source and tizen */
736 edje_object_part_geometry_get(wd->resize_obj, "frame_shadow_left_top_padding", NULL, NULL, &shadow_left_top.w, &shadow_left_top.h);
737 edje_object_part_geometry_get(wd->resize_obj, "frame_shadow_right_bottom_padding", NULL, NULL, &shadow_right_bottom.w, &shadow_right_bottom.h);
738 edje_object_part_geometry_get(wd->resize_obj, "ctxpopup_frame_left_top", NULL, NULL, &arrow_padding.w, &arrow_padding.h);
740 /* arrow is not being kept as sub-object on purpose, here. the
741 * design of the widget does not help with the contrary */
745 case ELM_CTXPOPUP_DIRECTION_RIGHT:
746 edje_object_signal_emit(sd->arrow, "elm,state,left", "elm");
747 edje_object_part_swallow
749 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_right" :
750 "elm.swallow.arrow_left"), sd->arrow);
754 if (y <= ((arrow_size.h * 0.5) + base_size.y + shadow_left_top.h + arrow_padding.h))
756 else if (y >= (base_size.y + base_size.h - ((arrow_size.h * 0.5) + shadow_right_bottom.h + arrow_padding.h)))
757 y = base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2));
759 y = y - base_size.y - ((arrow_size.h * 0.5) + shadow_left_top.h + arrow_padding.h);
760 drag = (double)(y) / (double)(base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2)));
761 edje_object_part_drag_value_set
763 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_right" :
764 "elm.swallow.arrow_left"), 1, drag);
768 case ELM_CTXPOPUP_DIRECTION_LEFT:
769 edje_object_signal_emit(sd->arrow, "elm,state,right", "elm");
770 edje_object_part_swallow
772 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_left" :
773 "elm.swallow.arrow_right"), sd->arrow);
777 if (y <= ((arrow_size.h * 0.5) + base_size.y + shadow_left_top.h + arrow_padding.h))
779 else if (y >= (base_size.y + base_size.h - ((arrow_size.h * 0.5) + shadow_right_bottom.h + arrow_padding.h)))
780 y = base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2));
782 y = y - base_size.y - ((arrow_size.h * 0.5) + shadow_left_top.h + arrow_padding.h);
783 drag = (double)(y) / (double)(base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2)));
784 edje_object_part_drag_value_set
786 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_left" :
787 "elm.swallow.arrow_right"), 0, drag);
791 case ELM_CTXPOPUP_DIRECTION_DOWN:
792 edje_object_signal_emit(sd->arrow, "elm,state,top", "elm");
793 edje_object_part_swallow
794 (wd->resize_obj, "elm.swallow.arrow_up",
799 if (x <= ((arrow_size.w * 0.5) + base_size.x + shadow_left_top.w + arrow_padding.w))
801 else if (x >= (base_size.x + base_size.w - ((arrow_size.w * 0.5) + shadow_right_bottom.w + arrow_padding.w)))
802 x = base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2));
804 x = x - base_size.x - ((arrow_size.w * 0.5) + shadow_left_top.w + arrow_padding.w);
805 drag = (double)(x) / (double)(base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2)));
806 edje_object_part_drag_value_set
807 (wd->resize_obj, "elm.swallow.arrow_up",
812 case ELM_CTXPOPUP_DIRECTION_UP:
813 edje_object_signal_emit(sd->arrow, "elm,state,bottom", "elm");
814 edje_object_part_swallow
815 (wd->resize_obj, "elm.swallow.arrow_down",
820 if (x <= ((arrow_size.w * 0.5) + base_size.x + shadow_left_top.w + arrow_padding.w))
822 else if (x >= (base_size.x + base_size.w - ((arrow_size.w * 0.5) + shadow_right_bottom.w + arrow_padding.w)))
823 x = base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2));
825 x = x - base_size.x - ((arrow_size.w * 0.5) + shadow_left_top.w + arrow_padding.w);
826 drag = (double)(x) / (double)(base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2)));
827 edje_object_part_drag_value_set
828 (wd->resize_obj, "elm.swallow.arrow_down",
837 //should be here for getting accurate geometry value
838 evas_object_smart_calculate(wd->resize_obj);
842 _show_signals_emit(Evas_Object *obj,
843 Elm_Ctxpopup_Direction dir)
845 ELM_CTXPOPUP_DATA_GET(obj, sd);
847 if (!sd->visible) return;
851 case ELM_CTXPOPUP_DIRECTION_UP:
852 edje_object_signal_emit(sd->layout, "elm,state,show,up", "elm");
855 case ELM_CTXPOPUP_DIRECTION_LEFT:
856 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,show,right" :
857 "elm,state,show,left"), "elm");
860 case ELM_CTXPOPUP_DIRECTION_RIGHT:
861 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,show,left" :
862 "elm,state,show,right"), "elm");
865 case ELM_CTXPOPUP_DIRECTION_DOWN:
866 edje_object_signal_emit(sd->layout, "elm,state,show,down", "elm");
873 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
877 _visible_signals_emit(Evas_Object *obj,
878 Elm_Ctxpopup_Direction dir)
880 ELM_CTXPOPUP_DATA_GET(obj, sd);
882 if (!sd->visible) return;
886 case ELM_CTXPOPUP_DIRECTION_UP:
887 edje_object_signal_emit(sd->layout, "elm,state,visible,up", "elm");
890 case ELM_CTXPOPUP_DIRECTION_LEFT:
891 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,visible,right" :
892 "elm,state,visible,left"), "elm");
895 case ELM_CTXPOPUP_DIRECTION_RIGHT:
896 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,visible,left" :
897 "elm,state,visible,right"), "elm");
900 case ELM_CTXPOPUP_DIRECTION_DOWN:
901 edje_object_signal_emit(sd->layout, "elm,state,visible,down", "elm");
908 edje_object_signal_emit(sd->bg, "elm,state,visible", "elm");
912 _hide_signals_emit(Evas_Object *obj,
913 Elm_Ctxpopup_Direction dir)
915 ELM_CTXPOPUP_DATA_GET(obj, sd);
917 if (!sd->visible) return;
921 case ELM_CTXPOPUP_DIRECTION_UP:
922 edje_object_signal_emit(sd->layout, "elm,state,hide,up", "elm");
925 case ELM_CTXPOPUP_DIRECTION_LEFT:
926 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,hide,right" :
927 "elm,state,hide,left"), "elm");
930 case ELM_CTXPOPUP_DIRECTION_RIGHT:
931 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,hide,left" :
932 "elm,state,hide,right"), "elm");
935 case ELM_CTXPOPUP_DIRECTION_DOWN:
936 edje_object_signal_emit(sd->layout, "elm,state,hide,down", "elm");
940 edje_object_signal_emit(sd->layout, "elm,state,hide,default", "elm");
944 edje_object_signal_emit(sd->bg, "elm,state,hide", "elm");
948 _base_shift_by_arrow(Evas_Object *obj,
950 Elm_Ctxpopup_Direction dir,
951 Evas_Coord_Rectangle *rect)
953 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
955 Evas_Coord arrow_w, arrow_h, diff_w, diff_h;
956 Evas_Coord_Rectangle shadow_left_top, shadow_right_bottom;
958 evas_object_geometry_get(arrow, NULL, NULL, &arrow_w, &arrow_h);
959 /* tizen only: since ctxpopup of tizen has shadow parts, start and end padding of arrow, it should be put together when shifting ctxpopup by arrow
960 * so there are some differences between opensource and tizen*/
961 edje_object_part_geometry_get(wd->resize_obj, "frame_shadow_left_top_padding", NULL, NULL, &shadow_left_top.w, &shadow_left_top.h);
962 edje_object_part_geometry_get(wd->resize_obj, "frame_shadow_right_bottom_padding", NULL, NULL, &shadow_right_bottom.w, &shadow_right_bottom.h);
967 case ELM_CTXPOPUP_DIRECTION_RIGHT:
968 diff_w = arrow_w - shadow_right_bottom.w;
972 case ELM_CTXPOPUP_DIRECTION_LEFT:
973 diff_w = arrow_w - shadow_left_top.w;
977 case ELM_CTXPOPUP_DIRECTION_DOWN:
978 diff_h = arrow_h - shadow_left_top.h;
982 case ELM_CTXPOPUP_DIRECTION_UP:
983 diff_h = arrow_h - shadow_right_bottom.h;
992 EOLIAN static Eina_Bool
993 _elm_ctxpopup_elm_layout_sub_object_add_enable(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *_pd EINA_UNUSED)
998 EOLIAN static Eina_Bool
999 _elm_ctxpopup_elm_widget_sub_object_add(Eo *obj, Elm_Ctxpopup_Data *_pd EINA_UNUSED, Evas_Object *sobj)
1001 Eina_Bool int_ret = EINA_FALSE;
1003 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_sub_object_add(sobj));
1009 _elm_ctxpopup_elm_layout_sizing_eval(Eo *obj, Elm_Ctxpopup_Data *sd)
1012 Elm_Ctxpopup_Item_Data *item;
1013 Evas_Coord_Rectangle rect = { 0, 0, 1, 1 };
1014 Evas_Coord_Point box_size = { 0, 0 };
1015 Evas_Coord_Point _box_size = { 0, 0 };
1016 Evas_Coord maxw = 0;
1017 Evas_Coord x, y, w, h;
1020 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1022 if (!sd->parent || !(sd->items || sd->content)) return;
1025 EINA_LIST_FOREACH(sd->items, elist, item)
1027 _item_sizing_eval(item);
1028 evas_object_size_hint_min_get(VIEW(item), &_box_size.x, &_box_size.y);
1030 str = edje_object_data_get(VIEW(item), "item_max_size");
1034 maxw = maxw * elm_config_scale_get()
1035 * elm_widget_scale_get(obj)
1036 / edje_object_base_scale_get(VIEW(item));
1038 if (_box_size.x > maxw)
1040 edje_object_signal_emit(VIEW(item), "elm,state,text,ellipsis", "elm");
1041 edje_object_message_signal_process(VIEW(item));
1045 if (!sd->horizontal)
1047 if (_box_size.x > box_size.x)
1048 box_size.x = _box_size.x;
1049 if (_box_size.y != -1)
1050 box_size.y += _box_size.y;
1054 if (_box_size.x != -1)
1055 box_size.x += _box_size.x;
1056 if (_box_size.y > box_size.y)
1057 box_size.y = _box_size.y;
1061 // if (!sd->arrow) return; /* simple way to flag "under deletion" */
1063 if ((!sd->content) && (sd->scr))
1065 evas_object_size_hint_min_set(sd->box, box_size.x, box_size.y);
1066 elm_scroller_content_min_limit(sd->scr, EINA_TRUE, EINA_TRUE);
1067 evas_object_size_hint_min_set(sd->scr, box_size.x, box_size.y);
1071 sd->dir = _base_geometry_calc(obj, &rect);
1073 _arrow_update(obj, sd->dir, rect);
1074 _base_shift_by_arrow(obj, sd->arrow, sd->dir, &rect);
1076 //resize scroller according to final size
1077 if ((!sd->content) && (sd->scr))
1079 elm_scroller_content_min_limit(sd->scr, EINA_FALSE, EINA_FALSE);
1080 evas_object_smart_calculate(sd->scr);
1083 evas_object_resize(obj, rect.w, rect.h);
1084 evas_object_size_hint_min_set(wd->resize_obj, rect.w, rect.h);
1086 evas_object_resize(sd->layout, rect.w, rect.h);
1087 evas_object_move(sd->layout, rect.x, rect.y);
1089 evas_object_geometry_get(sd->parent, &x, &y, &w, &h);
1090 evas_object_move(sd->bg, x, y);
1091 evas_object_resize(sd->bg, w, h);
1095 _on_parent_del(void *data,
1096 Evas *e EINA_UNUSED,
1097 Evas_Object *obj EINA_UNUSED,
1098 void *event_info EINA_UNUSED)
1100 evas_object_del(data);
1104 _on_parent_move(void *data,
1105 Evas *e EINA_UNUSED,
1106 Evas_Object *obj EINA_UNUSED,
1107 void *event_info EINA_UNUSED)
1109 ELM_CTXPOPUP_DATA_GET(data, sd);
1112 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1115 elm_layout_sizing_eval(data);
1119 _on_parent_resize(void *data,
1120 Evas *e EINA_UNUSED,
1121 Evas_Object *obj EINA_UNUSED,
1122 void *event_info EINA_UNUSED)
1124 ELM_CTXPOPUP_DATA_GET(data, sd);
1125 ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
1129 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1131 evas_object_hide(data);
1132 eo_do(data, eo_event_callback_call(ELM_CTXPOPUP_EVENT_DISMISSED, NULL));
1136 if (wd->orient_mode == 90 || wd->orient_mode == 270)
1137 elm_widget_theme_object_set
1138 (data, sd->layout, "ctxpopup", "layout/landscape", elm_widget_style_get(data));
1140 elm_widget_theme_object_set
1141 (data, sd->layout, "ctxpopup", "layout", elm_widget_style_get(data));
1142 edje_object_part_swallow(sd->layout, "swallow", wd->resize_obj);
1145 elm_layout_sizing_eval(data);
1147 /* TIZEN_ONLY(20170123): to avoid flickering problem when rotate device
1148 _show_signals_emit(data, sd->dir);
1150 _visible_signals_emit(data, sd->dir);
1156 _parent_detach(Evas_Object *obj)
1158 ELM_CTXPOPUP_DATA_GET(obj, sd);
1160 if (!sd->parent) return;
1162 evas_object_event_callback_del_full
1163 (sd->parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
1164 evas_object_event_callback_del_full
1165 (sd->parent, EVAS_CALLBACK_MOVE, _on_parent_move, obj);
1166 evas_object_event_callback_del_full
1167 (sd->parent, EVAS_CALLBACK_RESIZE, _on_parent_resize, obj);
1171 _on_content_resized(void *data,
1172 Evas *e EINA_UNUSED,
1173 Evas_Object *obj EINA_UNUSED,
1174 void *event_info EINA_UNUSED)
1176 elm_layout_sizing_eval(data);
1180 _access_outline_activate_cb(void *data,
1181 Evas_Object *part_obj EINA_UNUSED,
1182 Elm_Object_Item *item EINA_UNUSED)
1184 evas_object_hide(data);
1185 eo_do(data, eo_event_callback_call(ELM_CTXPOPUP_EVENT_DISMISSED, NULL));
1189 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
1192 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1196 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
1199 ao = _elm_access_edje_object_part_object_register
1200 (obj, wd->resize_obj, ACCESS_OUTLINE_PART);
1202 const char *style = elm_widget_style_get(obj);
1203 if (!strcmp(style, "more/default"))
1205 elm_access_info_set(ao, ELM_ACCESS_TYPE, TTS_STR_MENU_POPUP);
1206 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, TTS_STR_MENU_CLOSE);
1210 elm_access_info_set(ao, ELM_ACCESS_TYPE, E_("Contextual popup"));
1211 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, E_("Double tap to close popup"));
1213 _elm_access_activate_callback_set
1214 (_elm_access_info_get(ao), _access_outline_activate_cb, obj);
1219 _elm_access_edje_object_part_object_unregister
1220 (obj, wd->resize_obj, ACCESS_OUTLINE_PART);
1225 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
1227 ELM_CTXPOPUP_DATA_GET(obj, sd);
1228 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1230 edje_object_mirrored_set(sd->layout, rtl);
1231 edje_object_mirrored_set(sd->arrow, rtl);
1232 edje_object_mirrored_set(wd->resize_obj, rtl);
1235 EOLIAN static Eina_Bool
1236 _elm_ctxpopup_elm_widget_event(Eo *obj, Elm_Ctxpopup_Data *sd, Evas_Object *src EINA_UNUSED, Evas_Callback_Type type, void *event_info)
1238 Evas_Event_Key_Down *ev = event_info;
1240 // TIZEN ONLY(20131221) : When access mode, focused ui is disabled.
1241 if (_elm_config->access_mode) return EINA_FALSE;
1243 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
1244 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
1245 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
1247 //FIXME: for this key event, _elm_ctxpopup_smart_focus_next should be done first
1248 if ((!strcmp(ev->key, "Tab")) ||
1249 (!strcmp(ev->key, "ISO_Left_Tab")))
1252 Evas_Object *target = NULL;
1253 Elm_Object_Item *target_item = NULL;
1254 Elm_Focus_Direction dir;
1256 if (evas_key_modifier_is_set(ev->modifiers, "Control") ||
1257 evas_key_modifier_is_set(ev->modifiers, "Alt"))
1259 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1260 dir = ELM_FOCUS_PREVIOUS;
1262 dir = ELM_FOCUS_NEXT;
1264 ret = elm_widget_focus_next_get(sd->box, dir, &target, &target_item);
1265 if (ret) elm_widget_focus_steal(target, target_item);
1267 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1271 if (((!strcmp(ev->key, "Left")) ||
1272 (!strcmp(ev->key, "KP_Left")) ||
1273 (!strcmp(ev->key, "Right")) ||
1274 (!strcmp(ev->key, "KP_Right")) ||
1275 (!strcmp(ev->key, "Up")) ||
1276 (!strcmp(ev->key, "KP_Up")) ||
1277 (!strcmp(ev->key, "Down")) ||
1278 (!strcmp(ev->key, "KP_Down"))) && (!ev->string))
1280 double degree = 0.0;
1282 if ((!strcmp(ev->key, "Left")) ||
1283 (!strcmp(ev->key, "KP_Left")))
1285 else if ((!strcmp(ev->key, "Right")) ||
1286 (!strcmp(ev->key, "KP_Right")))
1288 else if ((!strcmp(ev->key, "Up")) ||
1289 (!strcmp(ev->key, "KP_Up")))
1291 else if ((!strcmp(ev->key, "Down")) ||
1292 (!strcmp(ev->key, "KP_Down")))
1295 elm_widget_focus_direction_go(sd->box, degree);
1296 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1299 else if (((!strcmp(ev->key, "Home")) ||
1300 (!strcmp(ev->key, "KP_Home")) ||
1301 (!strcmp(ev->key, "Prior")) ||
1302 (!strcmp(ev->key, "KP_Prior"))) && (!ev->string))
1304 Elm_Ctxpopup_Item_Data *it = eina_list_data_get(sd->items);
1305 Evas_Object *btn = it->btn;
1306 elm_object_focus_set(btn, EINA_TRUE);
1307 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1310 else if (((!strcmp(ev->key, "End")) ||
1311 (!strcmp(ev->key, "KP_End")) ||
1312 (!strcmp(ev->key, "Next")) ||
1313 (!strcmp(ev->key, "KP_Next"))) && (!ev->string))
1315 Elm_Ctxpopup_Item_Data *it = eina_list_data_get(eina_list_last(sd->items));
1316 Evas_Object *btn = it->btn;
1317 elm_object_focus_set(btn, EINA_TRUE);
1318 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1322 // TIZEN ONLY : 20130530 : ctxpopup will be dismissed by user
1323 //if (strcmp(ev->keyname, "Escape")) return EINA_FALSE;
1327 _hide_signals_emit(obj, sd->dir);
1329 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1334 //FIXME: lost the content size when theme hook is called.
1335 EOLIAN static Elm_Theme_Apply
1336 _elm_ctxpopup_elm_widget_theme_apply(Eo *obj, Elm_Ctxpopup_Data *sd)
1339 Elm_Ctxpopup_Item_Data *item;
1343 Elm_Theme_Apply int_ret = ELM_THEME_APPLY_FAILED;
1345 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, ELM_THEME_APPLY_FAILED);
1347 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
1348 if (!int_ret) return ELM_THEME_APPLY_FAILED;
1350 rtl = elm_widget_mirrored_get(obj);
1352 elm_widget_theme_object_set
1353 (obj, sd->bg, "ctxpopup", "bg", elm_widget_style_get(obj));
1355 elm_widget_theme_object_set
1356 (obj, sd->arrow, "ctxpopup", "arrow", elm_widget_style_get(obj));
1358 if (wd->orient_mode == 90 || wd->orient_mode == 270)
1359 elm_widget_theme_object_set
1360 (obj, sd->layout, "ctxpopup", "layout/landscape", elm_widget_style_get(obj));
1362 elm_widget_theme_object_set
1363 (obj, sd->layout, "ctxpopup", "layout", elm_widget_style_get(obj));
1364 edje_object_part_swallow(sd->layout, "swallow", wd->resize_obj);
1366 _mirrored_set(obj, rtl);
1369 EINA_LIST_FOREACH(sd->items, elist, item)
1371 edje_object_mirrored_set(VIEW(item), rtl);
1373 if (item->label && item->icon)
1375 if (!sd->horizontal)
1376 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1377 "icon_text_style_item",
1378 elm_widget_style_get(obj));
1380 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1381 "icon_text_style_item_horizontal",
1382 elm_widget_style_get(obj));
1384 else if (item->label)
1386 if (!sd->horizontal)
1387 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1389 elm_widget_style_get(obj));
1391 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1392 "text_style_item_horizontal",
1393 elm_widget_style_get(obj));
1397 if (!sd->horizontal)
1398 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1400 elm_widget_style_get(obj));
1402 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1403 "icon_style_item_horizontal",
1404 elm_widget_style_get(obj));
1408 edje_object_part_text_set(VIEW(item), "elm.text", item->label);
1410 if (eo_do_ret(EO_OBJ(item), tmp, elm_wdg_item_disabled_get()))
1411 edje_object_signal_emit(VIEW(item), "elm,state,disabled", "elm");
1414 * For separator, if the first item has visible separator,
1415 * then it should be aligned with edge of the base part.
1416 * In some cases, it gives improper display. Ex) rounded corner
1417 * So the first item separator should be invisible.
1420 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
1422 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
1424 // reset state of text to be default
1425 edje_object_signal_emit(VIEW(item), "elm,state,text,default", "elm");
1426 edje_object_message_signal_process(VIEW(item));
1429 if (evas_object_visible_get(sd->bg))
1430 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
1434 elm_layout_theme_set(sd->scr, "scroller", "ctxpopup", elm_widget_style_get(obj));
1437 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
1439 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
1442 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1445 elm_layout_sizing_eval(obj);
1448 if (_elm_config->access_mode) _access_obj_process(obj, EINA_TRUE);
1453 /* kind of a big and tricky override here: an internal box will hold
1454 * the actual content. content aliases won't be of much help here */
1455 EOLIAN static Eina_Bool
1456 _elm_ctxpopup_elm_container_content_set(Eo *obj, Elm_Ctxpopup_Data *sd, const char *part, Evas_Object *content)
1458 Evas_Coord min_w = -1, min_h = -1;
1459 Eina_Bool int_ret = EINA_TRUE;
1461 if ((part) && (strcmp(part, "default")))
1463 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_container_content_set(part, content));
1467 if (!content) return EINA_FALSE;
1469 if (content == sd->content) return EINA_TRUE;
1471 if (sd->items) elm_ctxpopup_clear(obj);
1472 if (sd->content) evas_object_del(sd->content);
1474 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1476 evas_object_event_callback_add
1477 (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1478 edje_object_part_swallow(wd->resize_obj, "elm.swallow.content", sd->box);
1480 evas_object_size_hint_weight_set
1481 (content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1482 evas_object_size_hint_fill_set
1483 (content, EVAS_HINT_FILL, EVAS_HINT_FILL);
1485 /* since it's going to be a box content, not a layout's... */
1486 evas_object_show(content);
1488 evas_object_size_hint_min_get(content, &min_w, &min_h);
1489 evas_object_size_hint_min_set(sd->box, min_w, min_h);
1490 elm_box_pack_end(sd->box, content);
1492 sd->content = content;
1493 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1495 if (sd->visible) elm_layout_sizing_eval(obj);
1500 EOLIAN static Evas_Object*
1501 _elm_ctxpopup_elm_container_content_get(Eo *obj, Elm_Ctxpopup_Data *sd, const char *part)
1504 if ((part) && (strcmp(part, "default")))
1506 Evas_Object *ret = NULL;
1507 eo_do_super(obj, MY_CLASS, ret = elm_obj_container_content_get(part));
1514 EOLIAN static Evas_Object*
1515 _elm_ctxpopup_elm_container_content_unset(Eo *obj, Elm_Ctxpopup_Data *sd, const char *part)
1517 Evas_Object *content = NULL;
1519 if ((part) && (strcmp(part, "default")))
1521 eo_do_super(obj, MY_CLASS, content = elm_obj_container_content_unset(part));
1525 content = sd->content;
1526 if (!content) return content;
1528 elm_box_unpack(sd->box, content);
1530 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1532 if (sd->visible) elm_layout_sizing_eval(obj);
1538 _elm_ctxpopup_item_elm_widget_item_part_text_set(Eo *eo_ctxpopup_it EINA_UNUSED,
1539 Elm_Ctxpopup_Item_Data *ctxpopup_it,
1543 if (!ctxpopup_it) return;
1544 if (ctxpopup_it->label == label) return;
1545 if ((part) && (strcmp(part, "default"))) return;
1547 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
1549 if (ctxpopup_it->label && !label)
1551 if (!sd->horizontal)
1552 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1554 elm_widget_style_get(WIDGET(ctxpopup_it)));
1556 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1557 "icon_style_item_horizontal",
1558 elm_widget_style_get(WIDGET(ctxpopup_it)));
1560 else if (!ctxpopup_it->label && label)
1562 if (!ctxpopup_it->icon)
1564 if (!sd->horizontal)
1565 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1567 elm_widget_style_get(WIDGET(ctxpopup_it)));
1569 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1570 "text_style_item_horizontal",
1571 elm_widget_style_get(WIDGET(ctxpopup_it)));
1575 if (!sd->horizontal)
1576 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1577 "icon_text_style_item",
1578 elm_widget_style_get(WIDGET(ctxpopup_it)));
1580 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1581 "icon_text_style_item_horizontal",
1582 elm_widget_style_get(WIDGET(ctxpopup_it)));
1586 eina_stringshare_replace(&ctxpopup_it->label, label);
1587 if (ctxpopup_it->label)
1588 edje_object_part_text_set(VIEW(ctxpopup_it), "elm.text", label);
1590 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1593 elm_layout_sizing_eval(WIDGET(ctxpopup_it));
1596 EOLIAN static const char *
1597 _elm_ctxpopup_item_elm_widget_item_part_text_get(Eo *eo_ctxpopup_it EINA_UNUSED,
1598 Elm_Ctxpopup_Item_Data *ctxpopup_it,
1601 if (part && strcmp(part, "default")) return NULL;
1603 return ctxpopup_it->label;
1607 _elm_ctxpopup_item_elm_widget_item_part_content_set(Eo *eo_ctxpopup_it EINA_UNUSED,
1608 Elm_Ctxpopup_Item_Data *ctxpopup_it,
1610 Evas_Object *content)
1612 if (!ctxpopup_it) return;
1613 if (ctxpopup_it->icon == content) return;
1614 if ((part) && (strcmp(part, "icon"))) return;
1616 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
1618 if (ctxpopup_it->icon)
1619 evas_object_del(ctxpopup_it->icon);
1621 if (ctxpopup_it->label)
1623 if (!ctxpopup_it->icon && content)
1625 if (!sd->horizontal)
1626 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1627 "icon_text_style_item",
1628 elm_widget_style_get(WIDGET(ctxpopup_it)));
1630 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1631 "icon_text_style_item_horizontal",
1632 elm_widget_style_get(WIDGET(ctxpopup_it)));
1634 else if (ctxpopup_it->icon && !content)
1636 if (!sd->horizontal)
1637 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1639 elm_widget_style_get(WIDGET(ctxpopup_it)));
1641 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1642 "text_style_item_horizontal",
1643 elm_widget_style_get(WIDGET(ctxpopup_it)));
1647 ctxpopup_it->icon = content;
1648 if (ctxpopup_it->icon)
1649 edje_object_part_swallow(VIEW(ctxpopup_it), "elm.swallow.icon", ctxpopup_it->icon);
1651 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1654 elm_layout_sizing_eval(WIDGET(ctxpopup_it));
1657 EOLIAN static Evas_Object *
1658 _elm_ctxpopup_item_elm_widget_item_part_content_get(Eo *eo_ctxpopup_it EINA_UNUSED,
1659 Elm_Ctxpopup_Item_Data *ctxpopup_it,
1662 if (part && strcmp(part, "icon")) return NULL;
1664 return ctxpopup_it->icon;
1667 EOLIAN static Evas_Object *
1668 _elm_ctxpopup_item_elm_widget_item_part_content_unset(Eo *eo_ctxpopup_it EINA_UNUSED,
1669 Elm_Ctxpopup_Item_Data *ctxpopup_it,
1672 Evas_Object *content = NULL;
1674 if (!ctxpopup_it || !ctxpopup_it->icon) return NULL;
1675 if ((part) && (strcmp(part, "icon"))) return NULL;
1677 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
1679 edje_object_part_unswallow(VIEW(ctxpopup_it), ctxpopup_it->icon);
1680 evas_object_hide(ctxpopup_it->icon);
1682 if (ctxpopup_it->label)
1684 if (!sd->horizontal)
1685 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1687 elm_widget_style_get(WIDGET(ctxpopup_it)));
1689 _elm_theme_object_set(WIDGET(ctxpopup_it), VIEW(ctxpopup_it), "ctxpopup",
1690 "text_style_item_horizontal",
1691 elm_widget_style_get(WIDGET(ctxpopup_it)));
1694 content = ctxpopup_it->icon;
1695 ctxpopup_it->icon = NULL;
1697 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1700 elm_layout_sizing_eval(WIDGET(ctxpopup_it));
1706 _elm_ctxpopup_item_elm_widget_item_disable(Eo *eo_ctxpopup_it,
1707 Elm_Ctxpopup_Item_Data *ctxpopup_it)
1709 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
1713 if (eo_do_ret(eo_ctxpopup_it, tmp, elm_wdg_item_disabled_get()))
1714 edje_object_signal_emit(VIEW(ctxpopup_it), "elm,state,disabled", "elm");
1716 edje_object_signal_emit(VIEW(ctxpopup_it), "elm,state,enabled", "elm");
1720 _elm_ctxpopup_item_elm_widget_item_signal_emit(Eo *eo_ctxpopup_it EINA_UNUSED,
1721 Elm_Ctxpopup_Item_Data *ctxpopup_it,
1722 const char *emission,
1725 edje_object_signal_emit(VIEW(ctxpopup_it), emission, source);
1729 _elm_ctxpopup_item_elm_widget_item_style_set(Eo *eo_item EINA_UNUSED,
1730 Elm_Ctxpopup_Item_Data *item,
1733 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
1735 if (item->icon && item->label)
1738 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "icon_text_style_item_horizontal", style);
1740 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "icon_text_style_item", style);
1742 else if (item->label)
1745 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "text_style_item_horizontal", style);
1747 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "text_style_item", style);
1752 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "icon_style_item_horizontal", style);
1754 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "icon_style_item", style);
1757 if (sd->visible) elm_layout_sizing_eval(WIDGET(item));
1761 _bg_clicked_cb(void *data,
1762 Evas_Object *obj EINA_UNUSED,
1763 const char *emission EINA_UNUSED,
1764 const char *source EINA_UNUSED)
1766 ELM_CTXPOPUP_DATA_GET(data, sd);
1768 _hide_signals_emit(data, sd->dir);
1772 _on_show(void *data EINA_UNUSED,
1773 Evas *e EINA_UNUSED,
1775 void *event_info EINA_UNUSED)
1778 Elm_Ctxpopup_Item_Data *item;
1781 ELM_CTXPOPUP_DATA_GET(obj, sd);
1782 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1784 sd->visible = EINA_TRUE;
1785 //TIZEN_ONLY(20170919): Handle default label object
1786 _elm_win_default_label_obj_append(obj);
1789 elm_layout_signal_emit(obj, "elm,state,show", "elm");
1791 if (wd->orient_mode == 90 || wd->orient_mode == 270)
1792 elm_widget_theme_object_set
1793 (obj, sd->layout, "ctxpopup", "layout/landscape", elm_widget_style_get(obj));
1795 elm_widget_theme_object_set
1796 (obj, sd->layout, "ctxpopup", "layout", elm_widget_style_get(obj));
1797 edje_object_part_swallow(sd->layout, "swallow", wd->resize_obj);
1799 EINA_LIST_FOREACH(sd->items, elist, item)
1801 if (item->label && item->icon)
1803 if (!sd->horizontal)
1804 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1805 "icon_text_style_item",
1806 elm_widget_style_get(obj));
1808 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1809 "icon_text_style_item_horizontal",
1810 elm_widget_style_get(obj));
1812 else if (item->label)
1814 if (!sd->horizontal)
1815 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1817 elm_widget_style_get(obj));
1819 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1820 "text_style_item_horizontal",
1821 elm_widget_style_get(obj));
1825 if (!sd->horizontal)
1826 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1828 elm_widget_style_get(obj));
1830 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1831 "icon_style_item_horizontal",
1832 elm_widget_style_get(obj));
1836 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
1838 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
1841 elm_layout_sizing_eval(obj);
1843 elm_object_focus_set(obj, EINA_TRUE);
1844 _show_signals_emit(obj, sd->dir);
1848 _elm_ctxpopup_item_elm_widget_item_focus_set(Eo *eo_ctxpopup_it EINA_UNUSED,
1849 Elm_Ctxpopup_Item_Data *ctxpopup_it,
1852 elm_object_focus_set(ctxpopup_it->btn, focused);
1855 EOLIAN static Eina_Bool
1856 _elm_ctxpopup_item_elm_widget_item_focus_get(Eo *eo_ctxpopup_it EINA_UNUSED,
1857 Elm_Ctxpopup_Item_Data *ctxpopup_it)
1859 return elm_object_focus_get(ctxpopup_it->btn);
1863 _on_hide(void *data EINA_UNUSED,
1864 Evas *e EINA_UNUSED,
1866 void *event_info EINA_UNUSED)
1868 ELM_CTXPOPUP_DATA_GET(obj, sd);
1870 if (!sd->visible) return;
1872 sd->visible = EINA_FALSE;
1873 //TIZEN_ONLY(20170919): Handle default label object
1874 _elm_win_default_label_obj_remove(obj);
1879 _on_move(void *data EINA_UNUSED,
1880 Evas *e EINA_UNUSED,
1882 void *event_info EINA_UNUSED)
1884 ELM_CTXPOPUP_DATA_GET(obj, sd);
1886 if (sd->visible) elm_layout_sizing_eval(obj);
1890 _hide_finished_cb(void *data,
1891 Evas_Object *obj EINA_UNUSED,
1892 const char *emission EINA_UNUSED,
1893 const char *source EINA_UNUSED)
1895 evas_object_hide(data);
1896 eo_do(data, eo_event_callback_call(ELM_CTXPOPUP_EVENT_DISMISSED, NULL));
1899 /* TIZEN_ONLY(20161207): add show finished callback */
1901 _show_finished_cb(void *data,
1902 Evas_Object *obj EINA_UNUSED,
1903 const char *emission EINA_UNUSED,
1904 const char *source EINA_UNUSED)
1906 elm_object_focus_set(data, EINA_TRUE);
1911 _list_del(Eo *obj, Elm_Ctxpopup_Data *sd)
1913 if (!sd->scr) return;
1915 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1917 edje_object_part_unswallow(wd->resize_obj, sd->scr);
1918 evas_object_del(sd->scr);
1920 evas_object_del(sd->box);
1925 _list_new(Evas_Object *obj)
1927 ELM_CTXPOPUP_DATA_GET(obj, sd);
1930 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1932 sd->scr = elm_scroller_add(obj);
1933 elm_layout_theme_set(sd->scr, "scroller", "ctxpopup", elm_widget_style_get(obj));
1934 evas_object_size_hint_align_set(sd->scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
1935 _elm_widget_color_class_parent_set(sd->scr, obj);
1938 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
1940 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
1942 edje_object_part_swallow(wd->resize_obj, "elm.swallow.content", sd->scr);
1943 //TIZEN ONLY(20161014) : Accessibility: scroll the content when highlight frame goes out of view port
1944 evas_object_smart_callback_add(sd->scr, "scroll,down", _content_move_down_cb, (void*)obj);
1945 evas_object_smart_callback_add(sd->scr, "scroll,up", _content_move_up_cb, (void*)obj);
1947 elm_object_content_set(sd->scr, sd->box);
1948 elm_ctxpopup_horizontal_set(obj, sd->horizontal);
1951 EOLIAN static Eina_Bool
1952 _elm_ctxpopup_elm_widget_disable(Eo *obj, Elm_Ctxpopup_Data *sd)
1955 Elm_Ctxpopup_Item_Data *it;
1956 Eina_Bool int_ret = EINA_FALSE;
1958 eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_disable());
1959 if (!int_ret) return EINA_FALSE;
1961 EINA_LIST_FOREACH(sd->items, l, it)
1962 elm_object_item_disabled_set(EO_OBJ(it), elm_widget_disabled_get(obj));
1968 _elm_ctxpopup_evas_object_smart_add(Eo *obj, Elm_Ctxpopup_Data *priv)
1970 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1972 eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
1974 if (!elm_widget_sub_object_parent_add(obj))
1975 ERR("could not add %p as sub object of %p", obj, elm_object_parent_widget_get(obj));
1977 elm_layout_theme_set(obj, "ctxpopup", "base", elm_widget_style_get(obj));
1980 priv->bg = edje_object_add(evas_object_evas_get(obj));
1981 elm_widget_theme_object_set(obj, priv->bg, "ctxpopup", "bg", "default");
1982 edje_object_signal_callback_add
1983 (priv->bg, "elm,action,click", "", _bg_clicked_cb, obj);
1984 evas_object_smart_member_add(priv->bg, obj);
1985 evas_object_stack_below(priv->bg, wd->resize_obj);
1986 _elm_widget_color_class_parent_set(priv->bg, obj);
1989 priv->arrow = edje_object_add(evas_object_evas_get(obj));
1990 elm_widget_theme_object_set
1991 (obj, priv->arrow, "ctxpopup", "arrow", "default");
1992 _elm_widget_color_class_parent_set(priv->arrow, obj);
1994 priv->dir_priority[0] = ELM_CTXPOPUP_DIRECTION_UP;
1995 priv->dir_priority[1] = ELM_CTXPOPUP_DIRECTION_LEFT;
1996 priv->dir_priority[2] = ELM_CTXPOPUP_DIRECTION_RIGHT;
1997 priv->dir_priority[3] = ELM_CTXPOPUP_DIRECTION_DOWN;
1998 priv->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
2000 priv->auto_hide = EINA_TRUE;
2001 priv->mouse_down = EINA_FALSE;
2002 priv->multi_down = 0;
2004 priv->box = elm_box_add(obj);
2005 evas_object_size_hint_weight_set
2006 (priv->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2008 priv->layout = edje_object_add(evas_object_evas_get(obj));
2009 if (wd->orient_mode == 90 || wd->orient_mode == 270)
2010 elm_widget_theme_object_set(obj, priv->layout, "ctxpopup", "layout/landscape", "default");
2012 elm_widget_theme_object_set(obj, priv->layout, "ctxpopup", "layout", "default");
2013 evas_object_smart_member_add(priv->layout, obj);
2014 _elm_widget_color_class_parent_set(priv->layout, obj);
2016 edje_object_signal_callback_add
2017 (priv->layout, "elm,action,hide,finished", "", _hide_finished_cb, obj);
2018 /* TIZEN_ONLY(20161207): Add show finished callback */
2019 edje_object_signal_callback_add
2020 (priv->layout, "elm,action,show,finished", "", _show_finished_cb, obj);
2023 edje_object_part_swallow(priv->layout, "swallow", wd->resize_obj);
2024 evas_object_size_hint_weight_set
2025 (priv->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2027 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _on_show, NULL);
2028 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _on_hide, NULL);
2029 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _on_move, NULL);
2031 _mirrored_set(obj, elm_widget_mirrored_get(obj));
2033 elm_widget_can_focus_set(obj, EINA_TRUE);
2034 elm_ctxpopup_hover_parent_set(obj, elm_object_parent_widget_get(obj));
2036 if (_elm_config->access_mode) _access_obj_process(obj, EINA_TRUE);
2038 /* access: parent could be any object such as elm_list which does
2039 not know elc_ctxpopup as its child object in the focus_next(); */
2041 wd->highlight_root = EINA_TRUE;
2043 //Tizen Only: This should be removed when eo is applied.
2044 wd->on_create = EINA_FALSE;
2048 _elm_ctxpopup_evas_object_smart_del(Eo *obj, Elm_Ctxpopup_Data *sd)
2050 evas_object_event_callback_del_full
2051 (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
2052 _parent_detach(obj);
2061 evas_object_del(sd->box);
2065 evas_object_del(sd->arrow);
2066 sd->arrow = NULL; /* stops _sizing_eval() from going on on deletion */
2068 evas_object_del(sd->bg);
2071 evas_object_del(sd->layout);
2074 eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
2078 _elm_ctxpopup_elm_widget_parent_set(Eo *obj, Elm_Ctxpopup_Data *_pd EINA_UNUSED, Evas_Object *parent)
2080 //default parent is to be hover parent
2081 elm_ctxpopup_hover_parent_set(obj, parent);
2086 _elm_ctxpopup_smart_access(Evas_Object *obj, Eina_Bool is_access)
2088 ELM_CTXPOPUP_CHECK(obj);
2090 _access_obj_process(obj, is_access);
2092 evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
2095 static Evas_Object *
2096 _elm_ctxpopup_smart_access_object_get(Evas_Object *obj, char *part)
2098 ELM_CTXPOPUP_CHECK(obj) NULL;
2100 return _access_object_get(obj, part);
2105 _elm_ctxpopup_class_constructor(Eo_Class *klass)
2107 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
2111 elm_ctxpopup_add(Evas_Object *parent)
2113 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
2114 Evas_Object *obj = eo_add(MY_CLASS, parent);
2116 /* access: parent could be any object such as elm_list which does
2117 not know elc_ctxpopup as its child object in the focus_next(); */
2118 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
2119 wd->highlight_root = EINA_TRUE;
2125 _elm_ctxpopup_eo_base_constructor(Eo *obj, Elm_Ctxpopup_Data *_pd EINA_UNUSED)
2127 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
2129 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
2130 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
2131 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_POPUP_MENU));
2138 _elm_ctxpopup_hover_parent_set(Eo *obj, Elm_Ctxpopup_Data *sd, Evas_Object *parent)
2140 Evas_Coord x, y, w, h;
2142 if (!parent) return;
2144 _parent_detach(obj);
2146 evas_object_event_callback_add
2147 (parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
2148 evas_object_event_callback_add
2149 (parent, EVAS_CALLBACK_MOVE, _on_parent_move, obj);
2150 evas_object_event_callback_add
2151 (parent, EVAS_CALLBACK_RESIZE, _on_parent_resize, obj);
2153 sd->parent = parent;
2156 evas_object_geometry_get(parent, &x, &y, &w, &h);
2157 evas_object_move(sd->bg, x, y);
2158 evas_object_resize(sd->bg, w, h);
2160 if (sd->visible) elm_layout_sizing_eval(obj);
2163 EOLIAN static Evas_Object*
2164 _elm_ctxpopup_hover_parent_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2170 _elm_ctxpopup_clear(Eo *obj, Elm_Ctxpopup_Data *sd)
2174 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
2176 elm_object_content_unset(sd->scr);
2177 edje_object_part_unswallow(wd->resize_obj, sd->scr);
2178 evas_object_del(sd->scr);
2180 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
2184 _elm_ctxpopup_horizontal_set(Eo *obj, Elm_Ctxpopup_Data *sd, Eina_Bool horizontal)
2187 Elm_Ctxpopup_Item_Data *item;
2190 sd->horizontal = !!horizontal;
2197 elm_box_horizontal_set(sd->box, EINA_FALSE);
2198 elm_scroller_bounce_set(sd->scr, EINA_FALSE, EINA_TRUE);
2199 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
2203 elm_box_horizontal_set(sd->box, EINA_TRUE);
2204 elm_scroller_bounce_set(sd->scr, EINA_TRUE, EINA_FALSE);
2205 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
2208 EINA_LIST_FOREACH(sd->items, elist, item)
2210 if (item->label && item->icon)
2212 if (!sd->horizontal)
2213 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
2214 "icon_text_style_item",
2215 elm_widget_style_get(obj));
2217 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
2218 "icon_text_style_item_horizontal",
2219 elm_widget_style_get(obj));
2221 else if (item->label)
2223 if (!sd->horizontal)
2224 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
2226 elm_widget_style_get(obj));
2228 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
2229 "text_style_item_horizontal",
2230 elm_widget_style_get(obj));
2234 if (!sd->horizontal)
2235 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
2237 elm_widget_style_get(obj));
2239 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
2240 "icon_style_item_horizontal",
2241 elm_widget_style_get(obj));
2244 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
2246 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
2248 eo_do(EO_OBJ(item), elm_wdg_item_disable());
2251 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
2253 if (sd->visible) elm_layout_sizing_eval(obj);
2256 EOLIAN static Eina_Bool
2257 _elm_ctxpopup_horizontal_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2259 return sd->horizontal;
2263 _elm_ctxpopup_item_eo_base_constructor(Eo *obj, Elm_Ctxpopup_Item_Data *it)
2265 obj = eo_do_super_ret(obj, ELM_CTXPOPUP_ITEM_CLASS, obj, eo_constructor());
2266 it->base = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
2267 //TIZEN ONLY(20150710)ctxpopup: Accessible methods for children_get, extents_get and item name_get
2268 eo_do(obj, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_MENU_ITEM));
2274 _elm_ctxpopup_item_eo_base_destructor(Eo *eo_ctxpopup_it,
2275 Elm_Ctxpopup_Item_Data *ctxpopup_it EINA_UNUSED)
2277 eo_do_super(eo_ctxpopup_it, ELM_CTXPOPUP_ITEM_CLASS, eo_destructor());
2280 static Elm_Ctxpopup_Item_Data *
2281 _item_new(Evas_Object *obj,
2282 Elm_Ctxpopup_Data *sd,
2288 Evas_Object *content, *focus_bt;
2291 eo_item = eo_add(ELM_CTXPOPUP_ITEM_CLASS, obj, elm_obj_ctxpopup_item_init(func, data));
2292 if (!eo_item) return NULL;
2294 ELM_CTXPOPUP_ITEM_DATA_GET(eo_item, item);
2296 //The first item is appended.
2297 content = elm_object_content_unset(obj);
2298 if (content) evas_object_del(content);
2305 if (!sd->horizontal)
2306 _item_theme_set(item, "icon_text_style_item");
2308 _item_theme_set(item, "icon_text_style_item_horizontal");
2312 if (!sd->horizontal)
2313 _item_theme_set(item, "text_style_item");
2315 _item_theme_set(item, "text_style_item_horizontal");
2319 if (!sd->horizontal)
2320 _item_theme_set(item, "icon_style_item");
2322 _item_theme_set(item, "icon_style_item_horizontal");
2327 edje_object_part_text_set(VIEW(item), "elm.text", label);
2328 item->label = eina_stringshare_add(label);
2333 edje_object_part_swallow(VIEW(item), "elm.swallow.icon", icon);
2337 focus_bt = _item_in_focusable_button(item);
2338 item->btn = focus_bt;
2339 _elm_widget_color_class_parent_set(VIEW(item), obj);
2341 if (_elm_config->access_mode) _access_focusable_button_register(focus_bt, item);
2346 EOLIAN static Elm_Object_Item*
2347 _elm_ctxpopup_item_insert_before(Eo *obj, Elm_Ctxpopup_Data *sd, Elm_Object_Item *eo_before, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
2349 Elm_Ctxpopup_Item_Data *item;
2351 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_before, NULL);
2352 ELM_CTXPOPUP_ITEM_DATA_GET(eo_before, before_it);
2353 ELM_CTXPOPUP_ITEM_CHECK_OR_RETURN(before_it, NULL);
2355 if (!before_it->btn) return NULL;
2357 item = _item_new(obj, sd, label, icon, func, data);
2358 if (!item) return NULL;
2360 elm_box_pack_before(sd->box, item->btn, before_it->btn);
2361 sd->items = eina_list_prepend_relative(sd->items, item, before_it);
2363 _items_sizing_eval(obj, sd);
2365 return EO_OBJ(item);
2368 EOLIAN static Elm_Object_Item*
2369 _elm_ctxpopup_item_insert_after(Eo *obj, Elm_Ctxpopup_Data *sd, Elm_Object_Item *eo_after, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
2371 Elm_Ctxpopup_Item_Data *item;
2373 EINA_SAFETY_ON_NULL_RETURN_VAL(eo_after, NULL);
2374 ELM_CTXPOPUP_ITEM_DATA_GET(eo_after, after_it);
2375 ELM_CTXPOPUP_ITEM_CHECK_OR_RETURN(after_it, NULL);
2377 if (!after_it->btn) return NULL;
2379 item = _item_new(obj, sd, label, icon, func, data);
2380 if (!item) return NULL;
2382 elm_box_pack_after(sd->box, item->btn, after_it->btn);
2383 sd->items = eina_list_append_relative(sd->items, item, after_it);
2385 _items_sizing_eval(obj, sd);
2387 return EO_OBJ(item);
2390 EOLIAN static Elm_Object_Item*
2391 _elm_ctxpopup_item_append(Eo *obj, Elm_Ctxpopup_Data *sd, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data)
2393 Elm_Ctxpopup_Item_Data *item;
2395 item = _item_new(obj, sd, label, icon, func, data);
2396 if (!item) return NULL;
2398 elm_box_pack_end(sd->box, item->btn);
2399 sd->items = eina_list_append(sd->items, item);
2401 _items_sizing_eval(obj, sd);
2403 return EO_OBJ(item);
2406 EOLIAN static Elm_Object_Item*
2407 _elm_ctxpopup_item_prepend(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd EINA_UNUSED, const char *label EINA_UNUSED, Evas_Object *icon EINA_UNUSED, Evas_Smart_Cb func EINA_UNUSED, const void *data EINA_UNUSED)
2409 Elm_Ctxpopup_Item_Data *item;
2411 item = _item_new(obj, sd, label, icon, func, data);
2412 if (!item) return NULL;
2414 elm_box_pack_start(sd->box, item->btn);
2415 sd->items = eina_list_prepend(sd->items, item);
2417 _items_sizing_eval(obj, sd);
2419 return EO_OBJ(item);
2423 _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)
2425 sd->dir_priority[0] = first;
2426 sd->dir_priority[1] = second;
2427 sd->dir_priority[2] = third;
2428 sd->dir_priority[3] = fourth;
2430 if (sd->visible) elm_layout_sizing_eval(obj);
2434 _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)
2436 if (first) *first = sd->dir_priority[0];
2437 if (second) *second = sd->dir_priority[1];
2438 if (third) *third = sd->dir_priority[2];
2439 if (fourth) *fourth = sd->dir_priority[3];
2442 EOLIAN static Elm_Ctxpopup_Direction
2443 _elm_ctxpopup_direction_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2449 elm_ctxpopup_direction_available_get(Evas_Object *obj, Elm_Ctxpopup_Direction direction)
2451 ELM_CTXPOPUP_CHECK(obj) EINA_FALSE;
2452 ELM_CTXPOPUP_DATA_GET(obj, sd);
2454 elm_layout_sizing_eval(obj);
2456 if (sd->dir == direction) return EINA_TRUE;
2461 _elm_ctxpopup_dismiss(Eo *obj, Elm_Ctxpopup_Data *sd)
2463 _hide_signals_emit(obj, sd->dir);
2467 _elm_ctxpopup_auto_hide_disabled_set(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd, Eina_Bool disabled)
2469 disabled = !!disabled;
2470 if (sd->auto_hide == !disabled) return;
2471 sd->auto_hide = !disabled;
2474 EOLIAN static Eina_Bool
2475 _elm_ctxpopup_auto_hide_disabled_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2477 return !sd->auto_hide;
2480 // TIZEN_ONLY(20170116): merge eo & header files for different profiles
2481 EOLIAN static const Eina_List*
2482 _elm_ctxpopup_items_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2487 EOLIAN static Elm_Object_Item*
2488 _elm_ctxpopup_first_item_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2490 if (!sd->items) return NULL;
2492 return eina_list_data_get(sd->items);
2495 EOLIAN static Elm_Object_Item*
2496 _elm_ctxpopup_last_item_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2498 if (!sd->items) return NULL;
2500 return eina_list_data_get(eina_list_last(sd->items));
2503 EOLIAN static Elm_Object_Item *
2504 _elm_ctxpopup_item_prev_get(Eo *eo_item EINA_UNUSED, Elm_Ctxpopup_Item_Data *item)
2508 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
2510 if (!sd->items) return NULL;
2512 l = eina_list_data_find_list(sd->items, eo_item);
2513 if (l && l->prev) return eina_list_data_get(l->prev);
2518 EOLIAN static Elm_Object_Item *
2519 _elm_ctxpopup_item_next_get(Eo *eo_item EINA_UNUSED, Elm_Ctxpopup_Item_Data *item)
2523 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
2525 if (!sd->items) return NULL;
2527 l = eina_list_data_find_list(sd->items, eo_item);
2528 if (l && l->next) return eina_list_data_get(l->next);
2535 _elm_ctxpopup_item_init(Eo *eo_item,
2536 Elm_Ctxpopup_Item_Data *item,
2541 eo_do(eo_item, obj = eo_parent_get());
2543 item->wcb.org_func_cb = func;
2544 item->wcb.org_data = data;
2545 item->wcb.cobj = obj;
2548 //TIZEN ONLY(20160918): name interface added
2549 EOLIAN static const char*
2550 _elm_ctxpopup_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Ctxpopup_Data *sd EINA_UNUSED)
2553 char *accessible_name = NULL;
2554 const char *style = elm_widget_style_get(obj);
2556 eo_do_super(obj, ELM_CTXPOPUP_CLASS, accessible_name = (char *)elm_interface_atspi_accessible_name_get());
2557 if (accessible_name) return accessible_name;
2559 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
2560 buf = eina_strbuf_new();
2561 if (!strcmp(style, "more/default"))
2562 eina_strbuf_append_printf(buf, "%s", N_("More menu popup"));
2564 eina_strbuf_append_printf(buf, "%s", E_("Alert"));
2565 accessible_name = eina_strbuf_string_steal(buf);
2566 eina_strbuf_free(buf);
2568 eina_stringshare_del(wd->accessible_name);
2569 wd->accessible_name = eina_stringshare_add(accessible_name);
2570 free(accessible_name);
2571 return wd->accessible_name;
2575 EOLIAN static const Elm_Atspi_Action*
2576 _elm_ctxpopup_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd EINA_UNUSED)
2578 static Elm_Atspi_Action atspi_actions[] = {
2579 { "escape", "escape", NULL, _key_action_escape},
2580 { "move,previous", "move", "previous", _key_action_move},
2581 { "move,next", "move", "next", _key_action_move},
2582 { "move,left", "move", "left", _key_action_move},
2583 { "move,right", "move", "right", _key_action_move},
2584 { "move,up", "move", "up", _key_action_move},
2585 { "move,down", "move", "down", _key_action_move},
2586 { NULL, NULL, NULL, NULL }
2588 return &atspi_actions[0];
2591 EOLIAN static Elm_Atspi_State_Set
2592 _elm_ctxpopup_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Ctxpopup_Data *sd)
2594 Elm_Atspi_State_Set ret;
2595 eo_do_super(obj, MY_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
2597 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MODAL);
2599 if (_elm_object_accessibility_currently_highlighted_get() == (void*)sd->scr)
2600 STATE_TYPE_SET(ret, ELM_ATSPI_STATE_HIGHLIGHTED);
2604 //TIZEN ONLY(20150710): ctxpopup: Accessible methods for children_get, extents_get and item name_get
2606 _elm_ctxpopup_elm_interface_atspi_accessible_children_get(Eo *eo_item EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2608 Eina_List *ret = NULL;
2609 Eina_List *l = NULL;
2610 Elm_Ctxpopup_Item_Data *it;
2612 EINA_LIST_FOREACH(sd->items, l, it)
2613 ret = eina_list_append(ret, EO_OBJ(it));
2619 _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)
2631 evas_object_geometry_get(sd->scr, x, y, w, h);
2635 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->scr));
2637 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
2644 //TIZEN ONLY(20150708): popup and ctxpopup accessibility highlight impementation
2645 EOLIAN static Eina_Bool
2646 _elm_ctxpopup_elm_interface_atspi_component_highlight_grab(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2650 elm_object_accessibility_highlight_set(sd->scr, EINA_TRUE);
2651 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
2652 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
2659 EOLIAN static Eina_Bool
2660 _elm_ctxpopup_elm_interface_atspi_component_highlight_clear(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd)
2664 elm_object_accessibility_highlight_set(sd->scr, EINA_FALSE);
2665 ///TIZEN_ONLY(20170717) : expose highlight information on atspi
2666 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
2674 //TIZEN ONLY(20150710)ctxpopup: Accessible methods for children_get, extents_get and item name_get
2676 _elm_ctxpopup_item_elm_interface_atspi_accessible_name_get(Eo *eo_it, Elm_Ctxpopup_Item_Data *item)
2678 char *accessible_name = NULL;
2679 eo_do_super(eo_it, ELM_CTXPOPUP_ITEM_CLASS, accessible_name = (char *)elm_interface_atspi_accessible_name_get());
2680 if (accessible_name) return accessible_name;
2682 if(item->icon && !item->label)
2684 const char *icon_name = NULL;
2685 eo_do(item->icon, icon_name = elm_interface_atspi_accessible_name_get());
2689 return _elm_widget_item_accessible_plain_name_get(eo_it, item->label);
2694 _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
2696 elm_ctxpopup_dismiss(obj);
2701 _item_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
2703 ELM_CTXPOPUP_ITEM_DATA_GET(obj, item);
2705 if (item->wcb.org_func_cb)
2706 item->wcb.org_func_cb((void*)item->wcb.org_data, WIDGET(item), EO_OBJ(item));
2710 EOLIAN static const Elm_Atspi_Action*
2711 _elm_ctxpopup_item_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Ctxpopup_Item_Data *sd EINA_UNUSED)
2713 static Elm_Atspi_Action atspi_actions[] = {
2714 { "activate", "activate", NULL, _item_action_activate},
2715 { NULL, NULL, NULL, NULL }
2717 return &atspi_actions[0];
2720 //TIZEN ONLY(20161014) : Accessibility: scroll the content when highlight frame goes out of view port
2722 _is_item_in_viewport(int viewport_y, int viewport_h, int obj_y, int obj_h)
2724 if ((obj_y + obj_h/2) < viewport_y)
2726 else if ((obj_y + obj_h/2) > viewport_y + viewport_h)
2731 EOLIAN static Eina_Bool
2732 _elm_ctxpopup_item_elm_interface_atspi_component_highlight_grab(Eo *eo_it, Elm_Ctxpopup_Item_Data *it)
2734 Evas_Coord wy, wh, x, y, w, h, bx, by;
2735 ELM_CTXPOPUP_DATA_GET_OR_RETURN_VAL(WIDGET(it), sd, EINA_FALSE);
2737 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
2738 eo_do(sd->scr, elm_interface_scrollable_content_viewport_geometry_get(NULL, &wy, NULL, &wh));
2739 int res = _is_item_in_viewport(wy, wh, y, h);
2743 evas_object_geometry_get(sd->box, &bx, &by, NULL, NULL);
2744 evas_smart_objects_calculate(evas_object_evas_get(sd->box));
2750 eo_do(sd->scr, elm_interface_scrollable_content_region_show(x, y, w, h));
2755 eo_do(sd->scr, elm_interface_scrollable_content_region_show(x, y, w, h));
2759 elm_object_accessibility_highlight_set(eo_it, EINA_TRUE);
2760 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
2761 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
2762 // If you call eo_do_super, then you do NOT have to call smart callback.
2763 evas_object_smart_callback_call(WIDGET(it), "atspi,highlighted", EO_OBJ(it));
2768 EOLIAN static Eina_Bool
2769 _elm_ctxpopup_item_elm_interface_atspi_component_highlight_clear(Eo *eo_it, Elm_Ctxpopup_Item_Data *it EINA_UNUSED)
2771 elm_object_accessibility_highlight_set(eo_it, EINA_FALSE);
2772 elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
2773 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
2774 // If you call eo_do_super, then you do NOT have to call smart callback.
2775 evas_object_smart_callback_call(WIDGET(it), "atspi,unhighlighted", EO_OBJ(it));
2781 _content_move_down_cb(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
2783 if (!_elm_atspi_enabled())
2785 ELM_CTXPOPUP_DATA_GET(data, pd);
2786 Elm_Ctxpopup_Item_Data *it_data;
2787 Evas_Object *highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
2789 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
2791 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
2792 highlighted_obj = id->view;
2795 Evas_Object *parent = highlighted_obj;
2797 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
2799 while ((parent = elm_widget_parent_get(parent)))
2803 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
2805 while ((parent = evas_object_smart_parent_get(parent)))
2809 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
2812 WRN("Improper highlighted object: %p", highlighted_obj);
2819 int obj_x, obj_y, w, h, hx, hy, hw, hh;
2820 eo_do(pd->scr, elm_interface_scrollable_content_viewport_geometry_get(&obj_x, &obj_y, &w, &h));
2821 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
2823 Elm_Ctxpopup_Item_Data *next_previous_item = NULL;
2824 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
2825 if (viewport_position_result > 0)
2827 Eina_List *l = pd->items;
2830 it_data = eina_list_data_get(l);
2831 next_previous_item = it_data;
2832 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
2834 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
2836 next_previous_item = NULL;
2838 l = eina_list_next(l);
2841 if (next_previous_item)
2843 elm_object_accessibility_highlight_set(EO_OBJ(next_previous_item), EINA_TRUE);
2844 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(next_previous_item), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
2851 _content_move_up_cb(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
2853 if (!_elm_atspi_enabled())
2855 ELM_CTXPOPUP_DATA_GET(data, pd);
2856 Elm_Ctxpopup_Item_Data *it_data;
2857 Evas_Object *highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
2859 if (eo_isa(highlighted_obj, ELM_WIDGET_ITEM_CLASS))
2861 Elm_Widget_Item_Data *id = eo_data_scope_get(highlighted_obj, ELM_WIDGET_ITEM_CLASS);
2862 highlighted_obj = id->view;
2865 Evas_Object *parent = highlighted_obj;
2867 if (eo_isa(highlighted_obj, ELM_WIDGET_CLASS))
2869 while ((parent = elm_widget_parent_get(parent)))
2873 else if (eo_isa(highlighted_obj, EDJE_OBJECT_CLASS))
2875 while ((parent = evas_object_smart_parent_get(parent)))
2879 // TIZEN_ONLY(20160805): set _accessibility_currently_highlighted_obj to NULL in object delete callback
2882 WRN("Improper highlighted object: %p", highlighted_obj);
2889 int obj_x, obj_y, w, h, hx, hy, hw, hh;
2890 eo_do(pd->scr, elm_interface_scrollable_content_viewport_geometry_get(&obj_x, &obj_y, &w, &h));
2891 evas_object_geometry_get(highlighted_obj, &hx, &hy, &hw, &hh);
2893 Elm_Ctxpopup_Item_Data *next_previous_item = NULL;
2894 int viewport_position_result = _is_item_in_viewport(obj_y, h, hy, hh);
2895 if (viewport_position_result < 0)
2897 Eina_List *l = eina_list_last(pd->items);
2900 it_data = eina_list_data_get(l);
2901 next_previous_item = it_data;
2902 evas_object_geometry_get(VIEW(next_previous_item), &hx, &hy, &hw, &hh);
2904 if (_is_item_in_viewport(obj_y, h, hy, hh) == 0)
2906 next_previous_item = NULL;
2908 l = eina_list_prev(l);
2911 if (next_previous_item)
2913 elm_object_accessibility_highlight_set(EO_OBJ(next_previous_item), EINA_TRUE);
2914 elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(next_previous_item), ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
2921 //TIZEN_ONLY ctx_popup: fix accessibility states
2922 EOLIAN static Elm_Atspi_State_Set
2923 _elm_ctxpopup_item_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Ctxpopup_Item_Data *it)
2925 Elm_Atspi_State_Set states;
2926 Eina_Rectangle r1, r2;
2927 Eina_Bool is_showing = EINA_FALSE;
2929 eo_do_super(obj, ELM_CTXPOPUP_ITEM_CLASS, states = elm_interface_atspi_accessible_state_set_get());
2931 // evaluate showing state
2934 evas_object_visible_get(VIEW(it)) &&
2935 _elm_widget_onscreen_is(WIDGET(it)))
2937 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
2939 evas_object_geometry_get(VIEW(it), &r1.x, &r1.y, &r1.w, &r1.h);
2940 evas_object_geometry_get(sd->scr, &r2.x, &r2.y, &r2.w, &r2.h);
2942 if (eina_rectangles_intersect(&r1, &r2))
2943 is_showing = EINA_TRUE;
2947 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
2949 STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_SHOWING);
2954 #include "elm_ctxpopup_item.eo.c"
2955 #include "elm_ctxpopup.eo.c"