Evas_Object *box;
Evas_Object *arrow;
Evas_Object *scroller;
+ Evas_Object *bg;
Eina_List *items;
- Evas_Coord x, y;
- Arrow_Direction last_arrow_dir;
Eina_Bool scroller_disabled:1;
Eina_Bool horizontal:1;
+ Eina_Bool arrow_disabled:1;
};
static const char *widtype = NULL;
static void _del_pre_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object *obj);
-static void _hover_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _bg_clicked_cb(void *data, Evas_Object *obj, void *event_info);
static void _parent_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _parent_move(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 _separator_obj_add(Evas_Object *obj);
static void _separator_obj_del(Widget_Data *wd, Elm_Ctxpopup_Item *remove_item);
static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
-static Arrow_Direction _calc_best_geometry(Widget_Data *wd, Evas_Coord_Rectangle *rect);
-static void _arrow_obj_add(Evas_Object *obj, const char *group_name);
+static Arrow_Direction _calc_base_geometry(Evas_Object *obj, Evas_Coord_Rectangle *rect);
+//static void _arrow_obj_add(Evas_Object *obj, const char *group_name);
static void _update_arrow_obj(Evas_Object *obj, Arrow_Direction arrow_dir);
-static Evas_Coord _adjust_arrow_pos_x(Widget_Data *wd);
-static Evas_Coord _adjust_arrow_pos_y(Widget_Data *wd);
-static void _shift_geometry_by_arrow(Evas_Object *arrow, Arrow_Direction arrow_dir, Evas_Coord_Rectangle *rect);
+static void _shift_base_by_arrow(Evas_Object *arrow, Arrow_Direction arrow_dir, Evas_Coord_Rectangle *rect);
static void
_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
return;
}
- _elm_theme_object_set(obj, item->obj, "ctxpopup", "seperator",
+ _elm_theme_object_set(obj, item->obj, "ctxpopup", "separator",
elm_widget_style_get(obj));
if (wd->horizontal)
else
edje_object_signal_emit(item->obj, "elm,state,vertical", "elm");
- evas_object_show(item->obj);
+ evas_object_show(item->obj);
item->separator = EINA_TRUE;
elm_box_pack_end(wd->box, item->obj);
wd->items = eina_list_append(wd->items, item);
#define BOX_HALF_W (box_w/2)
#define BOX_HALF_H (box_h/2)
-#define ADJUST_POS_X() do { \
- x = wd->x - (box_w/2); \
+#define ADJUST_POS_X(x) do { \
+ x = x - (box_w/2); \
if(x < x1) { \
x = x1; \
}else if(x + box_w > WORLD_PARENT_W) { \
} \
}while(0)
-#define ADJUST_POS_Y() do { \
- y = wd->y - (box_h/2); \
+#define ADJUST_POS_Y(y) do { \
+ y = y - (box_h/2); \
if(y < y1) { \
y = y1; \
}else if(y + box_h > WORLD_PARENT_H) \
}while(0)
static Arrow_Direction
-_calc_best_geometry(Widget_Data *wd, Evas_Coord_Rectangle *rect)
+_calc_base_geometry(Evas_Object *obj, Evas_Coord_Rectangle *rect)
{
- Evas_Coord x, y;
+ Widget_Data *wd;
+ Evas_Coord x, y;
Evas_Coord parent_x, parent_y, parent_w, parent_h;
Evas_Coord box_w, box_h;
Arrow_Direction arrow_dir;
Evas_Coord x1, x2, y1, y2;
- int available_direction[4] = { 1, 1, 1, 1 };
- int idx = 0;
+ int idx;
Evas_Coord finger_size;
- Evas_Coord arrow_size_w, arrow_size_h;
Evas_Coord max_width_size, max_height_size;
+ Evas_Coord arrow_w=0, arrow_h=0;
+ int available_direction[4] = { 1, 1, 1, 1 };
+
+ wd = elm_widget_data_get(obj);
if ((!wd) || (!rect))
- return arrow_dir;
- x = wd->x;
- y = wd->y;
- evas_object_geometry_get(wd->parent, &parent_x, &parent_y, &parent_w,
+ return NONE_ARROW;
+
+ evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+
+ evas_object_geometry_get(wd->parent, &parent_x, &parent_y, &parent_w,
&parent_h);
evas_object_geometry_get(wd->box, NULL, NULL, &box_w, &box_h);
box_w = max_width_size;
finger_size = elm_finger_size_get();
- edje_object_size_min_calc(wd->arrow, &arrow_size_w, &arrow_size_h);
+ if (!wd->arrow_disabled)
+ edje_object_size_min_calc(wd->arrow, &arrow_w, &arrow_h);
+
//Phase 1: Define x, y Segments and find invalidated direction.
//Left
x1 = x - box_w;
- if ((x1 - arrow_size_w - finger_size) < parent_x)
+ if ((x1 - arrow_w - finger_size) < parent_x)
{
x1 = parent_x;
available_direction[RIGHT_ARROW] = 0;
//Right
x2 = x + box_w;
- if (x2 + arrow_size_w + finger_size > WORLD_PARENT_W)
+ if (x2 + arrow_w + finger_size > WORLD_PARENT_W)
{
x2 = WORLD_PARENT_W - box_w;
available_direction[LEFT_ARROW] = 0;
//Top
y1 = y - box_h;
- if (y1 - arrow_size_h - finger_size < parent_y)
+ if (y1 - arrow_h - finger_size < parent_y)
{
y1 = parent_y;
available_direction[BOTTOM_ARROW] = 0;
}
//Bottom
y2 = y + box_h;
- if (y2 + arrow_size_h + finger_size > WORLD_PARENT_H)
+ if (y2 + arrow_h + finger_size > WORLD_PARENT_H)
{
y2 = WORLD_PARENT_H - box_h;
available_direction[TOP_ARROW] = 0;
//ADDITIONAL OPTION: Phase 2: Determine Direction Priority ?
-//Phase 3: adjust geometry information.
+//Phase 3: adjust base geometry.
for (idx = 0; idx < 4; ++idx)
{
if (available_direction[idx] == 0)
switch (idx)
{
case BOTTOM_ARROW:
- ADJUST_POS_X();
- y = wd->y - box_h - finger_size;
+ ADJUST_POS_X(x);
+ y -= (box_h + finger_size);
arrow_dir = BOTTOM_ARROW;
break;
case RIGHT_ARROW:
- ADJUST_POS_Y();
- x = wd->x - box_w - finger_size;
+ ADJUST_POS_Y(y);
+ x -= (box_w + finger_size);
arrow_dir = RIGHT_ARROW;
break;
case LEFT_ARROW:
- ADJUST_POS_Y();
- x = wd->x + finger_size;
+ ADJUST_POS_Y(y);
+ x += finger_size;
arrow_dir = LEFT_ARROW;
break;
case TOP_ARROW:
- ADJUST_POS_X();
- y = wd->y + finger_size;
+ ADJUST_POS_X(x);
+ y += finger_size;
arrow_dir = TOP_ARROW;
break;
default:
return arrow_dir;
}
-static Evas_Coord
-_adjust_arrow_pos_x(Widget_Data * wd)
-{
- Evas_Coord parent_x, parent_w;
- Evas_Coord arrow_x;
- Evas_Coord arrow_size;
- Evas_Coord half_arrow_size;
-
- if (!wd ) return 0;
-
- edje_object_size_max_get(wd->arrow, &arrow_size, NULL);
- half_arrow_size = (arrow_size * 0.5);
- evas_object_geometry_get(wd->parent, &parent_x, NULL, &parent_w, NULL);
- arrow_x = wd->x;
-
- if (arrow_x - half_arrow_size < parent_x)
- arrow_x = parent_x + half_arrow_size;
- else if (wd->x + arrow_size > WORLD_PARENT_W)
- arrow_x = WORLD_PARENT_W - half_arrow_size;
-
- return arrow_x;
-}
-
-static Evas_Coord
-_adjust_arrow_pos_y(Widget_Data *wd)
-{
- Evas_Coord parent_y, parent_h;
- Evas_Coord arrow_y;
- Evas_Coord arrow_size;
- Evas_Coord half_arrow_size;
-
- if (!wd) return 0;
-
- edje_object_size_max_get(wd->arrow, &arrow_size, NULL);
- half_arrow_size = (arrow_size * 0.5);
-
- evas_object_geometry_get(wd->parent, NULL, &parent_y, NULL, &parent_h);
-
- arrow_y = wd->y;
-
- if (arrow_y - half_arrow_size < parent_y)
- arrow_y = (parent_y + half_arrow_size);
- else if (wd->y + half_arrow_size > WORLD_PARENT_H)
- arrow_y = (WORLD_PARENT_H - half_arrow_size);
-
- return arrow_y;
-}
static void
_update_arrow_obj(Evas_Object *obj, Arrow_Direction arrow_dir)
{
- Evas_Coord arrow_x, arrow_y;
-
- Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Coord x, y;
+ Evas_Coord arrow_x, arrow_y, arrow_w, arrow_h;
+ Widget_Data *wd = elm_widget_data_get(obj);
if (!wd)
return;
- arrow_x = wd->x;
- arrow_y = wd->y;
+ evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+
+ edje_object_size_min_calc(wd->arrow, &arrow_w, &arrow_h);
+ evas_object_resize( wd->arrow, arrow_w, arrow_h );
switch (arrow_dir)
{
case LEFT_ARROW:
{
- if (wd->last_arrow_dir != LEFT_ARROW)
- {
- _arrow_obj_add(obj, "left_arrow");
- _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "left_arrow",
- elm_widget_style_get(obj));
- wd->last_arrow_dir = LEFT_ARROW;
- }
- arrow_y = _adjust_arrow_pos_y(wd);
- arrow_x += elm_finger_size_get();
+ edje_object_signal_emit(wd->arrow, "elm,state,left", "elm");
+ arrow_y = (y - (arrow_h*0.5));
+ arrow_x = (x + elm_finger_size_get());
break;
}
case RIGHT_ARROW:
{
- if (wd->last_arrow_dir != RIGHT_ARROW)
- {
- _arrow_obj_add(obj, "right_arrow");
- _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "right_arrow",
- elm_widget_style_get(obj));
- wd->last_arrow_dir = RIGHT_ARROW;
- }
- arrow_y = _adjust_arrow_pos_y(wd);
- arrow_y = _adjust_arrow_pos_y(wd);
- arrow_x -= elm_finger_size_get();
+ edje_object_signal_emit(wd->arrow, "elm,state,right", "elm");
+ arrow_y = (y - (arrow_h*0.5));
+ arrow_x = (x - elm_finger_size_get() - arrow_w);
break;
}
case TOP_ARROW:
{
- if (wd->last_arrow_dir != TOP_ARROW)
- {
- _arrow_obj_add(obj, "top_arrow");
- _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "top_arrow",
- elm_widget_style_get(obj));
- wd->last_arrow_dir = TOP_ARROW;
- }
- arrow_x = _adjust_arrow_pos_x(wd);
- arrow_y += elm_finger_size_get();
+ edje_object_signal_emit(wd->arrow, "elm,state,top", "elm");
+ arrow_x = (x - (arrow_w*0.5));
+ arrow_y = (y + elm_finger_size_get());
break;
}
case BOTTOM_ARROW:
{
- if (wd->last_arrow_dir != BOTTOM_ARROW)
- {
- _arrow_obj_add(obj, "bottom_arrow");
- _elm_theme_object_set(obj, wd->arrow, "ctxpopup",
- "bottom_arrow",
- elm_widget_style_get(obj));
- wd->last_arrow_dir = BOTTOM_ARROW;
- }
- arrow_x = _adjust_arrow_pos_x(wd);
- arrow_y -= elm_finger_size_get();
+ edje_object_signal_emit(wd->arrow, "elm,state,bottom", "elm");
+ arrow_x = (x - (arrow_w*0.5));
+ arrow_y = (y - elm_finger_size_get() - arrow_h);
break;
}
default:
break;
}
-
- evas_object_move(wd->arrow, arrow_x, arrow_y);
+
+ evas_object_move(wd->arrow, arrow_x, arrow_y);
}
static void
Widget_Data *wd;
Eina_List *elist;
Elm_Ctxpopup_Item *item;
- Evas_Coord_Rectangle rect;
+ Evas_Coord_Rectangle rect = {0,0,1,1};
wd = (Widget_Data *) elm_widget_data_get(obj);
if ((!wd) || (!wd->parent))
_item_sizing_eval(item);
}
- Arrow_Direction arrow_dir = _calc_best_geometry(wd, &rect);
- _update_arrow_obj(obj, arrow_dir);
- _shift_geometry_by_arrow(wd->arrow, arrow_dir, &rect);
+ Arrow_Direction arrow_dir = _calc_base_geometry(obj, &rect);
+ fprintf( stderr, "%d %d %d %d %d\n", arrow_dir, rect.x, rect.y, rect.w, rect.h );
- fprintf( stderr, "%d %d %d %d\n", rect.x, rect.y, rect.w, rect.h );
+ if(!wd->arrow_disabled)
+ {
+ _update_arrow_obj(obj, arrow_dir);
+ _shift_base_by_arrow(wd->arrow, arrow_dir, &rect);
+ }
evas_object_move(wd->scroller, rect.x, rect.y);
evas_object_resize(wd->scroller, rect.w, rect.h);
}
static void
-_shift_geometry_by_arrow(Evas_Object * arrow, Arrow_Direction arrow_dir,
- Evas_Coord_Rectangle * rect)
+_shift_base_by_arrow(Evas_Object *arrow, Arrow_Direction arrow_dir,
+ Evas_Coord_Rectangle *rect)
{
- Evas_Coord arrow_size_w, arrow_size_h;
-
- edje_object_size_min_calc(arrow, &arrow_size_w, &arrow_size_h);
+ Evas_Coord arrow_w, arrow_h;
+ edje_object_size_min_calc(arrow, &arrow_w, &arrow_h);
+ fprintf( stderr, "arrow size - %d %d\n", arrow_w, arrow_h );
switch (arrow_dir)
{
case LEFT_ARROW:
- rect->x += arrow_size_w;
+ rect->x += arrow_w;
break;
case RIGHT_ARROW:
- rect->x -= arrow_size_w;
+ rect->x -= arrow_w;
break;
case TOP_ARROW:
- rect->y += arrow_size_h;
+ rect->y += arrow_h;
break;
case BOTTOM_ARROW:
- rect->y -= arrow_size_h;
+ rect->y -= arrow_h;
break;
case NONE_ARROW:
- fprintf(stderr, "NONE ARROW?\n");
break;
}
}
if (!wd) return;
evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE,
_parent_resize, obj);
+ evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE, _parent_move, obj);
}
static void
if (!wd) return;
elm_ctxpopup_clear(obj);
+
free(wd);
}
static void
-_hover_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+_bg_clicked_cb(void *data, Evas_Object *obj, void *event_info)
{
evas_object_hide(data);
- evas_object_smart_callback_call(data, "ctxpopup,hide", NULL);
}
+static void
+_parent_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = (Widget_Data *) data;
+ if (!wd) return;
+
+ Evas_Coord x, y;
+ evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+ evas_object_move(wd->bg, x, y);
+
+ _sizing_eval(data);
+}
static void
_parent_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
- _sizing_eval(data);
+ Widget_Data *wd = (Widget_Data *) data;
+ if (!wd) return;
+
+ Evas_Coord w, h;
+ evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+ evas_object_move(wd->bg, w, h);
+
+ _sizing_eval(data);
}
static void
if (!wd) return;
if (eina_list_count(wd->items) < 1) return;
- evas_object_show(wd->arrow);
- evas_object_show(wd->base);
- fprintf( stderr, "show!\n" );
+
+ if(!wd->arrow_disabled) evas_object_show(wd->arrow);
+ evas_object_show(wd->bg);
+ evas_object_show(wd->base);
+
}
static void
if (!wd) return;
evas_object_hide(wd->arrow);
- evas_object_hide(wd->base);
+ evas_object_hide(wd->bg);
+ evas_object_hide(wd->base);
}
static void
static void
_ctxpopup_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
- Evas_Coord x, y, w, h;
-
Widget_Data *wd = (Widget_Data *) data;
if (!wd)
return;
- evas_object_geometry_get(obj, &x, &y, &w, &h);
- wd->x = x;
- wd->y = y;
- _sizing_eval(obj);
+
+ _sizing_eval(obj);
}
static void
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);
elm_widget_theme_hook_set(obj, _theme_hook);
wd->parent = parent;
- wd->last_arrow_dir = NONE_ARROW;
-
+ wd->scroller_disabled = EINA_FALSE;
+ wd->arrow_disabled = EINA_FALSE;
+
+ //Background
+ wd->bg = edje_object_add(e);
+ elm_widget_sub_object_add(obj, wd->bg);
+ _elm_theme_object_set(obj, wd->bg, "ctxpopup", "bg",
+ elm_widget_style_get(obj));
+ 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_theme_object_set(obj, wd->base, "ctxpopup", "base",
+ elm_widget_sub_object_add(obj, wd->base);
+ _elm_theme_object_set(obj, wd->base, "ctxpopup", "base",
elm_widget_style_get(obj));
//Scroller
wd->scroller = elm_scroller_add(obj);
- wd->scroller_disabled = EINA_FALSE;
- elm_object_style_set(wd->scroller, "ctxpopup_vbar");
+ elm_object_style_set(wd->scroller, "ctxpopup_vbar");
elm_scroller_content_min_limit(wd->scroller, EINA_TRUE, EINA_TRUE);
elm_scroller_policy_set(wd->scroller, ELM_SCROLLER_POLICY_OFF,
ELM_SCROLLER_POLICY_ON);
elm_scroller_bounce_set(wd->scroller, EINA_FALSE, EINA_TRUE);
-
edje_object_part_swallow(wd->base, "elm.swallow.content", wd->scroller);
+ evas_object_event_callback_add(wd->scroller, EVAS_CALLBACK_RESIZE,
+ _ctxpopup_scroller_resize, obj);
//Box
wd->box = elm_box_add(obj);
elm_scroller_content_set(wd->scroller, wd->box);
+ //Arrow
+ wd->arrow = edje_object_add(e);
+ elm_widget_sub_object_add(obj, wd->arrow);
+ _elm_theme_object_set(obj, wd->arrow, "ctxpopup", "arrow",
+ elm_widget_style_get(obj));
+
+ evas_object_event_callback_add(parent, EVAS_CALLBACK_MOVE, _parent_move, obj);
evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, _parent_resize,
obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _ctxpopup_show, wd);
evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _ctxpopup_hide, wd);
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _ctxpopup_move, wd);
- evas_object_event_callback_add(wd->scroller, EVAS_CALLBACK_RESIZE,
- _ctxpopup_scroller_resize, obj);
_sizing_eval(obj);
return obj;
edje_object_message_signal_process(item->obj);
item->disabled = disabled;
}
+
+/**
+ * Disable or Enable arrow.
+ * @param obj Ctxpopup object
+ * @param disabled EINA_TRUE - disable, EINA_FALSE - enable
+ *
+ * @ingroup Ctxpopup
+ */
+EAPI void
+elm_ctxpopup_arrow_disabled_set(Evas_Object* obj, Eina_Bool disabled)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+
+ Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+ if(!wd) return;
+
+ if(wd->arrow_disabled == disabled) return;
+
+ wd->arrow_disabled = disabled;
+
+ if(disabled) evas_object_hide(wd->arrow);
+ else evas_object_show(wd->arrow);
+
+}