1 #include <Elementary.h>
5 * @defgroup Ctxpopup Ctxpopup
10 * Signals that you can add callbacks for are:
12 * hide - This is emitted when the ctxpopup is hided.
16 typedef struct _Widget_Data Widget_Data;
18 struct _Ctxpopup_Item {
19 Evas_Object *ctxpopup;
23 void (*func)(void *data, Evas_Object * obj, void *event_info);
25 Eina_Bool disabled :1;
26 Eina_Bool separator :1;
35 Evas_Object *scroller;
37 Evas_Object *btn_layout;
38 Evas_Object *area_rect;
40 Elm_Ctxpopup_Arrow arrow_dir;
41 Elm_Ctxpopup_Arrow arrow_priority[4];
44 Evas_Coord max_sc_w, max_sc_h;
46 Eina_Bool scroller_disabled :1;
47 Eina_Bool horizontal :1;
49 Eina_Bool screen_dimmed_disabled :1;
50 Eina_Bool position_forced :1;
51 Eina_Bool finished :1;
54 static const char *widtype = NULL;
55 static void _del_hook(Evas_Object *obj);
56 static void _del_pre_hook(Evas_Object *obj);
57 static void _theme_hook(Evas_Object *obj);
58 static void _sizing_eval(Evas_Object *obj);
59 static void _area_rect_resize(void *data, Evas *e, Evas_Object *obj,
61 static void _area_rect_move(void *data, Evas *e, Evas_Object *obj,
63 static void _area_rect_del(void *data, Evas *e, Evas_Object *obj,
65 static void _bg_clicked_cb(void *data, Evas_Object *obj, const char *emission,
67 static void _parent_resize(void *data, Evas *e, Evas_Object *obj,
69 static void _ctxpopup_show(void *data, Evas *e, Evas_Object *obj,
71 static void _ctxpopup_hide(void *data, Evas *e, Evas_Object *obj,
73 static void _ctxpopup_move(void *data, Evas *e, Evas_Object *obj,
75 static void _ctxpopup_changed_size_hints(void *data, Evas *e, Evas_Object *obj,
77 static void _ctxpopup_scroller_resize(void *data, Evas *e, Evas_Object *obj,
79 static void _item_obj_create(Elm_Ctxpopup_Item *item, char *group_name);
80 static void _item_sizing_eval(Elm_Ctxpopup_Item *item);
81 static void _ctxpopup_item_select(void *data, Evas_Object *obj,
82 const char *emission, const char *source);
83 static void _separator_obj_add(Evas_Object *obj);
84 static void _separator_obj_del(Widget_Data *wd, Elm_Ctxpopup_Item *remove_item);
85 static Elm_Ctxpopup_Arrow _calc_base_geometry(Evas_Object *obj,
86 Evas_Coord_Rectangle *rect);
87 static void _update_arrow_obj(Evas_Object *obj, Elm_Ctxpopup_Arrow arrow_dir);
88 static void _shift_base_by_arrow(Evas_Object *arrow,
89 Elm_Ctxpopup_Arrow arrow_dir, Evas_Coord_Rectangle *rect);
90 static void _btn_layout_create(Evas_Object *obj);
91 static int _get_indicator_h(Evas_Object *parent);
92 static void _delete_area_rect_callbacks(Widget_Data *wd);
93 static void _adjust_pos_x(Evas_Coord_Point *pos, Evas_Coord_Point *base_size,
94 Evas_Coord_Rectangle *area_rect);
95 static void _adjust_pos_y(int indicator_h, Evas_Coord_Point *pos,
96 Evas_Coord_Point *base_size, Evas_Coord_Rectangle *area_rect);
97 static void _reset_scroller_size(Widget_Data *wd);
98 static void _hide_ctxpopup(Evas_Object *obj);
99 static void _content_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
100 static void _content_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
102 static void _reset_scroller_size(Widget_Data *wd)
104 wd->finished = EINA_FALSE;
109 static void _delete_area_rect_callbacks(Widget_Data *wd)
111 if (!wd->area_rect) return;
113 evas_object_event_callback_del(wd->area_rect, EVAS_CALLBACK_DEL,
115 evas_object_event_callback_del(wd->area_rect, EVAS_CALLBACK_MOVE,
117 evas_object_event_callback_del(wd->area_rect, EVAS_CALLBACK_RESIZE,
121 static void _area_rect_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
123 Widget_Data *wd = elm_widget_data_get(data);
125 _reset_scroller_size(wd);
130 static void _area_rect_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
132 Widget_Data *wd = elm_widget_data_get(data);
134 _reset_scroller_size(wd);
139 static void _area_rect_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
141 Widget_Data *wd = elm_widget_data_get(data);
142 wd->area_rect = NULL;
145 static void _show_effect_done(void *data, Elm_Transit *transit)
147 //TODO: Consider implementing effect in edc.
148 Widget_Data *wd = data;
149 elm_transit_fx_clear(transit);
152 elm_transit_fx_insert(transit, elm_fx_color_add(wd->box, 0, 0, 0, 0,
153 255, 255, 255, 255));
155 elm_transit_fx_insert(transit, elm_fx_color_add(wd->content, 0, 0, 0,
156 0, 255, 255, 255, 255));
158 elm_transit_fx_insert(transit, elm_fx_color_add(wd->btn_layout, 0, 0,
159 0, 0, 255, 255, 255, 255));
160 elm_transit_run(transit, 0.2);
161 elm_transit_completion_callback_set(transit, NULL, NULL);
162 elm_transit_del(transit);
164 edje_object_signal_emit(wd->base, "elm,state,show", "elm");
167 static void _show_effect(Widget_Data* wd)
169 //TODO: Consider implementing effect in edc.
171 elm_transit_stop(wd->transit);
172 elm_transit_fx_clear(wd->transit);
174 wd->transit = elm_transit_add(wd->base);
175 elm_transit_curve_style_set(wd->transit, ELM_ANIMATOR_CURVE_OUT);
176 elm_transit_completion_callback_set(wd->transit, _show_effect_done, wd);
179 elm_transit_fx_insert(wd->transit, elm_fx_color_add(wd->base, 0, 0, 0, 0,
180 255, 255, 255, 255));
181 elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base,
182 ELM_FX_WIPE_TYPE_SHOW, wd->arrow_dir));
184 if(!wd->position_forced)
185 elm_transit_fx_insert(wd->transit, elm_fx_color_add(wd->arrow, 0, 0, 0, 0, 255, 255, 255, 255));
188 evas_object_color_set(wd->box, 0, 0, 0, 0);
190 evas_object_color_set(wd->content, 0, 0, 0, 0);
192 evas_object_color_set(wd->btn_layout, 0, 0, 0, 0);
194 elm_transit_run(wd->transit, 0.3);
197 static void _hide_effect_done(void *data, Elm_Transit *transit)
199 //TODO: Consider implementing effect in edc.
200 Widget_Data *wd = elm_widget_data_get(data);
202 elm_transit_del(transit);
204 _hide_ctxpopup(data);
207 static void _hide_effect(Evas_Object *obj)
209 //TODO: Consider implementing effect in edc.
210 Widget_Data *wd = elm_widget_data_get(obj);
214 elm_transit_stop(wd->transit);
215 elm_transit_fx_clear(wd->transit);
217 wd->transit = elm_transit_add(wd->base);
218 elm_transit_curve_style_set(wd->transit, ELM_ANIMATOR_CURVE_OUT);
219 elm_transit_completion_callback_set(wd->transit, _hide_effect_done, obj);
222 // elm_transit_fx_insert(wd->transit, elm_fx_color_add(wd->base, 255, 255, 255, 255, 0, 0, 0, 0));
224 switch(wd->arrow_dir) {
225 case ELM_FX_WIPE_DIR_UP:
226 elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base, ELM_FX_WIPE_TYPE_HIDE, ELM_FX_WIPE_DIR_DOWN));
228 case ELM_FX_WIPE_DIR_LEFT:
229 elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base, ELM_FX_WIPE_TYPE_HIDE, ELM_FX_WIPE_DIR_RIGHT));
231 case ELM_FX_WIPE_DIR_RIGHT:
232 elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base, ELM_FX_WIPE_TYPE_HIDE, ELM_FX_WIPE_DIR_LEFT));
234 case ELM_FX_WIPE_DIR_DOWN:
235 elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base, ELM_FX_WIPE_TYPE_HIDE, ELM_FX_WIPE_DIR_UP));
241 elm_transit_run(wd->transit, 0.3);
244 static void _separator_obj_del(Widget_Data *wd, Elm_Ctxpopup_Item *remove_item)
246 Eina_List *elist, *cur_list, *prev_list;
247 Elm_Ctxpopup_Item *separator;
249 if ((!remove_item) || (!wd)) return;
252 cur_list = eina_list_data_find_list(elist, remove_item);
254 if (!cur_list) return;
256 prev_list = eina_list_prev(cur_list);
258 if (!prev_list) return;
260 separator = (Elm_Ctxpopup_Item *) eina_list_data_get(prev_list);
262 if (!separator)return;
264 wd->items = eina_list_remove(wd->items, separator);
265 evas_object_del(separator->base);
269 static void _btn_layout_create(Evas_Object *obj)
271 Widget_Data *wd = elm_widget_data_get(obj);
273 wd->btn_layout = edje_object_add(evas_object_evas_get(obj));
274 elm_widget_sub_object_add(obj, wd->btn_layout);
275 edje_object_signal_emit(wd->base, "elm,state,buttons,enable", "elm");
276 edje_object_part_swallow(wd->base, "elm.swallow.btns", wd->btn_layout);
279 static void _separator_obj_add(Evas_Object *obj)
281 Elm_Ctxpopup_Item *item;
283 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
286 if (eina_list_count(wd->items) == 0) return;
288 item = ELM_NEW(Elm_Ctxpopup_Item);
291 item->base = edje_object_add(evas_object_evas_get(wd->base));
298 _elm_theme_object_set(obj, item->base, "ctxpopup", "separator",
299 elm_widget_style_get(obj));
302 edje_object_signal_emit(item->base, "elm,state,horizontal", "elm");
304 edje_object_signal_emit(item->base, "elm,state,vertical", "elm");
306 evas_object_size_hint_align_set(item->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
307 evas_object_show(item->base);
308 item->separator = EINA_TRUE;
309 elm_box_pack_end(wd->box, item->base);
310 wd->items = eina_list_append(wd->items, item);
313 static void _item_sizing_eval(Elm_Ctxpopup_Item *item)
315 Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
316 Evas_Coord x, y, w, h;
320 if (!item->separator) elm_coords_finger_size_adjust(1, &min_w, 1, &min_h);
322 evas_object_geometry_get(item->base, &x, &y, &w, &h);
323 edje_object_size_min_restricted_calc(item->base, &min_w, &min_h, min_w, min_h);
324 evas_object_size_hint_min_set(item->base, min_w, min_h);
325 evas_object_size_hint_max_set(item->base, max_w, max_h);
328 static void _adjust_pos_x(Evas_Coord_Point *pos, Evas_Coord_Point *base_size,
329 Evas_Coord_Rectangle *area_rect)
331 pos->x -= (base_size->x / 2);
333 if (pos->x < area_rect->x) pos->x = area_rect->x;
334 else if ((pos->x + base_size->x) > (area_rect->x + area_rect->w))
335 pos->x = (area_rect->x + area_rect->w) - base_size->x;
337 if (base_size->x > area_rect->w)
338 base_size->x -= (base_size->x - area_rect->w);
339 if (pos->x < area_rect->x)
340 pos->x = area_rect->x;
343 static void _adjust_pos_y(int indicator_h, Evas_Coord_Point *pos,
344 Evas_Coord_Point *base_size, Evas_Coord_Rectangle *area_rect)
346 pos->y -= (base_size->y / 2);
348 if (pos->y < area_rect->y) pos->y = area_rect->y;
349 else if ((pos->y + base_size->y) > (area_rect->y + area_rect->h))
350 pos->y = area_rect->y + area_rect->h - base_size->y;
352 if (base_size->y > area_rect->h)
353 base_size->y -= (base_size->y - area_rect->h);
355 if (pos->y < area_rect->y) pos->y = area_rect->y;
358 static int _get_indicator_h(Evas_Object *parent)
360 Ecore_X_Window zone, xwin;
363 if (elm_win_indicator_state_get(parent) != 1)
366 xwin = elm_win_xwindow_get(parent);
367 zone = ecore_x_e_illume_zone_get(xwin);
368 ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &h);
373 static void _ctxpopup_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
375 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
377 if(wd->visible)_sizing_eval(obj);
380 static Elm_Ctxpopup_Arrow _calc_base_geometry(Evas_Object *obj, Evas_Coord_Rectangle *rect)
383 Evas_Coord_Point pos;
384 Evas_Coord_Point base_size;
385 Evas_Coord_Point max_size;
386 Evas_Coord_Point min_size;
387 Evas_Coord_Rectangle area_rect;
388 Evas_Coord_Point parent_size;
389 Evas_Coord_Point arrow_size;
390 Elm_Ctxpopup_Arrow arrow;
391 Evas_Coord finger_size;
392 Evas_Coord indicator_h;
393 Evas_Coord_Point temp;
394 Evas_Coord min_calc_h;
395 Evas_Coord min_calc_w;
398 wd = elm_widget_data_get(obj);
400 if ((!wd) || (!rect)) return ELM_CTXPOPUP_ARROW_DOWN;
402 indicator_h = _get_indicator_h(wd->parent);
403 finger_size = elm_finger_size_get();
405 edje_object_part_geometry_get(wd->arrow, "ctxpopup_arrow", NULL, NULL,
406 &arrow_size.x, &arrow_size.y);
407 evas_object_resize(wd->arrow, arrow_size.x, arrow_size.y);
409 //Initialize Area Rectangle.
411 evas_object_geometry_get(wd->area_rect, &area_rect.x, &area_rect.y,
412 &area_rect.w, &area_rect.h);
414 evas_object_geometry_get(wd->parent, NULL, NULL, &parent_size.x, &parent_size.y);
417 area_rect.w = parent_size.x;
418 area_rect.h = parent_size.y;
421 if (area_rect.y < indicator_h) {
422 temp.y = indicator_h - area_rect.y;
423 area_rect.y = indicator_h;
424 area_rect.h -= temp.y;
427 evas_object_geometry_get(obj, &pos.x, &pos.y, NULL, NULL);
428 edje_object_size_min_calc(wd->base, &base_size.x, &base_size.y);
430 min_calc_w = base_size.x;
431 min_calc_h = base_size.y;
434 evas_object_size_hint_max_get(obj, &max_size.x, &max_size.y);
437 if(base_size.y > max_size.y) base_size.y = max_size.y;
440 if(base_size.x > max_size.x) base_size.x = max_size.x;
443 evas_object_size_hint_min_get(obj, &min_size.x, &min_size.y);
445 if( min_size.y > 0 ) {
446 if(base_size.y < min_size.y) base_size.y = min_size.y;
447 if(min_calc_h < min_size.y) min_calc_h = min_size.y;
450 if( min_size.x > 0 ) {
451 if(base_size.x < min_size.x) base_size.x = min_size.x;
452 if(min_calc_w < min_size.x) min_calc_w = min_size.x;
455 //In case of position forced. It shows up just like popup.
456 if (wd->position_forced) {
457 //TODO: calculate the size of ctxpopup
460 rect->w = base_size.x;
461 rect->h = base_size.y;
462 return ELM_CTXPOPUP_ARROW_UP;
465 //Check the Which direction is available.
466 //If find a avaialble direction, it adjusts position and size.
467 for (idx = 0; idx < 4; ++idx) {
468 switch (wd->arrow_priority[idx]) {
469 case ELM_CTXPOPUP_ARROW_DOWN:
470 temp.y = pos.y - base_size.y;
471 if ((temp.y - arrow_size.y - finger_size) < area_rect.y) continue;
472 _adjust_pos_x(&pos, &base_size, &area_rect);
473 pos.y -= (base_size.y + finger_size);
474 arrow = ELM_CTXPOPUP_ARROW_DOWN;
476 case ELM_CTXPOPUP_ARROW_RIGHT:
477 temp.x = (pos.x - base_size.x);
478 if ((temp.x - arrow_size.x - finger_size) < area_rect.x) continue;
479 _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
480 pos.x -= (base_size.x + finger_size);
481 arrow = ELM_CTXPOPUP_ARROW_RIGHT;
483 case ELM_CTXPOPUP_ARROW_LEFT:
484 temp.x = (pos.x + base_size.x);
485 if ((temp.x + arrow_size.x + finger_size) > (area_rect.x + area_rect.w)) continue;
486 _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
487 pos.x += finger_size;
488 arrow = ELM_CTXPOPUP_ARROW_LEFT;
490 case ELM_CTXPOPUP_ARROW_UP:
491 temp.y = (pos.y + base_size.y);
492 if ((temp.y + arrow_size.y + finger_size) > (area_rect.y + area_rect.h)) continue;
493 _adjust_pos_x(&pos, &base_size, &area_rect);
494 pos.y += finger_size;
495 arrow = ELM_CTXPOPUP_ARROW_UP;
503 //In this case, all directions are invalid because of lack of space.
505 //TODO 1: Find the largest space direction.
507 Evas_Coord length[4];
509 length[ ELM_CTXPOPUP_ARROW_DOWN ] = pos.y - area_rect.y;
510 length[ ELM_CTXPOPUP_ARROW_UP ] = ( area_rect.y + area_rect.h ) - pos.y;
511 length[ ELM_CTXPOPUP_ARROW_RIGHT ] = pos.x - area_rect.x;
512 length[ ELM_CTXPOPUP_ARROW_LEFT ] = ( area_rect.x + area_rect.w ) - pos.x;
515 for( i = 0; i < 4; ++i ) {
516 for( j = 1; j < 4; ++j ) {
517 if( length[ idx ] < length[ j ] ) {
523 //TODO 1: Find the largest space direction.
524 Evas_Coord length[2];
525 length[0] = pos.y - area_rect.y;
526 length[1] = (area_rect.y + area_rect.h) - pos.y;
528 if (length[0] > length[1]) idx = ELM_CTXPOPUP_ARROW_DOWN;
529 else idx = ELM_CTXPOPUP_ARROW_UP;
531 //TODO 2: determine x , y
533 case ELM_CTXPOPUP_ARROW_DOWN:
534 _adjust_pos_x(&pos, &base_size, &area_rect);
535 pos.y -= (base_size.y + finger_size);
536 arrow = ELM_CTXPOPUP_ARROW_DOWN;
537 if (pos.y < area_rect.y + arrow_size.y) {
538 base_size.y -= ((area_rect.y + arrow_size.y) - pos.y);
539 pos.y = area_rect.y + arrow_size.y;
542 case ELM_CTXPOPUP_ARROW_RIGHT:
543 _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
544 pos.x -= (base_size.x + finger_size);
545 arrow = ELM_CTXPOPUP_ARROW_RIGHT;
546 if (pos.x < area_rect.x + arrow_size.x) {
547 base_size.x -= ((area_rect.x + arrow_size.x) - pos.x);
548 pos.x = area_rect.x + arrow_size.x;
551 case ELM_CTXPOPUP_ARROW_LEFT:
552 _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
553 pos.x += finger_size;
554 arrow = ELM_CTXPOPUP_ARROW_LEFT;
555 if (pos.x + arrow_size.x + base_size.x > area_rect.x + area_rect.w) {
556 base_size.x -= ((pos.x + arrow_size.x + base_size.x)
557 - (area_rect.x + area_rect.w));
560 case ELM_CTXPOPUP_ARROW_UP:
561 _adjust_pos_x(&pos, &base_size, &area_rect);
562 pos.y += finger_size;
563 arrow = ELM_CTXPOPUP_ARROW_UP;
564 if (pos.y + arrow_size.y + base_size.y > area_rect.y + area_rect.h) {
565 base_size.y -= ((pos.y + arrow_size.y + base_size.y) - (area_rect.y + area_rect.h));
573 //Final position and size.
576 rect->w = base_size.x;
577 rect->h = base_size.y;
579 //resize scroller according to final size.
581 evas_object_geometry_get(wd->box, NULL, NULL, &temp.x, &temp.y);
582 evas_object_size_hint_min_set(wd->scroller, temp.x + (base_size.x - min_calc_w), temp.y + (base_size.y - min_calc_h));
588 static void _update_arrow_obj(Evas_Object *obj, Elm_Ctxpopup_Arrow arrow_dir)
591 Evas_Coord_Rectangle arrow_size;
592 Evas_Coord_Rectangle area_rect;
593 Evas_Coord parent_w, parent_h;
594 Widget_Data *wd = elm_widget_data_get(obj);
598 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
599 evas_object_geometry_get(wd->arrow, NULL, NULL, &arrow_size.w,
603 case ELM_CTXPOPUP_ARROW_LEFT: {
604 edje_object_signal_emit(wd->arrow, "elm,state,left", "elm");
605 arrow_size.y = (y - (arrow_size.h * 0.5));
606 arrow_size.x = (x + elm_finger_size_get());
609 case ELM_CTXPOPUP_ARROW_RIGHT: {
610 edje_object_signal_emit(wd->arrow, "elm,state,right", "elm");
611 arrow_size.y = (y - (arrow_size.h * 0.5));
612 arrow_size.x = (x - elm_finger_size_get() - arrow_size.w);
615 case ELM_CTXPOPUP_ARROW_UP: {
616 edje_object_signal_emit(wd->arrow, "elm,state,top", "elm");
617 arrow_size.x = (x - (arrow_size.w * 0.5));
618 arrow_size.y = (y + elm_finger_size_get());
621 case ELM_CTXPOPUP_ARROW_DOWN: {
622 edje_object_signal_emit(wd->arrow, "elm,state,bottom", "elm");
623 arrow_size.x = (x - (arrow_size.w * 0.5));
624 arrow_size.y = (y - elm_finger_size_get() - arrow_size.h);
631 //Adjust arrow position to prevent out of area
633 evas_object_geometry_get(wd->area_rect, &area_rect.x, &area_rect.y,
634 &area_rect.w, &area_rect.h);
636 evas_object_geometry_get(wd->parent, NULL, NULL, &parent_w, &parent_h);
639 area_rect.w = parent_w;
640 area_rect.h = parent_h;
643 //TODO: Temporary Code. make it more flexible
644 if ((arrow_size.x - (arrow_size.w / 2)) < area_rect.x)
645 arrow_size.x = area_rect.x + (arrow_size.w / 2);
646 else if ((arrow_size.x + arrow_size.w) > (area_rect.x + area_rect.w))
647 arrow_size.x = (area_rect.x + area_rect.w) - arrow_size.w
648 - (arrow_size.w / 2);
650 //TODO: Temporary Code. make it more flexible
651 if ((arrow_size.y - (arrow_size.h / 2)) < area_rect.y) {
652 arrow_size.y = arrow_size.y + (arrow_size.h / 2);
653 } else if ((arrow_size.y + arrow_size.h) > (area_rect.y + area_rect.h)) {
654 arrow_size.y = (area_rect.y + area_rect.h) - arrow_size.h
655 - (arrow_size.h / 2);
658 evas_object_move(wd->arrow, arrow_size.x, arrow_size.y);
661 static void _sizing_eval(Evas_Object *obj)
665 Elm_Ctxpopup_Item *item;
666 Evas_Coord_Rectangle rect = { 0, 0, 1, 1 };
667 Evas_Coord_Point box_size = { 0, 0 };
668 Evas_Coord_Point _box_size = { 0, 0 };
670 wd = (Widget_Data *) elm_widget_data_get(obj);
671 if ((!wd) || (!wd->parent)) return;
675 EINA_LIST_FOREACH(wd->items, elist, item)
677 _item_sizing_eval(item);
678 evas_object_size_hint_min_get(item->base, &_box_size.x, &_box_size.y);
679 if(!wd->horizontal) {
680 if(_box_size.x > box_size.x) box_size.x = _box_size.x;
681 if(_box_size.y != -1 ) box_size.y += _box_size.y;
683 if(_box_size.x != -1 ) box_size.x += _box_size.x;
684 if(_box_size.y > box_size.y) box_size.y = _box_size.y;
690 evas_object_size_hint_min_set(wd->box, box_size.x, box_size.y);
691 evas_object_size_hint_min_set(wd->scroller, box_size.x, box_size.y);
695 wd->arrow_dir = _calc_base_geometry(obj, &rect);
696 if ((!wd->position_forced) && (wd->arrow_dir != -1)) {
697 _update_arrow_obj(obj, wd->arrow_dir);
698 _shift_base_by_arrow(wd->arrow, wd->arrow_dir, &rect);
701 evas_object_move(wd->base, rect.x, rect.y);
702 evas_object_resize(wd->base, rect.w, rect.h);
705 static void _shift_base_by_arrow(Evas_Object *arrow,
706 Elm_Ctxpopup_Arrow arrow_dir, Evas_Coord_Rectangle *rect)
708 Evas_Coord arrow_w, arrow_h;
709 evas_object_geometry_get(arrow, NULL, NULL, &arrow_w, &arrow_h);
712 case ELM_CTXPOPUP_ARROW_LEFT:
715 case ELM_CTXPOPUP_ARROW_RIGHT:
718 case ELM_CTXPOPUP_ARROW_UP:
721 case ELM_CTXPOPUP_ARROW_DOWN:
729 static void _del_pre_hook(Evas_Object *obj) {
731 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
734 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
735 _parent_resize, obj);
738 elm_transit_stop(wd->transit);
739 elm_transit_del(wd->transit);
743 _delete_area_rect_callbacks(wd);
747 static void _del_hook(Evas_Object *obj)
749 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
752 elm_ctxpopup_clear(obj);
753 evas_object_del(wd->arrow);
754 evas_object_del(wd->base);
759 static void _theme_hook(Evas_Object *obj)
762 Elm_Ctxpopup_Item *item;
765 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
770 EINA_LIST_FOREACH(wd->items, elist, item)
774 _elm_theme_object_set(obj, item->base, "ctxpopup", "separator",
775 elm_widget_style_get(obj));
777 edje_object_signal_emit(item->base, "elm,state,horizontal", "elm");
781 if (item->label && item->icon)
783 _elm_theme_object_set(obj, item->base, "ctxpopup",
784 "icon_text_style_item",
785 elm_widget_style_get(obj));
787 else if (item->label)
789 _elm_theme_object_set(obj, item->base, "ctxpopup",
791 elm_widget_style_get(obj));
795 _elm_theme_object_set(obj, item->base, "ctxpopup",
797 elm_widget_style_get(obj));
800 edje_object_part_text_set(item->base, "elm.text", item->label);
803 edje_object_signal_emit(item->base, "elm,state,disabled", "elm");
805 edje_object_message_signal_process(item->base);
809 if (wd->btn_layout) {
810 sprintf(buf, "buttons%d", wd->btn_cnt);
811 _elm_theme_object_set(obj, wd->btn_layout, "ctxpopup", buf,
812 elm_widget_style_get(obj));
815 _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg", elm_widget_style_get(obj));
816 _elm_theme_object_set(obj, wd->base, "ctxpopup", "base", elm_widget_style_get(obj));
817 _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow",
818 elm_widget_style_get(obj));
820 if (!strncmp(elm_object_style_get(obj), "default", strlen("default")
822 elm_object_style_set(wd->scroller, "ctxpopup");
824 elm_object_style_set(wd->scroller, elm_object_style_get(obj));
827 _reset_scroller_size(wd);
832 static void _bg_clicked_cb(void *data, Evas_Object *obj, const char *emission,
835 evas_object_hide(data);
838 static void _parent_resize(void *data, Evas *e, Evas_Object *obj,
843 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(data);
846 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
847 evas_object_resize(wd->bg, w, h);
849 if(wd->visible == EINA_FALSE) return;
850 wd->visible = EINA_FALSE;
851 _hide_ctxpopup(data);
855 static void _ctxpopup_show(void *data, Evas *e, Evas_Object *obj,
858 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
859 if(wd == NULL) return;
861 if ((eina_list_count(wd->items) < 1) && (!wd->content) && (wd->btn_cnt < 1))
864 wd->visible = EINA_TRUE;
867 if (!wd->screen_dimmed_disabled) {
868 evas_object_show(wd->bg);
869 edje_object_signal_emit(wd->bg, "elm,state,show", "elm");
872 evas_object_show(wd->base);
874 if (!wd->position_forced) {
875 evas_object_show(wd->arrow);
881 static void _hide_ctxpopup(Evas_Object *obj)
883 //TODO: Consider implementing effect in edc.
884 Widget_Data *wd = elm_widget_data_get(obj);
886 if (!wd->screen_dimmed_disabled)
887 evas_object_hide(wd->bg);
889 if(!wd->position_forced)
890 evas_object_hide(wd->arrow);
892 evas_object_hide(wd->base);
894 _reset_scroller_size(wd);
895 evas_object_smart_callback_call(obj, "hide", NULL);
898 static void _ctxpopup_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
900 Widget_Data *wd = (Widget_Data*) elm_widget_data_get(obj);
901 if(wd == NULL) return;
903 if(wd->visible == EINA_FALSE) return;
905 wd->visible = EINA_FALSE;
907 if (!wd->screen_dimmed_disabled)
908 edje_object_signal_emit(wd->bg, "elm,state,hide", "elm");
913 static void _ctxpopup_scroller_resize(void *data, Evas *e, Evas_Object * obj,
919 wd = elm_widget_data_get(data);
920 if(wd == NULL) return;
922 if(!wd->visible) return;
923 if(wd->finished) return;
925 evas_object_geometry_get(wd->scroller, 0, 0, &w, &h);
927 if( w != 0 && h !=0 ) {
928 if((w <= wd->max_sc_w) && (h <= wd->max_sc_h) ) {
930 wd->finished = EINA_TRUE;
935 if(wd->max_sc_w < w ) wd->max_sc_w = w;
936 if(wd->max_sc_h < h ) wd->max_sc_h = h;
941 static void _ctxpopup_move(void *data, Evas *e, Evas_Object *obj,
944 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
945 if(wd == NULL) return;
947 if (wd->visible && !wd->position_forced)
948 evas_object_show(wd->arrow);
950 _reset_scroller_size(wd);
954 static void _ctxpopup_item_select(void *data, Evas_Object *obj,
955 const char *emission, const char *source)
957 Elm_Ctxpopup_Item *item = (Elm_Ctxpopup_Item *) data;
960 if (item->disabled) return;
962 item->func(item->data, item->ctxpopup, item);
963 _ctxpopup_hide(item->ctxpopup, NULL, item->ctxpopup, NULL);
966 static void _item_obj_create(Elm_Ctxpopup_Item *item, char *group_name)
968 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(item->ctxpopup);
971 item->base = edje_object_add(evas_object_evas_get(wd->base));
972 _elm_theme_object_set(item->ctxpopup, item->base, "ctxpopup", group_name,
973 elm_widget_style_get(item->ctxpopup));
974 edje_object_signal_callback_add(item->base, "elm,action,click", "",
975 _ctxpopup_item_select, item);
976 evas_object_size_hint_align_set(item->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
977 evas_object_size_hint_weight_set(item->base, EVAS_HINT_EXPAND,
979 evas_object_show(item->base);
982 static void _content_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
984 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
987 if(wd->visible) _sizing_eval(data);
990 static void _content_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
992 elm_ctxpopup_content_unset(data, obj);
998 * Get the icon object for the given item.
1000 * @param[in] item Ctxpopup item
1001 * @return Icon object or NULL if the item does not have icon
1006 elm_ctxpopup_item_icon_get(Elm_Ctxpopup_Item *item)
1008 if (!item) return NULL;
1013 * Disable or Enable the scroller for contextual popup.
1015 * @param[in] obj Ctxpopup object
1016 * @param[in] disabled disable or enable
1020 EAPI void elm_ctxpopup_scroller_disabled_set(Evas_Object *obj,
1023 ELM_CHECK_WIDTYPE(obj, widtype);
1024 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1027 if (wd->scroller_disabled == disabled) return;
1030 elm_object_scroll_freeze_push(wd->scroller);
1032 elm_object_scroll_freeze_pop(wd->scroller);
1034 wd->scroller_disabled = disabled;
1038 * Get the label for the given item.
1040 * @param[in] item Ctxpopup item
1041 * @return Label or NULL if the item does not have label
1047 elm_ctxpopup_item_label_get(Elm_Ctxpopup_Item *item)
1049 if (!item) return NULL;
1054 * Add a new ctxpopup object to the parent.
1056 * @param[in] parent window object
1057 * @return New object or NULL if it cannot be created
1062 elm_ctxpopup_add(Evas_Object *parent)
1067 Evas_Coord x, y, w, h;
1069 wd = ELM_NEW(Widget_Data);
1070 e = evas_object_evas_get(parent);
1075 obj = elm_widget_add(e);
1076 ELM_SET_WIDTYPE(widtype, "ctxpopup");
1077 elm_widget_type_set(obj, "ctxpopup");
1078 elm_widget_sub_object_add(parent, obj);
1079 elm_widget_data_set(obj, wd);
1080 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
1081 elm_widget_del_hook_set(obj, _del_hook);
1082 elm_widget_theme_hook_set(obj, _theme_hook);
1084 wd->parent = parent;
1087 wd->bg = edje_object_add(e);
1088 elm_widget_sub_object_add(obj, wd->bg);
1089 _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg", "default");
1090 evas_object_geometry_get(parent, &x, &y, &w, &h);
1091 evas_object_move(wd->bg, x, y);
1092 evas_object_resize(wd->bg, w, h);
1093 edje_object_signal_callback_add(wd->bg, "elm,action,click", "",
1094 _bg_clicked_cb, obj);
1097 wd->base = edje_object_add(e);
1098 elm_widget_sub_object_add(obj, wd->base);
1099 _elm_theme_object_set(obj, wd->base, "ctxpopup", "base", "default");
1102 wd->scroller = elm_scroller_add(obj);
1103 elm_object_style_set(wd->scroller, "ctxpopup");
1104 evas_object_size_hint_align_set(wd->scroller, EVAS_HINT_FILL,
1106 elm_scroller_bounce_set(wd->scroller, EINA_FALSE, EINA_TRUE);
1107 evas_object_event_callback_add(wd->scroller, EVAS_CALLBACK_RESIZE,
1108 _ctxpopup_scroller_resize, obj);
1111 wd->box = elm_box_add(obj);
1112 evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND,
1114 elm_scroller_content_set(wd->scroller, wd->box);
1116 edje_object_part_swallow(wd->base, "elm.swallow.scroller", wd->scroller);
1119 wd->arrow = edje_object_add(e);
1120 elm_widget_sub_object_add(obj, wd->arrow);
1121 _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow", "default");
1123 wd->arrow_priority[0] = ELM_CTXPOPUP_ARROW_DOWN;
1124 wd->arrow_priority[1] = ELM_CTXPOPUP_ARROW_RIGHT;
1125 wd->arrow_priority[2] = ELM_CTXPOPUP_ARROW_LEFT;
1126 wd->arrow_priority[3] = ELM_CTXPOPUP_ARROW_UP;
1128 evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE,
1129 _parent_resize, obj);
1130 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _ctxpopup_show, NULL);
1131 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _ctxpopup_hide, NULL);
1132 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _ctxpopup_move, NULL);
1133 evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _ctxpopup_changed_size_hints, NULL);
1139 * Clear all items in given ctxpopup object.
1141 * @param[in] obj Ctxpopup object
1145 EAPI void elm_ctxpopup_clear(Evas_Object *obj)
1147 ELM_CHECK_WIDTYPE(obj, widtype);
1149 Elm_Ctxpopup_Item *item;
1151 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1155 EINA_LIST_FOREACH(wd->items, elist, item)
1158 eina_stringshare_del(item->label);
1160 evas_object_del(item->icon);
1161 wd->items = eina_list_remove(wd->items, item);
1165 evas_object_hide(wd->arrow);
1166 evas_object_hide(wd->base);
1170 * Change the mode to horizontal or vertical.
1172 * @param[in] obj Ctxpopup object
1173 * @param horizontal EINA_TRUE - horizontal mode, EINA_FALSE - vertical mode
1177 EAPI void elm_ctxpopup_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
1179 ELM_CHECK_WIDTYPE(obj, widtype);
1181 Elm_Ctxpopup_Item *item;
1182 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1186 if (wd->horizontal == horizontal) return;
1187 wd->horizontal = horizontal;
1189 elm_box_horizontal_set(wd->box, EINA_FALSE);
1190 elm_scroller_bounce_set(wd->scroller, EINA_FALSE, EINA_TRUE);
1191 EINA_LIST_FOREACH (wd->items, elist, item)
1192 edje_object_signal_emit(item->base, "elm,state,vertical", "elm");
1196 elm_box_horizontal_set(wd->box, EINA_TRUE);
1197 elm_scroller_bounce_set(wd->scroller, EINA_TRUE, EINA_FALSE);
1198 EINA_LIST_FOREACH(wd->items, elist, item)
1199 edje_object_signal_emit(item->base, "elm,state,horizontal", "elm");
1204 * Get the value of current horizontal mode.
1206 * @param[in] obj Ctxpopup object
1207 * @return EINA_TRUE - horizontal mode, EINA_FALSE - vertical mode.
1211 EAPI Eina_Bool elm_ctxpopup_horizontal_get(Evas_Object *obj)
1213 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1214 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1215 if (!wd) return EINA_FALSE;
1216 return wd->horizontal;
1220 * reset the icon on the given item.
1222 * @param[in] item Ctxpopup item
1223 * @param[in] icon Icon object to be set
1227 EAPI void elm_ctxpopup_item_icon_set(Elm_Ctxpopup_Item *item, Evas_Object *icon)
1232 wd = (Widget_Data *) elm_widget_data_get(item->ctxpopup);
1234 if (item->icon == icon) return;
1236 elm_widget_sub_object_del(item->base, item->icon);
1237 evas_object_del(item->icon);
1240 edje_object_part_swallow(item->base, "elm.swallow.icon", item->icon);
1241 edje_object_message_signal_process(item->base);
1244 _reset_scroller_size(wd);
1245 _sizing_eval(item->ctxpopup);
1250 * reset the label on the given item.
1252 * @param[in] item Ctxpopup item
1253 * @param[in] label Label to be set
1257 EAPI void elm_ctxpopup_item_label_set(Elm_Ctxpopup_Item *item,
1266 eina_stringshare_del(item->label);
1270 item->label = eina_stringshare_add(label);
1271 edje_object_message_signal_process(item->base);
1272 edje_object_part_text_set(item->base, "elm.text", label);
1274 wd = elm_widget_data_get(item->ctxpopup);
1279 _reset_scroller_size(wd);
1280 _sizing_eval(item->ctxpopup);
1285 * Add a new item in given ctxpopup object.
1287 * @param[in] obj Ctxpopup object
1288 * @param[in] icon Icon to be set
1289 * @param[in] label Label to be set
1290 * @param[in] func Callback function to call when this item click is clicked
1291 * @param[in] data User data for callback function
1292 * @return Added ctxpopup item
1296 EAPI Elm_Ctxpopup_Item *
1297 elm_ctxpopup_item_add(Evas_Object *obj, Evas_Object *icon, const char *label,
1298 Evas_Smart_Cb func, void *data)
1300 ELM_CHECK_WIDTYPE(obj, widtype)NULL;
1301 Elm_Ctxpopup_Item *item;
1302 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1307 _separator_obj_add(obj);
1309 item = ELM_NEW(Elm_Ctxpopup_Item);
1315 item->ctxpopup = obj;
1316 item->separator = EINA_FALSE;
1319 _item_obj_create(item, "icon_text_style_item");
1321 _item_obj_create(item, "icon_style_item");
1323 _item_obj_create(item, "text_style_item");
1325 wd->items = eina_list_append(wd->items, item);
1326 elm_box_pack_end(wd->box, item->base);
1327 elm_ctxpopup_item_icon_set(item, icon);
1328 elm_ctxpopup_item_label_set(item, label);
1334 * Delete the given item in ctxpopup object.
1336 * @param item[in] Ctxpopup item to be deleted
1340 EAPI void elm_ctxpopup_item_del(Elm_Ctxpopup_Item *item)
1348 obj = item->ctxpopup;
1351 eina_stringshare_del(item->label);
1353 evas_object_del(item->icon);
1355 evas_object_del(item->base);
1357 wd = (Widget_Data *) elm_widget_data_get(item->ctxpopup);
1359 _separator_obj_del(wd, item);
1360 wd->items = eina_list_remove(wd->items, item);
1363 if (eina_list_count(wd->items) == 0) {
1364 _ctxpopup_hide(obj, NULL, obj, NULL);
1369 * Disable or Enable the given item. Once an item is disabled, the click event will be never happend for the item.
1371 * @param[in] item Ctxpopup item to be disabled
1372 * @param[in] disabled EINA_TRUE - disable, EINA_FALSE - enable
1376 EAPI void elm_ctxpopup_item_disabled_set(Elm_Ctxpopup_Item *item,
1382 if (disabled == item->disabled) return;
1384 wd = (Widget_Data *) elm_widget_data_get(item->ctxpopup);
1387 edje_object_signal_emit(item->base, "elm,state,disabled", "elm");
1389 edje_object_signal_emit(item->base, "elm,state,enabled", "elm");
1391 edje_object_message_signal_process(item->base);
1392 item->disabled = disabled;
1396 * Disable or Enable background dimmed function
1397 * @param[in] obj Ctxpopup object
1398 * @param[in] dimmed EINA_TRUE - disable, EINA_FALSE - enable
1402 EAPI void elm_ctxpopup_screen_dimmed_disabled_set(Evas_Object *obj,
1405 ELM_CHECK_WIDTYPE(obj, widtype);
1406 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1411 wd->screen_dimmed_disabled = disabled;
1415 evas_object_show(wd->bg);
1421 * Append additional button in ctxpoppup bottom layout.
1422 * @param[in] obj Ctxpopup object
1423 * @param[in] label Button label
1424 * @param[in] func Button clicked event callback function
1425 * @param[in] data Button clicked event callback function data
1429 EAPI void elm_ctxpopup_button_append(Evas_Object *obj, const char *label,
1430 Evas_Smart_Cb func, const void *data)
1432 ELM_CHECK_WIDTYPE(obj, widtype);
1436 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1439 if (!wd->btn_layout) _btn_layout_create(obj);
1442 sprintf(buf, "buttons%d", wd->btn_cnt);
1443 _elm_theme_object_set(obj, wd->btn_layout, "ctxpopup", buf,
1444 elm_widget_style_get(obj));
1446 btn = elm_button_add(obj);
1447 elm_object_style_set(btn, "text_only/style1");
1448 elm_button_label_set(btn, label);
1449 evas_object_smart_callback_add(btn, "clicked", func, data);
1450 sprintf(buf, "actionbtn%d", wd->btn_cnt);
1451 edje_object_part_swallow(wd->btn_layout, buf, btn);
1453 edje_object_part_geometry_get(wd->btn_layout, buf, NULL, NULL, &w, &h);
1454 evas_object_size_hint_max_set(wd->btn_layout, -1, h);
1457 _reset_scroller_size(wd);
1463 * Set the priority of arrow direction
1465 * This functions gives user to set the priority of ctxpopup box showing position.
1467 * @param[in] obj Ctxpopup object
1468 * @param[in] first 1st priority of arrow direction
1469 * @param[in] second 2nd priority of arrow direction
1470 * @param[in] third 3th priority of arrow direction
1471 * @param[in] fourth 4th priority of arrow direction
1475 EAPI void elm_ctxpopup_arrow_priority_set(Evas_Object *obj,
1476 Elm_Ctxpopup_Arrow first, Elm_Ctxpopup_Arrow second,
1477 Elm_Ctxpopup_Arrow third, Elm_Ctxpopup_Arrow fourth)
1479 ELM_CHECK_WIDTYPE(obj, widtype);
1480 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1484 wd->arrow_priority[0] = first;
1485 wd->arrow_priority[1] = second;
1486 wd->arrow_priority[2] = third;
1487 wd->arrow_priority[3] = fourth;
1493 * Swallow the user content
1495 * @param[in] obj Ctxpopup object
1496 * @param[in] content Content to be swallowed
1500 EAPI void elm_ctxpopup_content_set(Evas_Object *obj, Evas_Object *content)
1502 ELM_CHECK_WIDTYPE(obj, widtype);
1503 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1506 if(!wd || !content) return;
1508 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _content_del, obj);
1509 evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _ctxpopup_changed_size_hints, NULL);
1511 edje_object_part_swallow(wd->base, "elm.swallow.content", content);
1512 elm_widget_sub_object_add(obj, content);
1513 edje_object_signal_emit(wd->base, "elm,state,content,enable", "elm");
1514 elm_ctxpopup_scroller_disabled_set(obj, EINA_TRUE);
1516 wd->content = content;
1518 if(wd->visible) _sizing_eval(obj);
1522 * Unswallow the user content
1524 * @param[in] obj Ctxpopup object
1525 * @return The unswallowed content
1530 elm_ctxpopup_content_unset(Evas_Object *obj)
1532 ELM_CHECK_WIDTYPE(obj, widtype)NULL;
1533 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1534 Evas_Object *content;
1536 content = wd->content;
1539 if (content) edje_object_part_unswallow(wd->base, content);
1541 elm_widget_sub_object_del(obj, content);
1542 edje_object_signal_emit(wd->base, "elm,state,content,disable", "elm");
1544 elm_ctxpopup_scroller_disabled_set(obj, EINA_FALSE);
1553 * Change the origin of the ctxpopup position.
1555 * Basically, ctxpopup position is computed internally. When user call evas_object_move,
1556 * Ctxpopup will be showed up with that position which is indicates the arrow point.
1558 * @param[in] obj Ctxpopup object
1559 * @param[in] forced EINA_TRUE is left-top. EINA_FALSE is indicates arrow point.
1563 EAPI void elm_ctxpopup_position_forced_set(Evas_Object *obj, Eina_Bool forced)
1565 ELM_CHECK_WIDTYPE(obj, widtype);
1566 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1568 wd->position_forced = forced;
1570 if (forced) evas_object_hide(wd->arrow);
1573 _reset_scroller_size(wd);
1579 * Get the status of the position forced
1581 * @param[in] obj Ctxpopup objet
1582 * @return value of position forced
1586 EAPI Eina_Bool elm_ctxpopup_position_forced_get(Evas_Object *obj)
1588 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1589 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1591 return wd->position_forced;
1594 EAPI Elm_Ctxpopup_Item *
1595 elm_ctxpopup_icon_add(Evas_Object *obj, Evas_Object *icon, Evas_Smart_Cb func,
1598 return elm_ctxpopup_item_add(obj, icon, NULL, func, data);
1601 EAPI Elm_Ctxpopup_Item *
1602 elm_ctxpopup_label_add(Evas_Object *obj, const char *label, Evas_Smart_Cb func,
1605 return elm_ctxpopup_item_add(obj, NULL, label, func, data);
1609 * Set the area of ctxpopup will show up. Ctxpopup will not be out of this area.
1610 * The responsibility of the area object is to user.
1612 * @param[in] obj Ctxpopup objet
1613 * @param[in] area area object
1617 EAPI void elm_ctxpopup_area_set(Evas_Object *obj, Evas_Object *area)
1619 ELM_CHECK_WIDTYPE(obj, widtype);
1620 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1622 _delete_area_rect_callbacks(wd);
1625 evas_object_event_callback_add(area, EVAS_CALLBACK_DEL, _area_rect_del,
1627 evas_object_event_callback_add(area, EVAS_CALLBACK_MOVE,
1628 _area_rect_move, obj);
1629 evas_object_event_callback_add(area, EVAS_CALLBACK_RESIZE,
1630 _area_rect_resize, obj);
1631 wd->area_rect = area;
1636 EAPI void elm_ctxpopup_title_set(Evas_Object *obj, const char *title )
1638 ELM_CHECK_WIDTYPE(obj, widtype);
1639 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1643 if(wd->title) eina_stringshare_del(wd->title);
1644 wd->title = eina_stringshare_add(title);
1645 edje_object_part_text_set(wd->base, "elm.title", title);
1649 EAPI const char* elm_ctxpopup_title_get(Evas_Object *obj)
1651 ELM_CHECK_WIDTYPE(obj, widtype);
1652 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);