diff --git a/ChangeLog b/ChangeLog index 85c6c8bd93..6a42020c7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-07-19 Cedric Bail + + * Edje: add threshold to draggable part. + 2013-07-18 Mike Blumenkrantz * Ecore-X: add ECORE_X_SYNC env variable for xlib backend diff --git a/NEWS b/NEWS index f323149450..446aeb09ad 100644 --- a/NEWS +++ b/NEWS @@ -120,6 +120,7 @@ Additions: - Add EDJE_INPUT_PANEL_LAYOUT_DATETIME layout - support edc proxy.source_visible, proxy.source_clip - support edc map color set + - Add threshold support to Edje draggable part. * Eeze: - Add a dummy libmount replacement for when libmount is not there. * Ecore_Con: diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index ad645fa2f6..0c1905c5ce 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -234,6 +234,7 @@ static void st_collections_group_parts_part_access(void); static void st_collections_group_parts_part_dragable_x(void); static void st_collections_group_parts_part_dragable_y(void); static void st_collections_group_parts_part_dragable_confine(void); +static void st_collections_group_parts_part_dragable_threshold(void); static void st_collections_group_parts_part_dragable_events(void); /* box and table items share these */ @@ -512,6 +513,7 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.dragable.x", st_collections_group_parts_part_dragable_x}, {"collections.group.parts.part.dragable.y", st_collections_group_parts_part_dragable_y}, {"collections.group.parts.part.dragable.confine", st_collections_group_parts_part_dragable_confine}, + {"collections.group.parts.part.dragable.threshold", st_collections_group_parts_part_dragable_threshold}, {"collections.group.parts.part.dragable.events", st_collections_group_parts_part_dragable_events}, {"collections.group.parts.part.entry_mode", st_collections_group_parts_part_entry_mode}, {"collections.group.parts.part.select_mode", st_collections_group_parts_part_select_mode}, @@ -2719,6 +2721,7 @@ st_collections_group_inherit(void) ep->nested_children_count = ep2->nested_children_count; data_queue_copied_part_lookup(pc, &(ep2->dragable.confine_id), &(ep->dragable.confine_id)); + data_queue_copied_part_lookup(pc, &(ep2->dragable.threshold_id), &(ep->dragable.threshold_id)); data_queue_copied_part_lookup(pc, &(ep2->dragable.event_id), &(ep->dragable.event_id)); epp = (Edje_Part_Parser *)ep; @@ -3353,6 +3356,7 @@ edje_cc_handlers_part_make(void) ep->access = 0; ep->clip_to_id = -1; ep->dragable.confine_id = -1; + ep->dragable.threshold_id = -1; ep->dragable.event_id = -1; ep->items = NULL; ep->nested_children_count = 0; @@ -4227,6 +4231,7 @@ st_collections_group_parts_part_access(void) .. dragable { confine: "another part"; + threshold: "another part"; events: "another dragable part"; x: 0 0 0; y: 0 0 0; @@ -4319,6 +4324,34 @@ st_collections_group_parts_part_dragable_confine(void) } } +/** + @page edcref + @property + threshold + @parameters + [another part's name] + @effect + When set, the movement of the dragged part can only start when it get + moved enough to be outside of the threshold part. + @endproperty +*/ +static void +st_collections_group_parts_part_dragable_threshold(void) +{ + Edje_Part_Collection *pc; + + check_arg_count(1); + + pc = eina_list_data_get(eina_list_last(edje_collections)); + { + char *name; + + name = parse_str(0); + data_queue_part_lookup(pc, name, &(current_part->dragable.threshold_id)); + free(name); + } +} + /** @page edcref @property diff --git a/src/examples/edje/Makefile.am b/src/examples/edje/Makefile.am index fc3ec351b1..5d5dfa8589 100644 --- a/src/examples/edje/Makefile.am +++ b/src/examples/edje/Makefile.am @@ -11,6 +11,7 @@ endif #put here all EDCs one needs to the examples EDCS = \ +edje-threshold.edc \ animations2.edc \ animations.edc \ basic2.edc \ diff --git a/src/examples/edje/edje-threshold.edc b/src/examples/edje/edje-threshold.edc new file mode 100644 index 0000000000..1216c2bbdd --- /dev/null +++ b/src/examples/edje/edje-threshold.edc @@ -0,0 +1,87 @@ +collections { + group { + name: "main"; + parts { + part { + type: RECT; + name: background; + mouse_events: 0; + description { + color: 0 0 0 255; + } + } + part { + type: RECT; + name: "area/vertical"; + mouse_events: 0; + description { + color: 255 0 0 255; + align: 0.5 0; + min: 20 30; + max: 20 -1; + } + } + part { + type: RECT; + name: "area/horizontal"; + mouse_events: 0; + description { + color: 255 0 0 255; + align: 0 0.5; + min: 30 20; + max: -1 20; + } + } + part { + type: RECT; + name: "threshold/horizontal"; + mouse_events: 0; + description { + color: 0 0 255 255; + rel1 { + to: "drag/horizontal"; + offset: -13 -13; + } + rel2 { + to: "drag/horizontal"; + offset: +12 +12; + } + } + } + part { + type: RECT; + name: "drag/horizontal"; + mouse_events: 1; + dragable { + confine: "area/horizontal"; + threshold: "threshold/horizontal"; + x: 1 1 0; + y: 0 0 0; + } + description { + aspect: 1 1; + color: 0 255 0 255; + min: 20 20; + max: 20 20; + } + } + part { + type: RECT; + name: "drag/vertical"; + mouse_events: 1; + dragable { + confine: "area/vertical"; + threshold: "threshold/horizontal"; + x: 0 0 0; + y: 1 1 0; + } + description { + aspect: 1 1; + color: 0 255 255 255; + min: 20 20; + max: 20 20; + } + } + } + } +} diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index d75c35046c..a11fb7c057 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -8,7 +8,8 @@ static void _edje_part_recalc_single(Edje *ed, Edje_Real_Part *ep, Edje_Real_Part *center, Edje_Real_Part *light, Edje_Real_Part *persp, Edje_Real_Part *rel1_to_x, Edje_Real_Part *rel1_to_y, Edje_Real_Part *rel2_to_x, Edje_Real_Part *rel2_to_y, - Edje_Real_Part *confine_to, Edje_Calc_Params *params, + Edje_Real_Part *confine_to, Edje_Real_Part *threshold, + Edje_Calc_Params *params, Evas_Coord mmw, Evas_Coord mmh, FLOAT_T pos); @@ -775,6 +776,15 @@ _edje_part_dragable_calc(Edje *ed EINA_UNUSED, Edje_Real_Part *ep, FLOAT_T *x, F { if (ep->drag) { + Eina_Bool tx = EINA_FALSE; + Eina_Bool ty = EINA_FALSE; + + if (ep->drag->threshold) + { + // Check if we are in the threshold or not and cancel the movement. + tx = ep->drag->threshold_x && ep->drag->threshold_started_x; + ty = ep->drag->threshold_y && ep->drag->threshold_started_y; + } if (ep->drag->confine_to) { FLOAT_T dx, dy, dw, dh; @@ -795,15 +805,15 @@ _edje_part_dragable_calc(Edje *ed EINA_UNUSED, Edje_Real_Part *ep, FLOAT_T *x, F if (dh != ZERO) dy = DIV(dy, dh); else dy = ZERO; - if (x) *x = dx; - if (y) *y = dy; + if (x) *x = tx ? ep->drag->x : dx; + if (y) *y = ty ? ep->drag->y : dy; return ret; } else { - if (x) *x = ADD(FROM_INT(ep->drag->tmp.x), ep->drag->x); - if (y) *y = ADD(FROM_INT(ep->drag->tmp.y), ep->drag->y); + if (x) *x = tx ? ep->drag->x : ADD(FROM_INT(ep->drag->tmp.x), ep->drag->x); + if (y) *y = ty ? ep->drag->y : ADD(FROM_INT(ep->drag->tmp.y), ep->drag->y); return 0; } } @@ -1798,9 +1808,57 @@ _edje_part_recalc_single_max(Edje_Part_Description_Common *desc, _edje_part_recalc_single_max_length(desc->align.y, ¶ms->eval.y, ¶ms->eval.h, maxh); } +static void +_edje_part_recalc_single_drag_threshold(Edje_Real_Part *ep, + Edje_Real_Part *threshold, + Edje_Calc_Params *params) +{ + if (threshold) + { + if (ep->drag->threshold_started_x && + threshold->x < TO_INT(params->eval.x) && + TO_INT(params->eval.x) + TO_INT(params->eval.w) < threshold->x + threshold->w) + { + // Cancel movement to previous position due to our presence inside the threshold + params->eval.x = FROM_INT(params->req_drag.x); + params->eval.w = FROM_INT(params->req_drag.w); + ep->drag->threshold_x = EINA_TRUE; + } + else + { + params->req_drag.x = TO_INT(params->eval.x); + params->req_drag.w = TO_INT(params->eval.w); + ep->drag->threshold_started_x = EINA_FALSE; + } + if (ep->drag->threshold_started_y && + threshold->y < TO_INT(params->eval.y) && + TO_INT(params->eval.y) + TO_INT(params->eval.h) < threshold->y + threshold->h) + { + // Cancel movement to previous position due to our presence inside the threshold + params->eval.y = FROM_INT(params->req_drag.y); + params->eval.h = FROM_INT(params->req_drag.h); + ep->drag->threshold_y = EINA_TRUE; + } + else + { + params->req_drag.y = TO_INT(params->eval.y); + params->req_drag.h = TO_INT(params->eval.h); + ep->drag->threshold_started_y = EINA_FALSE; + } + } + else + { + params->req_drag.x = TO_INT(params->eval.x); + params->req_drag.w = TO_INT(params->eval.w); + params->req_drag.y = TO_INT(params->eval.y); + params->req_drag.h = TO_INT(params->eval.h); + } +} + static void _edje_part_recalc_single_drag(Edje_Real_Part *ep, Edje_Real_Part *confine_to, + Edje_Real_Part *threshold, Edje_Calc_Params *params, int minw, int minh, int maxw, int maxh) @@ -1833,8 +1891,6 @@ _edje_part_recalc_single_drag(Edje_Real_Part *ep, params->eval.x = FROM_INT(confine_to->x + ((offset / step) * step)); } - params->req_drag.x = TO_INT(params->eval.x); - params->req_drag.w = TO_INT(params->eval.w); v = SCALE(ep->drag->size.y, confine_to->h); @@ -1856,8 +1912,8 @@ _edje_part_recalc_single_drag(Edje_Real_Part *ep, params->eval.y = FROM_INT(confine_to->y + ((offset / step) * step)); } - params->req_drag.y = TO_INT(params->eval.y); - params->req_drag.h = TO_INT(params->eval.h); + + _edje_part_recalc_single_drag_threshold(ep, threshold, params); /* limit to confine */ if (params->eval.x < FROM_INT(confine_to->x)) @@ -1881,12 +1937,9 @@ _edje_part_recalc_single_drag(Edje_Real_Part *ep, { /* simple dragable params */ params->eval.x = ADD(ADD(params->eval.x, ep->drag->x), FROM_INT(ep->drag->tmp.x)); - params->req_drag.x = FROM_INT(params->eval.x); - params->req_drag.w = FROM_INT(params->eval.w); - params->eval.y = ADD(ADD(params->eval.y, ep->drag->y), FROM_INT(ep->drag->tmp.y)); - params->req_drag.y = FROM_INT(params->eval.y); - params->req_drag.h = FROM_INT(params->eval.h); + + _edje_part_recalc_single_drag_threshold(ep, threshold, params); } } @@ -2183,6 +2236,7 @@ _edje_part_recalc_single(Edje *ed, Edje_Real_Part *rel2_to_x, Edje_Real_Part *rel2_to_y, Edje_Real_Part *confine_to, + Edje_Real_Part *threshold, Edje_Calc_Params *params, Evas_Coord mmw, Evas_Coord mmh, FLOAT_T pos) @@ -2289,7 +2343,7 @@ _edje_part_recalc_single(Edje *ed, /* take care of dragable part */ if (ep->drag) - _edje_part_recalc_single_drag(ep, confine_to, params, minw, minh, maxw, maxh); + _edje_part_recalc_single_drag(ep, confine_to, threshold, params, minw, minh, maxw, maxh); /* fill */ if (ep->part->type == EDJE_PART_TYPE_IMAGE) @@ -2962,6 +3016,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta int state1 = -1; int state2 = -1; int statec = -1; + int statet = -1; #else Edje_Calc_Params lp1, lp2; #endif @@ -2979,6 +3034,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta Edje_Calc_Params *p1, *pf; Edje_Part_Description_Common *chosen_desc; Edje_Real_Part *confine_to = NULL; + Edje_Real_Part *threshold = NULL; FLOAT_T pos = ZERO, pos2; Edje_Calc_Params lp3; Evas_Coord mmw = 0, mmh = 0; @@ -3160,13 +3216,26 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta } } } - if (ep->drag && ep->drag->confine_to) + if (ep->drag) { - confine_to = ep->drag->confine_to; - _edje_part_recalc(ed, confine_to, flags, NULL); + if (ep->drag->confine_to) + { + confine_to = ep->drag->confine_to; + _edje_part_recalc(ed, confine_to, flags, NULL); #ifdef EDJE_CALC_CACHE - statec = confine_to->state; + statec = confine_to->state; #endif + } + if (ep->drag->threshold) + { + threshold = ep->drag->threshold; + // We shall not recalculate the threshold position as + // we use it's previous position to assert the threshold + // the one before moving take action. +#ifdef EDJE_CALC_CACHE + statet = threshold->state; +#endif + } } // if (ep->text.source) _edje_part_recalc(ed, ep->text.source, flags); // if (ep->text.text_source) _edje_part_recalc(ed, ep->text.text_source, flags); @@ -3240,6 +3309,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta ep->invalidate || state1 >= ep->param1.state || statec >= ep->param1.state || + statet >= ep->param1.state || statec1 >= ep->param1.state || statel1 >= ep->param1.state || statep1 >= ep->param1.state || @@ -3250,7 +3320,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta { _edje_part_recalc_single(ed, ep, ep->param1.description, chosen_desc, center[0], light[0], persp[0], rp1[Rel1X], rp1[Rel1Y], rp1[Rel2X], rp1[Rel2Y], - confine_to, + confine_to, threshold, p1, mmw, mmh, pos); #ifdef EDJE_CALC_CACHE if (flags == FLAG_XY) @@ -3304,6 +3374,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta ep->invalidate || state2 >= ep->param2->state || statec >= ep->param2->state || + statet >= ep->param2->state || statec2 >= ep->param2->state || statel2 >= ep->param2->state || statep2 >= ep->param2->state || @@ -3319,7 +3390,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta rp2[Rel1Y], rp2[Rel2X], rp2[Rel2Y], - confine_to, + confine_to, threshold, p2, mmw, mmh, pos); #ifdef EDJE_CALC_CACHE if (flags == FLAG_XY) diff --git a/src/lib/edje/edje_callbacks.c b/src/lib/edje/edje_callbacks.c index 3be7cf0513..9a508c78e1 100644 --- a/src/lib/edje/edje_callbacks.c +++ b/src/lib/edje/edje_callbacks.c @@ -139,8 +139,10 @@ _edje_mouse_down_signal_cb(void *data, Eo *obj, const Eo_Event_Description *desc rp->drag->down.x = ev->canvas.x; if (rp->part->dragable.y) rp->drag->down.y = ev->canvas.y; - if (!ignored) - _edje_emit(ed, "drag,start", rp->part->name); + rp->drag->threshold_x = EINA_FALSE; + rp->drag->threshold_y = EINA_FALSE; + rp->drag->threshold_started_x = EINA_TRUE; + rp->drag->threshold_started_y = EINA_TRUE; } rp->drag->down.count++; } @@ -201,14 +203,18 @@ _edje_mouse_up_signal_cb(void *data, Eo *obj, const Eo_Event_Description *desc E rp->drag->down.count--; if (rp->drag->down.count == 0) { + rp->drag->threshold_started_x = EINA_FALSE; + rp->drag->threshold_started_y = EINA_FALSE; rp->drag->need_reset = 1; ed->recalc_call = EINA_TRUE; ed->dirty = EINA_TRUE; #ifdef EDJE_CALC_CACHE rp->invalidate = 1; #endif - if (!ignored) + if (!ignored && rp->drag->started) _edje_emit(ed, "drag,stop", rp->part->name); + rp->drag->started = EINA_FALSE; + _edje_recalc_do(ed); } } } @@ -306,7 +312,12 @@ _edje_mouse_move_signal_cb(void *data, Eo *obj, const Eo_Event_Description *desc rp->drag->val.x = dx; rp->drag->val.y = dy; if (!ignored) - _edje_emit(ed, "drag", rp->part->name); + { + if (!rp->drag->started) + _edje_emit(ed, "drag,start", rp->part->name); + _edje_emit(ed, "drag", rp->part->name); + rp->drag->started = EINA_TRUE; + } ed->recalc_call = EINA_TRUE; ed->dirty = EINA_TRUE; #ifdef EDJE_CALC_CACHE diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index da990e8797..f8f9bb713f 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -90,7 +90,27 @@ EMP(BOX, box); EMP(TABLE, table); EMP(EXTERNAL, external); EMP(SPACER, spacer); -EMP(part, part); + +EAPI Eina_Mempool *_emp_part = NULL; + +static void * +mem_alloc_part(size_t size) +{ + Edje_Part *ep; + + ep = eina_mempool_malloc(_emp_part, size); + memset(ep, 0, size); + // This value need to be defined for older file that didn't provide it + // as it should -1 by default instead of 0. + ep->dragable.threshold_id = -1; + return ep; +} + +static void +mem_free_part(void *data) +{ + eina_mempool_free(_emp_part, data); +} #define FREED(eed) \ if (eed) \ @@ -956,6 +976,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.step_y", dragable.step_y, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.count_y", dragable.count_y, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.counfine_id", dragable.confine_id, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.threshold_id", dragable.threshold_id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.events_id", dragable.event_id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_part, Edje_Part, "items", items, _edje_edd_edje_pack_element_pointer); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "type", type, EET_T_UCHAR); diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 70388be20a..df2b16892e 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -688,6 +688,8 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g { if (rp->part->dragable.confine_id >= 0) rp->drag->confine_to = ed->table_parts[rp->part->dragable.confine_id % ed->table_parts_size]; + if (rp->part->dragable.threshold_id >= 0) + rp->drag->threshold = ed->table_parts[rp->part->dragable.threshold_id % ed->table_parts_size]; } if ((rp->type == EDJE_RP_TYPE_SWALLOW) && diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 3ecd20fe09..d2bb323f0c 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -942,6 +942,7 @@ struct _Edje_Part_Dragable int count_y; /* drag area divided by n (0 = no limit) */ int confine_id; /* dragging within this bit, -1 = no */ + int threshold_id; /* dragging outside this bit, -1 = no */ /* davinchi */ int event_id; /* If it is used as scrollbar */ @@ -1487,8 +1488,14 @@ struct _Edje_Real_Part_Drag struct { int x, y; // 8 } tmp; - unsigned char need_reset : 1; // 4 Edje_Real_Part *confine_to; // 4 + Edje_Real_Part *threshold; // 4 + Eina_Bool need_reset : 1; // 4 + Eina_Bool threshold_started_x : 1; + Eina_Bool threshold_started_y : 1; + Eina_Bool threshold_x : 1; + Eina_Bool threshold_y : 1; + Eina_Bool started : 1; }; // 104 #define EDJE_RP_TYPE_NONE 0