#include "elm_priv.h"
/**
- * @defgroup Ctxpopup Ctxpopup
- * @ingroup Elementary
+ * @defgroup Ctxpopup
*
- * Contextual popup.
+ * A ctxpopup is a widget that, when shown, pops up a list of items.
+ * It automatically chooses an area inside its parent object's view
+ * (set via elm_ctxpopup_add() and elm_ctxpopup_hover_parent_set()) to
+ * optimally fit into it. In the default theme, it will also point an
+ * arrow to the cursor position at the time one shows it. Ctxpopup
+ * items have a label and/or an icon. It is intended for a small
+ * number of items (hence the use of list, not genlist).
*
* Signals that you can add callbacks for are:
*
- * hide - This is emitted when the ctxpopup is hided.
- *
+ * dismissed - the ctxpopup was dismissed
*/
typedef struct _Widget_Data Widget_Data;
-struct _Ctxpopup_Item {
- Elm_Widget_Item base;
- const char *label;
- Evas_Object *icon;
- Evas_Smart_Cb func;
- Eina_Bool disabled :1;
- Eina_Bool separator :1;
+struct _Elm_Ctxpopup_Item
+{
+ Elm_Widget_Item base;
+ const char *label;
+ Evas_Object *icon;
+ Evas_Smart_Cb func;
+ Eina_Bool disabled:1;
};
-struct _Widget_Data {
- Evas_Object *parent;
- Evas_Object *base;
- Evas_Object *content;
- Evas_Object *box;
- Evas_Object *arrow;
- Evas_Object *scroller;
- Evas_Object *bg;
- Evas_Object *btn_layout;
- Evas_Object *area_rect;
- Eina_List *items;
- Elm_Ctxpopup_Arrow arrow_dir;
- Elm_Ctxpopup_Arrow arrow_priority[4];
- int btn_cnt;
- Elm_Transit *transit;
- Evas_Coord max_sc_w, max_sc_h;
- char *title;
- Eina_Bool scroller_disabled :1;
- Eina_Bool horizontal :1;
- Eina_Bool visible :1;
- Eina_Bool screen_dimmed_disabled :1;
- Eina_Bool position_forced :1;
- Eina_Bool finished :1;
+struct _Widget_Data
+{
+ Evas_Object *parent;
+ Evas_Object *base;
+ Evas_Object *content;
+ Evas_Object *box;
+ Evas_Object *arrow;
+ Evas_Object *scr;
+ Evas_Object *bg;
+ Evas_Object *hover_parent;
+ Eina_List *items;
+ Elm_Ctxpopup_Direction dir;
+ Elm_Ctxpopup_Direction dir_priority[4];
+ Evas_Coord max_sc_w, max_sc_h;
+ Eina_Bool horizontal:1;
+ Eina_Bool visible:1;
+ Eina_Bool finished:1;
};
static const char *widtype = NULL;
+
static void _del_hook(Evas_Object *obj);
static void _del_pre_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object *obj);
-static void _area_rect_resize(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _area_rect_move(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _area_rect_del(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _bg_clicked_cb(void *data, Evas_Object *obj, const char *emission,
- const char *source);
+static void _hover_parent_resize(void *data, Evas *e __UNUSED__,
+ Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__);
+static void _hover_parent_move(void *data, Evas *e __UNUSED__,
+ Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__);
+static void _hover_parent_del(void *data, Evas *e __UNUSED__,
+ Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__);
+static void _hover_parent_callbacks_del(Evas_Object *obj);
+static void _bg_clicked_cb(void *data, Evas_Object *obj __UNUSED__,
+ const char *emission __UNUSED__,
+ const char *source __UNUSED__);
static void _parent_resize(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _ctxpopup_show(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _ctxpopup_hide(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _ctxpopup_move(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _ctxpopup_changed_size_hints(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _ctxpopup_scroller_resize(void *data, Evas *e, Evas_Object *obj,
- void *event_info);
-static void _item_obj_create(Elm_Ctxpopup_Item *item, char *group_name);
+ void *event_info __UNUSED__);
+static void _ctxpopup_show(void *data __UNUSED__, Evas *e __UNUSED__,
+ Evas_Object *obj, void *event_info __UNUSED__);
+static void _ctxpopup_hide(void *data __UNUSED__, Evas *e __UNUSED__,
+ Evas_Object *obj, void *event_info __UNUSED__);
+static void _ctxpopup_move(void *data __UNUSED__, Evas *e __UNUSED__,
+ Evas_Object *obj, void *event_info __UNUSED__);
+static void _scroller_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__);
+static void _ctxpopup_changed_size_hints(void *data __UNUSED__,
+ Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__);
+static void _item_new(Elm_Ctxpopup_Item *item, char *group_name);
+static void _list_new(Evas_Object *obj);
static void _item_sizing_eval(Elm_Ctxpopup_Item *item);
-static void _ctxpopup_item_select(void *data, Evas_Object *obj,
- const char *emission, const char *source);
-static void _separator_obj_add(Evas_Object *obj);
-static void _separator_obj_del(Widget_Data *wd, Elm_Ctxpopup_Item *remove_item);
-static Elm_Ctxpopup_Arrow _calc_base_geometry(Evas_Object *obj,
- Evas_Coord_Rectangle *rect);
-static void _update_arrow_obj(Evas_Object *obj, Elm_Ctxpopup_Arrow arrow_dir);
+static void _item_select_cb(void *data, Evas_Object *obj __UNUSED__,
+ const char *emission __UNUSED__,
+ const char *source __UNUSED__);
+static Elm_Ctxpopup_Direction _calc_base_geometry(Evas_Object *obj,
+ Evas_Coord_Rectangle *rect);
+static void _update_arrow(Evas_Object *obj, Elm_Ctxpopup_Direction dir);
static void _shift_base_by_arrow(Evas_Object *arrow,
- Elm_Ctxpopup_Arrow arrow_dir, Evas_Coord_Rectangle *rect);
-static void _btn_layout_create(Evas_Object *obj);
-static int _get_indicator_h(Evas_Object *parent);
-static void _delete_area_rect_callbacks(Widget_Data *wd);
+ Elm_Ctxpopup_Direction dir,
+ Evas_Coord_Rectangle *rect);
static void _adjust_pos_x(Evas_Coord_Point *pos, Evas_Coord_Point *base_size,
- Evas_Coord_Rectangle *area_rect);
-static void _adjust_pos_y(int indicator_h, Evas_Coord_Point *pos,
- Evas_Coord_Point *base_size, Evas_Coord_Rectangle *area_rect);
-static void _reset_scroller_size(Widget_Data *wd);
-static void _hide_ctxpopup(Evas_Object *obj);
-static void _content_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
-static void _content_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
-
-static void _reset_scroller_size(Widget_Data *wd)
-{
- wd->finished = EINA_FALSE;
- wd->max_sc_h = -1;
- wd->max_sc_w = -1;
-}
+ Evas_Coord_Rectangle *hover_area);
+static void _adjust_pos_y(Evas_Coord_Point *pos, Evas_Coord_Point *base_size,
+ Evas_Coord_Rectangle *hover_area);
+static void _scroller_size_reset(Widget_Data *wd);
+static void _hide(Evas_Object *obj);
+static void _content_del(void *data, Evas *e, Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__);
+static void _freeze_on(void *data __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__);
+static void _freeze_off(void *data __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__);
+static void _hold_on(void *data __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__);
+static void _hold_off(void *data __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__);
+static void _item_icon_set(Elm_Ctxpopup_Item *item, Evas_Object *icon);
+static void _item_label_set(Elm_Ctxpopup_Item *item, const char *label);
+static void _remove_items(Widget_Data * wd);
+
+static const char SIG_DISMISSED[] = "dismissed";
+static const char SIG_HIDE[] = "hide";
+
+static const Evas_Smart_Cb_Description _signals[] = {
+ {SIG_DISMISSED, ""},
+ {SIG_HIDE, ""}, //TOOD: Remove!!
+ {NULL, NULL}
+};
-static void _delete_area_rect_callbacks(Widget_Data *wd)
+#define ELM_CTXPOPUP_ITEM_CHECK_RETURN(it, ...) \
+ ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
+ELM_CHECK_WIDTYPE(item->base.widget, widtype) __VA_ARGS__;
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
{
- if (!wd->area_rect) return;
+ Widget_Data *wd = elm_widget_data_get(obj);
- evas_object_event_callback_del(wd->area_rect, EVAS_CALLBACK_DEL,
- _area_rect_del);
- evas_object_event_callback_del(wd->area_rect, EVAS_CALLBACK_MOVE,
- _area_rect_move);
- evas_object_event_callback_del(wd->area_rect, EVAS_CALLBACK_RESIZE,
- _area_rect_resize);
+ if (!wd)
+ return;
+ elm_object_scroll_freeze_push(wd->scr);
}
-static void _area_rect_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
{
- Widget_Data *wd = elm_widget_data_get(data);
- if(wd->visible) {
- _reset_scroller_size(wd);
- _sizing_eval(obj);
- }
-}
+ Widget_Data *wd = elm_widget_data_get(obj);
-static void _area_rect_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
- Widget_Data *wd = elm_widget_data_get(data);
- if(wd->visible) {
- _reset_scroller_size(wd);
- _sizing_eval(obj);
- }
+ if (!wd)
+ return;
+ elm_object_scroll_freeze_pop(wd->scr);
}
-static void _area_rect_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- Widget_Data *wd = elm_widget_data_get(data);
- wd->area_rect = NULL;
-}
-/*
-static void _show_effect_done(void *data, Elm_Transit *transit)
-{
- //TODO: Consider implementing effect in edc.
- Widget_Data *wd = data;
- elm_transit_fx_clear(transit);
-
- if (wd->box)
- elm_transit_fx_insert(transit, elm_fx_color_add(wd->box, 0, 0, 0, 0,
- 255, 255, 255, 255));
- if (wd->content)
- elm_transit_fx_insert(transit, elm_fx_color_add(wd->content, 0, 0, 0,
- 0, 255, 255, 255, 255));
- if (wd->btn_layout)
- elm_transit_fx_insert(transit, elm_fx_color_add(wd->btn_layout, 0, 0,
- 0, 0, 255, 255, 255, 255));
- elm_transit_run(transit, 0.2);
- elm_transit_completion_callback_set(transit, NULL, NULL);
- elm_transit_del(transit);
- wd->transit = NULL;
- edje_object_signal_emit(wd->base, "elm,state,show", "elm");
-}
+ Widget_Data *wd = elm_widget_data_get(obj);
-static void _show_effect(Widget_Data* wd)
-{
- //TODO: Consider implementing effect in edc.
- if (wd->transit) {
- elm_transit_stop(wd->transit);
- elm_transit_fx_clear(wd->transit);
- } else {
- wd->transit = elm_transit_add(wd->base);
- elm_transit_curve_style_set(wd->transit, ELM_ANIMATOR_CURVE_OUT);
- elm_transit_completion_callback_set(wd->transit, _show_effect_done, wd);
- }
-
- elm_transit_fx_insert(wd->transit, elm_fx_color_add(wd->base, 0, 0, 0, 0,
- 255, 255, 255, 255));
- elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base,
- ELM_FX_WIPE_TYPE_SHOW, wd->arrow_dir));
-
- if(!wd->position_forced)
- elm_transit_fx_insert(wd->transit, elm_fx_color_add(wd->arrow, 0, 0, 0, 0, 255, 255, 255, 255));
-
- if (wd->box)
- evas_object_color_set(wd->box, 0, 0, 0, 0);
- if (wd->content)
- evas_object_color_set(wd->content, 0, 0, 0, 0);
- if (wd->btn_layout)
- evas_object_color_set(wd->btn_layout, 0, 0, 0, 0);
-
- elm_transit_run(wd->transit, 0.3);
+ if (!wd)
+ return;
+ elm_object_scroll_hold_push(wd->scr);
}
-static void _hide_effect_done(void *data, Elm_Transit *transit)
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- //TODO: Consider implementing effect in edc.
- Widget_Data *wd = elm_widget_data_get(data);
- if(!wd) return ;
- elm_transit_del(transit);
- wd->transit = NULL;
- _hide_ctxpopup(data);
-}
+ Widget_Data *wd = elm_widget_data_get(obj);
-static void _hide_effect(Evas_Object *obj)
-{
- //TODO: Consider implementing effect in edc.
- Widget_Data *wd = elm_widget_data_get(obj);
- if(!wd) return;
-
- if (wd->transit) {
- elm_transit_stop(wd->transit);
- elm_transit_fx_clear(wd->transit);
- } else {
- wd->transit = elm_transit_add(wd->base);
- elm_transit_curve_style_set(wd->transit, ELM_ANIMATOR_CURVE_OUT);
- elm_transit_completion_callback_set(wd->transit, _hide_effect_done, obj);
- }
-
- switch(wd->arrow_dir) {
- case ELM_CTXPOPUP_ARROW_DOWN:
- elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base, ELM_FX_WIPE_TYPE_HIDE, ELM_FX_WIPE_DIR_DOWN));
- break;
- case ELM_CTXPOPUP_ARROW_RIGHT:
- elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base, ELM_FX_WIPE_TYPE_HIDE, ELM_FX_WIPE_DIR_RIGHT));
- break;
- case ELM_CTXPOPUP_ARROW_LEFT:
- elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base, ELM_FX_WIPE_TYPE_HIDE, ELM_FX_WIPE_DIR_LEFT));
- break;
- case ELM_CTXPOPUP_ARROW_UP:
- elm_transit_fx_insert(wd->transit, elm_fx_wipe_add(wd->base, ELM_FX_WIPE_TYPE_HIDE, ELM_FX_WIPE_DIR_UP));
- break;
- default:
- break;
- }
-
- elm_transit_run(wd->transit, 0.3);
+ if (!wd)
+ return;
+ elm_object_scroll_hold_pop(wd->scr);
}
-*/
-static void _separator_obj_del(Widget_Data *wd, Elm_Ctxpopup_Item *remove_item)
+static void
+_scroller_size_reset(Widget_Data *wd)
{
- Eina_List *elist, *cur_list, *prev_list;
- Elm_Ctxpopup_Item *separator;
-
- if ((!remove_item) || (!wd)) return;
-
- elist = wd->items;
- cur_list = eina_list_data_find_list(elist, remove_item);
+ wd->finished = EINA_FALSE;
+ wd->max_sc_h = -1;
+ wd->max_sc_w = -1;
+}
- if (!cur_list) return;
+static void
+_hover_parent_callbacks_del(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
- prev_list = eina_list_prev(cur_list);
-
- if (!prev_list) return;
+ if ((!wd) || (!wd->hover_parent))
+ return;
- separator = (Elm_Ctxpopup_Item *) eina_list_data_get(prev_list);
-
- if (!separator)return;
-
- wd->items = eina_list_remove(wd->items, separator);
- evas_object_del(separator->base.view);
- free(separator);
+ evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_DEL,
+ _hover_parent_del, obj);
+ evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_MOVE,
+ _hover_parent_move, obj);
+ evas_object_event_callback_del_full(wd->hover_parent, EVAS_CALLBACK_RESIZE,
+ _hover_parent_resize, obj);
}
-static void _btn_layout_create(Evas_Object *obj)
+static void
+_hover_parent_resize(void *data, Evas *e __UNUSED__,
+ Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
- Widget_Data *wd = elm_widget_data_get(obj);
+ Widget_Data *wd = elm_widget_data_get(data);
- wd->btn_layout = edje_object_add(evas_object_evas_get(obj));
- elm_widget_sub_object_add(obj, wd->btn_layout);
- edje_object_signal_emit(wd->base, "elm,state,buttons,enable", "elm");
- edje_object_part_swallow(wd->base, "elm.swallow.btns", wd->btn_layout);
+ if (!wd)
+ return;
+
+ if (wd->visible)
+ {
+ _scroller_size_reset(wd);
+ _sizing_eval(data);
+ }
}
-static void _separator_obj_add(Evas_Object *obj)
+static void
+_hover_parent_move(void *data, Evas *e __UNUSED__,
+ Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
- Elm_Ctxpopup_Item *item;
-
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
-
- if (!wd) return;
- if (eina_list_count(wd->items) == 0) return;
+ Widget_Data *wd = elm_widget_data_get(data);
- item = ELM_NEW(Elm_Ctxpopup_Item);
- if (!item) return;
+ if (!wd)
+ return;
- item->base.view = edje_object_add(evas_object_evas_get(wd->base));
- if (!item->base.view) {
- free(item);
- return;
- }
+ if (wd->visible)
+ {
+ _scroller_size_reset(wd);
+ _sizing_eval(obj);
+ }
+}
- _elm_theme_object_set(obj, item->base.view, "ctxpopup", "separator",
- elm_widget_style_get(obj));
+static void
+_hover_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
- if (wd->horizontal)
- edje_object_signal_emit(item->base.view, "elm,state,horizontal", "elm");
- else
- edje_object_signal_emit(item->base.view, "elm,state,vertical", "elm");
+ if (!wd)
+ return;
- evas_object_size_hint_align_set(item->base.view, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(item->base.view);
- item->separator = EINA_TRUE;
- elm_box_pack_end(wd->box, item->base.view);
- wd->items = eina_list_append(wd->items, item);
+ wd->hover_parent = NULL;
}
-static void _item_sizing_eval(Elm_Ctxpopup_Item *item)
+static void
+_item_sizing_eval(Elm_Ctxpopup_Item *item)
{
- Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
- Evas_Coord x, y, w, h;
+ Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
- if (!item) return;
+ Evas_Coord x, y, w, h;
- if (!item->separator) elm_coords_finger_size_adjust(1, &min_w, 1, &min_h);
+ if (!item)
+ return;
- evas_object_geometry_get(item->base.view, &x, &y, &w, &h);
- edje_object_size_min_restricted_calc(item->base.view, &min_w, &min_h, min_w, min_h);
- evas_object_size_hint_min_set(item->base.view, min_w, min_h);
- evas_object_size_hint_max_set(item->base.view, max_w, max_h);
+ evas_object_geometry_get(item->base.view, &x, &y, &w, &h);
+ edje_object_size_min_restricted_calc(item->base.view, &min_w, &min_h, min_w,
+ min_h);
+ evas_object_size_hint_min_set(item->base.view, min_w, min_h);
+ evas_object_size_hint_max_set(item->base.view, max_w, max_h);
}
-static void _adjust_pos_x(Evas_Coord_Point *pos, Evas_Coord_Point *base_size,
- Evas_Coord_Rectangle *area_rect)
+static void
+_adjust_pos_x(Evas_Coord_Point *pos, Evas_Coord_Point *base_size,
+ Evas_Coord_Rectangle *hover_area)
{
- pos->x -= (base_size->x / 2);
+ pos->x -= (base_size->x / 2);
+
+ if (pos->x < hover_area->x)
+ pos->x = hover_area->x;
+ else if ((pos->x + base_size->x) > (hover_area->x + hover_area->w))
+ pos->x = (hover_area->x + hover_area->w) - base_size->x;
- if (pos->x < area_rect->x) pos->x = area_rect->x;
- else if ((pos->x + base_size->x) > (area_rect->x + area_rect->w))
- pos->x = (area_rect->x + area_rect->w) - base_size->x;
+ if (base_size->x > hover_area->w)
+ base_size->x -= (base_size->x - hover_area->w);
- if (base_size->x > area_rect->w)
- base_size->x -= (base_size->x - area_rect->w);
- if (pos->x < area_rect->x)
- pos->x = area_rect->x;
+ if (pos->x < hover_area->x)
+ pos->x = hover_area->x;
}
-static void _adjust_pos_y(int indicator_h, Evas_Coord_Point *pos,
- Evas_Coord_Point *base_size, Evas_Coord_Rectangle *area_rect)
+static void
+_adjust_pos_y(Evas_Coord_Point *pos, Evas_Coord_Point *base_size,
+ Evas_Coord_Rectangle *hover_area)
{
- pos->y -= (base_size->y / 2);
+ pos->y -= (base_size->y / 2);
+
+ if (pos->y < hover_area->y)
+ pos->y = hover_area->y;
+ else if ((pos->y + base_size->y) > (hover_area->y + hover_area->h))
+ pos->y = hover_area->y + hover_area->h - base_size->y;
- if (pos->y < area_rect->y) pos->y = area_rect->y;
- else if ((pos->y + base_size->y) > (area_rect->y + area_rect->h))
- pos->y = area_rect->y + area_rect->h - base_size->y;
+ if (base_size->y > hover_area->h)
+ base_size->y -= (base_size->y - hover_area->h);
- if (base_size->y > area_rect->h)
- base_size->y -= (base_size->y - area_rect->h);
-
- if (pos->y < area_rect->y) pos->y = area_rect->y;
+ if (pos->y < hover_area->y)
+ pos->y = hover_area->y;
}
-static int _get_indicator_h(Evas_Object *parent)
+static void
+_ctxpopup_changed_size_hints(void *data __UNUSED__, Evas *e __UNUSED__,
+ Evas_Object *obj, void *event_info __UNUSED__)
{
- Ecore_X_Window zone, xwin;
- int h = 0;
+ Widget_Data *wd;
- if (elm_win_indicator_state_get(parent) != 1)
- return 0;
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
- xwin = elm_win_xwindow_get(parent);
- zone = ecore_x_e_illume_zone_get(xwin);
- ecore_x_e_illume_indicator_geometry_get(zone, NULL, NULL, NULL, &h);
-
- return h;
+ if (wd->visible)
+ _sizing_eval(obj);
}
-static void _ctxpopup_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
+static Elm_Ctxpopup_Direction
+_calc_base_geometry(Evas_Object *obj, Evas_Coord_Rectangle *rect)
{
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
- if (!wd) return;
- if(wd->visible)_sizing_eval(obj);
-}
-
-static Elm_Ctxpopup_Arrow _calc_base_geometry(Evas_Object *obj, Evas_Coord_Rectangle *rect)
-{
- Widget_Data *wd;
- Evas_Coord_Point pos;
- Evas_Coord_Point base_size;
- Evas_Coord_Point max_size;
- Evas_Coord_Point min_size;
- Evas_Coord_Rectangle area_rect;
- Evas_Coord_Point parent_size;
- Evas_Coord_Point arrow_size;
- Elm_Ctxpopup_Arrow arrow;
- Evas_Coord finger_size;
- Evas_Coord indicator_h;
- Evas_Coord_Point temp;
- int idx;
-
- wd = elm_widget_data_get(obj);
-
- if ((!wd) || (!rect)) return ELM_CTXPOPUP_ARROW_DOWN;
-
- indicator_h = _get_indicator_h(wd->parent);
- finger_size = elm_finger_size_get();
-
- edje_object_part_geometry_get(wd->arrow, "ctxpopup_arrow", NULL, NULL,
- &arrow_size.x, &arrow_size.y);
- evas_object_resize(wd->arrow, arrow_size.x, arrow_size.y);
-
- //Initialize Area Rectangle.
- if (wd->area_rect)
- evas_object_geometry_get(wd->area_rect, &area_rect.x, &area_rect.y,
- &area_rect.w, &area_rect.h);
- else {
- evas_object_geometry_get(wd->parent, NULL, NULL, &parent_size.x, &parent_size.y);
- area_rect.x = 0;
- area_rect.y = 0;
- area_rect.w = parent_size.x;
- area_rect.h = parent_size.y;
- }
-
- if (area_rect.y < indicator_h) {
- temp.y = indicator_h - area_rect.y;
- area_rect.y = indicator_h;
- area_rect.h -= temp.y;
- }
- evas_object_geometry_get(obj, &pos.x, &pos.y, NULL, NULL);
-
- //recalc the edje
- edje_object_size_min_calc(wd->base, &base_size.x, &base_size.y);
- evas_object_smart_calculate(wd->base);
-
- //Limit to Max Size
- evas_object_size_hint_max_get(obj, &max_size.x, &max_size.y);
-
- if((max_size.y > 0 ) && (base_size.y > max_size.y))
- base_size.y = max_size.y;
-
- if((max_size.x > 0 ) && (base_size.x > max_size.x))
- base_size.x = max_size.x;
-
- //Limit to Min Size
- evas_object_size_hint_min_get(obj, &min_size.x, &min_size.y);
-
- if( min_size.y > 0 )
- if(base_size.y < min_size.y) base_size.y = min_size.y;
-
- if( min_size.x > 0 )
- if(base_size.x < min_size.x) base_size.x = min_size.x;
-
- //In case of position forced. It shows up just like popup.
- if (wd->position_forced) {
- //TODO: calculate the size of ctxpopup
- rect->x = pos.x;
- rect->y = pos.y;
- rect->w = base_size.x;
- rect->h = base_size.y;
- return ELM_CTXPOPUP_ARROW_UP;
- }
-
- //Check the Which direction is available.
- //If find a avaialble direction, it adjusts position and size.
- for (idx = 0; idx < 4; ++idx) {
- switch (wd->arrow_priority[idx]) {
- case ELM_CTXPOPUP_ARROW_DOWN:
- temp.y = pos.y - base_size.y;
- if ((temp.y - arrow_size.y - finger_size) < area_rect.y) continue;
- _adjust_pos_x(&pos, &base_size, &area_rect);
- pos.y -= (base_size.y + finger_size);
- arrow = ELM_CTXPOPUP_ARROW_DOWN;
- break;
- case ELM_CTXPOPUP_ARROW_RIGHT:
- temp.x = (pos.x - base_size.x);
- if ((temp.x - arrow_size.x - finger_size) < area_rect.x) continue;
- _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
- pos.x -= (base_size.x + finger_size);
- arrow = ELM_CTXPOPUP_ARROW_RIGHT;
- break;
- case ELM_CTXPOPUP_ARROW_LEFT:
- temp.x = (pos.x + base_size.x);
- if ((temp.x + arrow_size.x + finger_size) > (area_rect.x + area_rect.w)) continue;
- _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
- pos.x += finger_size;
- arrow = ELM_CTXPOPUP_ARROW_LEFT;
- break;
- case ELM_CTXPOPUP_ARROW_UP:
- temp.y = (pos.y + base_size.y);
- if ((temp.y + arrow_size.y + finger_size) > (area_rect.y + area_rect.h)) continue;
- _adjust_pos_x(&pos, &base_size, &area_rect);
- pos.y += finger_size;
- arrow = ELM_CTXPOPUP_ARROW_UP;
- break;
- default:
- break;
- }
- break;
- }
-
- //In this case, all directions are invalid because of lack of space.
- if (idx == 4) {
- //TODO 1: Find the largest space direction.
- /*
- Evas_Coord length[4];
-
- length[ ELM_CTXPOPUP_ARROW_DOWN ] = pos.y - area_rect.y;
- length[ ELM_CTXPOPUP_ARROW_UP ] = ( area_rect.y + area_rect.h ) - pos.y;
- length[ ELM_CTXPOPUP_ARROW_RIGHT ] = pos.x - area_rect.x;
- length[ ELM_CTXPOPUP_ARROW_LEFT ] = ( area_rect.x + area_rect.w ) - pos.x;
-
- int i, j, idx;
- for( i = 0; i < 4; ++i ) {
- for( j = 1; j < 4; ++j ) {
- if( length[ idx ] < length[ j ] ) {
- idx = j;
- }
- }
- }
- */
- //TODO 1: Find the largest space direction.
- Evas_Coord length[2];
- length[0] = pos.y - area_rect.y;
- length[1] = (area_rect.y + area_rect.h) - pos.y;
-
- if (length[0] > length[1]) idx = ELM_CTXPOPUP_ARROW_DOWN;
- else idx = ELM_CTXPOPUP_ARROW_UP;
-
- //TODO 2: determine x , y
- switch (idx) {
- case ELM_CTXPOPUP_ARROW_DOWN:
- _adjust_pos_x(&pos, &base_size, &area_rect);
- pos.y -= (base_size.y + finger_size);
- arrow = ELM_CTXPOPUP_ARROW_DOWN;
- if (pos.y < area_rect.y + arrow_size.y) {
- base_size.y -= ((area_rect.y + arrow_size.y) - pos.y);
- pos.y = area_rect.y + arrow_size.y;
- }
- break;
- case ELM_CTXPOPUP_ARROW_RIGHT:
- _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
- pos.x -= (base_size.x + finger_size);
- arrow = ELM_CTXPOPUP_ARROW_RIGHT;
- if (pos.x < area_rect.x + arrow_size.x) {
- base_size.x -= ((area_rect.x + arrow_size.x) - pos.x);
- pos.x = area_rect.x + arrow_size.x;
- }
- break;
- case ELM_CTXPOPUP_ARROW_LEFT:
- _adjust_pos_y(indicator_h, &pos, &base_size, &area_rect);
- pos.x += finger_size;
- arrow = ELM_CTXPOPUP_ARROW_LEFT;
- if (pos.x + arrow_size.x + base_size.x > area_rect.x + area_rect.w) {
- base_size.x -= ((pos.x + arrow_size.x + base_size.x)
- - (area_rect.x + area_rect.w));
- }
- break;
- case ELM_CTXPOPUP_ARROW_UP:
- _adjust_pos_x(&pos, &base_size, &area_rect);
- pos.y += finger_size;
- arrow = ELM_CTXPOPUP_ARROW_UP;
- if (pos.y + arrow_size.y + base_size.y > area_rect.y + area_rect.h) {
- base_size.y -= ((pos.y + arrow_size.y + base_size.y) - (area_rect.y + area_rect.h));
- }
- break;
- default:
- break;
- }
- }
-
- //Final position and size.
- rect->x = pos.x;
- rect->y = pos.y;
- rect->w = base_size.x;
- rect->h = base_size.y;
-
- return arrow;
+ Widget_Data *wd;
+ Evas_Coord_Point pos = {0, 0};
+ Evas_Coord_Point base_size;
+ Evas_Coord_Point max_size;
+ Evas_Coord_Point min_size;
+ Evas_Coord_Rectangle hover_area;
+ Evas_Coord_Rectangle parent_size;
+ Evas_Coord_Point arrow_size;
+ Elm_Ctxpopup_Direction arrow = ELM_CTXPOPUP_DIRECTION_DOWN;
+ Evas_Coord finger_size;
+ Evas_Coord_Point temp;
+ int idx;
+
+ wd = elm_widget_data_get(obj);
+
+ if ((!wd) || (!rect))
+ return ELM_CTXPOPUP_DIRECTION_DOWN;
+
+ finger_size = elm_finger_size_get();
+
+ edje_object_part_geometry_get(wd->arrow, "ctxpopup_arrow", NULL, NULL,
+ &arrow_size.x, &arrow_size.y);
+ evas_object_resize(wd->arrow, arrow_size.x, arrow_size.y);
+
+ //Initialize Area Rectangle.
+ if (wd->hover_parent)
+ evas_object_geometry_get(wd->hover_parent, &hover_area.x, &hover_area.y,
+ &hover_area.w, &hover_area.h);
+ else
+ {
+ evas_object_geometry_get(wd->parent, &parent_size.x, &parent_size.y,
+ &parent_size.w, &parent_size.h);
+ hover_area.x = parent_size.x;
+ hover_area.y = parent_size.y;
+ hover_area.w = parent_size.w;
+ hover_area.h = parent_size.h;
+ }
+
+ evas_object_geometry_get(obj, &pos.x, &pos.y, NULL, NULL);
+
+ //recalc the edje
+ edje_object_size_min_calc(wd->base, &base_size.x, &base_size.y);
+ evas_object_smart_calculate(wd->base);
+
+ //Limit to Max Size
+ evas_object_size_hint_max_get(obj, &max_size.x, &max_size.y);
+
+ if ((max_size.y > 0) && (base_size.y > max_size.y))
+ base_size.y = max_size.y;
+
+ if ((max_size.x > 0) && (base_size.x > max_size.x))
+ base_size.x = max_size.x;
+
+ //Limit to Min Size
+ evas_object_size_hint_min_get(obj, &min_size.x, &min_size.y);
+
+ if ((min_size.y > 0) && (base_size.y < min_size.y))
+ base_size.y = min_size.y;
+
+ if ((min_size.x > 0) && (base_size.x < min_size.x))
+ base_size.x = min_size.x;
+
+ //Check the Which direction is available.
+ //If find a avaialble direction, it adjusts position and size.
+ for (idx = 0; idx < 4; idx++)
+ {
+ switch (wd->dir_priority[idx])
+ {
+ case ELM_CTXPOPUP_DIRECTION_UP:
+ temp.y = pos.y - base_size.y;
+ if ((temp.y - arrow_size.y - finger_size) < hover_area.y)
+ continue;
+ _adjust_pos_x(&pos, &base_size, &hover_area);
+ pos.y -= (base_size.y + finger_size);
+ arrow = ELM_CTXPOPUP_DIRECTION_DOWN;
+ break;
+ case ELM_CTXPOPUP_DIRECTION_LEFT:
+ temp.x = (pos.x - base_size.x);
+ if ((temp.x - arrow_size.x - finger_size) < hover_area.x)
+ continue;
+ _adjust_pos_y(&pos, &base_size, &hover_area);
+ pos.x -= (base_size.x + finger_size);
+ arrow = ELM_CTXPOPUP_DIRECTION_RIGHT;
+ break;
+ case ELM_CTXPOPUP_DIRECTION_RIGHT:
+ temp.x = (pos.x + base_size.x);
+ if ((temp.x + arrow_size.x + finger_size) >
+ (hover_area.x + hover_area.w))
+ continue;
+ _adjust_pos_y(&pos, &base_size, &hover_area);
+ pos.x += finger_size;
+ arrow = ELM_CTXPOPUP_DIRECTION_LEFT;
+ break;
+ case ELM_CTXPOPUP_DIRECTION_DOWN:
+ temp.y = (pos.y + base_size.y);
+ if ((temp.y + arrow_size.y + finger_size) >
+ (hover_area.y + hover_area.h))
+ continue;
+ _adjust_pos_x(&pos, &base_size, &hover_area);
+ pos.y += finger_size;
+ arrow = ELM_CTXPOPUP_DIRECTION_UP;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ //In this case, all directions are invalid because of lack of space.
+ if (idx == 4)
+ {
+ //TODO 1: Find the largest space direction.
+ Evas_Coord length[2];
+
+ length[0] = pos.y - hover_area.y;
+ length[1] = (hover_area.y + hover_area.h) - pos.y;
+
+ if (length[0] > length[1])
+ idx = ELM_CTXPOPUP_DIRECTION_DOWN;
+ else
+ idx = ELM_CTXPOPUP_DIRECTION_UP;
+
+ //TODO 2: determine x , y
+ switch (idx)
+ {
+ case ELM_CTXPOPUP_DIRECTION_UP:
+ _adjust_pos_x(&pos, &base_size, &hover_area);
+ pos.y -= (base_size.y + finger_size);
+ arrow = ELM_CTXPOPUP_DIRECTION_DOWN;
+ if (pos.y < hover_area.y + arrow_size.y)
+ {
+ base_size.y -= ((hover_area.y + arrow_size.y) - pos.y);
+ pos.y = hover_area.y + arrow_size.y;
+ }
+ break;
+ case ELM_CTXPOPUP_DIRECTION_LEFT:
+ _adjust_pos_y(&pos, &base_size, &hover_area);
+ pos.x -= (base_size.x + finger_size);
+ arrow = ELM_CTXPOPUP_DIRECTION_RIGHT;
+ if (pos.x < hover_area.x + arrow_size.x)
+ {
+ base_size.x -= ((hover_area.x + arrow_size.x) - pos.x);
+ pos.x = hover_area.x + arrow_size.x;
+ }
+ break;
+ case ELM_CTXPOPUP_DIRECTION_RIGHT:
+ _adjust_pos_y(&pos, &base_size, &hover_area);
+ pos.x += finger_size;
+ arrow = ELM_CTXPOPUP_DIRECTION_LEFT;
+ if (pos.x + arrow_size.x + base_size.x >
+ hover_area.x + hover_area.w)
+ base_size.x -=
+ ((pos.x + arrow_size.x + base_size.x) -
+ (hover_area.x + hover_area.w));
+ break;
+ case ELM_CTXPOPUP_DIRECTION_DOWN:
+ _adjust_pos_x(&pos, &base_size, &hover_area);
+ pos.y += finger_size;
+ arrow = ELM_CTXPOPUP_DIRECTION_UP;
+ if (pos.y + arrow_size.y + base_size.y >
+ hover_area.y + hover_area.h)
+ base_size.y -=
+ ((pos.y + arrow_size.y + base_size.y) -
+ (hover_area.y + hover_area.h));
+ break;
+ default:
+ break;
+ }
+ }
+
+ //Final position and size.
+ rect->x = pos.x;
+ rect->y = pos.y;
+ rect->w = base_size.x;
+ rect->h = base_size.y;
+
+ return arrow;
}
-static void _update_arrow_obj(Evas_Object *obj, Elm_Ctxpopup_Arrow arrow_dir)
-{
- Evas_Coord x, y;
- Evas_Coord_Rectangle arrow_size;
- Evas_Coord_Rectangle area_rect;
- Evas_Coord parent_w, parent_h;
- Widget_Data *wd = elm_widget_data_get(obj);
-
- if (!wd) return;
-
- evas_object_geometry_get(obj, &x, &y, NULL, NULL);
- evas_object_geometry_get(wd->arrow, NULL, NULL, &arrow_size.w,
- &arrow_size.h);
-
- switch (arrow_dir) {
- case ELM_CTXPOPUP_ARROW_LEFT: {
- edje_object_signal_emit(wd->arrow, "elm,state,left", "elm");
- arrow_size.y = (y - (arrow_size.h * 0.5));
- arrow_size.x = (x + elm_finger_size_get());
- break;
- }
- case ELM_CTXPOPUP_ARROW_RIGHT: {
- edje_object_signal_emit(wd->arrow, "elm,state,right", "elm");
- arrow_size.y = (y - (arrow_size.h * 0.5));
- arrow_size.x = (x - elm_finger_size_get() - arrow_size.w);
- break;
- }
- case ELM_CTXPOPUP_ARROW_UP: {
- edje_object_signal_emit(wd->arrow, "elm,state,top", "elm");
- arrow_size.x = (x - (arrow_size.w * 0.5));
- arrow_size.y = (y + elm_finger_size_get());
- break;
- }
- case ELM_CTXPOPUP_ARROW_DOWN: {
- edje_object_signal_emit(wd->arrow, "elm,state,bottom", "elm");
- arrow_size.x = (x - (arrow_size.w * 0.5));
- arrow_size.y = (y - elm_finger_size_get() - arrow_size.h);
- break;
- }
- default:
- break;
- }
-
- //Adjust arrow position to prevent out of area
- if (wd->area_rect)
- evas_object_geometry_get(wd->area_rect, &area_rect.x, &area_rect.y,
- &area_rect.w, &area_rect.h);
- else {
- evas_object_geometry_get(wd->parent, NULL, NULL, &parent_w, &parent_h);
- area_rect.x = 0;
- area_rect.y = 0;
- area_rect.w = parent_w;
- area_rect.h = parent_h;
- }
-
- //TODO: Temporary Code. make it more flexible
- if ((arrow_size.x - (arrow_size.w / 2)) < area_rect.x)
- arrow_size.x = area_rect.x + (arrow_size.w / 2);
- else if ((arrow_size.x + arrow_size.w) > (area_rect.x + area_rect.w))
- arrow_size.x = (area_rect.x + area_rect.w) - arrow_size.w
- - (arrow_size.w / 2);
-/*
- //TODO: Temporary Code. make it more flexible
- if ((arrow_size.y - (arrow_size.h / 2)) < area_rect.y) {
- arrow_size.y = arrow_size.y + (arrow_size.h / 2);
- } else if ((arrow_size.y + arrow_size.h) > (area_rect.y + area_rect.h)) {
- arrow_size.y = (area_rect.y + area_rect.h) - arrow_size.h
- - (arrow_size.h / 2);
- }
-*/
- evas_object_move(wd->arrow, arrow_size.x, arrow_size.y);
+static void
+_update_arrow(Evas_Object *obj, Elm_Ctxpopup_Direction dir)
+{
+ Evas_Coord x, y;
+ Evas_Coord_Rectangle arrow_size;
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
+
+ evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+ evas_object_geometry_get(wd->arrow, NULL, NULL, &arrow_size.w,
+ &arrow_size.h);
+
+ switch (dir)
+ {
+ case ELM_CTXPOPUP_DIRECTION_LEFT:
+ edje_object_signal_emit(wd->arrow, "elm,state,left", "elm");
+ arrow_size.y = (y - (arrow_size.h * 0.5));
+ arrow_size.x = (x + elm_finger_size_get());
+ break;
+ case ELM_CTXPOPUP_DIRECTION_RIGHT:
+ edje_object_signal_emit(wd->arrow, "elm,state,right", "elm");
+ arrow_size.y = (y - (arrow_size.h * 0.5));
+ arrow_size.x = (x - elm_finger_size_get() - arrow_size.w);
+ break;
+ case ELM_CTXPOPUP_DIRECTION_UP:
+ edje_object_signal_emit(wd->arrow, "elm,state,top", "elm");
+ arrow_size.x = (x - (arrow_size.w * 0.5));
+ arrow_size.y = (y + elm_finger_size_get());
+ break;
+ case ELM_CTXPOPUP_DIRECTION_DOWN:
+ edje_object_signal_emit(wd->arrow, "elm,state,bottom", "elm");
+ arrow_size.x = (x - (arrow_size.w * 0.5));
+ arrow_size.y = (y - elm_finger_size_get() - arrow_size.h);
+ break;
+ default:
+ break;
+ }
+
+ evas_object_move(wd->arrow, arrow_size.x, arrow_size.y);
}
-static void _sizing_eval(Evas_Object *obj)
-{
- Widget_Data *wd;
- Eina_List *elist;
- Elm_Ctxpopup_Item *item;
- Evas_Coord_Rectangle rect = { 0, 0, 1, 1 };
- Evas_Coord_Point box_size = { 0, 0 };
- Evas_Coord_Point _box_size = { 0, 0 };
-
- wd = (Widget_Data *) elm_widget_data_get(obj);
- if ((!wd) || (!wd->parent)) return;
- int idx = 0;
-
- //Box, scroller
- EINA_LIST_FOREACH(wd->items, elist, item)
- {
- _item_sizing_eval(item);
- evas_object_size_hint_min_get(item->base.view, &_box_size.x, &_box_size.y);
- if(!wd->horizontal) {
- if(_box_size.x > box_size.x) box_size.x = _box_size.x;
- if(_box_size.y != -1 ) box_size.y += _box_size.y;
- } else {
- if(_box_size.x != -1 ) box_size.x += _box_size.x;
- if(_box_size.y > box_size.y) box_size.y = _box_size.y;
- }
- ++idx;
- }
-
- if(!wd->content) {
- evas_object_size_hint_min_set(wd->box, box_size.x, box_size.y);
- evas_object_size_hint_min_set(wd->scroller, box_size.x, box_size.y);
- }
-
- //Base
- wd->arrow_dir = _calc_base_geometry(obj, &rect);
- if ((!wd->position_forced) && (wd->arrow_dir != -1)) {
- _update_arrow_obj(obj, wd->arrow_dir);
- _shift_base_by_arrow(wd->arrow, wd->arrow_dir, &rect);
- }
-
- //resize scroller according to final size.
- if (!wd->content) {
- evas_object_smart_calculate(wd->scroller);
- }
-
- evas_object_move(wd->base, rect.x, rect.y);
- evas_object_resize(wd->base, rect.w, rect.h);
-
- if(wd->visible)
- edje_object_signal_emit(wd->base, "elm,state,show", "elm");
+static void
+_sizing_eval(Evas_Object *obj)
+{
+ Widget_Data *wd;
+ Eina_List *elist;
+ Elm_Ctxpopup_Item *item;
+ Evas_Coord_Rectangle rect = { 0, 0, 1, 1 };
+ Evas_Coord_Point box_size = { 0, 0 };
+ Evas_Coord_Point _box_size = { 0, 0 };
+
+ wd = elm_widget_data_get(obj);
+ if ((!wd) || (!wd->parent))
+ return;
+
+ //Box, Scroller
+ EINA_LIST_FOREACH(wd->items, elist, item)
+ {
+ _item_sizing_eval(item);
+ evas_object_size_hint_min_get(item->base.view, &_box_size.x, &_box_size.y);
+ if (!wd->horizontal)
+ {
+ if (_box_size.x > box_size.x)
+ box_size.x = _box_size.x;
+ if (_box_size.y != -1)
+ box_size.y += _box_size.y;
+ }
+ else
+ {
+ if (_box_size.x != -1)
+ box_size.x += _box_size.x;
+ if (_box_size.y > box_size.y)
+ box_size.y = _box_size.y;
+ }
+ }
+
+ if (!wd->content)
+ {
+ evas_object_size_hint_min_set(wd->box, box_size.x, box_size.y);
+ evas_object_size_hint_min_set(wd->scr, box_size.x, box_size.y);
+ }
+
+ //Base
+ wd->dir = _calc_base_geometry(obj, &rect);
+ _update_arrow(obj, wd->dir);
+ _shift_base_by_arrow(wd->arrow, wd->dir, &rect);
+
+ //resize scroller according to final size.
+ if (!wd->content)
+ evas_object_smart_calculate(wd->scr);
+
+ evas_object_move(wd->base, rect.x, rect.y);
+ evas_object_resize(wd->base, rect.w, rect.h);
}
-static void _shift_base_by_arrow(Evas_Object *arrow,
- Elm_Ctxpopup_Arrow arrow_dir, Evas_Coord_Rectangle *rect)
-{
- Evas_Coord arrow_w, arrow_h;
- evas_object_geometry_get(arrow, NULL, NULL, &arrow_w, &arrow_h);
-
- switch (arrow_dir) {
- case ELM_CTXPOPUP_ARROW_LEFT:
- rect->x += arrow_w;
- break;
- case ELM_CTXPOPUP_ARROW_RIGHT:
- rect->x -= arrow_w;
- break;
- case ELM_CTXPOPUP_ARROW_UP:
- rect->y += arrow_h;
- break;
- case ELM_CTXPOPUP_ARROW_DOWN:
- rect->y -= arrow_h;
- break;
- default:
- break;
- }
+static void
+_shift_base_by_arrow(Evas_Object *arrow, Elm_Ctxpopup_Direction dir,
+ Evas_Coord_Rectangle *rect)
+{
+ Evas_Coord arrow_w, arrow_h;
+
+ evas_object_geometry_get(arrow, NULL, NULL, &arrow_w, &arrow_h);
+
+ switch (dir)
+ {
+ case ELM_CTXPOPUP_DIRECTION_LEFT:
+ rect->x += arrow_w;
+ break;
+ case ELM_CTXPOPUP_DIRECTION_RIGHT:
+ rect->x -= arrow_w;
+ break;
+ case ELM_CTXPOPUP_DIRECTION_UP:
+ rect->y += arrow_h;
+ break;
+ case ELM_CTXPOPUP_DIRECTION_DOWN:
+ rect->y -= arrow_h;
+ break;
+ default:
+ break;
+ }
}
-static void _del_pre_hook(Evas_Object *obj) {
-
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
- if (!wd) return;
-
- evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
- _parent_resize, obj);
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+ Widget_Data *wd;
- if(wd->transit) {
- elm_transit_stop(wd->transit);
- elm_transit_del(wd->transit);
- wd->transit = NULL;
- }
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
- _delete_area_rect_callbacks(wd);
+ evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
+ _parent_resize, obj);
+ _hover_parent_callbacks_del(obj);
}
-static void _del_hook(Evas_Object *obj)
+static void
+_del_hook(Evas_Object *obj)
{
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+ Widget_Data *wd;
- if (!wd) return;
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
- elm_ctxpopup_clear(obj);
- evas_object_del(wd->arrow);
- evas_object_del(wd->base);
-
- free(wd);
+ elm_ctxpopup_clear(obj);
+ evas_object_del(wd->arrow);
+ evas_object_del(wd->base);
+ free(wd);
}
-static void _theme_hook(Evas_Object *obj)
-{
- Eina_List *elist;
- Elm_Ctxpopup_Item *item;
- char buf[256];
-
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
-
- if (!wd) return;
-
- //Items
- EINA_LIST_FOREACH(wd->items, elist, item)
- {
- if (item->separator)
- {
- _elm_theme_object_set(obj, item->base.view, "ctxpopup", "separator",
- elm_widget_style_get(obj));
- if (wd->horizontal)
- edje_object_signal_emit(item->base.view, "elm,state,horizontal", "elm");
- }
- else
- {
- if (item->label && item->icon)
- {
- _elm_theme_object_set(obj, item->base.view, "ctxpopup",
- "icon_text_style_item",
- elm_widget_style_get(obj));
- }
- else if (item->label)
- {
- _elm_theme_object_set(obj, item->base.view, "ctxpopup",
- "text_style_item",
- elm_widget_style_get(obj));
- }
- else if (item->icon)
- {
- _elm_theme_object_set(obj, item->base.view, "ctxpopup",
- "icon_style_item",
- elm_widget_style_get(obj));
- }
- if (item->label)
- edje_object_part_text_set(item->base.view, "elm.text", item->label);
-
- if (item->disabled)
- edje_object_signal_emit(item->base.view, "elm,state,disabled", "elm");
- }
- edje_object_message_signal_process(item->base.view);
- }
-
- //button layout
- if (wd->btn_layout) {
- sprintf(buf, "buttons%d", wd->btn_cnt);
- _elm_theme_object_set(obj, wd->btn_layout, "ctxpopup", buf,
- elm_widget_style_get(obj));
- }
-
- _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg", elm_widget_style_get(obj));
- _elm_theme_object_set(obj, wd->base, "ctxpopup", "base", elm_widget_style_get(obj));
- _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow",
- elm_widget_style_get(obj));
-
- if (!strncmp(elm_object_style_get(obj), "default", strlen("default")
- * sizeof(char)))
- elm_object_style_set(wd->scroller, "ctxpopup");
- else
- elm_object_style_set(wd->scroller, elm_object_style_get(obj));
-
- if(wd->visible) {
- _reset_scroller_size(wd);
- _sizing_eval(obj);
- }
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd;
+ Eina_List *elist;
+ Elm_Ctxpopup_Item *item;
+
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
+
+ //Items
+ EINA_LIST_FOREACH(wd->items, elist, item)
+ {
+ if (item->label && item->icon)
+ _elm_theme_object_set(obj, item->base.view, "ctxpopup",
+ "icon_text_style_item",
+ elm_widget_style_get(obj));
+ else if (item->label)
+ _elm_theme_object_set(obj, item->base.view, "ctxpopup", "text_style_item",
+ elm_widget_style_get(obj));
+ else if (item->icon)
+ _elm_theme_object_set(obj, item->base.view, "ctxpopup", "icon_style_item",
+ elm_widget_style_get(obj));
+ if (item->label)
+ edje_object_part_text_set(item->base.view, "elm.text", item->label);
+
+ if (item->disabled)
+ edje_object_signal_emit(item->base.view, "elm,state,disabled", "elm");
+
+ edje_object_message_signal_process(item->base.view);
+ }
+
+ _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg",
+ elm_widget_style_get(obj));
+ _elm_theme_object_set(obj, wd->base, "ctxpopup", "base",
+ elm_widget_style_get(obj));
+ _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow",
+ elm_widget_style_get(obj));
+
+ if(wd->scr)
+ {
+ if (!strncmp(elm_object_style_get(obj), "default",
+ strlen("default")))
+ elm_object_style_set(wd->scr, "ctxpopup");
+ else
+ elm_object_style_set(wd->scr, elm_object_style_get(obj));
+ }
+
+ if (wd->visible)
+ {
+ _scroller_size_reset(wd);
+ _sizing_eval(obj);
+ }
}
-static void _bg_clicked_cb(void *data, Evas_Object *obj, const char *emission,
- const char *source)
+static void
+_bg_clicked_cb(void *data, Evas_Object *obj __UNUSED__,
+ const char *emission __UNUSED__, const char *source __UNUSED__)
{
- evas_object_hide(data);
+ evas_object_hide(data);
}
-static void _parent_resize(void *data, Evas *e, Evas_Object *obj,
- void *event_info)
+static void
+_parent_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
{
- Evas_Coord w, h;
+ Evas_Coord w, h;
+ Widget_Data *wd;
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(data);
- if (!wd) return;
+ wd = elm_widget_data_get(data);
+ if (!wd)
+ return;
- evas_object_geometry_get(obj, NULL, NULL, &w, &h);
- evas_object_resize(wd->bg, w, h);
+ evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+ evas_object_resize(wd->bg, w, h);
- if(wd->visible == EINA_FALSE) return;
- wd->visible = EINA_FALSE;
- _hide_ctxpopup(data);
+ if (!wd->visible)
+ return;
+ _hide(data);
}
-static void _ctxpopup_show(void *data, Evas *e, Evas_Object *obj,
- void *event_info)
+static void
+_ctxpopup_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
{
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
- if(wd == NULL) return;
-
- if ((eina_list_count(wd->items) < 1) && (!wd->content) && (wd->btn_cnt < 1))
- return;
+ Widget_Data *wd;
- wd->visible = EINA_TRUE;
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
- if (!wd->screen_dimmed_disabled) {
- evas_object_show(wd->bg);
- edje_object_signal_emit(wd->bg, "elm,state,show", "elm");
- }
+ if ((!wd->items) && (!wd->content))
+ return;
- evas_object_show(wd->base);
+ wd->visible = EINA_TRUE;
- if (!wd->position_forced) {
- evas_object_show(wd->arrow);
- }
+ evas_object_show(wd->bg);
+ evas_object_show(wd->base);
+ evas_object_show(wd->arrow);
- _sizing_eval(obj);
+ edje_object_signal_emit(wd->bg, "elm,state,show", "elm");
+ _sizing_eval(obj);
}
-static void _hide_ctxpopup(Evas_Object *obj)
+static void
+_hide(Evas_Object *obj)
{
- //TODO: Consider implementing effect in edc.
- Widget_Data *wd = elm_widget_data_get(obj);
-
- if (!wd->screen_dimmed_disabled)
- evas_object_hide(wd->bg);
+ Widget_Data *wd = elm_widget_data_get(obj);
- if(!wd->position_forced)
- evas_object_hide(wd->arrow);
+ if (!wd)
+ return;
- evas_object_hide(wd->base);
+ evas_object_hide(wd->bg);
+ evas_object_hide(wd->arrow);
+ evas_object_hide(wd->base);
- _reset_scroller_size(wd);
+ _scroller_size_reset(wd);
- evas_object_smart_callback_call(obj, "hide", NULL);
+ evas_object_smart_callback_call(obj, SIG_DISMISSED, NULL);
+ evas_object_smart_callback_call(obj, SIG_HIDE, NULL); //TODO: Remove!
+ wd->visible = EINA_FALSE;
}
-static void _ctxpopup_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
+static void
+_ctxpopup_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
{
- Widget_Data *wd = (Widget_Data*) elm_widget_data_get(obj);
- if(wd == NULL) return;
+ Widget_Data *wd;
- if(wd->visible == EINA_FALSE) return;
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
- wd->visible = EINA_FALSE;
-/*
- if (!wd->screen_dimmed_disabled)
- edje_object_signal_emit(wd->bg, "elm,state,hide", "elm");
+ if (!wd->visible)
+ return;
- _hide_effect(obj);
-*/
- _hide_ctxpopup(obj);
+ _hide(obj);
}
-static void _ctxpopup_scroller_resize(void *data, Evas *e, Evas_Object * obj,
- void *event_info)
+static void
+_scroller_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
{
- Widget_Data *wd;
- Evas_Coord w, h;
-
- wd = elm_widget_data_get(data);
- if(wd == NULL) return;
+ Widget_Data *wd;
+ Evas_Coord w, h;
+
+ wd = elm_widget_data_get(data);
+ if (!wd)
+ return;
+
+ if (!wd->visible)
+ return;
+ if (wd->finished)
+ return;
+
+ evas_object_geometry_get(obj, 0, 0, &w, &h);
+
+ if (w != 0 && h != 0)
+ {
+ if ((w <= wd->max_sc_w) && (h <= wd->max_sc_h))
+ {
+ _sizing_eval(data);
+ wd->finished = EINA_TRUE;
+ return;
+ }
+ }
+
+ if (wd->max_sc_w < w)
+ wd->max_sc_w = w;
+ if (wd->max_sc_h < h)
+ wd->max_sc_h = h;
+
+ _sizing_eval(data);
+}
- if(!wd->visible) return;
- if(wd->finished) return;
+static void
+_ctxpopup_move(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
+ void *event_info __UNUSED__)
+{
+ Widget_Data *wd;
- evas_object_geometry_get(wd->scroller, 0, 0, &w, &h);
+ wd = elm_widget_data_get(obj);
- if( w != 0 && h !=0 ) {
- if((w <= wd->max_sc_w) && (h <= wd->max_sc_h) ) {
- _sizing_eval(data);
- wd->finished = EINA_TRUE;
- return ;
- }
- }
+ if (!wd)
+ return;
- if(wd->max_sc_w < w ) wd->max_sc_w = w;
- if(wd->max_sc_h < h ) wd->max_sc_h = h;
+ if (wd->visible)
+ evas_object_show(wd->arrow);
- _sizing_eval(data);
+ _scroller_size_reset(wd);
+ _sizing_eval(obj);
}
-static void _ctxpopup_move(void *data, Evas *e, Evas_Object *obj,
- void *event_info)
+static void
+_item_select_cb(void *data, Evas_Object *obj __UNUSED__,
+ const char *emission __UNUSED__, const char *source __UNUSED__)
{
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
- if(wd == NULL) return;
+ Elm_Ctxpopup_Item *item = data;
- if (wd->visible && !wd->position_forced)
- evas_object_show(wd->arrow);
+ if (!item)
+ return;
+ if (item->disabled)
+ return;
- _reset_scroller_size(wd);
- _sizing_eval(obj);
+ if (item->func)
+ item->func((void*) item->base.data, item->base.widget, data);
}
-static void _ctxpopup_item_select(void *data, Evas_Object *obj,
- const char *emission, const char *source)
+static void
+_item_icon_set(Elm_Ctxpopup_Item *item, Evas_Object *icon)
{
- Elm_Ctxpopup_Item *item = (Elm_Ctxpopup_Item *) data;
+ if (item->icon)
+ {
+ elm_widget_sub_object_del(item->base.view, item->icon);
+ evas_object_del(item->icon);
+ }
+
+ item->icon = icon;
+ edje_object_part_swallow(item->base.view, "elm.swallow.icon", item->icon);
+ edje_object_message_signal_process(item->base.view);
+}
- if (!item) return;
- if (item->disabled) return;
+static void
+_item_label_set(Elm_Ctxpopup_Item *item, const char *label)
+{
+ if (!eina_stringshare_replace(&item->label, label))
+ return;
- if (item->func) {
- evas_object_hide(item->base.widget);
- item->func( (void *) item->base.data, item->base.widget, item);
- }
+ edje_object_part_text_set(item->base.view, "elm.text", label);
+ edje_object_message_signal_process(item->base.view);
}
-static void _item_obj_create(Elm_Ctxpopup_Item *item, char *group_name)
+static void
+_item_new(Elm_Ctxpopup_Item *item, char *group_name)
{
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(item->base.widget);
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(item->base.widget);
+ if (!wd)
+ return;
+
+ item->base.view = edje_object_add(evas_object_evas_get(wd->base));
+ _elm_theme_object_set(item->base.widget, item->base.view, "ctxpopup", group_name,
+ elm_widget_style_get(item->base.widget));
+ edje_object_signal_callback_add(item->base.view, "elm,action,click", "",
+ _item_select_cb, item);
+ evas_object_size_hint_align_set(item->base.view, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(item->base.view);
+}
- if (!wd) return;
- item->base.view = edje_object_add(evas_object_evas_get(wd->base));
- _elm_theme_object_set(item->base.widget, item->base.view, "ctxpopup", group_name,
- elm_widget_style_get(item->base.widget));
- edje_object_signal_callback_add(item->base.view, "elm,action,click", "",
- _ctxpopup_item_select, item);
- evas_object_size_hint_align_set(item->base.view, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_size_hint_weight_set(item->base.view, EVAS_HINT_EXPAND,
- EVAS_HINT_EXPAND);
- evas_object_show(item->base.view);
+static void
+_content_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__)
+{
+ elm_ctxpopup_content_unset(data);
}
-static void _content_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
+static void
+_list_del(Widget_Data *wd)
{
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(data);
- Evas_Coord w, h;
+ if (!wd->scr)
+ return;
- if(!wd) return;
+ edje_object_part_unswallow(wd->base, wd->scr);
+ evas_object_del(wd->scr);
+ wd->scr = NULL;
+ wd->box = NULL;
+}
- evas_object_geometry_get(obj, NULL, NULL, &w, &h);
- evas_object_size_hint_min_set(obj, w, h);
-
- if(wd->visible) _sizing_eval(data);
+static void
+_list_new(Evas_Object *obj)
+{
+ Widget_Data *wd;
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
+
+ //scroller
+ wd->scr = elm_scroller_add(obj);
+ elm_object_style_set(wd->scr, "ctxpopup");
+ evas_object_size_hint_align_set(wd->scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE,
+ _scroller_resize, obj);
+ edje_object_part_swallow(wd->base, "elm.swallow.content", wd->scr);
+
+ //box
+ wd->box = elm_box_add(obj);
+ evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND,
+ EVAS_HINT_EXPAND);
+
+ elm_scroller_content_set(wd->scr, wd->box);
+ elm_ctxpopup_horizontal_set(obj, wd->horizontal);
}
-static void _content_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
+/**
+ * Add a new Ctxpopup object to the parent.
+ *
+ * @param parent Parent object
+ * @return New object or @c NULL, if it cannot be created
+ *
+ * @ingroup Ctxpopup
+ */
+EAPI Evas_Object *
+elm_ctxpopup_add(Evas_Object *parent)
{
- elm_ctxpopup_content_unset(data);
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+ Evas_Coord x, y, w, h;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ if (!e)
+ return NULL;
+ obj = elm_widget_add(e);
+ ELM_SET_WIDTYPE(widtype, "ctxpopup");
+ elm_widget_type_set(obj, "ctxpopup");
+ elm_widget_sub_object_add(parent, obj);
+ elm_widget_data_set(obj, wd);
+ elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+ elm_widget_del_hook_set(obj, _del_hook);
+ elm_widget_theme_hook_set(obj, _theme_hook);
+
+ wd->parent = parent;
+
+ //Background
+ wd->bg = edje_object_add(e);
+ elm_widget_sub_object_add(obj, wd->bg);
+ _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg", "default");
+ evas_object_geometry_get(parent, &x, &y, &w, &h);
+ evas_object_move(wd->bg, x, y);
+ evas_object_resize(wd->bg, w, h);
+ edje_object_signal_callback_add(wd->bg, "elm,action,click", "",
+ _bg_clicked_cb, obj);
+
+ //Base
+ wd->base = edje_object_add(e);
+ elm_widget_sub_object_add(obj, wd->base);
+ _elm_theme_object_set(obj, wd->base, "ctxpopup", "base", "default");
+
+ //Arrow
+ wd->arrow = edje_object_add(e);
+ elm_widget_sub_object_add(obj, wd->arrow);
+ _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow", "default");
+
+ wd->dir_priority[0] = ELM_CTXPOPUP_DIRECTION_UP;
+ wd->dir_priority[1] = ELM_CTXPOPUP_DIRECTION_LEFT;
+ wd->dir_priority[2] = ELM_CTXPOPUP_DIRECTION_RIGHT;
+ wd->dir_priority[3] = ELM_CTXPOPUP_DIRECTION_DOWN;
+
+ evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, _parent_resize,
+ obj);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _ctxpopup_show,
+ NULL);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _ctxpopup_hide,
+ NULL);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _ctxpopup_move,
+ NULL);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _ctxpopup_changed_size_hints, NULL);
+ evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+ evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+
+ evas_object_smart_callbacks_descriptions_set(obj, _signals);
+
+ return obj;
}
/**
- * Get the icon object for the given item.
+ * Get the icon object for the given ctxpopup item.
*
- * @param[in] item Ctxpopup item
- * @return Icon object or NULL if the item does not have icon
+ * @param item Ctxpopup item
+ * @return icon object or @c NULL, if the item does not have icon or an error occurred
*
* @ingroup Ctxpopup
*/
EAPI Evas_Object *
-elm_ctxpopup_item_icon_get(Elm_Ctxpopup_Item *item)
+elm_ctxpopup_item_icon_get(const Elm_Ctxpopup_Item *item)
{
- if (!item) return NULL;
- return item->icon;
+ ELM_CTXPOPUP_ITEM_CHECK_RETURN(item, NULL);
+ return item->icon;
}
/**
- * Disable or Enable the scroller for contextual popup.
+ * Sets the side icon associated with the ctxpopup item
*
- * @param[in] obj Ctxpopup object
- * @param[in] disabled disable or enable
+ * Once the icon object is set, a previously set one will be deleted.
+ * You probably don't want, then, to have the <b>same</b> icon object
+ * set for more than one item of the list (when replacing one of its
+ * instances).
+ *
+ * @param item Ctxpopup item
+ * @param icon Icon object to be set
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_scroller_disabled_set(Evas_Object *obj,
- Eina_Bool disabled)
+EAPI void
+elm_ctxpopup_item_icon_set(Elm_Ctxpopup_Item *item, Evas_Object *icon)
{
- ELM_CHECK_WIDTYPE(obj, widtype);
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+ ELM_CTXPOPUP_ITEM_CHECK_RETURN(item);
+
+ Widget_Data *wd;
- if (!wd) return;
- if (wd->scroller_disabled == disabled) return;
+ wd = elm_widget_data_get(item->base.widget);
+ if (!wd)
+ return;
- if (disabled)
- elm_object_scroll_freeze_push(wd->scroller);
- else
- elm_object_scroll_freeze_pop(wd->scroller);
+ _item_icon_set(item, icon);
- wd->scroller_disabled = disabled;
+ if (wd->visible)
+ {
+ _scroller_size_reset(wd);
+ _sizing_eval(item->base.widget);
+ }
}
/**
- * Get the label for the given item.
+ * Get the label object for the given ctxpopup item.
*
- * @param[in] item Ctxpopup item
- * @return Label or NULL if the item does not have label
+ * @param item Ctxpopup item
+ * @return label object or @c NULL, if the item does not have label or an error occured
*
* @ingroup Ctxpopup
*
*/
EAPI const char *
-elm_ctxpopup_item_label_get(Elm_Ctxpopup_Item *item)
+elm_ctxpopup_item_label_get(const Elm_Ctxpopup_Item *item)
{
- if (!item) return NULL;
- return item->label;
+ ELM_CTXPOPUP_ITEM_CHECK_RETURN(item, NULL);
+ return item->label;
}
/**
- * Add a new ctxpopup object to the parent.
- *
- * @param[in] parent window object
- * @return New object or NULL if it cannot be created
+ * (Re)set the label on the given ctxpopup item.
*
+ * @param item Ctxpopup item
+ * @param label String to set as label
+ *
* @ingroup Ctxpopup
*/
-EAPI Evas_Object *
-elm_ctxpopup_add(Evas_Object *parent)
-{
- Evas_Object *obj;
- Evas *e;
- Widget_Data *wd;
- Evas_Coord x, y, w, h;
-
- wd = ELM_NEW(Widget_Data);
- e = evas_object_evas_get(parent);
-
- if (!e)
- return NULL;
-
- obj = elm_widget_add(e);
- ELM_SET_WIDTYPE(widtype, "ctxpopup");
- elm_widget_type_set(obj, "ctxpopup");
- elm_widget_sub_object_add(parent, obj);
- elm_widget_data_set(obj, wd);
- elm_widget_del_pre_hook_set(obj, _del_pre_hook);
- elm_widget_del_hook_set(obj, _del_hook);
- elm_widget_theme_hook_set(obj, _theme_hook);
-
- wd->parent = parent;
-
- //Background
- wd->bg = edje_object_add(e);
- elm_widget_sub_object_add(obj, wd->bg);
- _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg", "default");
- evas_object_geometry_get(parent, &x, &y, &w, &h);
- evas_object_move(wd->bg, x, y);
- evas_object_resize(wd->bg, w, h);
- edje_object_signal_callback_add(wd->bg, "elm,action,click", "",
- _bg_clicked_cb, obj);
-
- //Base
- wd->base = edje_object_add(e);
- elm_widget_sub_object_add(obj, wd->base);
- _elm_theme_object_set(obj, wd->base, "ctxpopup", "base", "default");
-
- //Scroller
- wd->scroller = elm_scroller_add(obj);
- elm_object_style_set(wd->scroller, "ctxpopup");
- evas_object_size_hint_align_set(wd->scroller, EVAS_HINT_FILL,
- EVAS_HINT_FILL);
- elm_scroller_bounce_set(wd->scroller, EINA_FALSE, EINA_TRUE);
- evas_object_event_callback_add(wd->scroller, EVAS_CALLBACK_RESIZE,
- _ctxpopup_scroller_resize, obj);
-
- //Box
- wd->box = elm_box_add(obj);
- evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- elm_scroller_content_set(wd->scroller, wd->box);
- edje_object_part_swallow(wd->base, "elm.swallow.scroller", wd->scroller);
-
- //Arrow
- wd->arrow = edje_object_add(e);
- elm_widget_sub_object_add(obj, wd->arrow);
- _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow", "default");
-
- wd->arrow_priority[0] = ELM_CTXPOPUP_ARROW_DOWN;
- wd->arrow_priority[1] = ELM_CTXPOPUP_ARROW_RIGHT;
- wd->arrow_priority[2] = ELM_CTXPOPUP_ARROW_LEFT;
- wd->arrow_priority[3] = ELM_CTXPOPUP_ARROW_UP;
-
- evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, _parent_resize, obj);
- evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _ctxpopup_show, NULL);
- evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _ctxpopup_hide, NULL);
- evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _ctxpopup_move, NULL);
- evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _ctxpopup_changed_size_hints, NULL);
-
- return obj;
+EAPI void
+elm_ctxpopup_item_label_set(Elm_Ctxpopup_Item *item, const char *label)
+{
+ ELM_CTXPOPUP_ITEM_CHECK_RETURN(item);
+
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(item->base.widget);
+ if (!wd)
+ return;
+
+ _item_label_set(item, label);
+
+ if (wd->visible)
+ {
+ _scroller_size_reset(wd);
+ _sizing_eval(item->base.widget);
+ }
}
/**
- * Clear all items in given ctxpopup object.
+ * Set the Ctxpopup's parent
+ * Set the parent object (it would much probably be the
+ * window that the ctxpopup is in).
*
- * @param[in] obj Ctxpopup object
+ * @param obj The ctxpopup object
+ * @param area The parent to use
+ *
+ * @note elm_ctxpopup_add() will automatically call this function
+ * with its @c parent argument.
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_clear(Evas_Object *obj)
+EAPI void
+elm_ctxpopup_hover_parent_set(Evas_Object *obj, Evas_Object *hover_parent)
{
- ELM_CHECK_WIDTYPE(obj, widtype);
- Eina_List *elist;
- Elm_Ctxpopup_Item *item;
+ ELM_CHECK_WIDTYPE(obj, widtype);
+
+ Widget_Data *wd;
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
- if (!wd) return;
+ _hover_parent_callbacks_del(obj);
- EINA_LIST_FOREACH(wd->items, elist, item)
- {
- if (item->label)
- eina_stringshare_del(item->label);
- if (item->icon)
- evas_object_del(item->icon);
- wd->items = eina_list_remove(wd->items, item);
- free(item);
- }
+ if (hover_parent)
+ {
+ evas_object_event_callback_add(hover_parent, EVAS_CALLBACK_DEL,
+ _hover_parent_del, obj);
+ evas_object_event_callback_add(hover_parent, EVAS_CALLBACK_MOVE,
+ _hover_parent_move, obj);
+ evas_object_event_callback_add(hover_parent, EVAS_CALLBACK_RESIZE,
+ _hover_parent_resize, obj);
+ }
- evas_object_hide(wd->arrow);
- evas_object_hide(wd->base);
+ wd->hover_parent = hover_parent;
}
/**
- * Change the mode to horizontal or vertical.
+ * Get the Ctxpopup's parent
*
- * @param[in] obj Ctxpopup object
- * @param horizontal EINA_TRUE - horizontal mode, EINA_FALSE - vertical mode
+ * @param obj The ctxpopup object
+ *
+ * @see elm_ctxpopup_hover_parent_set() for more information
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
-{
- ELM_CHECK_WIDTYPE(obj, widtype);
- Eina_List *elist;
- Elm_Ctxpopup_Item *item;
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
-
- if (!wd) return;
-
- if (wd->horizontal == horizontal) return;
- wd->horizontal = horizontal;
- if (!horizontal) {
- elm_box_horizontal_set(wd->box, EINA_FALSE);
- elm_scroller_bounce_set(wd->scroller, EINA_FALSE, EINA_TRUE);
- EINA_LIST_FOREACH (wd->items, elist, item)
- edje_object_signal_emit(item->base.view, "elm,state,vertical", "elm");
- }
- else
- {
- elm_box_horizontal_set(wd->box, EINA_TRUE);
- elm_scroller_bounce_set(wd->scroller, EINA_TRUE, EINA_FALSE);
- EINA_LIST_FOREACH(wd->items, elist, item)
- edje_object_signal_emit(item->base.view, "elm,state,horizontal", "elm");
- }
+EAPI Evas_Object *
+elm_ctxpopup_hover_parent_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return NULL;
+
+ return wd->hover_parent;
+}
+
+static void
+_remove_items(Widget_Data *wd)
+{
+ Eina_List *elist;
+ Elm_Ctxpopup_Item *item;
+
+ if (!wd->items)
+ return;
+
+ EINA_LIST_FOREACH(wd->items, elist, item)
+ {
+ if (item->label)
+ eina_stringshare_del(item->label);
+ if (item->icon)
+ evas_object_del(item->icon);
+ wd->items = eina_list_remove(wd->items, item);
+ free(item);
+ }
+
+ wd->items = NULL;
}
/**
- * Get the value of current horizontal mode.
+ * Clear all items in the given ctxpopup object.
*
- * @param[in] obj Ctxpopup object
- * @return EINA_TRUE - horizontal mode, EINA_FALSE - vertical mode.
+ * @param obj Ctxpopup object
*
* @ingroup Ctxpopup
*/
-EAPI Eina_Bool elm_ctxpopup_horizontal_get(Evas_Object *obj)
+EAPI void
+elm_ctxpopup_clear(Evas_Object * obj)
{
- ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
- if (!wd) return EINA_FALSE;
- return wd->horizontal;
+ ELM_CHECK_WIDTYPE(obj, widtype);
+
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd)
+ return;
+
+ _remove_items(wd);
+ _list_del(wd);
}
/**
- * reset the icon on the given item.
+ * Change the ctxpopup's orientation to horizontal or vertical.
*
- * @param[in] item Ctxpopup item
- * @param[in] icon Icon object to be set
+ * @param obj Ctxpopup object
+ * @param horizontal @c EINA_TRUE for horizontal mode, @c EINA_FALSE for vertical
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_item_icon_set(Elm_Ctxpopup_Item *item, Evas_Object *icon)
-{
- Widget_Data *wd;
-
- if (!item) return;
- wd = (Widget_Data *) elm_widget_data_get(item->base.widget);
- if (!wd) return;
- if (item->icon == icon) return;
- if (item->icon) {
- elm_widget_sub_object_del(item->base.view, item->icon);
- evas_object_del(item->icon);
- }
- item->icon = icon;
- edje_object_part_swallow(item->base.view, "elm.swallow.icon", item->icon);
- edje_object_message_signal_process(item->base.view);
-
- if (wd->visible) {
- _reset_scroller_size(wd);
- _sizing_eval(item->base.widget);
- }
+EAPI void
+elm_ctxpopup_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
+
+ wd->horizontal = !!horizontal;
+
+ if ((!wd->scr) && (!wd->box))
+ return;
+
+ if (!horizontal)
+ {
+ elm_box_horizontal_set(wd->box, EINA_FALSE);
+ elm_scroller_bounce_set(wd->scr, EINA_FALSE, EINA_TRUE);
+ }
+ else
+ {
+ elm_box_horizontal_set(wd->box, EINA_TRUE);
+ elm_scroller_bounce_set(wd->scr, EINA_TRUE, EINA_FALSE);
+ }
+
+ if (wd->visible)
+ _sizing_eval(obj);
}
/**
- * reset the label on the given item.
+ * Get the value of current ctxpopup object's orientation.
+ *
+ * @param obj Ctxpopup object
+ * @return @c EINA_TRUE for horizontal mode, @c EINA_FALSE for vertical mode (or errors)
*
- * @param[in] item Ctxpopup item
- * @param[in] label Label to be set
- *
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_item_label_set(Elm_Ctxpopup_Item *item,
- const char *label)
+EAPI Eina_Bool
+elm_ctxpopup_horizontal_get(const Evas_Object *obj)
{
- Widget_Data *wd;
-
- if (!item)
- return;
-
- if (item->label) {
- eina_stringshare_del(item->label);
- item->label = NULL;
- }
+ ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
- item->label = eina_stringshare_add(label);
- edje_object_message_signal_process(item->base.view);
- edje_object_part_text_set(item->base.view, "elm.text", label);
+ Widget_Data *wd;
- wd = elm_widget_data_get(item->base.widget);
- if (!wd)
- return;
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return EINA_FALSE;
- if (wd->visible) {
- _reset_scroller_size(wd);
- _sizing_eval(item->base.widget);
- }
+ return wd->horizontal;
}
/**
- * Add a new item in given ctxpopup object.
+ * Add a new item to a ctxpopup object.
*
- * @param[in] obj Ctxpopup object
- * @param[in] icon Icon to be set
- * @param[in] label Label to be set
- * @param[in] func Callback function to call when this item click is clicked
- * @param[in] data User data for callback function
- * @return Added ctxpopup item
+ * Both a item list and a content could not be set at the same time!
+ * once you set add a item, the previous content will be removed.
+ *
+ * @param obj Ctxpopup object
+ * @param icon Icon to be set on new item
+ * @param label The Label of the new item
+ * @param func Convenience function called when item selected
+ * @param data Data passed to @p func above
+ * @return A handle to the item added or @c NULL, on errors
*
* @ingroup Ctxpopup
*/
EAPI Elm_Ctxpopup_Item *
-elm_ctxpopup_item_add(Evas_Object *obj, Evas_Object *icon, const char *label,
- Evas_Smart_Cb func, void *data)
+elm_ctxpopup_item_append(Evas_Object *obj, const char *label,
+ Evas_Object *icon, Evas_Smart_Cb func,
+ const void *data)
{
- ELM_CHECK_WIDTYPE(obj, widtype)NULL;
- Elm_Ctxpopup_Item *item;
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
- if (!wd)
- return NULL;
+ Widget_Data *wd;
+ Elm_Ctxpopup_Item *item;
- _separator_obj_add(obj);
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return NULL;
- item = ELM_NEW(Elm_Ctxpopup_Item);
- if (!item)
- return NULL;
+ item = elm_widget_item_new(obj, Elm_Ctxpopup_Item);
+ if (!item)
+ return NULL;
- item->func = func;
- item->base.data = data;
- item->base.widget = obj;
- item->separator = EINA_FALSE;
+ //The first item is appended.
+ if (wd->content)
+ evas_object_del(elm_ctxpopup_content_unset(obj));
- if (icon && label)
- _item_obj_create(item, "icon_text_style_item");
- else if (icon)
- _item_obj_create(item, "icon_style_item");
- else
- _item_obj_create(item, "text_style_item");
+ if (!wd->items)
+ _list_new(obj);
- wd->items = eina_list_append(wd->items, item);
- elm_box_pack_end(wd->box, item->base.view);
- elm_ctxpopup_item_icon_set(item, icon);
- elm_ctxpopup_item_label_set(item, label);
+ item->func = func;
+ item->base.data = data;
- return item;
-}
+ if (icon && label)
+ _item_new(item, "icon_text_style_item");
+ else if (label)
+ _item_new(item, "text_style_item");
+ else
+ _item_new(item, "icon_style_item");
-/**
- * Delete the given item in ctxpopup object.
- *
- * @param item[in] Ctxpopup item to be deleted
- *
- * @ingroup Ctxpopup
- */
-EAPI void elm_ctxpopup_item_del(Elm_Ctxpopup_Item *item)
-{
- Widget_Data *wd;
- Evas_Object *obj;
-
- if (!item)
- return;
-
- obj = item->base.widget;
-
- if (item->label)
- eina_stringshare_del(item->label);
- if (item->icon)
- evas_object_del(item->icon);
- if (item->base.view)
- evas_object_del(item->base.view);
-
- wd = (Widget_Data *) elm_widget_data_get(item->base.widget);
- if (wd) {
- _separator_obj_del(wd, item);
- wd->items = eina_list_remove(wd->items, item);
- }
- free(item);
- if (eina_list_count(wd->items) == 0) {
- evas_object_hide(obj);
- }
+ _item_icon_set(item, icon);
+ _item_label_set(item, label);
+ elm_box_pack_end(wd->box, item->base.view);
+ wd->items = eina_list_append(wd->items, item);
+
+ if (wd->visible)
+ {
+ _scroller_size_reset(wd);
+ _sizing_eval(obj);
+ }
+
+ return item;
}
/**
- * Disable or Enable the given item. Once an item is disabled, the click event will be never happend for the item.
+ * Delete the given item in a ctxpopup object.
*
- * @param[in] item Ctxpopup item to be disabled
- * @param[in] disabled EINA_TRUE - disable, EINA_FALSE - enable
+ * @param item Ctxpopup item to be deleted
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_item_disabled_set(Elm_Ctxpopup_Item *item,
- Eina_Bool disabled)
+EAPI void
+elm_ctxpopup_item_del(Elm_Ctxpopup_Item *item)
{
- Widget_Data *wd;
+ ELM_CTXPOPUP_ITEM_CHECK_RETURN(item);
+
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(item->base.widget);
+ if (!wd)
+ return;
- if (!item) return;
- if (disabled == item->disabled) return;
+ if (item->icon)
+ evas_object_del(item->icon);
+ if (item->base.view)
+ evas_object_del(item->base.view);
- wd = (Widget_Data *) elm_widget_data_get(item->base.widget);
-
- if (disabled)
- edje_object_signal_emit(item->base.view, "elm,state,disabled", "elm");
- else
- edje_object_signal_emit(item->base.view, "elm,state,enabled", "elm");
+ eina_stringshare_del(item->label);
- edje_object_message_signal_process(item->base.view);
- item->disabled = disabled;
+ wd->items = eina_list_remove(wd->items, item);
+
+ if (eina_list_count(wd->items) < 1)
+ wd->items = NULL;
+
+ if (wd->visible)
+ _sizing_eval(item->base.widget);
+
+ free(item);
}
/**
- * Disable or Enable background dimmed function
- * @param[in] obj Ctxpopup object
- * @param[in] dimmed EINA_TRUE - disable, EINA_FALSE - enable
+ * Set the ctxpopup item's state as disabled or enabled.
+ *
+ * @param item Ctxpopup item to be enabled/disabled
+ * @param disabled @c EINA_TRUE to disable it, @c EINA_FALSE to enable it
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_screen_dimmed_disabled_set(Evas_Object *obj,
- Eina_Bool disabled)
+EAPI void
+elm_ctxpopup_item_disabled_set(Elm_Ctxpopup_Item *item, Eina_Bool disabled)
{
- ELM_CHECK_WIDTYPE(obj, widtype);
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+ ELM_CTXPOPUP_ITEM_CHECK_RETURN(item);
- if (!wd)
- return;
+ Widget_Data *wd;
- wd->screen_dimmed_disabled = disabled;
+ wd = elm_widget_data_get(item->base.widget);
+ if (!wd)
+ return;
- if (wd->visible) {
- if (!disabled) {
- evas_object_show(wd->bg);
- }
- }
-}
+ if (disabled == item->disabled)
+ return;
-/**
- * Append additional button in ctxpoppup bottom layout.
- * @param[in] obj Ctxpopup object
- * @param[in] label Button label
- * @param[in] func Button clicked event callback function
- * @param[in] data Button clicked event callback function data
- *
- * @ingroup Ctxpopup
- */
-EAPI void elm_ctxpopup_button_append(Evas_Object *obj, const char *label,
- Evas_Smart_Cb func, const void *data)
-{
- ELM_CHECK_WIDTYPE(obj, widtype);
- char buf[256];
- Evas_Object *btn;
- Evas_Coord w, h;
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
-
- if (!wd) return;
- if (!wd->btn_layout) _btn_layout_create(obj);
-
- ++wd->btn_cnt;
- sprintf(buf, "buttons%d", wd->btn_cnt);
- _elm_theme_object_set(obj, wd->btn_layout, "ctxpopup", buf,
- elm_widget_style_get(obj));
-
- btn = elm_button_add(obj);
- elm_object_style_set(btn, "text_only/style1");
- elm_button_label_set(btn, label);
- evas_object_smart_callback_add(btn, "clicked", func, data);
- sprintf(buf, "actionbtn%d", wd->btn_cnt);
- edje_object_part_swallow(wd->btn_layout, buf, btn);
-
- edje_object_part_geometry_get(wd->btn_layout, buf, NULL, NULL, &w, &h);
- evas_object_size_hint_max_set(wd->btn_layout, -1, h);
-
- if (wd->visible) {
- _reset_scroller_size(wd);
- _sizing_eval(obj);
- }
+ if (disabled)
+ edje_object_signal_emit(item->base.view, "elm,state,disabled", "elm");
+ else
+ edje_object_signal_emit(item->base.view, "elm,state,enabled", "elm");
+
+ item->disabled = !!disabled;
}
/**
- * Set the priority of arrow direction
+ * Get the ctxpopup item's disabled/enabled state.
*
- * This functions gives user to set the priority of ctxpopup box showing position.
- *
- * @param[in] obj Ctxpopup object
- * @param[in] first 1st priority of arrow direction
- * @param[in] second 2nd priority of arrow direction
- * @param[in] third 3th priority of arrow direction
- * @param[in] fourth 4th priority of arrow direction
+ * @param item Ctxpopup item to be enabled/disabled
+ * @return disabled @c EINA_TRUE, if disabled, @c EINA_FALSE otherwise
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_arrow_priority_set(Evas_Object *obj,
- Elm_Ctxpopup_Arrow first, Elm_Ctxpopup_Arrow second,
- Elm_Ctxpopup_Arrow third, Elm_Ctxpopup_Arrow fourth)
-{
- ELM_CHECK_WIDTYPE(obj, widtype);
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
-
- if (!wd)
- return;
- wd->arrow_priority[0] = first;
- wd->arrow_priority[1] = second;
- wd->arrow_priority[2] = third;
- wd->arrow_priority[3] = fourth;
+EAPI Eina_Bool
+elm_ctxpopup_item_disabled_get(const Elm_Ctxpopup_Item *item)
+{
+ ELM_CTXPOPUP_ITEM_CHECK_RETURN(item, EINA_FALSE);
+
+ return item->disabled;
}
/**
- * Swallow the user content
+ * Once the content object is set, a previously set one will be deleted.
+ * If you want to keep that old content object, use the
+ * elm_ctxpopup_content_unset() function
+ *
+ * Both a item list and a content could not be set at the same time!
+ * once you set a content, the previous list items will be removed.
*
- * @param[in] obj Ctxpopup object
- * @param[in] content Content to be swallowed
+ * @param obj Ctxpopup object
+ * @param content Content to be swallowed
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_content_set(Evas_Object *obj, Evas_Object *content)
-{
- ELM_CHECK_WIDTYPE(obj, widtype);
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
- Evas_Coord w, h;
- if(!wd || !content) return;
-
- evas_object_event_callback_add(content, EVAS_CALLBACK_DEL, _content_del, obj);
- evas_object_event_callback_add(content, EVAS_CALLBACK_RESIZE, _content_resize, obj);
-
- evas_object_geometry_get(content, NULL, NULL, &w, &h);
-
- if((w > 0) || (h > 0)) evas_object_size_hint_min_set(content, w, h);
-
- edje_object_part_swallow(wd->base, "elm.swallow.content", content);
- elm_widget_sub_object_add(obj, content);
- edje_object_signal_emit(wd->base, "elm,state,content,enable", "elm");
- elm_ctxpopup_scroller_disabled_set(obj, EINA_TRUE);
- wd->content = content;
-
- if(wd->visible) _sizing_eval(obj);
+EAPI void
+elm_ctxpopup_content_set(Evas_Object *obj, Evas_Object *content)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(obj);
+ if ((!wd) || (!content))
+ return;
+
+ if (wd->items)
+ elm_ctxpopup_clear(obj);
+
+ if (wd->content)
+ evas_object_del(wd->content);
+
+ evas_object_event_callback_add(content, EVAS_CALLBACK_DEL, _content_del,
+ obj);
+
+ elm_widget_sub_object_add(obj, content);
+ edje_object_part_swallow(wd->base, "elm.swallow.content", content);
+ edje_object_message_signal_process(wd->base);
+
+ wd->content = content;
+
+ if (wd->visible)
+ _sizing_eval(obj);
}
/**
- * Unswallow the user content
+ * Unset the ctxpopup content
*
- * @param[in] obj Ctxpopup object
- * @return The unswallowed content
+ * Unparent and return the content object which was set for this widget
+ *
+ * @param obj Ctxpopup object
+ * @return The content that was being used
*
* @ingroup Ctxpopup
*/
EAPI Evas_Object *
-elm_ctxpopup_content_unset(Evas_Object *obj)
+elm_ctxpopup_content_unset(Evas_Object *obj)
{
- ELM_CHECK_WIDTYPE(obj, widtype)NULL;
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
- Evas_Object *content;
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+
+ Widget_Data *wd;
+ Evas_Object *content;
- content = wd->content;
-
- if(!content) return NULL;
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return NULL;
- edje_object_part_unswallow(wd->base, content);
- elm_widget_sub_object_del(obj, content);
- evas_object_event_callback_del(content, EVAS_CALLBACK_DEL, _content_del);
- evas_object_event_callback_del(content, EVAS_CALLBACK_RESIZE, _content_resize);
- edje_object_signal_emit(wd->base, "elm,state,content,disable", "elm");
+ content = wd->content;
+ if (!content)
+ return NULL;
- elm_ctxpopup_scroller_disabled_set(obj, EINA_FALSE);
+ edje_object_part_unswallow(wd->base, content);
+ elm_widget_sub_object_del(obj, content);
+ evas_object_event_callback_del(content, EVAS_CALLBACK_DEL, _content_del);
+ edje_object_signal_emit(wd->base, "elm,state,content,disable", "elm");
- if (wd->visible)
- _sizing_eval(obj);
+ wd->content = NULL;
- return content;
+ return content;
}
/**
- * Change the origin of the ctxpopup position.
+ * Set the direction priority of a ctxpopup.
+ * This functions gives a chance to user to set the priority of ctxpopup showing direction.
*
- * Basically, ctxpopup position is computed internally. When user call evas_object_move,
- * Ctxpopup will be showed up with that position which is indicates the arrow point.
- *
- * @param[in] obj Ctxpopup object
- * @param[in] forced EINA_TRUE is left-top. EINA_FALSE is indicates arrow point.
+ * @param obj Ctxpopup object
+ * @param first 1st priority of direction
+ * @param second 2nd priority of direction
+ * @param third 3th priority of direction
+ * @param fourth 4th priority of direction
*
* @ingroup Ctxpopup
*/
-EAPI void elm_ctxpopup_position_forced_set(Evas_Object *obj, Eina_Bool forced)
+EAPI void
+elm_ctxpopup_direction_priority_set(Evas_Object *obj,
+ Elm_Ctxpopup_Direction first,
+ Elm_Ctxpopup_Direction second,
+ Elm_Ctxpopup_Direction third,
+ Elm_Ctxpopup_Direction fourth)
{
- ELM_CHECK_WIDTYPE(obj, widtype);
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd;
- wd->position_forced = forced;
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
- if (forced) evas_object_hide(wd->arrow);
+ wd->dir_priority[0] = first;
+ wd->dir_priority[1] = second;
+ wd->dir_priority[2] = third;
+ wd->dir_priority[3] = fourth;
- if (wd->visible) {
- _reset_scroller_size(wd);
- _sizing_eval(obj);
- }
+ if (wd->visible)
+ _sizing_eval(obj);
}
/**
- * Get the status of the position forced
+ * Get the direction priority of a ctxpopup.
*
- * @param[in] obj Ctxpopup objet
- * @return value of position forced
+ * @param obj Ctxpopup object
+ * @param first 1st priority of direction to be returned
+ * @param second 2nd priority of direction to be returned
+ * @param third 3th priority of direction to be returned
+ * @param fourth 4th priority of direction to be returned
*
+ * @see elm_ctxpopup_direction_priority_set for more information.
+ *
* @ingroup Ctxpopup
*/
-EAPI Eina_Bool elm_ctxpopup_position_forced_get(Evas_Object *obj)
+EAPI void
+elm_ctxpopup_direction_priority_get(Evas_Object *obj,
+ Elm_Ctxpopup_Direction *first,
+ Elm_Ctxpopup_Direction *second,
+ Elm_Ctxpopup_Direction *third,
+ Elm_Ctxpopup_Direction *fourth)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
+
+ if (first)
+ *first = wd->dir_priority[0];
+ if (second)
+ *second = wd->dir_priority[1];
+ if (third)
+ *third = wd->dir_priority[2];
+ if (fourth)
+ *fourth = wd->dir_priority[3];
+}
+
+EAPI void
+elm_ctxpopup_screen_dimmed_disabled_set(Evas_Object *obj,
+ Eina_Bool disabled)
{
- ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
- return wd->position_forced;
+ return ;
+}
+
+EAPI void
+elm_ctxpopup_button_append(Evas_Object *obj, const char *label,
+ Evas_Smart_Cb func, const void *data)
+{
+ return ;
+}
+
+EAPI void
+elm_ctxpopup_position_forced_set(Evas_Object *obj, Eina_Bool forced)
+{
+ return;
+}
+
+EAPI Eina_Bool
+elm_ctxpopup_position_forced_get(const Evas_Object *obj)
+{
+ return EINA_FALSE;
}
EAPI Elm_Ctxpopup_Item *
elm_ctxpopup_icon_add(Evas_Object *obj, Evas_Object *icon, Evas_Smart_Cb func,
- void *data)
+ void *data)
{
- return elm_ctxpopup_item_add(obj, icon, NULL, func, data);
+ return elm_ctxpopup_item_append(obj, NULL, icon, func, data);
}
EAPI Elm_Ctxpopup_Item *
elm_ctxpopup_label_add(Evas_Object *obj, const char *label, Evas_Smart_Cb func,
- void *data)
+ void *data)
{
- return elm_ctxpopup_item_add(obj, NULL, label, func, data);
+ return elm_ctxpopup_item_add(obj, label, NULL, func, data);
}
-/**
- * Set the area of ctxpopup will show up. Ctxpopup will not be out of this area.
- * The responsibility of the area object is to user.
- *
- * @param[in] obj Ctxpopup objet
- * @param[in] area area object
- *
- * @ingroup Ctxpopup
- */
-EAPI void elm_ctxpopup_area_set(Evas_Object *obj, Evas_Object *area)
-{
- ELM_CHECK_WIDTYPE(obj, widtype);
- Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
-
- _delete_area_rect_callbacks(wd);
-
- if (area) {
- evas_object_event_callback_add(area, EVAS_CALLBACK_DEL, _area_rect_del,
- obj);
- evas_object_event_callback_add(area, EVAS_CALLBACK_MOVE,
- _area_rect_move, obj);
- evas_object_event_callback_add(area, EVAS_CALLBACK_RESIZE,
- _area_rect_resize, obj);
- wd->area_rect = area;
- }
+EAPI void
+elm_ctxpopup_area_set(Evas_Object *obj, Evas_Object *area)
+{
+ elm_ctxpopup_hover_parent_set(obj, area);
+}
+
+EAPI void
+elm_ctxpopup_scroller_disabled_set(Evas_Object *obj, Eina_Bool disabled)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+
+ Widget_Data *wd;
+
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ return;
+
+ if (disabled)
+ elm_object_scroll_freeze_push(wd->scr);
+ else
+ elm_object_scroll_freeze_pop(wd->scr);
+}
+
+EAPI Elm_Ctxpopup_Item *
+elm_ctxpopup_item_add(Evas_Object *obj, Evas_Object *icon, const char *label,
+ Evas_Smart_Cb func, void *data)
+{
+ return elm_ctxpopup_item_append(obj, label, icon, func, data);
}
+
+EAPI void
+elm_ctxpopup_arrow_priority_set(Evas_Object *obj,
+ Elm_Ctxpopup_Arrow first, Elm_Ctxpopup_Arrow second,
+ Elm_Ctxpopup_Arrow third, Elm_Ctxpopup_Arrow fourth)
+{
+ elm_ctxpopup_direction_priority_set(obj, first, second, third, fourth);
+}
+