1 #include <Elementary.h>
3 #include "elm_widget_ctxpopup.h"
5 #define TTS_STR_MENU_POPUP dgettext(PACKAGE, "IDS_SCR_OPT_MENU_POP_UP_TTS")
6 #define TTS_STR_MENU_CLOSE dgettext(PACKAGE, "IDS_ST_BODY_DOUBLE_TAP_TO_CLOSE_THE_MENU_T_TTS")
8 EAPI const char ELM_CTXPOPUP_SMART_NAME[] = "elm_ctxpopup";
10 static const char ACCESS_OUTLINE_PART[] = "access.outline";
12 static const char SIG_DISMISSED[] = "dismissed";
13 static const char SIG_LANG_CHANGED[] = "language,changed";
14 static const char SIG_ACCESS_CHANGED[] = "access,changed";
16 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
18 {SIG_LANG_CHANGED, ""},
19 {SIG_ACCESS_CHANGED, ""},
23 static void _on_move(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__);
24 static void _item_sizing_eval(Elm_Ctxpopup_Item *item);
27 EVAS_SMART_SUBCLASS_NEW
28 (ELM_CTXPOPUP_SMART_NAME, _elm_ctxpopup, Elm_Ctxpopup_Smart_Class,
29 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
32 _elm_ctxpopup_smart_translate(Evas_Object *obj)
34 ELM_CTXPOPUP_DATA_GET(obj, sd);
35 Elm_Ctxpopup_Item *it;
39 evas_object_hide(obj);
41 EINA_LIST_FOREACH(sd->items, l, it)
42 elm_widget_item_translate(it);
48 _access_object_get(const Evas_Object *obj, const char* part)
51 ELM_CTXPOPUP_DATA_GET(obj, sd);
53 po = (Evas_Object *)edje_object_part_object_get(ELM_WIDGET_DATA(sd)->resize_obj, part);
54 ao = evas_object_data_get(po, "_part_access_obj");
59 // FIXME: There are applications which do not use elm_win as top widget.
60 // This is workaround! Those could not use focus!
61 static Eina_Bool _focus_enabled(Evas_Object *obj)
63 if (!elm_widget_focus_get(obj)) return EINA_FALSE;
65 const Evas_Object *win = elm_widget_top_get(obj);
66 const char *type = evas_object_type_get(win);
68 if (type && !strcmp(type, "elm_win"))
70 return elm_win_focus_highlight_enabled_get(win);
76 _elm_ctxpopup_smart_focus_next(const Evas_Object *obj,
77 Elm_Focus_Direction dir,
80 Eina_List *items = NULL;
83 ELM_CTXPOPUP_DATA_GET(obj, sd);
88 if (_elm_config->access_mode)
92 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
93 if (ao) items = eina_list_append(items, ao);
95 /* scroller exists when ctxpopup has an item */
97 items = eina_list_append(items, sd->scr);
99 items = eina_list_append(items, sd->box);
101 _elm_access_auto_highlight_set(EINA_TRUE);
102 ret = elm_widget_focus_list_next_get
103 (obj, items, eina_list_data_get, dir, next);
104 _elm_access_auto_highlight_set(EINA_FALSE);
109 elm_widget_focus_next_get(sd->box, dir, next);
110 if (!*next) *next = (Evas_Object *)obj;
116 _elm_ctxpopup_smart_focus_direction_manager_is(const Evas_Object *obj __UNUSED__)
122 _elm_ctxpopup_smart_focus_direction(const Evas_Object *obj,
123 const Evas_Object *base,
125 Evas_Object **direction,
130 void *(*list_data_get)(const Eina_List *list);
132 ELM_CTXPOPUP_DATA_GET(obj, sd);
137 list_data_get = eina_list_data_get;
139 l = eina_list_append(l, sd->box);
140 ret = elm_widget_focus_list_direction_get
141 (obj, base, l, list_data_get, degree, direction, weight);
148 _x_pos_adjust(Evas_Coord_Point *pos,
149 Evas_Coord_Point *base_size,
150 Evas_Coord_Rectangle *hover_area)
152 pos->x -= (base_size->x / 2);
154 if (pos->x < hover_area->x)
155 pos->x = hover_area->x;
156 else if ((pos->x + base_size->x) > (hover_area->x + hover_area->w))
157 pos->x = (hover_area->x + hover_area->w) - base_size->x;
159 if (base_size->x > hover_area->w)
160 base_size->x -= (base_size->x - hover_area->w);
162 if (pos->x < hover_area->x)
163 pos->x = hover_area->x;
167 _y_pos_adjust(Evas_Coord_Point *pos,
168 Evas_Coord_Point *base_size,
169 Evas_Coord_Rectangle *hover_area)
171 pos->y -= (base_size->y / 2);
173 if (pos->y < hover_area->y)
174 pos->y = hover_area->y;
175 else if ((pos->y + base_size->y) > (hover_area->y + hover_area->h))
176 pos->y = hover_area->y + hover_area->h - base_size->y;
178 if (base_size->y > hover_area->h)
179 base_size->y -= (base_size->y - hover_area->h);
181 if (pos->y < hover_area->y)
182 pos->y = hover_area->y;
186 _item_select_cb(void *data,
187 Evas_Object *obj __UNUSED__,
188 void *event_info __UNUSED__)
190 Elm_Ctxpopup_Item *item = data;
193 if (elm_widget_item_disabled_get(item))
195 if (_elm_config->access_mode)
196 elm_access_say(E_("Disabled"));
201 item->func((void*)item->base.data, WIDGET(item), data);
205 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
207 Elm_Ctxpopup_Item *it = (Elm_Ctxpopup_Item *)data;
208 const char *txt = NULL;
209 Evas_Object *icon = NULL;
211 if (!it) return NULL;
216 if (txt) return strdup(txt);
217 if (icon) return strdup(E_("icon"));
222 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
224 Elm_Ctxpopup_Item *it = (Elm_Ctxpopup_Item *)data;
225 if (!it) return NULL;
227 if (it->base.disabled)
228 return strdup(E_("Disabled"));
234 _access_focusable_button_register(Evas_Object *obj, Elm_Ctxpopup_Item *it)
238 ai = _elm_access_object_get(obj);
240 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
241 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
242 _elm_access_callback_set(ai, ELM_ACCESS_TYPE, NULL, NULL);
244 ((Elm_Widget_Item *)it)->access_obj = obj;
248 _mouse_down_cb(Elm_Ctxpopup_Item *it,
249 Evas *evas __UNUSED__,
250 Evas_Object *obj __UNUSED__,
251 Evas_Event_Mouse_Down *ev)
253 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
255 if (ev->button != 1) return;
257 //If counter is not zero, it means all other multi down is not released.
258 if (sd->multi_down != 0) return;
259 sd->mouse_down = EINA_TRUE;
260 //******************** TIZEN Only
261 sd->pressed = EINA_TRUE;
262 //****************************
265 //******************** TIZEN Only
267 _mouse_move_cb(Elm_Ctxpopup_Item *it,
268 Evas *evas __UNUSED__,
272 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
273 Evas_Event_Mouse_Move *ev = event_info;
275 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
279 edje_object_signal_emit(obj,"elm,action,unpressed", "elm");
280 sd->pressed = EINA_FALSE;
285 Evas_Coord x, y, w, h;
286 evas_object_geometry_get(obj, &x, &y, &w, &h);
287 if ((sd->pressed) && (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y)))
289 edje_object_signal_emit(obj,"elm,action,unpressed", "elm");
290 sd->pressed = EINA_FALSE;
294 //****************************
297 _mouse_up_cb(Elm_Ctxpopup_Item *it,
298 Evas *evas __UNUSED__,
299 Evas_Object *obj __UNUSED__,
300 Evas_Event_Mouse_Up *ev)
302 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
304 if (ev->button != 1) return;
306 if (!sd->mouse_down) return;
307 sd->mouse_down = EINA_FALSE;
308 //******************** TIZEN Only
309 sd->pressed = EINA_FALSE;
310 //****************************
314 _multi_down_cb(void *data,
315 Evas *evas __UNUSED__,
316 Evas_Object *obj __UNUSED__,
317 void *event_info __UNUSED__)
319 Elm_Ctxpopup_Item *it = data;
320 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
322 //Emitting signal to inform edje about multi down event.
323 edje_object_signal_emit(VIEW(it), "elm,action,multi,down", "elm");
328 _multi_up_cb(void *data,
329 Evas *evas __UNUSED__,
330 Evas_Object *obj __UNUSED__,
331 void *event_info __UNUSED__)
333 Elm_Ctxpopup_Item *it = data;
334 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
337 if(sd->multi_down == 0)
339 //Emitting signal to inform edje about last multi up event.
340 edje_object_signal_emit(VIEW(it), "elm,action,multi,up", "elm");
345 _item_new(Elm_Ctxpopup_Item *item,
348 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
351 VIEW(item) = edje_object_add(evas_object_evas_get(sd->box));
352 edje_object_mirrored_set(VIEW(item), elm_widget_mirrored_get(WIDGET(item)));
353 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", group_name,
354 elm_widget_style_get(WIDGET(item)));
355 evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
356 evas_object_show(VIEW(item));
358 evas_object_event_callback_add
359 (VIEW(item), EVAS_CALLBACK_MOUSE_DOWN, (Evas_Object_Event_Cb)_mouse_down_cb,
361 //******************** TIZEN Only
362 evas_object_event_callback_add
363 (VIEW(item), EVAS_CALLBACK_MOUSE_MOVE, (Evas_Object_Event_Cb)_mouse_move_cb,
365 //****************************
366 evas_object_event_callback_add
367 (VIEW(item), EVAS_CALLBACK_MOUSE_UP, (Evas_Object_Event_Cb)_mouse_up_cb, item);
369 /*Registering Multi down/up events to ignore mouse down/up events untill all
370 multi down/up events are released.*/
371 evas_object_event_callback_add
372 (VIEW(item), EVAS_CALLBACK_MULTI_DOWN, (Evas_Object_Event_Cb)_multi_down_cb,
374 evas_object_event_callback_add
375 (VIEW(item), EVAS_CALLBACK_MULTI_UP, (Evas_Object_Event_Cb)_multi_up_cb,
380 _item_icon_set(Elm_Ctxpopup_Item *item,
384 evas_object_del(item->icon);
389 edje_object_part_swallow(VIEW(item), "elm.swallow.icon", item->icon);
393 _item_label_set(Elm_Ctxpopup_Item *item,
396 if (!eina_stringshare_replace(&item->label, label))
399 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
401 edje_object_part_text_set(VIEW(item), "elm.text", label);
402 if (sd->visible) _item_sizing_eval(item);
406 _item_in_focusable_button(Elm_Ctxpopup_Item *item)
410 bt = elm_button_add(WIDGET(item));
411 elm_object_style_set(bt, "focus");
412 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
413 elm_object_part_content_set(bt, "elm.swallow.content", VIEW(item));
414 evas_object_smart_callback_add(bt, "clicked", _item_select_cb, item);
415 evas_object_show(bt);
421 _item_del_pre_hook(Elm_Object_Item *it)
423 Elm_Ctxpopup_Item *ctxpopup_it = (Elm_Ctxpopup_Item *)it;
426 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
427 if (!sd) return EINA_FALSE;
429 btn = ctxpopup_it->btn;
430 elm_box_unpack(sd->box, btn);
431 evas_object_smart_callback_del_full(btn, "clicked", _item_select_cb, ctxpopup_it);
432 evas_object_del(btn);
434 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
436 if (ctxpopup_it->icon)
437 evas_object_del(ctxpopup_it->icon);
438 if (VIEW(ctxpopup_it))
439 evas_object_del(VIEW(ctxpopup_it));
441 eina_stringshare_del(ctxpopup_it->label);
442 sd->items = eina_list_remove(sd->items, ctxpopup_it);
444 if (eina_list_count(sd->items) < 1)
446 evas_object_hide(WIDGET(ctxpopup_it));
449 if (sd->visible) elm_layout_sizing_eval(WIDGET(ctxpopup_it));
451 #ifndef ELM_FEATURE_WEARABLE
452 if (ctxpopup_it == sd->top_drawn_item) sd->top_drawn_item = NULL;
458 _items_remove(Elm_Ctxpopup_Smart_Data *sd)
460 Eina_List *l, *l_next;
461 Elm_Ctxpopup_Item *item;
463 if (!sd->items) return;
465 EINA_LIST_FOREACH_SAFE(sd->items, l, l_next, item)
466 elm_widget_item_del(item);
472 _item_sizing_eval(Elm_Ctxpopup_Item *item)
474 Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
478 edje_object_signal_emit(VIEW(item), "elm,state,text,default", "elm");
479 edje_object_message_signal_process(VIEW(item));
480 edje_object_size_min_restricted_calc(VIEW(item), &min_w, &min_h, min_w,
482 evas_object_size_hint_min_set(VIEW(item), min_w, min_h);
483 evas_object_size_hint_max_set(VIEW(item), max_w, max_h);
486 static Elm_Ctxpopup_Direction
487 _base_geometry_calc(Evas_Object *obj,
488 Evas_Coord_Rectangle *rect)
490 Elm_Ctxpopup_Direction dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
491 Evas_Coord_Rectangle hover_area;
492 Evas_Coord_Point pos = {0, 0};
493 Evas_Coord_Point arrow_size;
494 Evas_Coord_Point base_size;
495 Evas_Coord_Point max_size;
496 Evas_Coord_Point min_size;
497 Evas_Coord_Point temp;
501 ELM_CTXPOPUP_DATA_GET(obj, sd);
503 if (!rect) return ELM_CTXPOPUP_DIRECTION_DOWN;
505 edje_object_part_geometry_get
506 (sd->arrow, "ctxpopup_arrow", NULL, NULL, &arrow_size.x, &arrow_size.y);
507 evas_object_resize(sd->arrow, arrow_size.x, arrow_size.y);
509 //Initialize Area Rectangle.
510 evas_object_geometry_get
511 (sd->parent, &hover_area.x, &hover_area.y, &hover_area.w,
514 evas_object_geometry_get(obj, &pos.x, &pos.y, NULL, NULL);
517 edje_object_size_min_calc
518 (ELM_WIDGET_DATA(sd)->resize_obj, &base_size.x, &base_size.y);
519 evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj);
522 evas_object_size_hint_max_get(obj, &max_size.x, &max_size.y);
523 if ((max_size.x == -1) || (max_size.y == -1))
525 str = edje_object_data_get(sd->layout, "visible_maxw");
527 max_size.x = atoi(str) * elm_widget_scale_get(obj) * elm_config_scale_get();
528 str = edje_object_data_get(sd->layout, "visible_maxh");
530 max_size.y = atoi(str) * elm_widget_scale_get(obj) * elm_config_scale_get();
533 if ((max_size.y > 0) && (base_size.y > max_size.y))
534 base_size.y = max_size.y;
536 if ((max_size.x > 0) && (base_size.x > max_size.x))
537 base_size.x = max_size.x;
540 evas_object_size_hint_min_get(obj, &min_size.x, &min_size.y);
541 if ((min_size.x == 0) || (min_size.y == 0))
542 edje_object_size_min_get(sd->layout, &min_size.x, &min_size.y);
544 if ((min_size.y > 0) && (base_size.y < min_size.y))
545 base_size.y = min_size.y;
547 if ((min_size.x > 0) && (base_size.x < min_size.x))
548 base_size.x = min_size.x;
550 //Check the Which direction is available.
551 //If find a avaialble direction, it adjusts position and size.
552 for (idx = 0; idx < 4; idx++)
554 switch (sd->dir_priority[idx])
556 case ELM_CTXPOPUP_DIRECTION_UNKNOWN:
558 case ELM_CTXPOPUP_DIRECTION_UP:
559 temp.y = (pos.y - base_size.y);
560 if ((temp.y - arrow_size.y) < hover_area.y)
563 _x_pos_adjust(&pos, &base_size, &hover_area);
564 pos.y -= base_size.y;
565 dir = ELM_CTXPOPUP_DIRECTION_UP;
568 case ELM_CTXPOPUP_DIRECTION_LEFT:
569 temp.x = (pos.x - base_size.x);
570 if ((temp.x - arrow_size.x) < hover_area.x)
573 _y_pos_adjust(&pos, &base_size, &hover_area);
574 pos.x -= base_size.x;
575 dir = ELM_CTXPOPUP_DIRECTION_LEFT;
578 case ELM_CTXPOPUP_DIRECTION_RIGHT:
579 temp.x = (pos.x + base_size.x);
580 if ((temp.x + arrow_size.x) >
581 (hover_area.x + hover_area.w))
584 _y_pos_adjust(&pos, &base_size, &hover_area);
585 dir = ELM_CTXPOPUP_DIRECTION_RIGHT;
588 case ELM_CTXPOPUP_DIRECTION_DOWN:
589 temp.y = (pos.y + base_size.y);
590 if ((temp.y + arrow_size.y) >
591 (hover_area.y + hover_area.h))
594 _x_pos_adjust(&pos, &base_size, &hover_area);
595 dir = ELM_CTXPOPUP_DIRECTION_DOWN;
604 //In this case, all directions are invalid because of lack of space.
607 Evas_Coord length[2];
611 length[0] = pos.y - hover_area.y;
612 length[1] = (hover_area.y + hover_area.h) - pos.y;
614 // ELM_CTXPOPUP_DIRECTION_UP
615 if (length[0] > length[1])
617 _x_pos_adjust(&pos, &base_size, &hover_area);
618 pos.y -= base_size.y;
619 dir = ELM_CTXPOPUP_DIRECTION_UP;
620 if (pos.y < (hover_area.y + arrow_size.y))
622 base_size.y -= ((hover_area.y + arrow_size.y) - pos.y);
623 pos.y = hover_area.y + arrow_size.y;
626 //ELM_CTXPOPUP_DIRECTION_DOWN
629 _x_pos_adjust(&pos, &base_size, &hover_area);
630 dir = ELM_CTXPOPUP_DIRECTION_DOWN;
631 if ((pos.y + arrow_size.y + base_size.y) >
632 (hover_area.y + hover_area.h))
634 ((pos.y + arrow_size.y + base_size.y) -
635 (hover_area.y + hover_area.h));
640 length[0] = pos.x - hover_area.x;
641 length[1] = (hover_area.x + hover_area.w) - pos.x;
643 //ELM_CTXPOPUP_DIRECTION_LEFT
644 if (length[0] > length[1])
646 _y_pos_adjust(&pos, &base_size, &hover_area);
647 pos.x -= base_size.x;
648 dir = ELM_CTXPOPUP_DIRECTION_LEFT;
649 if (pos.x < (hover_area.x + arrow_size.x))
651 base_size.x -= ((hover_area.x + arrow_size.x) - pos.x);
652 pos.x = hover_area.x + arrow_size.x;
655 //ELM_CTXPOPUP_DIRECTION_RIGHT
658 _y_pos_adjust(&pos, &base_size, &hover_area);
659 dir = ELM_CTXPOPUP_DIRECTION_RIGHT;
660 if (pos.x + (arrow_size.x + base_size.x) >
661 hover_area.x + hover_area.w)
663 ((pos.x + arrow_size.x + base_size.x) -
664 (hover_area.x + hover_area.w));
669 //Final position and size.
672 rect->w = base_size.x;
673 rect->h = base_size.y;
679 _arrow_update(Evas_Object *obj,
680 Elm_Ctxpopup_Direction dir,
681 Evas_Coord_Rectangle base_size)
683 Evas_Coord_Rectangle arrow_size;
686 Evas_Coord_Rectangle shadow_left_top, shadow_right_bottom, arrow_padding;
688 ELM_CTXPOPUP_DATA_GET(obj, sd);
690 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
691 evas_object_geometry_get
692 (sd->arrow, NULL, NULL, &arrow_size.w, &arrow_size.h);
694 /* tizen only : since ctxpopup of tizen has shadow, start and end padding of arrow, it should be put together when updating arrow
695 * so there are some differences between open source and tizen */
696 edje_object_part_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, "frame_shadow_left_top_padding", NULL, NULL, &shadow_left_top.w, &shadow_left_top.h);
697 edje_object_part_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, "frame_shadow_right_bottom_padding", NULL, NULL, &shadow_right_bottom.w, &shadow_right_bottom.h);
698 edje_object_part_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, "ctxpopup_frame_left_top", NULL, NULL, &arrow_padding.w, &arrow_padding.h);
700 /* arrow is not being kept as sub-object on purpose, here. the
701 * design of the widget does not help with the contrary */
705 case ELM_CTXPOPUP_DIRECTION_RIGHT:
706 edje_object_signal_emit(sd->arrow, "elm,state,left", "elm");
707 edje_object_part_swallow
708 (ELM_WIDGET_DATA(sd)->resize_obj,
709 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_right" :
710 "elm.swallow.arrow_left"), sd->arrow);
714 if (y <= ((arrow_size.h * 0.5) + base_size.y + shadow_left_top.h + arrow_padding.h))
716 else if (y >= (base_size.y + base_size.h - ((arrow_size.h * 0.5) + shadow_right_bottom.h + arrow_padding.h)))
717 y = base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2));
719 y = y - base_size.y - ((arrow_size.h * 0.5) + shadow_left_top.h + arrow_padding.h);
720 drag = (double)(y) / (double)(base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2)));
721 edje_object_part_drag_value_set
722 (ELM_WIDGET_DATA(sd)->resize_obj,
723 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_right" :
724 "elm.swallow.arrow_left"), 1, drag);
728 case ELM_CTXPOPUP_DIRECTION_LEFT:
729 edje_object_signal_emit(sd->arrow, "elm,state,right", "elm");
730 edje_object_part_swallow
731 (ELM_WIDGET_DATA(sd)->resize_obj,
732 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_left" :
733 "elm.swallow.arrow_right"), sd->arrow);
737 if (y <= ((arrow_size.h * 0.5) + base_size.y + shadow_left_top.h + arrow_padding.h))
739 else if (y >= (base_size.y + base_size.h - ((arrow_size.h * 0.5) + shadow_right_bottom.h + arrow_padding.h)))
740 y = base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2));
742 y = y - base_size.y - ((arrow_size.h * 0.5) + shadow_left_top.h + arrow_padding.h);
743 drag = (double)(y) / (double)(base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2)));
744 edje_object_part_drag_value_set
745 (ELM_WIDGET_DATA(sd)->resize_obj,
746 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_left" :
747 "elm.swallow.arrow_right"), 0, drag);
751 case ELM_CTXPOPUP_DIRECTION_DOWN:
752 edje_object_signal_emit(sd->arrow, "elm,state,top", "elm");
753 edje_object_part_swallow
754 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.arrow_up",
759 if (x <= ((arrow_size.w * 0.5) + base_size.x + shadow_left_top.w + arrow_padding.w))
761 else if (x >= (base_size.x + base_size.w - ((arrow_size.w * 0.5) + shadow_right_bottom.w + arrow_padding.w)))
762 x = base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2));
764 x = x - base_size.x - ((arrow_size.w * 0.5) + shadow_left_top.w + arrow_padding.w);
765 drag = (double)(x) / (double)(base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2)));
766 edje_object_part_drag_value_set
767 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.arrow_up",
772 case ELM_CTXPOPUP_DIRECTION_UP:
773 edje_object_signal_emit(sd->arrow, "elm,state,bottom", "elm");
774 edje_object_part_swallow
775 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.arrow_down",
780 if (x <= ((arrow_size.w * 0.5) + base_size.x + shadow_left_top.w + arrow_padding.w))
782 else if (x >= (base_size.x + base_size.w - ((arrow_size.w * 0.5) + shadow_right_bottom.w + arrow_padding.w)))
783 x = base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2));
785 x = x - base_size.x - ((arrow_size.w * 0.5) + shadow_left_top.w + arrow_padding.w);
786 drag = (double)(x) / (double)(base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2)));
787 edje_object_part_drag_value_set
788 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.arrow_down",
797 //should be here for getting accurate geometry value
798 evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj);
802 _show_signals_emit(Evas_Object *obj,
803 Elm_Ctxpopup_Direction dir)
805 ELM_CTXPOPUP_DATA_GET(obj, sd);
807 if (!sd->visible) return;
811 case ELM_CTXPOPUP_DIRECTION_UP:
812 edje_object_signal_emit(sd->layout, "elm,state,show,up", "elm");
815 case ELM_CTXPOPUP_DIRECTION_LEFT:
816 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,show,right" :
817 "elm,state,show,left"), "elm");
820 case ELM_CTXPOPUP_DIRECTION_RIGHT:
821 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,show,left" :
822 "elm,state,show,right"), "elm");
825 case ELM_CTXPOPUP_DIRECTION_DOWN:
826 edje_object_signal_emit(sd->layout, "elm,state,show,down", "elm");
833 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
837 _hide_signals_emit(Evas_Object *obj,
838 Elm_Ctxpopup_Direction dir)
840 ELM_CTXPOPUP_DATA_GET(obj, sd);
842 if (!sd->visible) return;
846 case ELM_CTXPOPUP_DIRECTION_UP:
847 edje_object_signal_emit(sd->layout, "elm,state,hide,up", "elm");
850 case ELM_CTXPOPUP_DIRECTION_LEFT:
851 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,hide,right" :
852 "elm,state,hide,left"), "elm");
855 case ELM_CTXPOPUP_DIRECTION_RIGHT:
856 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,hide,left" :
857 "elm,state,hide,right"), "elm");
860 case ELM_CTXPOPUP_DIRECTION_DOWN:
861 edje_object_signal_emit(sd->layout, "elm,state,hide,down", "elm");
868 edje_object_signal_emit(sd->bg, "elm,state,hide", "elm");
872 _base_shift_by_arrow(Evas_Object *obj,
874 Elm_Ctxpopup_Direction dir,
875 Evas_Coord_Rectangle *rect)
877 ELM_CTXPOPUP_DATA_GET(obj, sd);
879 Evas_Coord arrow_w, arrow_h, diff_w, diff_h;
880 Evas_Coord_Rectangle shadow_left_top, shadow_right_bottom;
882 evas_object_geometry_get(arrow, NULL, NULL, &arrow_w, &arrow_h);
883 /* 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
884 * so there are some differences between opensource and tizen*/
885 edje_object_part_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, "frame_shadow_left_top_padding", NULL, NULL, &shadow_left_top.w, &shadow_left_top.h);
886 edje_object_part_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, "frame_shadow_right_bottom_padding", NULL, NULL, &shadow_right_bottom.w, &shadow_right_bottom.h);
891 case ELM_CTXPOPUP_DIRECTION_RIGHT:
892 diff_w = arrow_w - shadow_right_bottom.w;
896 case ELM_CTXPOPUP_DIRECTION_LEFT:
897 diff_w = arrow_w - shadow_left_top.w;
901 case ELM_CTXPOPUP_DIRECTION_DOWN:
902 diff_h = arrow_h - shadow_left_top.h;
906 case ELM_CTXPOPUP_DIRECTION_UP:
907 diff_h = arrow_h - shadow_right_bottom.h;
917 _elm_ctxpopup_smart_sub_object_add(Evas_Object *obj,
920 Elm_Widget_Smart_Class *parent_parent;
922 parent_parent = (Elm_Widget_Smart_Class *)((Evas_Smart_Class *)
923 _elm_ctxpopup_parent_sc)->parent;
925 /* skipping layout's code, which registers size hint changing
926 * callback on sub objects. a hack to make ctxpopup live, as it is,
927 * on the new classing schema. this widget needs a total
929 if (!parent_parent->sub_object_add(obj, sobj))
936 _elm_ctxpopup_smart_sizing_eval(Evas_Object *obj)
939 Elm_Ctxpopup_Item *item;
940 Evas_Coord_Rectangle rect = { 0, 0, 1, 1 };
941 Evas_Coord_Point box_size = { 0, 0 };
942 Evas_Coord_Point _box_size = { 0, 0 };
944 Evas_Coord x, y, w, h;
947 ELM_CTXPOPUP_DATA_GET(obj, sd);
949 if (!sd->parent || !(sd->items || sd->content)) return;
952 EINA_LIST_FOREACH(sd->items, elist, item)
954 _item_sizing_eval(item);
955 evas_object_size_hint_min_get(VIEW(item), &_box_size.x, &_box_size.y);
956 #ifndef ELM_FEATURE_WEARABLE
958 if (!sd->color_calculated)
960 int item_r, item_g, item_b, item_a = 0;
961 int bg_r, bg_g, bg_b, bg_a = 0;
962 int item_banded_a ,bg_banded_a = 0;
963 const char *item_bg_color = NULL;
964 const char *list_bg_color = NULL;
966 item_bg_color = edje_object_data_get(VIEW(item), "bg_color");
967 list_bg_color = edje_object_data_get(sd->bg, "personalized_color");
968 if (item_bg_color != NULL && list_bg_color != NULL )
970 edje_color_class_get (item_bg_color, &item_r, &item_g, &item_b, &item_a, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
971 edje_color_class_get (list_bg_color, &bg_r, &bg_g, &bg_b, &bg_a, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
972 for (i = 0; i < MAX_ITEMS_PER_VIEWPORT; i++)
974 item_banded_a = 255 - i*10;
975 bg_banded_a = 255 - item_banded_a;
976 sd->item_color[i][0] = ((item_r * item_banded_a) >> 8) + ((bg_r * bg_banded_a) >> 8);
977 sd->item_color[i][1] = ((item_g * item_banded_a) >> 8) + ((bg_g * bg_banded_a) >> 8);
978 sd->item_color[i][2] = ((item_b * item_banded_a) >> 8) + ((bg_b * bg_banded_a) >> 8);
980 sd->color_calculated = EINA_TRUE;
984 str = edje_object_data_get(VIEW(item), "item_max_size");
988 maxw = maxw * elm_widget_scale_get(obj) * elm_config_scale_get();
990 if (_box_size.x > maxw)
992 edje_object_signal_emit(VIEW(item), "elm,state,text,ellipsis", "elm");
993 edje_object_message_signal_process(VIEW(item));
999 if (_box_size.x > box_size.x)
1000 box_size.x = _box_size.x;
1001 if (_box_size.y != -1)
1002 box_size.y += _box_size.y;
1006 if (_box_size.x != -1)
1007 box_size.x += _box_size.x;
1008 if (_box_size.y > box_size.y)
1009 box_size.y = _box_size.y;
1013 // if (!sd->arrow) return; /* simple way to flag "under deletion" */
1015 if ((!sd->content) && (sd->scr))
1017 evas_object_size_hint_min_set(sd->box, box_size.x, box_size.y);
1018 elm_scroller_content_min_limit(sd->scr, EINA_TRUE, EINA_TRUE);
1019 evas_object_size_hint_min_set(sd->scr, box_size.x, box_size.y);
1023 sd->dir = _base_geometry_calc(obj, &rect);
1025 _arrow_update(obj, sd->dir, rect);
1026 _base_shift_by_arrow(obj, sd->arrow, sd->dir, &rect);
1028 //resize scroller according to final size
1029 if ((!sd->content) && (sd->scr))
1031 elm_scroller_content_min_limit(sd->scr, EINA_FALSE, EINA_FALSE);
1032 evas_object_smart_calculate(sd->scr);
1035 evas_object_size_hint_min_set(ELM_WIDGET_DATA(sd)->resize_obj, rect.w, rect.h);
1036 evas_object_resize(ELM_WIDGET_DATA(sd)->resize_obj, rect.w, rect.h);
1038 evas_object_resize(sd->layout, rect.w, rect.h);
1039 evas_object_move(sd->layout, rect.x, rect.y);
1041 evas_object_geometry_get(sd->parent, &x, &y, &w, &h);
1042 evas_object_move(sd->bg, x, y);
1043 evas_object_resize(sd->bg, w, h);
1047 _on_parent_del(void *data,
1049 Evas_Object *obj __UNUSED__,
1050 void *event_info __UNUSED__)
1052 evas_object_del(data);
1056 _on_parent_move(void *data,
1058 Evas_Object *obj __UNUSED__,
1059 void *event_info __UNUSED__)
1061 ELM_CTXPOPUP_DATA_GET(data, sd);
1064 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1067 elm_layout_sizing_eval(data);
1071 _on_parent_resize(void *data,
1073 Evas_Object *obj __UNUSED__,
1074 void *event_info __UNUSED__)
1076 ELM_CTXPOPUP_DATA_GET(data, sd);
1077 ELM_WIDGET_DATA_GET(data, wsd);
1081 _hide_signals_emit(data, sd->dir);
1083 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1085 evas_object_hide(data);
1086 evas_object_smart_callback_call(data, SIG_DISMISSED, NULL);
1090 if (wsd->orient_mode == 90 || wsd->orient_mode == 270)
1091 elm_widget_theme_object_set
1092 (data, sd->layout, "ctxpopup", "layout/landscape", elm_widget_style_get(data));
1094 elm_widget_theme_object_set
1095 (data, sd->layout, "ctxpopup", "layout", elm_widget_style_get(data));
1098 elm_layout_sizing_eval(data);
1100 _show_signals_emit(data, sd->dir);
1105 _parent_detach(Evas_Object *obj)
1107 ELM_CTXPOPUP_DATA_GET(obj, sd);
1109 if (!sd->parent) return;
1111 evas_object_event_callback_del_full
1112 (sd->parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
1113 evas_object_event_callback_del_full
1114 (sd->parent, EVAS_CALLBACK_MOVE, _on_parent_move, obj);
1115 evas_object_event_callback_del_full
1116 (sd->parent, EVAS_CALLBACK_RESIZE, _on_parent_resize, obj);
1120 _on_content_resized(void *data,
1122 Evas_Object *obj __UNUSED__,
1123 void *event_info __UNUSED__)
1125 elm_layout_sizing_eval(data);
1129 _access_outline_activate_cb(void *data,
1130 Evas_Object *part_obj __UNUSED__,
1131 Elm_Object_Item *item __UNUSED__)
1133 evas_object_hide(data);
1134 evas_object_smart_callback_call(data, SIG_DISMISSED, NULL);
1138 _access_obj_process(Evas_Object *obj, Eina_Bool is_access)
1141 ELM_CTXPOPUP_DATA_GET(obj, sd);
1145 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
1148 ao = _elm_access_edje_object_part_object_register
1149 (obj, ELM_WIDGET_DATA(sd)->resize_obj, ACCESS_OUTLINE_PART);
1151 const char *style = elm_widget_style_get(obj);
1152 if (!strcmp(style, "more/default"))
1154 elm_access_info_set(ao, ELM_ACCESS_TYPE, TTS_STR_MENU_POPUP);
1155 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, TTS_STR_MENU_CLOSE);
1159 elm_access_info_set(ao, ELM_ACCESS_TYPE, E_("Contextual popup"));
1160 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, E_("Double tap to close popup"));
1162 _elm_access_activate_callback_set
1163 (_elm_access_object_get(ao), _access_outline_activate_cb, obj);
1168 _elm_access_edje_object_part_object_unregister
1169 (obj, ELM_WIDGET_DATA(sd)->resize_obj, ACCESS_OUTLINE_PART);
1174 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
1176 ELM_CTXPOPUP_DATA_GET(obj, sd);
1178 edje_object_mirrored_set(sd->layout, rtl);
1179 edje_object_mirrored_set(sd->arrow, rtl);
1180 edje_object_mirrored_set(ELM_WIDGET_DATA(sd)->resize_obj, rtl);
1184 _elm_ctxpopup_smart_event(Evas_Object *obj,
1185 Evas_Object *src __UNUSED__,
1186 Evas_Callback_Type type,
1189 Evas_Event_Key_Down *ev = event_info;
1191 ELM_CTXPOPUP_DATA_GET(obj, sd);
1193 // TIZEN ONLY(20131221) : When access mode, focused ui is disabled.
1194 if (_elm_config->access_mode) return EINA_FALSE;
1196 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
1197 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
1198 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
1199 if (!_focus_enabled(obj)) return EINA_FALSE;
1201 //FIXME: for this key event, _elm_ctxpopup_smart_focus_next should be done first
1202 if ((!strcmp(ev->keyname, "Tab")) ||
1203 (!strcmp(ev->keyname, "ISO_Left_Tab")))
1205 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1209 if (((!strcmp(ev->keyname, "Left")) ||
1210 (!strcmp(ev->keyname, "KP_Left")) ||
1211 (!strcmp(ev->keyname, "Right")) ||
1212 (!strcmp(ev->keyname, "KP_Right")) ||
1213 (!strcmp(ev->keyname, "Up")) ||
1214 (!strcmp(ev->keyname, "KP_Up")) ||
1215 (!strcmp(ev->keyname, "Down")) ||
1216 (!strcmp(ev->keyname, "KP_Down"))) && (!ev->string))
1218 double degree = 0.0;
1220 if ((!strcmp(ev->keyname, "Left")) ||
1221 (!strcmp(ev->keyname, "KP_Left")))
1223 else if ((!strcmp(ev->keyname, "Right")) ||
1224 (!strcmp(ev->keyname, "KP_Right")))
1226 else if ((!strcmp(ev->keyname, "Up")) ||
1227 (!strcmp(ev->keyname, "KP_Up")))
1229 else if ((!strcmp(ev->keyname, "Down")) ||
1230 (!strcmp(ev->keyname, "KP_Down")))
1233 elm_widget_focus_direction_go(sd->box, degree);
1234 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1237 else if (((!strcmp(ev->keyname, "Home")) ||
1238 (!strcmp(ev->keyname, "KP_Home")) ||
1239 (!strcmp(ev->keyname, "Prior")) ||
1240 (!strcmp(ev->keyname, "KP_Prior"))) && (!ev->string))
1242 Elm_Ctxpopup_Item *it = eina_list_data_get(sd->items);
1243 Evas_Object *btn = it->btn;
1244 elm_object_focus_set(btn, EINA_TRUE);
1245 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1248 else if (((!strcmp(ev->keyname, "End")) ||
1249 (!strcmp(ev->keyname, "KP_End")) ||
1250 (!strcmp(ev->keyname, "Next")) ||
1251 (!strcmp(ev->keyname, "KP_Next"))) && (!ev->string))
1253 Elm_Ctxpopup_Item *it = eina_list_data_get(eina_list_last(sd->items));
1254 Evas_Object *btn = it->btn;
1255 elm_object_focus_set(btn, EINA_TRUE);
1256 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1260 // TIZEN ONLY : 20130530 : ctxpopup will be dismissed by user
1261 //if (strcmp(ev->keyname, "Escape")) return EINA_FALSE;
1265 _hide_signals_emit(obj, sd->dir);
1267 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1272 //FIXME: lost the content size when theme hook is called.
1274 _elm_ctxpopup_smart_theme(Evas_Object *obj)
1277 Elm_Ctxpopup_Item *item;
1281 ELM_CTXPOPUP_DATA_GET(obj, sd);
1282 ELM_WIDGET_DATA_GET(obj, wsd);
1284 if (!ELM_WIDGET_CLASS(_elm_ctxpopup_parent_sc)->theme(obj))
1287 rtl = elm_widget_mirrored_get(obj);
1289 elm_widget_theme_object_set
1290 (obj, sd->bg, "ctxpopup", "bg", elm_widget_style_get(obj));
1292 elm_widget_theme_object_set
1293 (obj, sd->arrow, "ctxpopup", "arrow", elm_widget_style_get(obj));
1295 if (wsd->orient_mode == 90 || wsd->orient_mode == 270)
1296 elm_widget_theme_object_set
1297 (obj, sd->layout, "ctxpopup", "layout/landscape", elm_widget_style_get(obj));
1299 elm_widget_theme_object_set
1300 (obj, sd->layout, "ctxpopup", "layout", elm_widget_style_get(obj));
1302 _mirrored_set(obj, rtl);
1305 EINA_LIST_FOREACH(sd->items, elist, item)
1307 edje_object_mirrored_set(VIEW(item), rtl);
1309 if (item->label && item->icon)
1310 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1311 "icon_text_style_item",
1312 elm_widget_style_get(obj));
1313 else if (item->label)
1316 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1318 elm_widget_style_get(obj));
1320 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1321 "text_style_item_horizontal",
1322 elm_widget_style_get(obj));
1324 else if (item->icon)
1325 _elm_theme_object_set
1326 (obj, VIEW(item), "ctxpopup", "icon_style_item",
1327 elm_widget_style_get(obj));
1329 edje_object_part_text_set(VIEW(item), "elm.text", item->label);
1331 if (elm_widget_item_disabled_get(item))
1332 edje_object_signal_emit(VIEW(item), "elm,state,disabled", "elm");
1335 * For separator, if the first item has visible separator,
1336 * then it should be aligned with edge of the base part.
1337 * In some cases, it gives improper display. Ex) rounded corner
1338 * So the first item separator should be invisible.
1341 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
1343 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
1345 // reset state of text to be default
1346 edje_object_signal_emit(VIEW(item), "elm,state,text,default", "elm");
1347 edje_object_message_signal_process(VIEW(item));
1350 if (evas_object_visible_get(sd->bg))
1351 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
1355 elm_object_style_set(sd->scr, "list_effect");
1358 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
1360 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
1363 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1366 _elm_ctxpopup_smart_sizing_eval(obj);
1369 if (_elm_config->access_mode) _access_obj_process(obj, EINA_TRUE);
1374 /* kind of a big and tricky override here: an internal box will hold
1375 * the actual content. content aliases won't be of much help here */
1377 _elm_ctxpopup_smart_content_set(Evas_Object *obj,
1379 Evas_Object *content)
1381 Evas_Coord min_w = -1, min_h = -1;
1383 ELM_CTXPOPUP_DATA_GET(obj, sd);
1385 if ((part) && (strcmp(part, "default")))
1386 return ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_set
1387 (obj, part, content);
1389 if (!content) return EINA_FALSE;
1391 if (content == sd->content) return EINA_TRUE;
1393 if (sd->items) elm_ctxpopup_clear(obj);
1394 if (sd->content) evas_object_del(sd->content);
1396 evas_object_event_callback_add
1397 (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1398 edje_object_part_swallow(ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.content", sd->box);
1400 evas_object_size_hint_weight_set
1401 (content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1402 evas_object_size_hint_fill_set
1403 (content, EVAS_HINT_FILL, EVAS_HINT_FILL);
1405 /* since it's going to be a box content, not a layout's... */
1406 evas_object_show(content);
1408 evas_object_size_hint_min_get(content, &min_w, &min_h);
1409 evas_object_size_hint_min_set(sd->box, min_w, min_h);
1410 elm_box_pack_end(sd->box, content);
1412 sd->content = content;
1413 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1415 if (sd->visible) elm_layout_sizing_eval(obj);
1420 static Evas_Object *
1421 _elm_ctxpopup_smart_content_get(const Evas_Object *obj,
1424 ELM_CTXPOPUP_DATA_GET(obj, sd);
1426 if ((part) && (strcmp(part, "default")))
1427 return ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_get
1433 static Evas_Object *
1434 _elm_ctxpopup_smart_content_unset(Evas_Object *obj,
1437 Evas_Object *content;
1439 ELM_CTXPOPUP_DATA_GET(obj, sd);
1441 if ((part) && (strcmp(part, "default")))
1442 return ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_unset
1445 content = sd->content;
1446 if (!content) return NULL;
1448 elm_box_unpack(sd->box, sd->content);
1451 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1453 if (sd->visible) elm_layout_sizing_eval(obj);
1459 _item_text_set_hook(Elm_Object_Item *it,
1463 Elm_Ctxpopup_Item *ctxpopup_it;
1465 if ((part) && (strcmp(part, "default"))) return;
1467 ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1469 _item_label_set(ctxpopup_it, label);
1473 _item_text_get_hook(const Elm_Object_Item *it,
1476 Elm_Ctxpopup_Item *ctxpopup_it;
1478 if (part && strcmp(part, "default")) return NULL;
1480 ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1481 return ctxpopup_it->label;
1485 _item_content_set_hook(Elm_Object_Item *it,
1487 Evas_Object *content)
1489 Elm_Ctxpopup_Item *ctxpopup_it;
1491 if ((part) && (strcmp(part, "icon"))) return;
1493 ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1495 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
1497 _item_icon_set(ctxpopup_it, content);
1498 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1501 _elm_ctxpopup_smart_sizing_eval(WIDGET(ctxpopup_it));
1504 static Evas_Object *
1505 _item_content_get_hook(const Elm_Object_Item *it,
1508 Elm_Ctxpopup_Item *ctxpopup_it;
1510 if (part && strcmp(part, "icon")) return NULL;
1512 ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1513 return ctxpopup_it->icon;
1517 _item_disable_hook(Elm_Object_Item *it)
1519 Elm_Ctxpopup_Item *ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1521 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
1524 if (elm_widget_item_disabled_get(it))
1525 edje_object_signal_emit(VIEW(ctxpopup_it), "elm,state,disabled", "elm");
1527 edje_object_signal_emit(VIEW(ctxpopup_it), "elm,state,enabled", "elm");
1531 _item_signal_emit_hook(Elm_Object_Item *it,
1532 const char *emission,
1535 Elm_Ctxpopup_Item *ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1537 edje_object_signal_emit(VIEW(ctxpopup_it), emission, source);
1541 _item_style_set_hook(Elm_Object_Item *it,
1544 Elm_Ctxpopup_Item *item = (Elm_Ctxpopup_Item *)it;
1545 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
1547 if (item->icon && item->label)
1548 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "icon_text_style_item", style);
1549 else if (item->label)
1552 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "text_style_item_horizontal", style);
1554 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "text_style_item", style);
1557 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", "icon_style_item", style);
1559 if (sd->visible) elm_layout_sizing_eval(WIDGET(item));
1563 _bg_clicked_cb(void *data,
1564 Evas_Object *obj __UNUSED__,
1565 const char *emission __UNUSED__,
1566 const char *source __UNUSED__)
1568 ELM_CTXPOPUP_DATA_GET(data, sd);
1570 _hide_signals_emit(data, sd->dir);
1574 _on_show(void *data __UNUSED__,
1577 void *event_info __UNUSED__)
1580 Elm_Ctxpopup_Item *item;
1583 ELM_CTXPOPUP_DATA_GET(obj, sd);
1584 ELM_WIDGET_DATA_GET(obj, wsd);
1586 if ((!sd->items) && (!sd->content)) return;
1588 sd->visible = EINA_TRUE;
1590 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
1591 elm_layout_signal_emit(obj, "elm,state,show", "elm");
1593 if (wsd->orient_mode == 90 || wsd->orient_mode == 270)
1594 elm_widget_theme_object_set
1595 (obj, sd->layout, "ctxpopup", "layout/landscape", elm_widget_style_get(obj));
1597 elm_widget_theme_object_set
1598 (obj, sd->layout, "ctxpopup", "layout", elm_widget_style_get(obj));
1600 EINA_LIST_FOREACH(sd->items, elist, item)
1602 if (item->label && !item->icon)
1605 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1607 elm_widget_style_get(obj));
1609 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
1610 "text_style_item_horizontal",
1611 elm_widget_style_get(obj));
1615 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
1617 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
1620 elm_layout_sizing_eval(obj);
1622 elm_object_focus_set(obj, EINA_TRUE);
1623 _show_signals_emit(obj, sd->dir);
1627 _on_hide(void *data __UNUSED__,
1630 void *event_info __UNUSED__)
1632 ELM_CTXPOPUP_DATA_GET(obj, sd);
1634 if (!sd->visible) return;
1636 sd->visible = EINA_FALSE;
1640 _on_move(void *data __UNUSED__,
1643 void *event_info __UNUSED__)
1645 ELM_CTXPOPUP_DATA_GET(obj, sd);
1647 if (sd->visible) _elm_ctxpopup_smart_sizing_eval(obj);
1651 _hide_finished_cb(void *data,
1652 Evas_Object *obj __UNUSED__,
1653 const char *emission __UNUSED__,
1654 const char *source __UNUSED__)
1656 evas_object_hide(data);
1657 evas_object_smart_callback_call(data, SIG_DISMISSED, NULL);
1661 _list_del(Elm_Ctxpopup_Smart_Data *sd)
1663 if (!sd->scr) return;
1665 edje_object_part_unswallow(ELM_WIDGET_DATA(sd)->resize_obj, sd->scr);
1666 evas_object_del(sd->scr);
1668 evas_object_del(sd->box);
1673 scroll_up_down_cb(void *data, Evas_Object *obj, void *event_info)
1675 #ifndef ELM_FEATURE_WEARABLE
1676 ELM_CTXPOPUP_DATA_GET(data, sd);
1678 Evas_Coord x, y, w, h;
1679 Evas_Coord x2, y2, w2, h2;
1680 const char *color = NULL;
1683 Elm_Ctxpopup_Item *item , *top_drawn_item = NULL;
1685 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, &x2, &y2, &w2, &h2);
1686 EINA_LIST_FOREACH(sd->items, elist, item) {
1687 evas_object_geometry_get(VIEW(item), &x, &y, &w, &h);
1688 if ( y <= y2 && ELM_RECTS_INTERSECT(x,y,w,h,x2,y2,w2,h2))
1689 top_drawn_item = item;
1690 if( top_drawn_item && ( top_drawn_item != sd->top_drawn_item )) {
1691 if( i < MAX_ITEMS_PER_VIEWPORT ) {
1692 color = edje_object_data_get(VIEW(item), "bg_color");
1693 edje_object_color_class_set(VIEW(item), color, sd->item_color[i][0], sd->item_color[i][1], sd->item_color[i][2], 255, 255, 255, 255, 255, 255, 255, 255, 255);
1698 sd->top_drawn_item = top_drawn_item;
1703 _list_new(Evas_Object *obj)
1705 ELM_CTXPOPUP_DATA_GET(obj, sd);
1709 sd->scr = elm_scroller_add(obj);
1710 elm_object_style_set(sd->scr, "list_effect");
1711 evas_object_size_hint_align_set(sd->scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
1712 #ifndef ELM_FEATURE_WEARABLE
1713 evas_object_smart_callback_add(sd->scr, "scroll,up", scroll_up_down_cb, obj);
1714 evas_object_smart_callback_add(sd->scr, "scroll,down", scroll_up_down_cb, obj);
1717 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
1719 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
1721 edje_object_part_swallow(ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.content", sd->scr);
1723 elm_object_content_set(sd->scr, sd->box);
1724 elm_ctxpopup_horizontal_set(obj, sd->horizontal);
1728 _elm_ctxpopup_smart_disable(Evas_Object *obj)
1731 Elm_Object_Item *it;
1733 ELM_CTXPOPUP_DATA_GET(obj, sd);
1735 if (!ELM_WIDGET_CLASS(_elm_ctxpopup_parent_sc)->disable(obj))
1738 EINA_LIST_FOREACH(sd->items, l, it)
1739 elm_object_item_disabled_set(it, elm_widget_disabled_get(obj));
1745 _elm_ctxpopup_smart_add(Evas_Object *obj)
1747 EVAS_SMART_DATA_ALLOC(obj, Elm_Ctxpopup_Smart_Data);
1749 ELM_WIDGET_CLASS(_elm_ctxpopup_parent_sc)->base.add(obj);
1754 _elm_ctxpopup_smart_del(Evas_Object *obj)
1756 ELM_CTXPOPUP_DATA_GET(obj, sd);
1758 evas_object_event_callback_del_full
1759 (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1760 _parent_detach(obj);
1769 evas_object_del(sd->box);
1773 evas_object_del(sd->arrow);
1774 sd->arrow = NULL; /* stops _sizing_eval() from going on on deletion */
1776 evas_object_del(sd->bg);
1779 evas_object_del(sd->layout);
1782 ELM_WIDGET_CLASS(_elm_ctxpopup_parent_sc)->base.del(obj);
1786 _elm_ctxpopup_smart_parent_set(Evas_Object *obj,
1787 Evas_Object *parent)
1789 //default parent is to be hover parent
1790 elm_ctxpopup_hover_parent_set(obj, parent);
1794 _elm_ctxpopup_smart_access(Evas_Object *obj, Eina_Bool is_access)
1796 ELM_CTXPOPUP_CHECK(obj);
1798 _access_obj_process(obj, is_access);
1800 evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
1803 static Evas_Object *
1804 _elm_ctxpopup_smart_access_object_get(Evas_Object *obj, char *part)
1806 ELM_CTXPOPUP_CHECK(obj) NULL;
1808 return _access_object_get(obj, part);
1812 _elm_ctxpopup_smart_set_user(Elm_Ctxpopup_Smart_Class *sc)
1814 ELM_WIDGET_CLASS(sc)->base.add = _elm_ctxpopup_smart_add;
1815 ELM_WIDGET_CLASS(sc)->base.del = _elm_ctxpopup_smart_del;
1817 ELM_WIDGET_CLASS(sc)->parent_set = _elm_ctxpopup_smart_parent_set;
1818 ELM_WIDGET_CLASS(sc)->disable = _elm_ctxpopup_smart_disable;
1819 ELM_WIDGET_CLASS(sc)->event = _elm_ctxpopup_smart_event;
1820 ELM_WIDGET_CLASS(sc)->theme = _elm_ctxpopup_smart_theme;
1821 ELM_WIDGET_CLASS(sc)->translate = _elm_ctxpopup_smart_translate;
1822 ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_ctxpopup_smart_sub_object_add;
1823 ELM_WIDGET_CLASS(sc)->focus_next = _elm_ctxpopup_smart_focus_next;
1824 ELM_WIDGET_CLASS(sc)->focus_direction_manager_is =
1825 _elm_ctxpopup_smart_focus_direction_manager_is;
1826 ELM_WIDGET_CLASS(sc)->focus_direction = _elm_ctxpopup_smart_focus_direction;
1828 ELM_CONTAINER_CLASS(sc)->content_get = _elm_ctxpopup_smart_content_get;
1829 ELM_CONTAINER_CLASS(sc)->content_set = _elm_ctxpopup_smart_content_set;
1830 ELM_CONTAINER_CLASS(sc)->content_unset = _elm_ctxpopup_smart_content_unset;
1832 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_ctxpopup_smart_sizing_eval;
1834 ELM_WIDGET_CLASS(sc)->access = _elm_ctxpopup_smart_access;
1835 ELM_WIDGET_CLASS(sc)->access_object_get = _elm_ctxpopup_smart_access_object_get;
1838 EAPI const Elm_Ctxpopup_Smart_Class *
1839 elm_ctxpopup_smart_class_get(void)
1841 static Elm_Ctxpopup_Smart_Class _sc =
1842 ELM_CTXPOPUP_SMART_CLASS_INIT_NAME_VERSION(ELM_CTXPOPUP_SMART_NAME);
1843 static const Elm_Ctxpopup_Smart_Class *class = NULL;
1844 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1849 _elm_ctxpopup_smart_set(&_sc);
1850 esc->callbacks = _smart_callbacks;
1857 elm_ctxpopup_add(Evas_Object *parent)
1861 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1863 obj = elm_widget_add(_elm_ctxpopup_smart_class_new(), parent);
1864 if (!obj) return NULL;
1866 if (!elm_widget_sub_object_add(parent, obj))
1867 ERR("could not add %p as sub object of %p", obj, parent);
1869 elm_layout_theme_set(obj, "ctxpopup", "base", elm_widget_style_get(obj));
1870 elm_layout_signal_callback_add
1871 (obj, "elm,action,hide,finished", "", _hide_finished_cb, obj);
1873 ELM_CTXPOPUP_DATA_GET(obj, sd);
1876 sd->bg = edje_object_add(evas_object_evas_get(obj));
1877 elm_widget_theme_object_set(obj, sd->bg, "ctxpopup", "bg", "default");
1878 edje_object_signal_callback_add
1879 (sd->bg, "elm,action,click", "", _bg_clicked_cb, obj);
1880 evas_object_smart_member_add(sd->bg, obj);
1881 evas_object_stack_below(sd->bg, ELM_WIDGET_DATA(sd)->resize_obj);
1882 #ifndef ELM_FEATURE_WEARABLE
1883 sd->color_calculated = EINA_FALSE;
1884 sd->top_drawn_item = NULL;
1887 sd->arrow = edje_object_add(evas_object_evas_get(obj));
1888 elm_widget_theme_object_set
1889 (obj, sd->arrow, "ctxpopup", "arrow", "default");
1891 sd->dir_priority[0] = ELM_CTXPOPUP_DIRECTION_UP;
1892 sd->dir_priority[1] = ELM_CTXPOPUP_DIRECTION_LEFT;
1893 sd->dir_priority[2] = ELM_CTXPOPUP_DIRECTION_RIGHT;
1894 sd->dir_priority[3] = ELM_CTXPOPUP_DIRECTION_DOWN;
1895 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1897 sd->auto_hide = EINA_TRUE;
1898 sd->mouse_down = EINA_FALSE;
1901 sd->box = elm_box_add(obj);
1902 evas_object_size_hint_weight_set
1903 (sd->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1905 ELM_WIDGET_DATA_GET(obj, wsd);
1907 sd->layout = edje_object_add(evas_object_evas_get(obj));
1908 if (wsd->orient_mode == 90 || wsd->orient_mode == 270)
1909 elm_widget_theme_object_set(obj, sd->layout, "ctxpopup", "layout/landscape", "default");
1911 elm_widget_theme_object_set(obj, sd->layout, "ctxpopup", "layout", "default");
1912 evas_object_smart_member_add(sd->layout, obj);
1914 edje_object_signal_callback_add
1915 (sd->layout, "elm,action,hide,finished", "", _hide_finished_cb, obj);
1916 edje_object_part_swallow(sd->layout, "swallow", ELM_WIDGET_DATA(sd)->resize_obj);
1917 evas_object_size_hint_weight_set
1918 (sd->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1920 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _on_show, NULL);
1921 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _on_hide, NULL);
1922 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _on_move, NULL);
1924 _mirrored_set(obj, elm_widget_mirrored_get(obj));
1926 elm_widget_can_focus_set(obj, EINA_TRUE);
1927 elm_ctxpopup_hover_parent_set(obj, parent);
1929 if (_elm_config->access_mode) _access_obj_process(obj, EINA_TRUE);
1931 /* access: parent could be any object such as elm_list which does
1932 not know elc_ctxpopup as its child object in the focus_next(); */
1934 wsd->highlight_root = EINA_TRUE;
1936 //Tizen Only: This should be removed when eo is applied.
1937 wsd->on_create = EINA_FALSE;
1943 elm_ctxpopup_hover_parent_set(Evas_Object *obj,
1944 Evas_Object *parent)
1946 Evas_Coord x, y, w, h;
1948 ELM_CTXPOPUP_CHECK(obj);
1949 ELM_CTXPOPUP_DATA_GET(obj, sd);
1951 if (!parent) return;
1953 _parent_detach(obj);
1955 evas_object_event_callback_add
1956 (parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
1957 evas_object_event_callback_add
1958 (parent, EVAS_CALLBACK_MOVE, _on_parent_move, obj);
1959 evas_object_event_callback_add
1960 (parent, EVAS_CALLBACK_RESIZE, _on_parent_resize, obj);
1962 sd->parent = parent;
1965 evas_object_geometry_get(parent, &x, &y, &w, &h);
1966 evas_object_move(sd->bg, x, y);
1967 evas_object_resize(sd->bg, w, h);
1969 if (sd->visible) elm_layout_sizing_eval(obj);
1973 elm_ctxpopup_hover_parent_get(const Evas_Object *obj)
1975 ELM_CTXPOPUP_CHECK(obj) NULL;
1976 ELM_CTXPOPUP_DATA_GET(obj, sd);
1982 elm_ctxpopup_clear(Evas_Object *obj)
1984 ELM_CTXPOPUP_CHECK(obj);
1985 ELM_CTXPOPUP_DATA_GET(obj, sd);
1989 elm_object_content_unset(sd->scr);
1990 edje_object_part_unswallow(ELM_WIDGET_DATA(sd)->resize_obj, sd->scr);
1991 evas_object_del(sd->scr);
1993 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1997 elm_ctxpopup_horizontal_set(Evas_Object *obj,
1998 Eina_Bool horizontal)
2001 Elm_Ctxpopup_Item *item;
2004 ELM_CTXPOPUP_CHECK(obj);
2005 ELM_CTXPOPUP_DATA_GET(obj, sd);
2007 sd->horizontal = !!horizontal;
2014 elm_box_horizontal_set(sd->box, EINA_FALSE);
2015 elm_scroller_bounce_set(sd->scr, EINA_FALSE, EINA_TRUE);
2016 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
2020 elm_box_horizontal_set(sd->box, EINA_TRUE);
2021 elm_scroller_bounce_set(sd->scr, EINA_TRUE, EINA_FALSE);
2022 elm_scroller_policy_set(sd->scr, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
2025 EINA_LIST_FOREACH(sd->items, elist, item)
2027 if (item->label && !item->icon && !horizontal)
2028 _elm_theme_object_set(obj, VIEW(item), "ctxpopup", "text_style_item",
2029 elm_widget_style_get(obj));
2030 else if (item->label && !item->icon && horizontal)
2031 _elm_theme_object_set(obj, VIEW(item), "ctxpopup",
2032 "text_style_item_horizontal",
2033 elm_widget_style_get(obj));
2036 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
2038 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
2040 _item_disable_hook((Elm_Object_Item *)item);
2043 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
2045 if (sd->visible) elm_layout_sizing_eval(obj);
2049 elm_ctxpopup_horizontal_get(const Evas_Object *obj)
2051 ELM_CTXPOPUP_CHECK(obj) EINA_FALSE;
2052 ELM_CTXPOPUP_DATA_GET(obj, sd);
2054 return sd->horizontal;
2057 EAPI Elm_Object_Item *
2058 elm_ctxpopup_item_append(Evas_Object *obj,
2064 Elm_Ctxpopup_Item *item, *it;
2065 Evas_Object *content, *focus_bt;
2069 ELM_CTXPOPUP_CHECK(obj) NULL;
2070 ELM_CTXPOPUP_DATA_GET(obj, sd);
2072 item = elm_widget_item_new(obj, Elm_Ctxpopup_Item);
2073 if (!item) return NULL;
2075 elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
2076 elm_widget_item_disable_hook_set(item, _item_disable_hook);
2077 elm_widget_item_text_set_hook_set(item, _item_text_set_hook);
2078 elm_widget_item_text_get_hook_set(item, _item_text_get_hook);
2079 elm_widget_item_content_set_hook_set(item, _item_content_set_hook);
2080 elm_widget_item_content_get_hook_set(item, _item_content_get_hook);
2081 elm_widget_item_signal_emit_hook_set(item, _item_signal_emit_hook);
2082 elm_widget_item_style_set_hook_set(item, _item_style_set_hook);
2084 //The first item is appended.
2085 content = elm_object_content_unset(obj);
2086 if (content) evas_object_del(content);
2092 item->base.data = data;
2095 _item_new(item, "icon_text_style_item");
2098 if (!sd->horizontal)
2099 _item_new(item, "text_style_item");
2101 _item_new(item, "text_style_item_horizontal");
2104 _item_new(item, "icon_style_item");
2106 _item_icon_set(item, icon);
2107 _item_label_set(item, label);
2108 focus_bt = _item_in_focusable_button(item);
2109 elm_box_pack_end(sd->box, focus_bt);
2110 sd->items = eina_list_append(sd->items, item);
2111 item->btn = focus_bt;
2113 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
2114 #ifndef ELM_FEATURE_WEARABLE
2115 const char *color = NULL;
2117 if (sd->color_calculated) {
2118 EINA_LIST_FOREACH(sd->items, elist, it) {
2119 if( i < MAX_ITEMS_PER_VIEWPORT ) {
2120 color = edje_object_data_get(VIEW(it), "bg_color");
2121 edje_object_color_class_set(VIEW(it), color, sd->item_color[i][0], sd->item_color[i][1], sd->item_color[i][2], 255, 255, 255, 255, 255, 255, 255, 255, 255);
2129 EINA_LIST_FOREACH(sd->items, elist, it)
2132 edje_object_signal_emit(VIEW(it), "elm,state,default", "elm");
2134 edje_object_signal_emit(VIEW(it), "elm,state,separator", "elm");
2136 _elm_ctxpopup_smart_sizing_eval(obj);
2139 if (_elm_config->access_mode) _access_focusable_button_register(focus_bt, item);
2141 return (Elm_Object_Item *)item;
2145 elm_ctxpopup_direction_priority_set(Evas_Object *obj,
2146 Elm_Ctxpopup_Direction first,
2147 Elm_Ctxpopup_Direction second,
2148 Elm_Ctxpopup_Direction third,
2149 Elm_Ctxpopup_Direction fourth)
2151 ELM_CTXPOPUP_CHECK(obj);
2152 ELM_CTXPOPUP_DATA_GET(obj, sd);
2154 sd->dir_priority[0] = first;
2155 sd->dir_priority[1] = second;
2156 sd->dir_priority[2] = third;
2157 sd->dir_priority[3] = fourth;
2159 if (sd->visible) elm_layout_sizing_eval(obj);
2163 elm_ctxpopup_direction_priority_get(Evas_Object *obj,
2164 Elm_Ctxpopup_Direction *first,
2165 Elm_Ctxpopup_Direction *second,
2166 Elm_Ctxpopup_Direction *third,
2167 Elm_Ctxpopup_Direction *fourth)
2169 ELM_CTXPOPUP_CHECK(obj);
2170 ELM_CTXPOPUP_DATA_GET(obj, sd);
2172 if (first) *first = sd->dir_priority[0];
2173 if (second) *second = sd->dir_priority[1];
2174 if (third) *third = sd->dir_priority[2];
2175 if (fourth) *fourth = sd->dir_priority[3];
2178 EAPI Elm_Ctxpopup_Direction
2179 elm_ctxpopup_direction_get(const Evas_Object *obj)
2181 ELM_CTXPOPUP_CHECK(obj) ELM_CTXPOPUP_DIRECTION_UNKNOWN;
2182 ELM_CTXPOPUP_DATA_GET(obj, sd);
2188 elm_ctxpopup_direction_available_get(Evas_Object *obj, Elm_Ctxpopup_Direction direction)
2190 ELM_CTXPOPUP_CHECK(obj) EINA_FALSE;
2191 ELM_CTXPOPUP_DATA_GET(obj, sd);
2193 elm_layout_sizing_eval(obj);
2195 if (sd->dir == direction) return EINA_TRUE;
2200 elm_ctxpopup_dismiss(Evas_Object *obj)
2202 ELM_CTXPOPUP_CHECK(obj);
2203 ELM_CTXPOPUP_DATA_GET(obj, sd);
2205 _hide_signals_emit(obj, sd->dir);
2209 elm_ctxpopup_auto_hide_disabled_set(Evas_Object *obj, Eina_Bool disabled)
2211 ELM_CTXPOPUP_CHECK(obj);
2212 ELM_CTXPOPUP_DATA_GET(obj, sd);
2214 disabled = !!disabled;
2216 if (sd->auto_hide == !disabled) return;
2217 sd->auto_hide = !disabled;