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_resize(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));
297 _elm_theme_object_set(obj, item->base, "ctxpopup", "separator",
298 elm_widget_style_get(obj));
301 edje_object_signal_emit(item->base, "elm,state,horizontal", "elm");
303 edje_object_signal_emit(item->base, "elm,state,vertical", "elm");
305 evas_object_size_hint_align_set(item->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
306 evas_object_show(item->base);
307 item->separator = EINA_TRUE;
308 elm_box_pack_end(wd->box, item->base);
309 wd->items = eina_list_append(wd->items, item);
312 static void _item_sizing_eval(Elm_Ctxpopup_Item *item)
314 Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
315 Evas_Coord x, y, w, h;
319 if (!item->separator) elm_coords_finger_size_adjust(1, &min_w, 1, &min_h);
321 evas_object_geometry_get(item->base, &x, &y, &w, &h);
322 edje_object_size_min_restricted_calc(item->base, &min_w, &min_h, min_w, min_h);
323 evas_object_size_hint_min_set(item->base, min_w, min_h);
324 evas_object_size_hint_max_set(item->base, max_w, max_h);
327 static void _adjust_pos_x(Evas_Coord_Point *pos, Evas_Coord_Point *base_size,
328 Evas_Coord_Rectangle *area_rect)
330 pos->x -= (base_size->x / 2);
332 if (pos->x < area_rect->x) pos->x = area_rect->x;
333 else if ((pos->x + base_size->x) > (area_rect->x + area_rect->w))
334 pos->x = (area_rect->x + area_rect->w) - base_size->x;
336 if (base_size->x > area_rect->w)
337 base_size->x -= (base_size->x - area_rect->w);
338 if (pos->x < area_rect->x)
339 pos->x = area_rect->x;
342 static void _adjust_pos_y(int indicator_h, Evas_Coord_Point *pos,
343 Evas_Coord_Point *base_size, Evas_Coord_Rectangle *area_rect)
345 pos->y -= (base_size->y / 2);
347 if (pos->y < area_rect->y) pos->y = area_rect->y;
348 else if ((pos->y + base_size->y) > (area_rect->y + area_rect->h))
349 pos->y = area_rect->y + area_rect->h - base_size->y;
351 if (base_size->y > area_rect->h)
352 base_size->y -= (base_size->y - area_rect->h);
354 if (pos->y < area_rect->y) pos->y = area_rect->y;
357 static int _get_indicator_h(Evas_Object *parent)
359 Ecore_X_Window zone, xwin;
362 if (elm_win_indicator_state_get(parent) != 1)
365 xwin = elm_win_xwindow_get(parent);
366 zone = ecore_x_e_illume_zone_get(xwin);
367 ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &h);
372 static void _ctxpopup_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
374 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
376 if(wd->visible)_sizing_eval(obj);
379 static Elm_Ctxpopup_Arrow _calc_base_geometry(Evas_Object *obj, Evas_Coord_Rectangle *rect)
382 Evas_Coord_Point pos;
383 Evas_Coord_Point base_size;
384 Evas_Coord_Point max_size;
385 Evas_Coord_Point min_size;
386 Evas_Coord_Rectangle area_rect;
387 Evas_Coord_Point parent_size;
388 Evas_Coord_Point arrow_size;
389 Elm_Ctxpopup_Arrow arrow;
390 Evas_Coord finger_size;
391 Evas_Coord indicator_h;
392 Evas_Coord_Point temp;
395 wd = elm_widget_data_get(obj);
397 if ((!wd) || (!rect)) return ELM_CTXPOPUP_ARROW_DOWN;
399 indicator_h = _get_indicator_h(wd->parent);
400 finger_size = elm_finger_size_get();
402 edje_object_part_geometry_get(wd->arrow, "ctxpopup_arrow", NULL, NULL,
403 &arrow_size.x, &arrow_size.y);
404 evas_object_resize(wd->arrow, arrow_size.x, arrow_size.y);
406 //Initialize Area Rectangle.
408 evas_object_geometry_get(wd->area_rect, &area_rect.x, &area_rect.y,
409 &area_rect.w, &area_rect.h);
411 evas_object_geometry_get(wd->parent, NULL, NULL, &parent_size.x, &parent_size.y);
414 area_rect.w = parent_size.x;
415 area_rect.h = parent_size.y;
418 if (area_rect.y < indicator_h) {
419 temp.y = indicator_h - area_rect.y;
420 area_rect.y = indicator_h;
421 area_rect.h -= temp.y;
423 evas_object_geometry_get(obj, &pos.x, &pos.y, NULL, NULL);
426 edje_object_size_min_calc(wd->base, &base_size.x, &base_size.y);
427 evas_object_smart_calculate(wd->base);
430 evas_object_size_hint_max_get(obj, &max_size.x, &max_size.y);
432 if((max_size.y > 0 ) && (base_size.y > max_size.y))
433 base_size.y = max_size.y;
435 if((max_size.x > 0 ) && (base_size.x > max_size.x))
436 base_size.x = max_size.x;
439 evas_object_size_hint_min_get(obj, &min_size.x, &min_size.y);
442 if(base_size.y < min_size.y) base_size.y = min_size.y;
445 if(base_size.x < min_size.x) base_size.x = min_size.x;
447 //In case of position forced. It shows up just like popup.
448 if (wd->position_forced) {
449 //TODO: calculate the size of ctxpopup
452 rect->w = base_size.x;
453 rect->h = base_size.y;
454 return ELM_CTXPOPUP_ARROW_UP;
457 //Check the Which direction is available.
458 //If find a avaialble direction, it adjusts position and size.
459 for (idx = 0; idx < 4; ++idx) {
460 switch (wd->arrow_priority[idx]) {
461 case ELM_CTXPOPUP_ARROW_DOWN:
462 temp.y = pos.y - base_size.y;
463 if ((temp.y - arrow_size.y - finger_size) < area_rect.y) continue;
464 _adjust_pos_x(&pos, &base_size, &area_rect);
465 pos.y -= (base_size.y + finger_size);
466 arrow = ELM_CTXPOPUP_ARROW_DOWN;
468 case ELM_CTXPOPUP_ARROW_RIGHT:
469 temp.x = (pos.x - base_size.x);
470 if ((temp.x - arrow_size.x - finger_size) < area_rect.x) continue;
471 _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
472 pos.x -= (base_size.x + finger_size);
473 arrow = ELM_CTXPOPUP_ARROW_RIGHT;
475 case ELM_CTXPOPUP_ARROW_LEFT:
476 temp.x = (pos.x + base_size.x);
477 if ((temp.x + arrow_size.x + finger_size) > (area_rect.x + area_rect.w)) continue;
478 _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
479 pos.x += finger_size;
480 arrow = ELM_CTXPOPUP_ARROW_LEFT;
482 case ELM_CTXPOPUP_ARROW_UP:
483 temp.y = (pos.y + base_size.y);
484 if ((temp.y + arrow_size.y + finger_size) > (area_rect.y + area_rect.h)) continue;
485 _adjust_pos_x(&pos, &base_size, &area_rect);
486 pos.y += finger_size;
487 arrow = ELM_CTXPOPUP_ARROW_UP;
495 //In this case, all directions are invalid because of lack of space.
497 //TODO 1: Find the largest space direction.
499 Evas_Coord length[4];
501 length[ ELM_CTXPOPUP_ARROW_DOWN ] = pos.y - area_rect.y;
502 length[ ELM_CTXPOPUP_ARROW_UP ] = ( area_rect.y + area_rect.h ) - pos.y;
503 length[ ELM_CTXPOPUP_ARROW_RIGHT ] = pos.x - area_rect.x;
504 length[ ELM_CTXPOPUP_ARROW_LEFT ] = ( area_rect.x + area_rect.w ) - pos.x;
507 for( i = 0; i < 4; ++i ) {
508 for( j = 1; j < 4; ++j ) {
509 if( length[ idx ] < length[ j ] ) {
515 //TODO 1: Find the largest space direction.
516 Evas_Coord length[2];
517 length[0] = pos.y - area_rect.y;
518 length[1] = (area_rect.y + area_rect.h) - pos.y;
520 if (length[0] > length[1]) idx = ELM_CTXPOPUP_ARROW_DOWN;
521 else idx = ELM_CTXPOPUP_ARROW_UP;
523 //TODO 2: determine x , y
525 case ELM_CTXPOPUP_ARROW_DOWN:
526 _adjust_pos_x(&pos, &base_size, &area_rect);
527 pos.y -= (base_size.y + finger_size);
528 arrow = ELM_CTXPOPUP_ARROW_DOWN;
529 if (pos.y < area_rect.y + arrow_size.y) {
530 base_size.y -= ((area_rect.y + arrow_size.y) - pos.y);
531 pos.y = area_rect.y + arrow_size.y;
534 case ELM_CTXPOPUP_ARROW_RIGHT:
535 _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
536 pos.x -= (base_size.x + finger_size);
537 arrow = ELM_CTXPOPUP_ARROW_RIGHT;
538 if (pos.x < area_rect.x + arrow_size.x) {
539 base_size.x -= ((area_rect.x + arrow_size.x) - pos.x);
540 pos.x = area_rect.x + arrow_size.x;
543 case ELM_CTXPOPUP_ARROW_LEFT:
544 _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
545 pos.x += finger_size;
546 arrow = ELM_CTXPOPUP_ARROW_LEFT;
547 if (pos.x + arrow_size.x + base_size.x > area_rect.x + area_rect.w) {
548 base_size.x -= ((pos.x + arrow_size.x + base_size.x)
549 - (area_rect.x + area_rect.w));
552 case ELM_CTXPOPUP_ARROW_UP:
553 _adjust_pos_x(&pos, &base_size, &area_rect);
554 pos.y += finger_size;
555 arrow = ELM_CTXPOPUP_ARROW_UP;
556 if (pos.y + arrow_size.y + base_size.y > area_rect.y + area_rect.h) {
557 base_size.y -= ((pos.y + arrow_size.y + base_size.y) - (area_rect.y + area_rect.h));
565 //Final position and size.
568 rect->w = base_size.x;
569 rect->h = base_size.y;
574 static void _update_arrow_obj(Evas_Object *obj, Elm_Ctxpopup_Arrow arrow_dir)
577 Evas_Coord_Rectangle arrow_size;
578 Evas_Coord_Rectangle area_rect;
579 Evas_Coord parent_w, parent_h;
580 Widget_Data *wd = elm_widget_data_get(obj);
584 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
585 evas_object_geometry_get(wd->arrow, NULL, NULL, &arrow_size.w,
589 case ELM_CTXPOPUP_ARROW_LEFT: {
590 edje_object_signal_emit(wd->arrow, "elm,state,left", "elm");
591 arrow_size.y = (y - (arrow_size.h * 0.5));
592 arrow_size.x = (x + elm_finger_size_get());
595 case ELM_CTXPOPUP_ARROW_RIGHT: {
596 edje_object_signal_emit(wd->arrow, "elm,state,right", "elm");
597 arrow_size.y = (y - (arrow_size.h * 0.5));
598 arrow_size.x = (x - elm_finger_size_get() - arrow_size.w);
601 case ELM_CTXPOPUP_ARROW_UP: {
602 edje_object_signal_emit(wd->arrow, "elm,state,top", "elm");
603 arrow_size.x = (x - (arrow_size.w * 0.5));
604 arrow_size.y = (y + elm_finger_size_get());
607 case ELM_CTXPOPUP_ARROW_DOWN: {
608 edje_object_signal_emit(wd->arrow, "elm,state,bottom", "elm");
609 arrow_size.x = (x - (arrow_size.w * 0.5));
610 arrow_size.y = (y - elm_finger_size_get() - arrow_size.h);
617 //Adjust arrow position to prevent out of area
619 evas_object_geometry_get(wd->area_rect, &area_rect.x, &area_rect.y,
620 &area_rect.w, &area_rect.h);
622 evas_object_geometry_get(wd->parent, NULL, NULL, &parent_w, &parent_h);
625 area_rect.w = parent_w;
626 area_rect.h = parent_h;
629 //TODO: Temporary Code. make it more flexible
630 if ((arrow_size.x - (arrow_size.w / 2)) < area_rect.x)
631 arrow_size.x = area_rect.x + (arrow_size.w / 2);
632 else if ((arrow_size.x + arrow_size.w) > (area_rect.x + area_rect.w))
633 arrow_size.x = (area_rect.x + area_rect.w) - arrow_size.w
634 - (arrow_size.w / 2);
636 //TODO: Temporary Code. make it more flexible
637 if ((arrow_size.y - (arrow_size.h / 2)) < area_rect.y) {
638 arrow_size.y = arrow_size.y + (arrow_size.h / 2);
639 } else if ((arrow_size.y + arrow_size.h) > (area_rect.y + area_rect.h)) {
640 arrow_size.y = (area_rect.y + area_rect.h) - arrow_size.h
641 - (arrow_size.h / 2);
644 evas_object_move(wd->arrow, arrow_size.x, arrow_size.y);
647 static void _sizing_eval(Evas_Object *obj)
651 Elm_Ctxpopup_Item *item;
652 Evas_Coord_Rectangle rect = { 0, 0, 1, 1 };
653 Evas_Coord_Point box_size = { 0, 0 };
654 Evas_Coord_Point _box_size = { 0, 0 };
656 wd = (Widget_Data *) elm_widget_data_get(obj);
657 if ((!wd) || (!wd->parent)) return;
661 EINA_LIST_FOREACH(wd->items, elist, item)
663 _item_sizing_eval(item);
664 evas_object_size_hint_min_get(item->base, &_box_size.x, &_box_size.y);
665 if(!wd->horizontal) {
666 if(_box_size.x > box_size.x) box_size.x = _box_size.x;
667 if(_box_size.y != -1 ) box_size.y += _box_size.y;
669 if(_box_size.x != -1 ) box_size.x += _box_size.x;
670 if(_box_size.y > box_size.y) box_size.y = _box_size.y;
676 evas_object_size_hint_min_set(wd->box, box_size.x, box_size.y);
677 evas_object_size_hint_min_set(wd->scroller, box_size.x, box_size.y);
681 wd->arrow_dir = _calc_base_geometry(obj, &rect);
682 if ((!wd->position_forced) && (wd->arrow_dir != -1)) {
683 _update_arrow_obj(obj, wd->arrow_dir);
684 _shift_base_by_arrow(wd->arrow, wd->arrow_dir, &rect);
687 //resize scroller according to final size.
689 evas_object_smart_calculate(wd->scroller);
692 evas_object_move(wd->base, rect.x, rect.y);
693 evas_object_resize(wd->base, rect.w, rect.h);
695 if(wd->visible) _show_effect(wd);
698 static void _shift_base_by_arrow(Evas_Object *arrow,
699 Elm_Ctxpopup_Arrow arrow_dir, Evas_Coord_Rectangle *rect)
701 Evas_Coord arrow_w, arrow_h;
702 evas_object_geometry_get(arrow, NULL, NULL, &arrow_w, &arrow_h);
705 case ELM_CTXPOPUP_ARROW_LEFT:
708 case ELM_CTXPOPUP_ARROW_RIGHT:
711 case ELM_CTXPOPUP_ARROW_UP:
714 case ELM_CTXPOPUP_ARROW_DOWN:
722 static void _del_pre_hook(Evas_Object *obj) {
724 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
727 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
728 _parent_resize, obj);
731 elm_transit_stop(wd->transit);
732 elm_transit_del(wd->transit);
736 _delete_area_rect_callbacks(wd);
740 static void _del_hook(Evas_Object *obj)
742 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
746 elm_ctxpopup_clear(obj);
747 evas_object_del(wd->arrow);
748 evas_object_del(wd->base);
753 static void _theme_hook(Evas_Object *obj)
756 Elm_Ctxpopup_Item *item;
759 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
764 EINA_LIST_FOREACH(wd->items, elist, item)
768 _elm_theme_object_set(obj, item->base, "ctxpopup", "separator",
769 elm_widget_style_get(obj));
771 edje_object_signal_emit(item->base, "elm,state,horizontal", "elm");
775 if (item->label && item->icon)
777 _elm_theme_object_set(obj, item->base, "ctxpopup",
778 "icon_text_style_item",
779 elm_widget_style_get(obj));
781 else if (item->label)
783 _elm_theme_object_set(obj, item->base, "ctxpopup",
785 elm_widget_style_get(obj));
789 _elm_theme_object_set(obj, item->base, "ctxpopup",
791 elm_widget_style_get(obj));
794 edje_object_part_text_set(item->base, "elm.text", item->label);
797 edje_object_signal_emit(item->base, "elm,state,disabled", "elm");
799 edje_object_message_signal_process(item->base);
803 if (wd->btn_layout) {
804 sprintf(buf, "buttons%d", wd->btn_cnt);
805 _elm_theme_object_set(obj, wd->btn_layout, "ctxpopup", buf,
806 elm_widget_style_get(obj));
809 _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg", elm_widget_style_get(obj));
810 _elm_theme_object_set(obj, wd->base, "ctxpopup", "base", elm_widget_style_get(obj));
811 _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow",
812 elm_widget_style_get(obj));
814 if (!strncmp(elm_object_style_get(obj), "default", strlen("default")
816 elm_object_style_set(wd->scroller, "ctxpopup");
818 elm_object_style_set(wd->scroller, elm_object_style_get(obj));
821 _reset_scroller_size(wd);
826 static void _bg_clicked_cb(void *data, Evas_Object *obj, const char *emission,
829 evas_object_hide(data);
832 static void _parent_resize(void *data, Evas *e, Evas_Object *obj,
837 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(data);
840 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
841 evas_object_resize(wd->bg, w, h);
843 if(wd->visible == EINA_FALSE) return;
844 wd->visible = EINA_FALSE;
845 _hide_ctxpopup(data);
849 static void _ctxpopup_show(void *data, Evas *e, Evas_Object *obj,
852 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
853 if(wd == NULL) return;
855 if ((eina_list_count(wd->items) < 1) && (!wd->content) && (wd->btn_cnt < 1))
858 wd->visible = EINA_TRUE;
860 if (!wd->screen_dimmed_disabled) {
861 evas_object_show(wd->bg);
862 edje_object_signal_emit(wd->bg, "elm,state,show", "elm");
865 evas_object_show(wd->base);
867 if (!wd->position_forced) {
868 evas_object_show(wd->arrow);
875 static void _hide_ctxpopup(Evas_Object *obj)
877 //TODO: Consider implementing effect in edc.
878 Widget_Data *wd = elm_widget_data_get(obj);
880 if (!wd->screen_dimmed_disabled)
881 evas_object_hide(wd->bg);
883 if(!wd->position_forced)
884 evas_object_hide(wd->arrow);
886 evas_object_hide(wd->base);
888 _reset_scroller_size(wd);
889 evas_object_smart_callback_call(obj, "hide", NULL);
892 static void _ctxpopup_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
894 Widget_Data *wd = (Widget_Data*) elm_widget_data_get(obj);
895 if(wd == NULL) return;
897 if(wd->visible == EINA_FALSE) return;
899 wd->visible = EINA_FALSE;
901 if (!wd->screen_dimmed_disabled)
902 edje_object_signal_emit(wd->bg, "elm,state,hide", "elm");
907 static void _ctxpopup_scroller_resize(void *data, Evas *e, Evas_Object * obj,
913 wd = elm_widget_data_get(data);
914 if(wd == NULL) return;
916 if(!wd->visible) return;
917 if(wd->finished) return;
919 evas_object_geometry_get(wd->scroller, 0, 0, &w, &h);
921 if( w != 0 && h !=0 ) {
922 if((w <= wd->max_sc_w) && (h <= wd->max_sc_h) ) {
924 wd->finished = EINA_TRUE;
929 if(wd->max_sc_w < w ) wd->max_sc_w = w;
930 if(wd->max_sc_h < h ) wd->max_sc_h = h;
935 static void _ctxpopup_move(void *data, Evas *e, Evas_Object *obj,
938 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
939 if(wd == NULL) return;
941 if (wd->visible && !wd->position_forced)
942 evas_object_show(wd->arrow);
944 _reset_scroller_size(wd);
948 static void _ctxpopup_item_select(void *data, Evas_Object *obj,
949 const char *emission, const char *source)
951 Elm_Ctxpopup_Item *item = (Elm_Ctxpopup_Item *) data;
954 if (item->disabled) return;
957 _ctxpopup_hide(item->ctxpopup, NULL, item->ctxpopup, NULL);
958 item->func(item->data, item->ctxpopup, item);
962 static void _item_obj_create(Elm_Ctxpopup_Item *item, char *group_name)
964 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(item->ctxpopup);
967 item->base = edje_object_add(evas_object_evas_get(wd->base));
968 _elm_theme_object_set(item->ctxpopup, item->base, "ctxpopup", group_name,
969 elm_widget_style_get(item->ctxpopup));
970 edje_object_signal_callback_add(item->base, "elm,action,click", "",
971 _ctxpopup_item_select, item);
972 evas_object_size_hint_align_set(item->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
973 evas_object_size_hint_weight_set(item->base, EVAS_HINT_EXPAND,
975 evas_object_show(item->base);
978 static void _content_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
980 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(data);
985 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
986 evas_object_size_hint_min_set(obj, w, h);
988 if(wd->visible) _sizing_eval(data);
991 static void _content_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
993 elm_ctxpopup_content_unset(data);
997 * Get the icon object for the given item.
999 * @param[in] item Ctxpopup item
1000 * @return Icon object or NULL if the item does not have icon
1005 elm_ctxpopup_item_icon_get(Elm_Ctxpopup_Item *item)
1007 if (!item) return NULL;
1012 * Disable or Enable the scroller for contextual popup.
1014 * @param[in] obj Ctxpopup object
1015 * @param[in] disabled disable or enable
1019 EAPI void elm_ctxpopup_scroller_disabled_set(Evas_Object *obj,
1022 ELM_CHECK_WIDTYPE(obj, widtype);
1023 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1026 if (wd->scroller_disabled == disabled) return;
1029 elm_object_scroll_freeze_push(wd->scroller);
1031 elm_object_scroll_freeze_pop(wd->scroller);
1033 wd->scroller_disabled = disabled;
1037 * Get the label for the given item.
1039 * @param[in] item Ctxpopup item
1040 * @return Label or NULL if the item does not have label
1046 elm_ctxpopup_item_label_get(Elm_Ctxpopup_Item *item)
1048 if (!item) return NULL;
1053 * Add a new ctxpopup object to the parent.
1055 * @param[in] parent window object
1056 * @return New object or NULL if it cannot be created
1061 elm_ctxpopup_add(Evas_Object *parent)
1066 Evas_Coord x, y, w, h;
1068 wd = ELM_NEW(Widget_Data);
1069 e = evas_object_evas_get(parent);
1074 obj = elm_widget_add(e);
1075 ELM_SET_WIDTYPE(widtype, "ctxpopup");
1076 elm_widget_type_set(obj, "ctxpopup");
1077 elm_widget_sub_object_add(parent, obj);
1078 elm_widget_data_set(obj, wd);
1079 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
1080 elm_widget_del_hook_set(obj, _del_hook);
1081 elm_widget_theme_hook_set(obj, _theme_hook);
1083 wd->parent = parent;
1086 wd->bg = edje_object_add(e);
1087 elm_widget_sub_object_add(obj, wd->bg);
1088 _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg", "default");
1089 evas_object_geometry_get(parent, &x, &y, &w, &h);
1090 evas_object_move(wd->bg, x, y);
1091 evas_object_resize(wd->bg, w, h);
1092 edje_object_signal_callback_add(wd->bg, "elm,action,click", "",
1093 _bg_clicked_cb, obj);
1096 wd->base = edje_object_add(e);
1097 elm_widget_sub_object_add(obj, wd->base);
1098 _elm_theme_object_set(obj, wd->base, "ctxpopup", "base", "default");
1101 wd->scroller = elm_scroller_add(obj);
1102 elm_object_style_set(wd->scroller, "ctxpopup");
1103 evas_object_size_hint_align_set(wd->scroller, EVAS_HINT_FILL,
1105 elm_scroller_bounce_set(wd->scroller, EINA_FALSE, EINA_TRUE);
1106 evas_object_event_callback_add(wd->scroller, EVAS_CALLBACK_RESIZE,
1107 _ctxpopup_scroller_resize, obj);
1110 wd->box = elm_box_add(obj);
1111 evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1112 elm_scroller_content_set(wd->scroller, wd->box);
1113 edje_object_part_swallow(wd->base, "elm.swallow.scroller", wd->scroller);
1116 wd->arrow = edje_object_add(e);
1117 elm_widget_sub_object_add(obj, wd->arrow);
1118 _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow", "default");
1120 wd->arrow_priority[0] = ELM_CTXPOPUP_ARROW_DOWN;
1121 wd->arrow_priority[1] = ELM_CTXPOPUP_ARROW_RIGHT;
1122 wd->arrow_priority[2] = ELM_CTXPOPUP_ARROW_LEFT;
1123 wd->arrow_priority[3] = ELM_CTXPOPUP_ARROW_UP;
1125 evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, _parent_resize, obj);
1126 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _ctxpopup_show, NULL);
1127 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _ctxpopup_hide, NULL);
1128 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _ctxpopup_move, NULL);
1129 evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _ctxpopup_changed_size_hints, NULL);
1135 * Clear all items in given ctxpopup object.
1137 * @param[in] obj Ctxpopup object
1141 EAPI void elm_ctxpopup_clear(Evas_Object *obj)
1143 ELM_CHECK_WIDTYPE(obj, widtype);
1145 Elm_Ctxpopup_Item *item;
1147 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1151 EINA_LIST_FOREACH(wd->items, elist, item)
1154 eina_stringshare_del(item->label);
1156 evas_object_del(item->icon);
1157 wd->items = eina_list_remove(wd->items, item);
1161 evas_object_hide(wd->arrow);
1162 evas_object_hide(wd->base);
1166 * Change the mode to horizontal or vertical.
1168 * @param[in] obj Ctxpopup object
1169 * @param horizontal EINA_TRUE - horizontal mode, EINA_FALSE - vertical mode
1173 EAPI void elm_ctxpopup_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
1175 ELM_CHECK_WIDTYPE(obj, widtype);
1177 Elm_Ctxpopup_Item *item;
1178 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1182 if (wd->horizontal == horizontal) return;
1183 wd->horizontal = horizontal;
1185 elm_box_horizontal_set(wd->box, EINA_FALSE);
1186 elm_scroller_bounce_set(wd->scroller, EINA_FALSE, EINA_TRUE);
1187 EINA_LIST_FOREACH (wd->items, elist, item)
1188 edje_object_signal_emit(item->base, "elm,state,vertical", "elm");
1192 elm_box_horizontal_set(wd->box, EINA_TRUE);
1193 elm_scroller_bounce_set(wd->scroller, EINA_TRUE, EINA_FALSE);
1194 EINA_LIST_FOREACH(wd->items, elist, item)
1195 edje_object_signal_emit(item->base, "elm,state,horizontal", "elm");
1200 * Get the value of current horizontal mode.
1202 * @param[in] obj Ctxpopup object
1203 * @return EINA_TRUE - horizontal mode, EINA_FALSE - vertical mode.
1207 EAPI Eina_Bool elm_ctxpopup_horizontal_get(Evas_Object *obj)
1209 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1210 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1211 if (!wd) return EINA_FALSE;
1212 return wd->horizontal;
1216 * reset the icon on the given item.
1218 * @param[in] item Ctxpopup item
1219 * @param[in] icon Icon object to be set
1223 EAPI void elm_ctxpopup_item_icon_set(Elm_Ctxpopup_Item *item, Evas_Object *icon)
1228 wd = (Widget_Data *) elm_widget_data_get(item->ctxpopup);
1230 if (item->icon == icon) return;
1232 elm_widget_sub_object_del(item->base, item->icon);
1233 evas_object_del(item->icon);
1236 edje_object_part_swallow(item->base, "elm.swallow.icon", item->icon);
1237 edje_object_message_signal_process(item->base);
1240 _reset_scroller_size(wd);
1241 _sizing_eval(item->ctxpopup);
1246 * reset the label on the given item.
1248 * @param[in] item Ctxpopup item
1249 * @param[in] label Label to be set
1253 EAPI void elm_ctxpopup_item_label_set(Elm_Ctxpopup_Item *item,
1262 eina_stringshare_del(item->label);
1266 item->label = eina_stringshare_add(label);
1267 edje_object_message_signal_process(item->base);
1268 edje_object_part_text_set(item->base, "elm.text", label);
1270 wd = elm_widget_data_get(item->ctxpopup);
1275 _reset_scroller_size(wd);
1276 _sizing_eval(item->ctxpopup);
1281 * Add a new item in given ctxpopup object.
1283 * @param[in] obj Ctxpopup object
1284 * @param[in] icon Icon to be set
1285 * @param[in] label Label to be set
1286 * @param[in] func Callback function to call when this item click is clicked
1287 * @param[in] data User data for callback function
1288 * @return Added ctxpopup item
1292 EAPI Elm_Ctxpopup_Item *
1293 elm_ctxpopup_item_add(Evas_Object *obj, Evas_Object *icon, const char *label,
1294 Evas_Smart_Cb func, void *data)
1296 ELM_CHECK_WIDTYPE(obj, widtype)NULL;
1297 Elm_Ctxpopup_Item *item;
1298 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1303 _separator_obj_add(obj);
1305 item = ELM_NEW(Elm_Ctxpopup_Item);
1311 item->ctxpopup = obj;
1312 item->separator = EINA_FALSE;
1315 _item_obj_create(item, "icon_text_style_item");
1317 _item_obj_create(item, "icon_style_item");
1319 _item_obj_create(item, "text_style_item");
1321 wd->items = eina_list_append(wd->items, item);
1322 elm_box_pack_end(wd->box, item->base);
1323 elm_ctxpopup_item_icon_set(item, icon);
1324 elm_ctxpopup_item_label_set(item, label);
1330 * Delete the given item in ctxpopup object.
1332 * @param item[in] Ctxpopup item to be deleted
1336 EAPI void elm_ctxpopup_item_del(Elm_Ctxpopup_Item *item)
1344 obj = item->ctxpopup;
1347 eina_stringshare_del(item->label);
1349 evas_object_del(item->icon);
1351 evas_object_del(item->base);
1353 wd = (Widget_Data *) elm_widget_data_get(item->ctxpopup);
1355 _separator_obj_del(wd, item);
1356 wd->items = eina_list_remove(wd->items, item);
1359 if (eina_list_count(wd->items) == 0) {
1360 _ctxpopup_hide(obj, NULL, obj, NULL);
1365 * Disable or Enable the given item. Once an item is disabled, the click event will be never happend for the item.
1367 * @param[in] item Ctxpopup item to be disabled
1368 * @param[in] disabled EINA_TRUE - disable, EINA_FALSE - enable
1372 EAPI void elm_ctxpopup_item_disabled_set(Elm_Ctxpopup_Item *item,
1378 if (disabled == item->disabled) return;
1380 wd = (Widget_Data *) elm_widget_data_get(item->ctxpopup);
1383 edje_object_signal_emit(item->base, "elm,state,disabled", "elm");
1385 edje_object_signal_emit(item->base, "elm,state,enabled", "elm");
1387 edje_object_message_signal_process(item->base);
1388 item->disabled = disabled;
1392 * Disable or Enable background dimmed function
1393 * @param[in] obj Ctxpopup object
1394 * @param[in] dimmed EINA_TRUE - disable, EINA_FALSE - enable
1398 EAPI void elm_ctxpopup_screen_dimmed_disabled_set(Evas_Object *obj,
1401 ELM_CHECK_WIDTYPE(obj, widtype);
1402 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1407 wd->screen_dimmed_disabled = disabled;
1411 evas_object_show(wd->bg);
1417 * Append additional button in ctxpoppup bottom layout.
1418 * @param[in] obj Ctxpopup object
1419 * @param[in] label Button label
1420 * @param[in] func Button clicked event callback function
1421 * @param[in] data Button clicked event callback function data
1425 EAPI void elm_ctxpopup_button_append(Evas_Object *obj, const char *label,
1426 Evas_Smart_Cb func, const void *data)
1428 ELM_CHECK_WIDTYPE(obj, widtype);
1432 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1435 if (!wd->btn_layout) _btn_layout_create(obj);
1438 sprintf(buf, "buttons%d", wd->btn_cnt);
1439 _elm_theme_object_set(obj, wd->btn_layout, "ctxpopup", buf,
1440 elm_widget_style_get(obj));
1442 btn = elm_button_add(obj);
1443 elm_object_style_set(btn, "text_only/style1");
1444 elm_button_label_set(btn, label);
1445 evas_object_smart_callback_add(btn, "clicked", func, data);
1446 sprintf(buf, "actionbtn%d", wd->btn_cnt);
1447 edje_object_part_swallow(wd->btn_layout, buf, btn);
1449 edje_object_part_geometry_get(wd->btn_layout, buf, NULL, NULL, &w, &h);
1450 evas_object_size_hint_max_set(wd->btn_layout, -1, h);
1453 _reset_scroller_size(wd);
1459 * Set the priority of arrow direction
1461 * This functions gives user to set the priority of ctxpopup box showing position.
1463 * @param[in] obj Ctxpopup object
1464 * @param[in] first 1st priority of arrow direction
1465 * @param[in] second 2nd priority of arrow direction
1466 * @param[in] third 3th priority of arrow direction
1467 * @param[in] fourth 4th priority of arrow direction
1471 EAPI void elm_ctxpopup_arrow_priority_set(Evas_Object *obj,
1472 Elm_Ctxpopup_Arrow first, Elm_Ctxpopup_Arrow second,
1473 Elm_Ctxpopup_Arrow third, Elm_Ctxpopup_Arrow fourth)
1475 ELM_CHECK_WIDTYPE(obj, widtype);
1476 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1480 wd->arrow_priority[0] = first;
1481 wd->arrow_priority[1] = second;
1482 wd->arrow_priority[2] = third;
1483 wd->arrow_priority[3] = fourth;
1487 * Swallow the user content
1489 * @param[in] obj Ctxpopup object
1490 * @param[in] content Content to be swallowed
1494 EAPI void elm_ctxpopup_content_set(Evas_Object *obj, Evas_Object *content)
1496 ELM_CHECK_WIDTYPE(obj, widtype);
1497 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1499 if(!wd || !content) return;
1501 evas_object_event_callback_add(content, EVAS_CALLBACK_DEL, _content_del, obj);
1502 evas_object_event_callback_add(content, EVAS_CALLBACK_RESIZE, _content_resize, obj);
1504 evas_object_geometry_get(content, NULL, NULL, &w, &h);
1506 if((w > 0) || (h > 0)) evas_object_size_hint_min_set(content, w, h);
1508 edje_object_part_swallow(wd->base, "elm.swallow.content", content);
1509 elm_widget_sub_object_add(obj, content);
1510 edje_object_signal_emit(wd->base, "elm,state,content,enable", "elm");
1511 elm_ctxpopup_scroller_disabled_set(obj, EINA_TRUE);
1512 wd->content = content;
1514 if(wd->visible) _sizing_eval(obj);
1518 * Unswallow the user content
1520 * @param[in] obj Ctxpopup object
1521 * @return The unswallowed content
1526 elm_ctxpopup_content_unset(Evas_Object *obj)
1528 ELM_CHECK_WIDTYPE(obj, widtype)NULL;
1529 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1530 Evas_Object *content;
1532 content = wd->content;
1534 if(!content) return NULL;
1536 edje_object_part_unswallow(wd->base, content);
1537 elm_widget_sub_object_del(obj, content);
1538 evas_object_event_callback_del(content, EVAS_CALLBACK_DEL, _content_del);
1539 evas_object_event_callback_del(content, EVAS_CALLBACK_RESIZE, _content_resize);
1540 edje_object_signal_emit(wd->base, "elm,state,content,disable", "elm");
1542 elm_ctxpopup_scroller_disabled_set(obj, EINA_FALSE);
1551 * Change the origin of the ctxpopup position.
1553 * Basically, ctxpopup position is computed internally. When user call evas_object_move,
1554 * Ctxpopup will be showed up with that position which is indicates the arrow point.
1556 * @param[in] obj Ctxpopup object
1557 * @param[in] forced EINA_TRUE is left-top. EINA_FALSE is indicates arrow point.
1561 EAPI void elm_ctxpopup_position_forced_set(Evas_Object *obj, Eina_Bool forced)
1563 ELM_CHECK_WIDTYPE(obj, widtype);
1564 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1566 wd->position_forced = forced;
1568 if (forced) evas_object_hide(wd->arrow);
1571 _reset_scroller_size(wd);
1577 * Get the status of the position forced
1579 * @param[in] obj Ctxpopup objet
1580 * @return value of position forced
1584 EAPI Eina_Bool elm_ctxpopup_position_forced_get(Evas_Object *obj)
1586 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1587 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1588 return wd->position_forced;
1591 EAPI Elm_Ctxpopup_Item *
1592 elm_ctxpopup_icon_add(Evas_Object *obj, Evas_Object *icon, Evas_Smart_Cb func,
1595 return elm_ctxpopup_item_add(obj, icon, NULL, func, data);
1598 EAPI Elm_Ctxpopup_Item *
1599 elm_ctxpopup_label_add(Evas_Object *obj, const char *label, Evas_Smart_Cb func,
1602 return elm_ctxpopup_item_add(obj, NULL, label, func, data);
1606 * Set the area of ctxpopup will show up. Ctxpopup will not be out of this area.
1607 * The responsibility of the area object is to user.
1609 * @param[in] obj Ctxpopup objet
1610 * @param[in] area area object
1614 EAPI void elm_ctxpopup_area_set(Evas_Object *obj, Evas_Object *area)
1616 ELM_CHECK_WIDTYPE(obj, widtype);
1617 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1619 _delete_area_rect_callbacks(wd);
1622 evas_object_event_callback_add(area, EVAS_CALLBACK_DEL, _area_rect_del,
1624 evas_object_event_callback_add(area, EVAS_CALLBACK_MOVE,
1625 _area_rect_move, obj);
1626 evas_object_event_callback_add(area, EVAS_CALLBACK_RESIZE,
1627 _area_rect_resize, obj);
1628 wd->area_rect = area;
1632 EAPI void elm_ctxpopup_title_set(Evas_Object *obj, const char *title )
1634 ELM_CHECK_WIDTYPE(obj, widtype);
1635 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
1639 if(wd->title) eina_stringshare_del(wd->title);
1640 wd->title = eina_stringshare_add(title);
1641 edje_object_part_text_set(wd->base, "elm.title", title);
1644 EAPI const char* elm_ctxpopup_title_get(Evas_Object *obj)
1646 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1647 Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);