1 #include <Elementary.h>
3 #include "elm_widget_ctxpopup.h"
5 EAPI const char ELM_CTXPOPUP_SMART_NAME[] = "elm_ctxpopup";
7 static const char SIG_DISMISSED[] = "dismissed";
8 static const char SIG_LANG_CHANGED[] = "language,changed";
10 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
12 {SIG_LANG_CHANGED, ""},
16 EVAS_SMART_SUBCLASS_NEW
17 (ELM_CTXPOPUP_SMART_NAME, _elm_ctxpopup, Elm_Ctxpopup_Smart_Class,
18 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
21 _elm_ctxpopup_smart_translate(Evas_Object *obj)
23 evas_object_hide(obj);
29 _elm_ctxpopup_smart_focus_next(const Evas_Object *obj,
30 Elm_Focus_Direction dir,
33 Eina_List *items = NULL;
34 Eina_List *elist = NULL;
35 Elm_Ctxpopup_Item *it;
37 ELM_CTXPOPUP_DATA_GET(obj, sd);
42 if (eina_list_count(sd->items))
44 EINA_LIST_FOREACH(sd->items, elist, it)
45 items = eina_list_append(items, it->base.access_obj);
47 return elm_widget_focus_list_next_get
48 (obj, items, eina_list_data_get, dir, next);
52 return elm_widget_focus_next_get(sd->box, dir, next);
57 _elm_ctxpopup_smart_focus_direction(const Evas_Object *obj,
58 const Evas_Object *base,
60 Evas_Object **direction,
65 void *(*list_data_get)(const Eina_List *list);
67 ELM_CTXPOPUP_DATA_GET(obj, sd);
72 list_data_get = eina_list_data_get;
74 l = eina_list_append(l, sd->box);
75 ret = elm_widget_focus_list_direction_get
76 (obj, base, l, list_data_get, degree, direction, weight);
83 _elm_ctxpopup_smart_event(Evas_Object *obj,
84 Evas_Object *src __UNUSED__,
85 Evas_Callback_Type type,
88 Evas_Event_Key_Down *ev = event_info;
90 ELM_CTXPOPUP_DATA_GET(obj, sd);
92 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
93 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
94 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
96 if (!strcmp(ev->keyname, "Tab"))
98 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
99 elm_widget_focus_cycle(sd->box, ELM_FOCUS_PREVIOUS);
101 elm_widget_focus_cycle(sd->box, ELM_FOCUS_NEXT);
105 if (strcmp(ev->keyname, "Escape")) return EINA_FALSE;
107 evas_object_hide(obj);
108 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
113 _freeze_on_cb(void *data __UNUSED__,
115 void *event_info __UNUSED__)
117 ELM_CTXPOPUP_DATA_GET(obj, sd);
119 if ((!sd) || (!sd->scr)) return;
120 elm_object_scroll_freeze_push(sd->scr);
124 _freeze_off_cb(void *data __UNUSED__,
126 void *event_info __UNUSED__)
128 ELM_CTXPOPUP_DATA_GET(obj, sd);
130 if ((!sd) || (!sd->scr)) return;
131 elm_object_scroll_freeze_pop(sd->scr);
135 _hold_on_cb(void *data __UNUSED__,
137 void *event_info __UNUSED__)
139 ELM_CTXPOPUP_DATA_GET(obj, sd);
141 if ((!sd) || (!sd->scr)) return;
142 elm_object_scroll_hold_push(sd->scr);
146 _hold_off_cb(void *data __UNUSED__,
148 void *event_info __UNUSED__)
150 ELM_CTXPOPUP_DATA_GET(obj, sd);
152 if ((!sd) || (!sd->scr)) return;
153 elm_object_scroll_hold_pop(sd->scr);
157 _x_pos_adjust(Evas_Coord_Point *pos,
158 Evas_Coord_Point *base_size,
159 Evas_Coord_Rectangle *hover_area)
161 pos->x -= (base_size->x / 2);
163 if (pos->x < hover_area->x)
164 pos->x = hover_area->x;
165 else if ((pos->x + base_size->x) > (hover_area->x + hover_area->w))
166 pos->x = (hover_area->x + hover_area->w) - base_size->x;
168 if (base_size->x > hover_area->w)
169 base_size->x -= (base_size->x - hover_area->w);
171 if (pos->x < hover_area->x)
172 pos->x = hover_area->x;
176 _y_pos_adjust(Evas_Coord_Point *pos,
177 Evas_Coord_Point *base_size,
178 Evas_Coord_Rectangle *hover_area)
180 pos->y -= (base_size->y / 2);
182 if (pos->y < hover_area->y)
183 pos->y = hover_area->y;
184 else if ((pos->y + base_size->y) > (hover_area->y + hover_area->h))
185 pos->y = hover_area->y + hover_area->h - base_size->y;
187 if (base_size->y > hover_area->h)
188 base_size->y -= (base_size->y - hover_area->h);
190 if (pos->y < hover_area->y)
191 pos->y = hover_area->y;
195 _item_select_cb(void *data, Evas_Object *obj __UNUSED__,
196 const char *emission __UNUSED__,
197 const char *source __UNUSED__)
199 Elm_Ctxpopup_Item *item = data;
202 if (elm_widget_item_disabled_get(item)) return;
205 item->func((void*)item->base.data, WIDGET(item), data);
209 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
211 Elm_Ctxpopup_Item *it = (Elm_Ctxpopup_Item *)data;
212 const char *txt = NULL;
213 Evas_Object *icon = NULL;
214 Eina_Strbuf *buf = NULL;
217 if (!it) return NULL;
224 buf = eina_strbuf_new();
225 eina_strbuf_append(buf, E_("icon "));
226 eina_strbuf_append(buf, txt);
227 str = eina_strbuf_string_steal(buf);
228 eina_strbuf_free(buf);
231 else if ((!txt) && icon) return strdup(E_("icon"));
232 else if (txt && (!icon)) return strdup(txt);
238 _access_state_cb(void *data, Evas_Object *obj __UNUSED__)
240 Elm_Ctxpopup_Item *it = (Elm_Ctxpopup_Item *)data;
241 if (!it) return NULL;
243 if (it->base.disabled)
244 return strdup(E_("State: Disabled"));
250 _access_activate_cb(void *data __UNUSED__,
251 Evas_Object *part_obj __UNUSED__,
252 Elm_Object_Item *item)
254 _item_select_cb(item, NULL, NULL, NULL);
258 _access_widget_item_register(Elm_Ctxpopup_Item *it, Eina_Bool is_access)
262 if (!is_access) _elm_access_widget_item_unregister((Elm_Widget_Item *)it);
265 _elm_access_widget_item_register((Elm_Widget_Item *)it);
267 ai = _elm_access_object_get(it->base.access_obj);
269 _elm_access_callback_set(ai, ELM_ACCESS_INFO, _access_info_cb, it);
270 _elm_access_callback_set(ai, ELM_ACCESS_STATE, _access_state_cb, it);
271 _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("Contextual Popup"));
272 _elm_access_activate_callback_set(ai, _access_activate_cb, it);
277 _item_new(Elm_Ctxpopup_Item *item,
280 ELM_CTXPOPUP_DATA_GET(WIDGET(item), sd);
283 VIEW(item) = edje_object_add(evas_object_evas_get(sd->box));
284 edje_object_mirrored_set(VIEW(item), elm_widget_mirrored_get(WIDGET(item)));
285 _elm_theme_object_set(WIDGET(item), VIEW(item), "ctxpopup", group_name,
286 elm_widget_style_get(WIDGET(item)));
287 edje_object_signal_callback_add(VIEW(item), "elm,action,click", "",
288 _item_select_cb, item);
289 evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL, EVAS_HINT_FILL);
290 evas_object_show(VIEW(item));
293 if (_elm_config->access_mode) _access_widget_item_register(item, EINA_TRUE);
297 _item_icon_set(Elm_Ctxpopup_Item *item,
301 evas_object_del(item->icon);
306 edje_object_part_swallow(VIEW(item), "elm.swallow.icon", item->icon);
307 edje_object_message_signal_process(VIEW(item));
311 _item_label_set(Elm_Ctxpopup_Item *item,
314 if (!eina_stringshare_replace(&item->label, label))
317 edje_object_part_text_set(VIEW(item), "elm.text", label);
318 edje_object_message_signal_process(VIEW(item));
322 _item_del_pre_hook(Elm_Object_Item *it)
324 Elm_Ctxpopup_Item *ctxpopup_it = (Elm_Ctxpopup_Item *)it;
326 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
327 if (!sd) return EINA_FALSE;
329 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
331 if (ctxpopup_it->icon)
332 evas_object_del(ctxpopup_it->icon);
333 if (VIEW(ctxpopup_it))
334 evas_object_del(VIEW(ctxpopup_it));
336 eina_stringshare_del(ctxpopup_it->label);
337 sd->items = eina_list_remove(sd->items, ctxpopup_it);
339 if (eina_list_count(sd->items) < 1)
341 evas_object_hide(WIDGET(ctxpopup_it));
344 if (sd->visible) elm_layout_sizing_eval(WIDGET(ctxpopup_it));
350 _items_remove(Elm_Ctxpopup_Smart_Data *sd)
353 Elm_Ctxpopup_Item *item;
355 if (!sd->items) return;
357 EINA_LIST_FOREACH(sd->items, elist, item)
359 _item_del_pre_hook((Elm_Object_Item *)item);
366 _scroller_size_reset(Elm_Ctxpopup_Smart_Data *sd)
368 sd->finished = EINA_FALSE;
374 _item_sizing_eval(Elm_Ctxpopup_Item *item)
376 Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
380 edje_object_size_min_restricted_calc(VIEW(item), &min_w, &min_h, min_w,
382 evas_object_size_hint_min_set(VIEW(item), min_w, min_h);
383 evas_object_size_hint_max_set(VIEW(item), max_w, max_h);
386 static Elm_Ctxpopup_Direction
387 _base_geometry_calc(Evas_Object *obj,
388 Evas_Coord_Rectangle *rect)
390 Elm_Ctxpopup_Direction dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
391 Evas_Coord_Rectangle hover_area;
392 Evas_Coord_Point pos = {0, 0};
393 Evas_Coord_Point arrow_size;
394 Evas_Coord_Point base_size;
395 Evas_Coord_Point max_size;
396 Evas_Coord_Point min_size;
397 Evas_Coord_Point temp;
400 ELM_CTXPOPUP_DATA_GET(obj, sd);
402 if (!rect) return ELM_CTXPOPUP_DIRECTION_DOWN;
404 edje_object_part_geometry_get
405 (sd->arrow, "ctxpopup_arrow", NULL, NULL, &arrow_size.x, &arrow_size.y);
406 evas_object_resize(sd->arrow, arrow_size.x, arrow_size.y);
408 //Initialize Area Rectangle.
409 evas_object_geometry_get
410 (sd->parent, &hover_area.x, &hover_area.y, &hover_area.w,
413 evas_object_geometry_get(obj, &pos.x, &pos.y, NULL, NULL);
416 edje_object_size_min_calc
417 (ELM_WIDGET_DATA(sd)->resize_obj, &base_size.x, &base_size.y);
418 evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj);
421 evas_object_size_hint_max_get(obj, &max_size.x, &max_size.y);
422 if ((max_size.x == -1) || (max_size.y == -1))
423 edje_object_size_max_get(sd->layout, &max_size.x, &max_size.y);
425 if ((max_size.y > 0) && (base_size.y > max_size.y))
426 base_size.y = max_size.y;
428 if ((max_size.x > 0) && (base_size.x > max_size.x))
429 base_size.x = max_size.x;
432 evas_object_size_hint_min_get(obj, &min_size.x, &min_size.y);
433 if ((min_size.x == 0) || (min_size.y == 0))
434 edje_object_size_min_get(sd->layout, &min_size.x, &min_size.y);
436 if ((min_size.y > 0) && (base_size.y < min_size.y))
437 base_size.y = min_size.y;
439 if ((min_size.x > 0) && (base_size.x < min_size.x))
440 base_size.x = min_size.x;
442 //Check the Which direction is available.
443 //If find a avaialble direction, it adjusts position and size.
444 for (idx = 0; idx < 4; idx++)
446 switch (sd->dir_priority[idx])
448 case ELM_CTXPOPUP_DIRECTION_UNKNOWN:
450 case ELM_CTXPOPUP_DIRECTION_UP:
451 temp.y = (pos.y - base_size.y);
452 if ((temp.y - arrow_size.y) < hover_area.y)
455 _x_pos_adjust(&pos, &base_size, &hover_area);
456 pos.y -= base_size.y;
457 dir = ELM_CTXPOPUP_DIRECTION_UP;
460 case ELM_CTXPOPUP_DIRECTION_LEFT:
461 temp.x = (pos.x - base_size.x);
462 if ((temp.x - arrow_size.x) < hover_area.x)
465 _y_pos_adjust(&pos, &base_size, &hover_area);
466 pos.x -= base_size.x;
467 dir = ELM_CTXPOPUP_DIRECTION_LEFT;
470 case ELM_CTXPOPUP_DIRECTION_RIGHT:
471 temp.x = (pos.x + base_size.x);
472 if ((temp.x + arrow_size.x) >
473 (hover_area.x + hover_area.w))
476 _y_pos_adjust(&pos, &base_size, &hover_area);
477 dir = ELM_CTXPOPUP_DIRECTION_RIGHT;
480 case ELM_CTXPOPUP_DIRECTION_DOWN:
481 temp.y = (pos.y + base_size.y);
482 if ((temp.y + arrow_size.y) >
483 (hover_area.y + hover_area.h))
486 _x_pos_adjust(&pos, &base_size, &hover_area);
487 dir = ELM_CTXPOPUP_DIRECTION_DOWN;
496 //In this case, all directions are invalid because of lack of space.
499 Evas_Coord length[2];
503 length[0] = pos.y - hover_area.y;
504 length[1] = (hover_area.y + hover_area.h) - pos.y;
506 // ELM_CTXPOPUP_DIRECTION_UP
507 if (length[0] > length[1])
509 _x_pos_adjust(&pos, &base_size, &hover_area);
510 pos.y -= base_size.y;
511 dir = ELM_CTXPOPUP_DIRECTION_UP;
512 if (pos.y < (hover_area.y + arrow_size.y))
514 base_size.y -= ((hover_area.y + arrow_size.y) - pos.y);
515 pos.y = hover_area.y + arrow_size.y;
518 //ELM_CTXPOPUP_DIRECTION_DOWN
521 _x_pos_adjust(&pos, &base_size, &hover_area);
522 dir = ELM_CTXPOPUP_DIRECTION_DOWN;
523 if ((pos.y + arrow_size.y + base_size.y) >
524 (hover_area.y + hover_area.h))
526 ((pos.y + arrow_size.y + base_size.y) -
527 (hover_area.y + hover_area.h));
532 length[0] = pos.x - hover_area.x;
533 length[1] = (hover_area.x + hover_area.w) - pos.x;
535 //ELM_CTXPOPUP_DIRECTION_LEFT
536 if (length[0] > length[1])
538 _y_pos_adjust(&pos, &base_size, &hover_area);
539 pos.x -= base_size.x;
540 dir = ELM_CTXPOPUP_DIRECTION_LEFT;
541 if (pos.x < (hover_area.x + arrow_size.x))
543 base_size.x -= ((hover_area.x + arrow_size.x) - pos.x);
544 pos.x = hover_area.x + arrow_size.x;
547 //ELM_CTXPOPUP_DIRECTION_RIGHT
550 _y_pos_adjust(&pos, &base_size, &hover_area);
551 dir = ELM_CTXPOPUP_DIRECTION_RIGHT;
552 if (pos.x + (arrow_size.x + base_size.x) >
553 hover_area.x + hover_area.w)
555 ((pos.x + arrow_size.x + base_size.x) -
556 (hover_area.x + hover_area.w));
561 //Final position and size.
564 rect->w = base_size.x;
565 rect->h = base_size.y;
571 _arrow_update(Evas_Object *obj,
572 Elm_Ctxpopup_Direction dir,
573 Evas_Coord_Rectangle base_size)
575 Evas_Coord_Rectangle arrow_size;
578 Evas_Coord_Rectangle shadow_left_top, shadow_right_bottom, arrow_padding;
580 ELM_CTXPOPUP_DATA_GET(obj, sd);
582 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
583 evas_object_geometry_get
584 (sd->arrow, NULL, NULL, &arrow_size.w, &arrow_size.h);
586 /* tizen only : since ctxpopup of tizen has shadow, start and end padding of arrow, it should be put together when updating arrow
587 * so there are some differences between open source and tizen */
588 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);
589 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);
590 edje_object_part_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj, "ctxpopup_frame_left_top", NULL, NULL, &arrow_padding.w, &arrow_padding.h);
592 /* arrow is not being kept as sub-object on purpose, here. the
593 * design of the widget does not help with the contrary */
597 case ELM_CTXPOPUP_DIRECTION_RIGHT:
598 edje_object_signal_emit(sd->arrow, "elm,state,left", "elm");
599 edje_object_part_swallow
600 (ELM_WIDGET_DATA(sd)->resize_obj,
601 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_right" :
602 "elm.swallow.arrow_left"), sd->arrow);
606 if (y <= ((arrow_size.h * 0.5) + base_size.y + shadow_left_top.h + arrow_padding.h))
608 else if (y >= (base_size.y + base_size.h - ((arrow_size.h * 0.5) + shadow_right_bottom.h + arrow_padding.h)))
609 y = base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2));
611 y = y - base_size.y - ((arrow_size.h * 0.5) + shadow_left_top.h + arrow_padding.h);
612 drag = (double)(y) / (double)(base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2)));
613 edje_object_part_drag_value_set
614 (ELM_WIDGET_DATA(sd)->resize_obj,
615 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_right" :
616 "elm.swallow.arrow_left"), 1, drag);
620 case ELM_CTXPOPUP_DIRECTION_LEFT:
621 edje_object_signal_emit(sd->arrow, "elm,state,right", "elm");
622 edje_object_part_swallow
623 (ELM_WIDGET_DATA(sd)->resize_obj,
624 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_left" :
625 "elm.swallow.arrow_right"), sd->arrow);
629 if (y <= ((arrow_size.h * 0.5) + base_size.y + shadow_left_top.h + arrow_padding.h))
631 else if (y >= (base_size.y + base_size.h - ((arrow_size.h * 0.5) + shadow_right_bottom.h + arrow_padding.h)))
632 y = base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2));
634 y = y - base_size.y - ((arrow_size.h * 0.5) + shadow_left_top.h + arrow_padding.h);
635 drag = (double)(y) / (double)(base_size.h - (arrow_size.h + shadow_right_bottom.h + shadow_left_top.h + (arrow_padding.h * 2)));
636 edje_object_part_drag_value_set
637 (ELM_WIDGET_DATA(sd)->resize_obj,
638 (elm_widget_mirrored_get(obj) ? "elm.swallow.arrow_left" :
639 "elm.swallow.arrow_right"), 0, drag);
643 case ELM_CTXPOPUP_DIRECTION_DOWN:
644 edje_object_signal_emit(sd->arrow, "elm,state,top", "elm");
645 edje_object_part_swallow
646 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.arrow_up",
651 if (x <= ((arrow_size.w * 0.5) + base_size.x + shadow_left_top.w + arrow_padding.w))
653 else if (x >= (base_size.x + base_size.w - ((arrow_size.w * 0.5) + shadow_right_bottom.w + arrow_padding.w)))
654 x = base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2));
656 x = x - base_size.x - ((arrow_size.w * 0.5) + shadow_left_top.w + arrow_padding.w);
657 drag = (double)(x) / (double)(base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2)));
658 edje_object_part_drag_value_set
659 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.arrow_up",
664 case ELM_CTXPOPUP_DIRECTION_UP:
665 edje_object_signal_emit(sd->arrow, "elm,state,bottom", "elm");
666 edje_object_part_swallow
667 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.arrow_down",
672 if (x <= ((arrow_size.w * 0.5) + base_size.x + shadow_left_top.w + arrow_padding.w))
674 else if (x >= (base_size.x + base_size.w - ((arrow_size.w * 0.5) + shadow_right_bottom.w + arrow_padding.w)))
675 x = base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2));
677 x = x - base_size.x - ((arrow_size.w * 0.5) + shadow_left_top.w + arrow_padding.w);
678 drag = (double)(x) / (double)(base_size.w - (arrow_size.w + shadow_right_bottom.w + shadow_left_top.w + (arrow_padding.w * 2)));
679 edje_object_part_drag_value_set
680 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.arrow_down",
689 //should be here for getting accurate geometry value
690 evas_object_smart_calculate(ELM_WIDGET_DATA(sd)->resize_obj);
694 _show_signals_emit(Evas_Object *obj,
695 Elm_Ctxpopup_Direction dir)
697 ELM_CTXPOPUP_DATA_GET(obj, sd);
699 if (!sd->visible) return;
703 case ELM_CTXPOPUP_DIRECTION_UP:
704 edje_object_signal_emit(sd->layout, "elm,state,show,up", "elm");
707 case ELM_CTXPOPUP_DIRECTION_LEFT:
708 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,show,right" :
709 "elm,state,show,left"), "elm");
712 case ELM_CTXPOPUP_DIRECTION_RIGHT:
713 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,show,left" :
714 "elm,state,show,right"), "elm");
717 case ELM_CTXPOPUP_DIRECTION_DOWN:
718 edje_object_signal_emit(sd->layout, "elm,state,show,down", "elm");
725 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
726 // elm_layout_signal_emit(obj, "elm,state,show", "elm");
730 _hide_signals_emit(Evas_Object *obj,
731 Elm_Ctxpopup_Direction dir)
733 ELM_CTXPOPUP_DATA_GET(obj, sd);
735 if (!sd->visible) return;
739 case ELM_CTXPOPUP_DIRECTION_UP:
740 edje_object_signal_emit(sd->layout, "elm,state,hide,up", "elm");
743 case ELM_CTXPOPUP_DIRECTION_LEFT:
744 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,hide,right" :
745 "elm,state,hide,left"), "elm");
748 case ELM_CTXPOPUP_DIRECTION_RIGHT:
749 edje_object_signal_emit(sd->layout, (elm_widget_mirrored_get(obj) ? "elm,state,hide,left" :
750 "elm,state,hide,right"), "elm");
753 case ELM_CTXPOPUP_DIRECTION_DOWN:
754 edje_object_signal_emit(sd->layout, "elm,state,hide,down", "elm");
761 edje_object_signal_emit(sd->bg, "elm,state,hide", "elm");
765 _base_shift_by_arrow(Evas_Object *arrow,
766 Elm_Ctxpopup_Direction dir,
767 Evas_Coord_Rectangle *rect)
769 Evas_Coord arrow_w, arrow_h;
771 evas_object_geometry_get(arrow, NULL, NULL, &arrow_w, &arrow_h);
775 case ELM_CTXPOPUP_DIRECTION_RIGHT:
779 case ELM_CTXPOPUP_DIRECTION_LEFT:
783 case ELM_CTXPOPUP_DIRECTION_DOWN:
787 case ELM_CTXPOPUP_DIRECTION_UP:
796 //TODO: compress item - different from opensource
798 _compress_item(Evas_Object *obj)
801 Elm_Ctxpopup_Item *item;
803 ELM_CTXPOPUP_DATA_GET(obj, sd);
806 EINA_LIST_FOREACH(sd->items, elist, item)
808 edje_object_signal_emit(item->base.view, "elm,state,compress", "elm");
813 _elm_ctxpopup_smart_sub_object_add(Evas_Object *obj,
816 Elm_Widget_Smart_Class *parent_parent;
818 parent_parent = (Elm_Widget_Smart_Class *)((Evas_Smart_Class *)
819 _elm_ctxpopup_parent_sc)->parent;
821 /* skipping layout's code, which registers size hint changing
822 * callback on sub objects. a hack to make ctxpopup live, as it is,
823 * on the new classing schema. this widget needs a total
825 if (!parent_parent->sub_object_add(obj, sobj))
832 _elm_ctxpopup_smart_sizing_eval(Evas_Object *obj)
835 Elm_Ctxpopup_Item *item;
836 Evas_Coord_Rectangle rect = { 0, 0, 1, 1 };
837 Evas_Coord_Point box_size = { 0, 0 };
838 Evas_Coord_Point _box_size = { 0, 0 };
842 ELM_CTXPOPUP_DATA_GET(obj, sd);
845 EINA_LIST_FOREACH(sd->items, elist, item)
847 _item_sizing_eval(item);
848 evas_object_size_hint_min_get(VIEW(item), &_box_size.x, &_box_size.y);
850 str = edje_object_data_get(VIEW(item), "item_max_size");
854 maxw = maxw * elm_widget_scale_get(obj) * elm_config_scale_get();
856 if (_box_size.x > maxw)
858 edje_object_signal_emit(VIEW(item), "elm,state,text,ellipsis", "elm");
859 edje_object_message_signal_process(VIEW(item));
865 if (_box_size.x > box_size.x)
866 box_size.x = _box_size.x;
867 if (_box_size.y != -1)
868 box_size.y += _box_size.y;
872 if (_box_size.x != -1)
873 box_size.x += _box_size.x;
874 if (_box_size.y > box_size.y)
875 box_size.y = _box_size.y;
879 if (!sd->arrow) return; /* simple way to flag "under deletion" */
881 if ((!sd->content) && (sd->scr))
883 evas_object_size_hint_min_set(sd->box, box_size.x, box_size.y);
884 elm_scroller_content_min_limit(sd->scr, EINA_TRUE, EINA_TRUE);
885 evas_object_size_hint_min_set(sd->scr, box_size.x, box_size.y);
889 sd->dir = _base_geometry_calc(obj, &rect);
891 //TODO: compress item - different from opensource
892 if (!sd->horizontal && !sd->content)
895 _arrow_update(obj, sd->dir, rect);
896 _base_shift_by_arrow(sd->arrow, sd->dir, &rect);
898 //resize scroller according to final size
899 if ((!sd->content) && (sd->scr))
901 elm_scroller_content_min_limit(sd->scr, EINA_FALSE, EINA_FALSE);
902 evas_object_smart_calculate(sd->scr);
905 evas_object_size_hint_min_set(ELM_WIDGET_DATA(sd)->resize_obj, rect.w, rect.h);
906 evas_object_resize(ELM_WIDGET_DATA(sd)->resize_obj, rect.w, rect.h);
908 evas_object_move(sd->layout, rect.x, rect.y);
909 evas_object_resize(sd->layout, rect.w, rect.h);
911 _show_signals_emit(obj, sd->dir);
915 _on_parent_del(void *data,
917 Evas_Object *obj __UNUSED__,
918 void *event_info __UNUSED__)
920 evas_object_del(data);
924 _on_parent_move(void *data,
926 Evas_Object *obj __UNUSED__,
927 void *event_info __UNUSED__)
929 ELM_CTXPOPUP_DATA_GET(data, sd);
932 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
936 _scroller_size_reset(sd);
937 elm_layout_sizing_eval(data);
942 _on_parent_resize(void *data,
944 Evas_Object *obj __UNUSED__,
945 void *event_info __UNUSED__)
947 ELM_CTXPOPUP_DATA_GET(data, sd);
949 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
951 evas_object_hide(data);
952 evas_object_smart_callback_call(data, SIG_DISMISSED, NULL);
956 _parent_detach(Evas_Object *obj)
958 ELM_CTXPOPUP_DATA_GET(obj, sd);
960 if (!sd->parent) return;
962 evas_object_event_callback_del_full
963 (sd->parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
964 evas_object_event_callback_del_full
965 (sd->parent, EVAS_CALLBACK_MOVE, _on_parent_move, obj);
966 evas_object_event_callback_del_full
967 (sd->parent, EVAS_CALLBACK_RESIZE, _on_parent_resize, obj);
971 _on_content_resized(void *data,
973 Evas_Object *obj __UNUSED__,
974 void *event_info __UNUSED__)
976 ELM_CTXPOPUP_DATA_GET(data, sd);
978 elm_box_recalculate(sd->box);
979 elm_layout_sizing_eval(data);
982 //FIXME: lost the content size when theme hook is called.
984 _elm_ctxpopup_smart_theme(Evas_Object *obj)
987 Elm_Ctxpopup_Item *item;
991 ELM_CTXPOPUP_DATA_GET(obj, sd);
993 if (!ELM_WIDGET_CLASS(_elm_ctxpopup_parent_sc)->theme(obj))
996 rtl = elm_widget_mirrored_get(obj);
998 elm_widget_theme_object_set
999 (obj, sd->bg, "ctxpopup", "bg", elm_widget_style_get(obj));
1000 elm_widget_theme_object_set
1001 (obj, sd->arrow, "ctxpopup", "arrow", elm_widget_style_get(obj));
1002 elm_widget_theme_object_set
1003 (obj, sd->layout, "ctxpopup", "layout", elm_widget_style_get(obj));
1006 EINA_LIST_FOREACH(sd->items, elist, item)
1008 edje_object_mirrored_set(VIEW(item), rtl);
1010 if (item->label && item->icon)
1011 _elm_theme_object_set
1012 (obj, VIEW(item), "ctxpopup", "icon_text_style_item", elm_widget_style_get(obj));
1013 else if (item->label)
1016 _elm_theme_object_set(obj, VIEW(item), "ctxpopup", "text_style_item",
1017 elm_widget_style_get(obj));
1019 _elm_theme_object_set(obj, VIEW(item), "ctxpopup", "text_style_item_horizontal",
1020 elm_widget_style_get(obj));
1022 else if (item->icon)
1023 _elm_theme_object_set
1024 (obj, VIEW(item), "ctxpopup", "icon_style_item", elm_widget_style_get(obj));
1026 edje_object_part_text_set(VIEW(item), "elm.text", item->label);
1028 if (elm_widget_item_disabled_get(item))
1029 edje_object_signal_emit(VIEW(item), "elm,state,disabled", "elm");
1032 * For separator, if the first item has visible separator,
1033 * then it should be aligned with edge of the base part.
1034 * In some cases, it gives improper display. Ex) rounded corner
1035 * So the first item separator should be invisible.
1038 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
1040 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
1042 edje_object_message_signal_process(VIEW(item));
1045 if (evas_object_visible_get(sd->bg))
1046 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
1050 if (!strncmp(elm_object_style_get(obj), "default", strlen("default")))
1051 elm_object_style_set(sd->scr, "ctxpopup");
1053 elm_object_style_set(sd->scr, elm_object_style_get(obj));
1056 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1060 _scroller_size_reset(sd);
1061 _elm_ctxpopup_smart_sizing_eval(obj);
1067 /* kind of a big and tricky override here: an internal box will hold
1068 * the actual content. content aliases won't be of much help here */
1070 _elm_ctxpopup_smart_content_set(Evas_Object *obj,
1072 Evas_Object *content)
1074 Evas_Coord min_w = -1, min_h = -1;
1076 ELM_CTXPOPUP_DATA_GET(obj, sd);
1078 if ((part) && (strcmp(part, "default")))
1079 return ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_set
1080 (obj, part, content);
1082 if (!content) return EINA_FALSE;
1084 if (content == sd->content) return EINA_TRUE;
1086 if (sd->items) elm_ctxpopup_clear(obj);
1087 if (sd->content) evas_object_del(sd->content);
1092 sd->box = elm_box_add(obj);
1093 evas_object_size_hint_weight_set(sd->box, EVAS_HINT_EXPAND,
1095 evas_object_event_callback_add
1096 (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1097 ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_set
1098 (obj, "elm.swallow.content", sd->box);
1101 evas_object_size_hint_weight_set
1102 (content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1103 evas_object_size_hint_fill_set
1104 (content, EVAS_HINT_FILL, EVAS_HINT_FILL);
1106 /* since it's going to be a box content, not a layout's... */
1107 evas_object_show(content);
1109 evas_object_size_hint_min_get(content, &min_w, &min_h);
1110 evas_object_size_hint_min_set(sd->box, min_w, min_h);
1111 elm_box_pack_end(sd->box, content);
1113 sd->content = content;
1114 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1116 if (sd->visible) elm_layout_sizing_eval(obj);
1121 static Evas_Object *
1122 _elm_ctxpopup_smart_content_get(const Evas_Object *obj,
1125 ELM_CTXPOPUP_DATA_GET(obj, sd);
1127 if ((part) && (strcmp(part, "default")))
1128 return ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_get
1134 static Evas_Object *
1135 _elm_ctxpopup_smart_content_unset(Evas_Object *obj,
1138 Evas_Object *content;
1140 ELM_CTXPOPUP_DATA_GET(obj, sd);
1142 if ((part) && (strcmp(part, "default")))
1143 return ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_unset
1146 content = sd->content;
1147 if (!content) return NULL;
1149 evas_object_del(sd->box);
1152 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1154 if (sd->visible) elm_layout_sizing_eval(obj);
1160 _item_text_set_hook(Elm_Object_Item *it,
1164 Elm_Ctxpopup_Item *ctxpopup_it;
1166 if ((part) && (strcmp(part, "default"))) return;
1168 ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1170 _item_label_set(ctxpopup_it, label);
1174 _item_text_get_hook(const Elm_Object_Item *it,
1177 Elm_Ctxpopup_Item *ctxpopup_it;
1179 if (part && strcmp(part, "default")) return NULL;
1181 ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1182 return ctxpopup_it->label;
1186 _item_content_set_hook(Elm_Object_Item *it,
1188 Evas_Object *content)
1190 Elm_Ctxpopup_Item *ctxpopup_it;
1192 if ((part) && (strcmp(part, "icon"))) return;
1194 ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1196 ELM_CTXPOPUP_DATA_GET(WIDGET(ctxpopup_it), sd);
1198 _item_icon_set(ctxpopup_it, content);
1199 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1203 _scroller_size_reset(sd);
1204 _elm_ctxpopup_smart_sizing_eval(WIDGET(ctxpopup_it));
1208 static Evas_Object *
1209 _item_content_get_hook(const Elm_Object_Item *it,
1212 Elm_Ctxpopup_Item *ctxpopup_it;
1214 if (part && strcmp(part, "icon")) return NULL;
1216 ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1217 return ctxpopup_it->icon;
1221 _item_disable_hook(Elm_Object_Item *it)
1223 Elm_Ctxpopup_Item *ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1225 ELM_CTXPOPUP_DATA_GET(WIDGET(it), sd);
1228 if (elm_widget_item_disabled_get(it))
1229 edje_object_signal_emit(VIEW(ctxpopup_it), "elm,state,disabled", "elm");
1231 edje_object_signal_emit(VIEW(ctxpopup_it), "elm,state,enabled", "elm");
1235 _item_signal_emit_hook(Elm_Object_Item *it,
1236 const char *emission,
1239 Elm_Ctxpopup_Item *ctxpopup_it = (Elm_Ctxpopup_Item *)it;
1241 edje_object_signal_emit(VIEW(ctxpopup_it), emission, source);
1245 _bg_clicked_cb(void *data,
1246 Evas_Object *obj __UNUSED__,
1247 const char *emission __UNUSED__,
1248 const char *source __UNUSED__)
1250 ELM_CTXPOPUP_DATA_GET(data, sd);
1252 _hide_signals_emit(data, sd->dir);
1256 _on_show(void *data __UNUSED__,
1259 void *event_info __UNUSED__)
1262 Elm_Ctxpopup_Item *item;
1265 ELM_CTXPOPUP_DATA_GET(obj, sd);
1267 if ((!sd->items) && (!sd->content)) return;
1269 sd->visible = EINA_TRUE;
1271 evas_object_show(sd->bg);
1272 evas_object_show(sd->arrow);
1273 evas_object_show(sd->layout);
1275 edje_object_signal_emit(sd->bg, "elm,state,show", "elm");
1276 elm_layout_signal_emit(obj, "elm,state,show", "elm");
1278 EINA_LIST_FOREACH(sd->items, elist, item)
1280 if (item->label && !item->icon)
1283 _elm_theme_object_set(obj, VIEW(item), "ctxpopup", "text_style_item",
1284 elm_widget_style_get(obj));
1286 _elm_theme_object_set(obj, VIEW(item), "ctxpopup", "text_style_item_horizontal",
1287 elm_widget_style_get(obj));
1291 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
1293 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
1296 elm_layout_sizing_eval(obj);
1298 elm_object_focus_set(obj, EINA_TRUE);
1302 _on_hide(void *data __UNUSED__,
1305 void *event_info __UNUSED__)
1307 ELM_CTXPOPUP_DATA_GET(obj, sd);
1309 if (!sd->visible) return;
1311 evas_object_hide(sd->bg);
1312 evas_object_hide(sd->arrow);
1313 evas_object_hide(sd->layout);
1315 _scroller_size_reset(sd);
1317 sd->visible = EINA_FALSE;
1321 _on_move(void *data __UNUSED__,
1324 void *event_info __UNUSED__)
1326 ELM_CTXPOPUP_DATA_GET(obj, sd);
1328 if (sd->visible) evas_object_show(sd->arrow);
1330 _scroller_size_reset(sd);
1331 _elm_ctxpopup_smart_sizing_eval(obj);
1335 _hide_finished_cb(void *data,
1336 Evas_Object *obj __UNUSED__,
1337 const char *emission __UNUSED__,
1338 const char *source __UNUSED__)
1340 evas_object_hide(data);
1341 evas_object_smart_callback_call(data, SIG_DISMISSED, NULL);
1345 _scroller_resize(void *data, Evas *e __UNUSED__,
1347 void *event_info __UNUSED__)
1351 ELM_CTXPOPUP_DATA_GET(data, sd);
1353 if (!sd->visible) return;
1354 if (sd->finished) return;
1356 evas_object_geometry_get(obj, 0, 0, &w, &h);
1358 if (w != 0 && h != 0)
1360 if ((w <= sd->max_sc_w) && (h <= sd->max_sc_h))
1362 _elm_ctxpopup_smart_sizing_eval(data);
1363 sd->finished = EINA_TRUE;
1368 if (sd->max_sc_w < w)
1370 if (sd->max_sc_h < h)
1373 _elm_ctxpopup_smart_sizing_eval(data);
1377 _ctxpopup_restack_cb(void *data __UNUSED__,
1380 void *event_info __UNUSED__)
1382 ELM_CTXPOPUP_DATA_GET(obj, sd);
1383 evas_object_stack_below(sd->bg, obj);
1384 evas_object_stack_below(sd->layout, obj);
1388 _list_del(Elm_Ctxpopup_Smart_Data *sd)
1390 if (!sd->scr) return;
1392 edje_object_part_unswallow(ELM_WIDGET_DATA(sd)->resize_obj, sd->scr);
1393 evas_object_del(sd->scr);
1395 evas_object_del(sd->box);
1400 _list_new(Evas_Object *obj)
1402 ELM_CTXPOPUP_DATA_GET(obj, sd);
1406 sd->scr = elm_scroller_add(obj);
1407 elm_object_style_set(sd->scr, "ctxpopup");
1408 evas_object_size_hint_align_set(sd->scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
1409 evas_object_event_callback_add(sd->scr, EVAS_CALLBACK_RESIZE,
1410 _scroller_resize, obj);
1411 edje_object_part_swallow(ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.content", sd->scr);
1416 sd->box = elm_box_add(obj);
1417 evas_object_size_hint_weight_set(sd->box, EVAS_HINT_EXPAND,
1419 evas_object_event_callback_add
1420 (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1421 ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_set
1422 (obj, "elm.swallow.content", sd->box);
1425 elm_object_content_set(sd->scr, sd->box);
1426 elm_ctxpopup_horizontal_set(obj, sd->horizontal);
1430 _elm_ctxpopup_smart_disable(Evas_Object *obj)
1433 Elm_Object_Item *it;
1435 ELM_CTXPOPUP_DATA_GET(obj, sd);
1437 if (!ELM_WIDGET_CLASS(_elm_ctxpopup_parent_sc)->disable(obj))
1440 EINA_LIST_FOREACH(sd->items, l, it)
1441 elm_object_item_disabled_set(it, elm_widget_disabled_get(obj));
1447 _elm_ctxpopup_smart_add(Evas_Object *obj)
1449 EVAS_SMART_DATA_ALLOC(obj, Elm_Ctxpopup_Smart_Data);
1450 ELM_CTXPOPUP_DATA_GET(obj, sd);
1452 ELM_WIDGET_CLASS(_elm_ctxpopup_parent_sc)->base.add(obj);
1454 elm_layout_theme_set(obj, "ctxpopup", "base", elm_widget_style_get(obj));
1455 elm_layout_signal_callback_add
1456 (obj, "elm,action,hide,finished", "", _hide_finished_cb, obj);
1459 priv->bg = edje_object_add(evas_object_evas_get(obj));
1460 elm_widget_theme_object_set(obj, priv->bg, "ctxpopup", "bg", "default");
1461 edje_object_signal_callback_add
1462 (priv->bg, "elm,action,click", "", _bg_clicked_cb, obj);
1464 evas_object_stack_below(priv->bg, obj);
1467 priv->arrow = edje_object_add(evas_object_evas_get(obj));
1468 elm_widget_theme_object_set
1469 (obj, priv->arrow, "ctxpopup", "arrow", "default");
1471 priv->dir_priority[0] = ELM_CTXPOPUP_DIRECTION_UP;
1472 priv->dir_priority[1] = ELM_CTXPOPUP_DIRECTION_LEFT;
1473 priv->dir_priority[2] = ELM_CTXPOPUP_DIRECTION_RIGHT;
1474 priv->dir_priority[3] = ELM_CTXPOPUP_DIRECTION_DOWN;
1475 priv->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1477 evas_object_event_callback_add
1478 (obj, EVAS_CALLBACK_RESTACK, _ctxpopup_restack_cb, obj);
1480 evas_object_smart_callback_add
1481 (obj, "scroll-freeze-on", _freeze_on_cb, obj);
1482 evas_object_smart_callback_add
1483 (obj, "scroll-freeze-off", _freeze_off_cb, obj);
1484 evas_object_smart_callback_add
1485 (obj, "scroll-hold-on", _hold_on_cb, obj);
1486 evas_object_smart_callback_add
1487 (obj, "scroll-hold-off", _hold_off_cb, obj);
1489 priv->box = elm_box_add(obj);
1490 evas_object_size_hint_weight_set
1491 (priv->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1493 evas_object_event_callback_add
1494 (priv->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1496 /* box will be our content placeholder, thus the parent's version call */
1497 ELM_CONTAINER_CLASS(_elm_ctxpopup_parent_sc)->content_set
1498 (obj, "elm.swallow.content", priv->box);
1500 priv->layout = edje_object_add(evas_object_evas_get(obj));
1501 elm_widget_theme_object_set(obj, priv->layout, "ctxpopup", "layout", "default");
1503 edje_object_signal_callback_add
1504 (priv->layout, "elm,action,hide,finished", "", _hide_finished_cb, obj);
1505 edje_object_part_swallow(priv->layout, "swallow", ELM_WIDGET_DATA(sd)->resize_obj);
1506 evas_object_size_hint_weight_set
1507 (priv->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1509 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _on_show, NULL);
1510 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _on_hide, NULL);
1511 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _on_move, NULL);
1513 elm_widget_can_focus_set(obj, EINA_TRUE);
1517 _elm_ctxpopup_smart_del(Evas_Object *obj)
1519 ELM_CTXPOPUP_DATA_GET(obj, sd);
1521 evas_object_event_callback_del_full
1522 (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
1523 _parent_detach(obj);
1525 elm_ctxpopup_clear(obj);
1526 evas_object_del(sd->arrow);
1527 sd->arrow = NULL; /* stops _sizing_eval() from going on on deletion */
1529 evas_object_del(sd->bg);
1532 evas_object_del(sd->layout);
1535 ELM_WIDGET_CLASS(_elm_ctxpopup_parent_sc)->base.del(obj);
1539 _elm_ctxpopup_smart_parent_set(Evas_Object *obj,
1540 Evas_Object *parent)
1542 //default parent is to be hover parent
1543 elm_ctxpopup_hover_parent_set(obj, parent);
1547 _elm_ctxpopup_smart_access(Evas_Object *obj, Eina_Bool is_access)
1549 Eina_List *elist = NULL;
1550 Elm_Ctxpopup_Item *it;
1552 ELM_CTXPOPUP_CHECK(obj);
1553 ELM_CTXPOPUP_DATA_GET(obj, sd);
1555 EINA_LIST_FOREACH(sd->items, elist, it)
1556 _access_widget_item_register(it, is_access);
1560 _elm_ctxpopup_smart_set_user(Elm_Ctxpopup_Smart_Class *sc)
1562 ELM_WIDGET_CLASS(sc)->base.add = _elm_ctxpopup_smart_add;
1563 ELM_WIDGET_CLASS(sc)->base.del = _elm_ctxpopup_smart_del;
1565 ELM_WIDGET_CLASS(sc)->parent_set = _elm_ctxpopup_smart_parent_set;
1566 ELM_WIDGET_CLASS(sc)->disable = _elm_ctxpopup_smart_disable;
1567 ELM_WIDGET_CLASS(sc)->event = _elm_ctxpopup_smart_event;
1568 ELM_WIDGET_CLASS(sc)->theme = _elm_ctxpopup_smart_theme;
1569 ELM_WIDGET_CLASS(sc)->sub_object_add = _elm_ctxpopup_smart_sub_object_add;
1570 ELM_WIDGET_CLASS(sc)->focus_next = _elm_ctxpopup_smart_focus_next;
1571 ELM_WIDGET_CLASS(sc)->focus_direction = _elm_ctxpopup_smart_focus_direction;
1572 ELM_WIDGET_CLASS(sc)->translate = _elm_ctxpopup_smart_translate;
1574 ELM_CONTAINER_CLASS(sc)->content_get = _elm_ctxpopup_smart_content_get;
1575 ELM_CONTAINER_CLASS(sc)->content_set = _elm_ctxpopup_smart_content_set;
1576 ELM_CONTAINER_CLASS(sc)->content_unset = _elm_ctxpopup_smart_content_unset;
1578 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_ctxpopup_smart_sizing_eval;
1580 ELM_WIDGET_CLASS(sc)->access = _elm_ctxpopup_smart_access;
1583 EAPI const Elm_Ctxpopup_Smart_Class *
1584 elm_ctxpopup_smart_class_get(void)
1586 static Elm_Ctxpopup_Smart_Class _sc =
1587 ELM_CTXPOPUP_SMART_CLASS_INIT_NAME_VERSION(ELM_CTXPOPUP_SMART_NAME);
1588 static const Elm_Ctxpopup_Smart_Class *class = NULL;
1589 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1594 _elm_ctxpopup_smart_set(&_sc);
1595 esc->callbacks = _smart_callbacks;
1602 elm_ctxpopup_add(Evas_Object *parent)
1606 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1608 obj = elm_widget_add(_elm_ctxpopup_smart_class_new(), parent);
1609 if (!obj) return NULL;
1611 if (!elm_widget_sub_object_add(parent, obj))
1612 ERR("could not add %p as sub object of %p", obj, parent);
1614 /* access: parent could be any object such as elm_list which does
1615 not know elc_ctxpopup as its child object in the focus_next(); */
1616 ELM_WIDGET_DATA_GET(obj, sd);
1617 sd->highlight_root = EINA_TRUE;
1623 elm_ctxpopup_hover_parent_set(Evas_Object *obj,
1624 Evas_Object *parent)
1626 Evas_Coord x, y, w, h;
1628 ELM_CTXPOPUP_CHECK(obj);
1629 ELM_CTXPOPUP_DATA_GET(obj, sd);
1631 if (!parent) return;
1633 _parent_detach(obj);
1635 evas_object_event_callback_add
1636 (parent, EVAS_CALLBACK_DEL, _on_parent_del, obj);
1637 evas_object_event_callback_add
1638 (parent, EVAS_CALLBACK_MOVE, _on_parent_move, obj);
1639 evas_object_event_callback_add
1640 (parent, EVAS_CALLBACK_RESIZE, _on_parent_resize, obj);
1642 sd->parent = parent;
1645 evas_object_geometry_get(parent, &x, &y, &w, &h);
1646 evas_object_move(sd->bg, x, y);
1647 evas_object_resize(sd->bg, w, h);
1649 if (sd->visible) elm_layout_sizing_eval(obj);
1653 elm_ctxpopup_hover_parent_get(const Evas_Object *obj)
1655 ELM_CTXPOPUP_CHECK(obj) NULL;
1656 ELM_CTXPOPUP_DATA_GET(obj, sd);
1662 elm_ctxpopup_clear(Evas_Object *obj)
1664 ELM_CTXPOPUP_CHECK(obj);
1665 ELM_CTXPOPUP_DATA_GET(obj, sd);
1669 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1673 elm_ctxpopup_horizontal_set(Evas_Object *obj,
1674 Eina_Bool horizontal)
1677 Elm_Ctxpopup_Item *item;
1680 ELM_CTXPOPUP_CHECK(obj);
1681 ELM_CTXPOPUP_DATA_GET(obj, sd);
1683 sd->horizontal = !!horizontal;
1690 elm_box_horizontal_set(sd->box, EINA_FALSE);
1691 elm_scroller_bounce_set(sd->scr, EINA_FALSE, EINA_TRUE);
1695 elm_box_horizontal_set(sd->box, EINA_TRUE);
1696 elm_scroller_bounce_set(sd->scr, EINA_TRUE, EINA_FALSE);
1699 EINA_LIST_FOREACH(sd->items, elist, item)
1701 if (item->label && !item->icon && !horizontal)
1702 _elm_theme_object_set(obj, VIEW(item), "ctxpopup", "text_style_item",
1703 elm_widget_style_get(obj));
1704 else if (item->label && !item->icon && horizontal)
1705 _elm_theme_object_set(obj, VIEW(item), "ctxpopup", "text_style_item_horizontal",
1706 elm_widget_style_get(obj));
1709 edje_object_signal_emit(VIEW(item), "elm,state,default", "elm");
1711 edje_object_signal_emit(VIEW(item), "elm,state,separator", "elm");
1713 _item_disable_hook((Elm_Object_Item *)item);
1716 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1718 if (sd->visible) elm_layout_sizing_eval(obj);
1722 elm_ctxpopup_horizontal_get(const Evas_Object *obj)
1724 ELM_CTXPOPUP_CHECK(obj) EINA_FALSE;
1725 ELM_CTXPOPUP_DATA_GET(obj, sd);
1727 return sd->horizontal;
1730 EAPI Elm_Object_Item *
1731 elm_ctxpopup_item_append(Evas_Object *obj,
1737 Elm_Ctxpopup_Item *item;
1738 Evas_Object *content;
1740 ELM_CTXPOPUP_CHECK(obj) NULL;
1741 ELM_CTXPOPUP_DATA_GET(obj, sd);
1743 item = elm_widget_item_new(obj, Elm_Ctxpopup_Item);
1744 if (!item) return NULL;
1746 elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
1747 elm_widget_item_disable_hook_set(item, _item_disable_hook);
1748 elm_widget_item_text_set_hook_set(item, _item_text_set_hook);
1749 elm_widget_item_text_get_hook_set(item, _item_text_get_hook);
1750 elm_widget_item_content_set_hook_set(item, _item_content_set_hook);
1751 elm_widget_item_content_get_hook_set(item, _item_content_get_hook);
1752 elm_widget_item_signal_emit_hook_set(item, _item_signal_emit_hook);
1754 //The first item is appended.
1755 content = elm_object_content_unset(obj);
1756 if (content) evas_object_del(content);
1762 item->base.data = data;
1765 _item_new(item, "icon_text_style_item");
1768 if (!sd->horizontal)
1769 _item_new(item, "text_style_item");
1771 _item_new(item, "text_style_item_horizontal");
1774 _item_new(item, "icon_style_item");
1776 _item_icon_set(item, icon);
1777 _item_label_set(item, label);
1778 elm_box_pack_end(sd->box, VIEW(item));
1779 sd->items = eina_list_append(sd->items, item);
1781 sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1785 _scroller_size_reset(sd);
1786 _elm_ctxpopup_smart_sizing_eval(obj);
1790 return (Elm_Object_Item *)item;
1794 elm_ctxpopup_direction_priority_set(Evas_Object *obj,
1795 Elm_Ctxpopup_Direction first,
1796 Elm_Ctxpopup_Direction second,
1797 Elm_Ctxpopup_Direction third,
1798 Elm_Ctxpopup_Direction fourth)
1800 ELM_CTXPOPUP_CHECK(obj);
1801 ELM_CTXPOPUP_DATA_GET(obj, sd);
1803 sd->dir_priority[0] = first;
1804 sd->dir_priority[1] = second;
1805 sd->dir_priority[2] = third;
1806 sd->dir_priority[3] = fourth;
1808 if (sd->visible) elm_layout_sizing_eval(obj);
1812 elm_ctxpopup_direction_priority_get(Evas_Object *obj,
1813 Elm_Ctxpopup_Direction *first,
1814 Elm_Ctxpopup_Direction *second,
1815 Elm_Ctxpopup_Direction *third,
1816 Elm_Ctxpopup_Direction *fourth)
1818 ELM_CTXPOPUP_CHECK(obj);
1819 ELM_CTXPOPUP_DATA_GET(obj, sd);
1821 if (first) *first = sd->dir_priority[0];
1822 if (second) *second = sd->dir_priority[1];
1823 if (third) *third = sd->dir_priority[2];
1824 if (fourth) *fourth = sd->dir_priority[3];
1827 EAPI Elm_Ctxpopup_Direction
1828 elm_ctxpopup_direction_get(const Evas_Object *obj)
1830 ELM_CTXPOPUP_CHECK(obj) ELM_CTXPOPUP_DIRECTION_UNKNOWN;
1831 ELM_CTXPOPUP_DATA_GET(obj, sd);
1837 elm_ctxpopup_dismiss(Evas_Object *obj)
1839 ELM_CTXPOPUP_CHECK(obj);
1840 ELM_CTXPOPUP_DATA_GET(obj, sd);
1842 _hide_signals_emit(obj, sd->dir);