From 26ccfb25b5a0fb1387363c6c6f703cd497df09b9 Mon Sep 17 00:00:00 2001 From: raster Date: Wed, 25 May 2011 06:06:48 +0000 Subject: [PATCH] flip now supports the beginnings of interactive mode. - drag to flip it in a direction. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/elementary@59660 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/bin/test.c | 2 + src/bin/test_flip.c | 71 ++++++- src/lib/Elementary.h.in | 18 ++ src/lib/elm_flip.c | 554 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 612 insertions(+), 33 deletions(-) diff --git a/src/bin/test.c b/src/bin/test.c index 43f4d10..4c96bf7 100644 --- a/src/bin/test.c +++ b/src/bin/test.c @@ -100,6 +100,7 @@ void test_weather(void *data, Evas_Object *obj, void *event_info); void test_flip(void *data, Evas_Object *obj, void *event_info); void test_flip2(void *data, Evas_Object *obj, void *event_info); void test_flip3(void *data, Evas_Object *obj, void *event_info); +void test_flip4(void *data, Evas_Object *obj, void *event_info); void test_flip_page(void *data, Evas_Object *obj, void *event_info); void test_label(void *data, Evas_Object *obj, void *event_info); void test_conformant(void *data, Evas_Object *obj, void *event_info); @@ -357,6 +358,7 @@ my_win_main(char *autorun) ADD_TEST("Flip", test_flip); ADD_TEST("Flip 2", test_flip2); ADD_TEST("Flip 3", test_flip3); + ADD_TEST("Flip Interactive", test_flip4); ADD_TEST("Flip Page", test_flip_page); ADD_TEST("Label", test_label); ADD_TEST("Conformant", test_conformant); diff --git a/src/bin/test_flip.c b/src/bin/test_flip.c index bb56a41..731bbd2 100644 --- a/src/bin/test_flip.c +++ b/src/bin/test_flip.c @@ -378,7 +378,7 @@ test_flip3(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info Evas_Object *win, *bg, *bx, *bx2, *fl, *fl_f, *fl_b, *o, *bt, *fr; char buf[PATH_MAX]; - win = elm_win_add(NULL, "flip flip", ELM_WIN_BASIC); + win = elm_win_add(NULL, "flip3", ELM_WIN_BASIC); elm_win_title_set(win, "Flip Flip"); elm_win_autodel_set(win, 1); @@ -491,4 +491,73 @@ test_flip3(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info evas_object_resize(win, 320, 480); evas_object_show(win); } + +static void +my_fl_go(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Evas_Object *fl = data; + elm_flip_go(fl, ELM_FLIP_ROTATE_Y_CENTER_AXIS); +} + +void +test_flip4(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Evas_Object *win, *bg, *bx, *fl, *im, *li, *bt; + char buf[PATH_MAX]; + + win = elm_win_add(NULL, "flip4", ELM_WIN_BASIC); + elm_win_title_set(win, "Flip Interactive"); + elm_win_autodel_set(win, 1); + + bg = elm_bg_add(win); + elm_win_resize_object_add(win, bg); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(bg); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bx); + evas_object_show(bx); + + fl = elm_flip_add(win); + evas_object_size_hint_align_set(fl, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(fl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(bx, fl); + + elm_flip_interaction_set(fl, ELM_FLIP_INTERACTION_CUBE); + elm_flip_interacton_direction_enabled_set(fl, ELM_FLIP_DIRECTION_UP, EINA_TRUE); + elm_flip_interacton_direction_enabled_set(fl, ELM_FLIP_DIRECTION_DOWN, EINA_TRUE); + elm_flip_interacton_direction_enabled_set(fl, ELM_FLIP_DIRECTION_LEFT, EINA_TRUE); + elm_flip_interacton_direction_enabled_set(fl, ELM_FLIP_DIRECTION_RIGHT, EINA_TRUE); + evas_object_show(fl); + + im = evas_object_image_filled_add(evas_object_evas_get(win)); + evas_object_size_hint_weight_set(im, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + snprintf(buf, sizeof(buf), "%s/images/%s", + PACKAGE_DATA_DIR, "twofish.jpg"); + evas_object_image_file_set(im, buf, NULL); + elm_flip_content_front_set(fl, im); + evas_object_show(im); + + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_list_item_append(li, "Item 0", NULL, NULL, NULL, NULL); + elm_list_item_append(li, "Item 1", NULL, NULL, NULL, NULL); + elm_list_item_append(li, "Item 2", NULL, NULL, NULL, NULL); + elm_list_item_append(li, "Item 3 (Which is very long just for testing purposes)", NULL, NULL, NULL, NULL); + elm_list_go(li); + elm_flip_content_back_set(fl, li); + evas_object_show(li); + + bt = elm_button_add(win); + elm_button_label_set(bt, "Go"); + evas_object_smart_callback_add(bt, "clicked", my_fl_go, fl); + evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + evas_object_resize(win, 320, 480); + evas_object_show(win); +} #endif diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index 199c22e..7b6c73b 100644 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -2494,6 +2494,20 @@ extern "C" { ELM_FLIP_CUBE_UP, ELM_FLIP_CUBE_DOWN } Elm_Flip_Mode; + typedef enum _Elm_Flip_Interaction + { + ELM_FLIP_INTERACTION_NONE, + ELM_FLIP_INTERACTION_ROTATE, + ELM_FLIP_INTERACTION_CUBE, + ELM_FLIP_INTERACTION_PAGE + } Elm_Flip_Interaction; + typedef enum _Elm_Flip_Direction + { + ELM_FLIP_DIRECTION_UP, + ELM_FLIP_DIRECTION_DOWN, + ELM_FLIP_DIRECTION_LEFT, + ELM_FLIP_DIRECTION_RIGHT + } Elm_Flip_Direction; EAPI Evas_Object *elm_flip_add(Evas_Object *parent) EINA_ARG_NONNULL(1); EAPI void elm_flip_content_front_set(Evas_Object *obj, Evas_Object *content) EINA_ARG_NONNULL(1); @@ -2505,6 +2519,10 @@ extern "C" { EAPI Eina_Bool elm_flip_front_get(const Evas_Object *obj) EINA_ARG_NONNULL(1); EAPI void elm_flip_perspective_set(Evas_Object *obj, Evas_Coord foc, Evas_Coord x, Evas_Coord y) EINA_ARG_NONNULL(1); EAPI void elm_flip_go(Evas_Object *obj, Elm_Flip_Mode mode) EINA_ARG_NONNULL(1); + EAPI void elm_flip_interaction_set(Evas_Object *obj, Elm_Flip_Interaction mode); + EAPI Elm_Flip_Interaction elm_flip_interaction_get(const Evas_Object *obj); + EAPI void elm_flip_interacton_direction_enabled_set(Evas_Object *obj, Elm_Flip_Direction dir, Eina_Bool enabled); + EAPI Eina_Bool elm_flip_interacton_direction_enabled_get(Evas_Object *obj, Elm_Flip_Direction dir); /* smart callbacks called: * "animate,done" - when a flip animation is finished */ diff --git a/src/lib/elm_flip.c b/src/lib/elm_flip.c index 176861e..2ccbd9d 100644 --- a/src/lib/elm_flip.c +++ b/src/lib/elm_flip.c @@ -26,14 +26,24 @@ typedef struct _Widget_Data Widget_Data; struct _Widget_Data { + Evas_Object *obj; Ecore_Animator *animator; double start, len; Elm_Flip_Mode mode; Evas_Object *clip; + Evas_Object *event[4]; struct { - Evas_Object *content, *clip; + Evas_Object *content, *clip; } front, back; + Ecore_Job *job; + Evas_Coord down_x, down_y, x, y, ox, oy, w, h; + Elm_Flip_Interaction intmode; + int dir; + Eina_Bool dir_enabled[4]; Eina_Bool state : 1; + Eina_Bool down : 1; + Eina_Bool finish : 1; + Eina_Bool started : 1; }; static const char *widtype = NULL; @@ -91,6 +101,7 @@ _sizing_eval(Evas_Object *obj) Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord minw = -1, minh = -1, minw2 = -1, minh2 = -1; Evas_Coord maxw = -1, maxh = -1, maxw2 = -1, maxh2 = -1; + int fingx = 0, fingy = 0; if (!wd) return; if (wd->front.content) evas_object_size_hint_min_get(wd->front.content, &minw, &minh); @@ -106,6 +117,13 @@ _sizing_eval(Evas_Object *obj) if ((maxw2 >= 0) && (maxw2 < maxw)) maxw = maxw2; if ((maxh2 >= 0) && (maxh2 < maxh)) maxh = maxh2; + if (wd->dir_enabled[0]) fingy++; + if (wd->dir_enabled[1]) fingy++; + if (wd->dir_enabled[2]) fingx++; + if (wd->dir_enabled[3]) fingx++; + + elm_coords_finger_size_adjust(fingx, &minw, fingy, &minh); + evas_object_size_hint_min_set(obj, minw, minh); evas_object_size_hint_max_set(obj, maxw, maxh); } @@ -170,21 +188,17 @@ flip_show_hide(Evas_Object *obj) } } -static Eina_Bool -_flip(Evas_Object *obj) +static void +_flip_do(Evas_Object *obj, double t, Elm_Flip_Mode mode, int lin, int rev) { - Widget_Data *wd = elm_widget_data_get(obj); - double t = ecore_loop_time_get() - wd->start; Evas_Coord x, y, w, h; - double p, deg; + double p, deg, pp; Evas_Map *mf, *mb; Evas_Coord cx, cy, px, py, foc; int lx, ly, lz, lr, lg, lb, lar, lag, lab; - if (!wd->animator) return ECORE_CALLBACK_CANCEL; - t = t / wd->len; - if (t > 1.0) t = 1.0; + Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return ECORE_CALLBACK_CANCEL; + if (!wd) return; mf = evas_map_new(4); evas_map_smooth_set(mf, 0); @@ -193,13 +207,46 @@ _flip(Evas_Object *obj) if (wd->front.content) { - evas_object_geometry_get(wd->front.content, &x, &y, &w, &h); - evas_map_util_points_populate_from_geometry(mf, x, y, w, h, 0); + const char *type = evas_object_type_get(wd->front.content); + + // FIXME: only handles filled obj + if ((type) && (!strcmp(type, "image"))) + { + int iw, ih; + evas_object_image_size_get(wd->front.content, &iw, &ih); + evas_object_geometry_get(wd->front.content, &x, &y, &w, &h); + evas_map_util_points_populate_from_geometry(mf, x, y, w, h, 0); + evas_map_point_image_uv_set(mf, 0, 0, 0); + evas_map_point_image_uv_set(mf, 1, iw, 0); + evas_map_point_image_uv_set(mf, 2, iw, ih); + evas_map_point_image_uv_set(mf, 3, 0, ih); + } + else + { + evas_object_geometry_get(wd->front.content, &x, &y, &w, &h); + evas_map_util_points_populate_from_geometry(mf, x, y, w, h, 0); + } } if (wd->back.content) { - evas_object_geometry_get(wd->back.content, &x, &y, &w, &h); - evas_map_util_points_populate_from_geometry(mb, x, y, w, h, 0); + const char *type = evas_object_type_get(wd->back.content); + + if ((type) && (!strcmp(type, "image"))) + { + int iw, ih; + evas_object_image_size_get(wd->back.content, &iw, &ih); + evas_object_geometry_get(wd->back.content, &x, &y, &w, &h); + evas_map_util_points_populate_from_geometry(mb, x, y, w, h, 0); + evas_map_point_image_uv_set(mb, 0, 0, 0); + evas_map_point_image_uv_set(mb, 1, iw, 0); + evas_map_point_image_uv_set(mb, 2, iw, ih); + evas_map_point_image_uv_set(mb, 3, 0, ih); + } + else + { + evas_object_geometry_get(wd->back.content, &x, &y, &w, &h); + evas_map_util_points_populate_from_geometry(mb, x, y, w, h, 0); + } } evas_object_geometry_get(obj, &x, &y, &w, &h); @@ -221,43 +268,57 @@ _flip(Evas_Object *obj) lag = 0; lab = 0; - switch (wd->mode) + switch (mode) { case ELM_FLIP_ROTATE_Y_CENTER_AXIS: p = 1.0 - t; - p = 1.0 - (p * p); + pp = p; + if (!lin) pp = (p * p); + p = 1.0 - pp; if (wd->state) deg = 180.0 * p; else deg = 180 + (180.0 * p); + if (rev) deg = -deg; evas_map_util_3d_rotate(mf, 0.0, deg, 0.0, cx, cy, 0); - evas_map_util_3d_rotate(mb, 0.0, deg + 180.0, 0.0, cx, cy, 0); + evas_map_util_3d_rotate(mb, 0.0, 180 + deg, 0.0, cx, cy, 0); break; case ELM_FLIP_ROTATE_X_CENTER_AXIS: p = 1.0 - t; - p = 1.0 - (p * p); + pp = p; + if (!lin) pp = (p * p); + p = 1.0 - pp; if (wd->state) deg = 180.0 * p; else deg = 180 + (180.0 * p); + if (rev) deg = -deg; evas_map_util_3d_rotate(mf, deg, 0.0, 0.0, cx, cy, 0); - evas_map_util_3d_rotate(mb, deg + 180.0, 0.0, 0.0, cx, cy, 0); + evas_map_util_3d_rotate(mb, 180.0 + deg, 0.0, 0.0, cx, cy, 0); break; case ELM_FLIP_ROTATE_XZ_CENTER_AXIS: p = 1.0 - t; - p = 1.0 - (p * p); + pp = p; + if (!lin) pp = (p * p); + p = 1.0 - pp; if (wd->state) deg = 180.0 * p; else deg = 180 + (180.0 * p); + if (rev) deg = -deg; evas_map_util_3d_rotate(mf, deg, 0.0, deg, cx, cy, 0); - evas_map_util_3d_rotate(mb, deg + 180.0, 0.0, deg + 180.0, cx, cy, 0); + evas_map_util_3d_rotate(mb, 180 + deg, 0.0, 180 + deg, cx, cy, 0); break; case ELM_FLIP_ROTATE_YZ_CENTER_AXIS: p = 1.0 - t; - p = 1.0 - (p * p); + pp = p; + if (!lin) pp = (p * p); + p = 1.0 - pp; if (wd->state) deg = 180.0 * p; else deg = 180 + (180.0 * p); + if (rev) deg = -deg; evas_map_util_3d_rotate(mf, 0.0, deg, deg, cx, cy, 0); - evas_map_util_3d_rotate(mb, 0.0, deg + 180.0, deg + 180.0, cx, cy, 0); + evas_map_util_3d_rotate(mb, 0.0, 180.0 + deg, 180.0 + deg, cx, cy, 0); break; case ELM_FLIP_CUBE_LEFT: p = 1.0 - t; - p = 1.0 - (p * p); + pp = p; + if (!lin) pp = (p * p); + p = 1.0 - pp; deg = -90.0 * p; if (wd->state) { @@ -272,7 +333,9 @@ _flip(Evas_Object *obj) break; case ELM_FLIP_CUBE_RIGHT: p = 1.0 - t; - p = 1.0 - (p * p); + pp = p; + if (!lin) pp = (p * p); + p = 1.0 - pp; deg = 90.0 * p; if (wd->state) { @@ -287,7 +350,9 @@ _flip(Evas_Object *obj) break; case ELM_FLIP_CUBE_UP: p = 1.0 - t; - p = 1.0 - (p * p); + pp = p; + if (!lin) pp = (p * p); + p = 1.0 - pp; deg = -90.0 * p; if (wd->state) { @@ -302,7 +367,9 @@ _flip(Evas_Object *obj) break; case ELM_FLIP_CUBE_DOWN: p = 1.0 - t; - p = 1.0 - (p * p); + pp = p; + if (!lin) pp = (p * p); + p = 1.0 - pp; deg = 90.0 * p; if (wd->state) { @@ -342,6 +409,20 @@ _flip(Evas_Object *obj) evas_map_free(mf); evas_map_free(mb); +} + +static Eina_Bool +_flip(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + double t = ecore_loop_time_get() - wd->start; + if (!wd) return ECORE_CALLBACK_CANCEL; + if (!wd->animator) return ECORE_CALLBACK_CANCEL; + + t = t / wd->len; + if (t > 1.0) t = 1.0; + + _flip_do(obj, t, wd->mode, 0, 0); if (t >= 1.0) { @@ -366,6 +447,7 @@ _configure(Evas_Object *obj) { Widget_Data *wd = elm_widget_data_get(obj); Evas_Coord x, y, w, h; + Evas_Coord fsize; if (!wd) return; evas_object_geometry_get(obj, &x, &y, &w, &h); if (wd->front.content) @@ -381,6 +463,35 @@ _configure(Evas_Object *obj) evas_object_resize(wd->back.content, w, h); } _flip(obj); + + if (wd->event[0]) + { + fsize = 16; // FIXME: 16? + elm_coords_finger_size_adjust(0, NULL, 1, &fsize); + evas_object_move(wd->event[0], x, y); + evas_object_resize(wd->event[0], w, fsize); + } + if (wd->event[1]) + { + fsize = 16; // FIXME: 16? + elm_coords_finger_size_adjust(0, NULL, 1, &fsize); + evas_object_move(wd->event[1], x, y + h - fsize); + evas_object_resize(wd->event[1], w, fsize); + } + if (wd->event[2]) + { + fsize = 16; // FIXME: 16? + elm_coords_finger_size_adjust(1, &fsize, 0, NULL); + evas_object_move(wd->event[2], x, y); + evas_object_resize(wd->event[2], fsize, h); + } + if (wd->event[3]) + { + fsize = 16; // FIXME: 16? + elm_coords_finger_size_adjust(1, &fsize, 0, NULL); + evas_object_move(wd->event[3], x + w - fsize, y); + evas_object_resize(wd->event[3], fsize, h); + } } static void @@ -401,6 +512,304 @@ _animate(void *data) return _flip(data); } +static double +_pos_get(Widget_Data *wd, int *rev, Elm_Flip_Mode *m) +{ + Evas_Coord x, y, w, h; + double t = 1.0; + + evas_object_geometry_get(wd->obj, &x, &y, &w, &h); + switch (wd->intmode) + { + case ELM_FLIP_INTERACTION_ROTATE: + case ELM_FLIP_INTERACTION_CUBE: + { + if (wd->dir == 0) + { + if (wd->down_x > 0) + t = 1.0 - ((double)wd->x / (double)wd->down_x); + *rev = 1; + } + else if (wd->dir == 1) + { + if (wd->down_x < w) + t = 1.0 - ((double)(w - wd->x) / (double)(w - wd->down_x)); + } + else if (wd->dir == 2) + { + if (wd->down_y > 0) + t = 1.0 - ((double)wd->y / (double)wd->down_y); + } + else if (wd->dir == 3) + { + if (wd->down_y < h) + t = 1.0 - ((double)(h - wd->y) / (double)(h - wd->down_y)); + *rev = 1; + } + + if (t < 0.0) t = 0.0; + else if (t > 1.0) t = 1.0; + + if ((wd->dir == 0) || (wd->dir == 1)) + { + if (wd->intmode == ELM_FLIP_INTERACTION_ROTATE) + *m = ELM_FLIP_ROTATE_Y_CENTER_AXIS; + else if (wd->intmode == ELM_FLIP_INTERACTION_CUBE) + { + if (*rev) + *m = ELM_FLIP_CUBE_LEFT; + else + *m = ELM_FLIP_CUBE_RIGHT; + } + } + else + { + if (wd->intmode == ELM_FLIP_INTERACTION_ROTATE) + *m = ELM_FLIP_ROTATE_X_CENTER_AXIS; + else if (wd->intmode == ELM_FLIP_INTERACTION_CUBE) + { + if (*rev) + *m = ELM_FLIP_CUBE_UP; + else + *m = ELM_FLIP_CUBE_DOWN; + } + } + } + default: + break; + } + return t; +} + +static Eina_Bool +_event_anim(void *data, double pos) +{ + Widget_Data *wd = data; + double p; + + p = ecore_animator_pos_map(pos, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0); + if (wd->finish) + { + if (wd->dir == 0) + wd->x = wd->ox * (1.0 - p); + else if (wd->dir == 1) + wd->x = wd->ox + ((wd->w - wd->ox) * p); + else if (wd->dir == 2) + wd->y = wd->oy * (1.0 - p); + else if (wd->dir == 3) + wd->y = wd->oy + ((wd->h - wd->oy) * p); + } + else + { + if (wd->dir == 0) + wd->x = wd->ox + ((wd->w - wd->ox) * p); + else if (wd->dir == 1) + wd->x = wd->ox * (1.0 - p); + else if (wd->dir == 2) + wd->y = wd->oy + ((wd->h - wd->oy) * p); + else if (wd->dir == 3) + wd->y = wd->oy * (1.0 - p); + } + switch (wd->intmode) + { + case ELM_FLIP_INTERACTION_NONE: + break; + case ELM_FLIP_INTERACTION_ROTATE: + case ELM_FLIP_INTERACTION_CUBE: + { + Elm_Flip_Mode m = ELM_FLIP_ROTATE_X_CENTER_AXIS; + int rev = 0; + p = _pos_get(wd, &rev, &m); + _flip_do(wd->obj, p, m, 1, rev); + } + break; + case ELM_FLIP_INTERACTION_PAGE: + /* + _state_update(st); + */ + break; + default: + break; + } + if (pos < 1.0) return ECORE_CALLBACK_RENEW; + + evas_object_map_enable_set(wd->front.content, 0); + evas_object_map_enable_set(wd->back.content, 0); + // FIXME: hack around evas rendering bug (only fix makes evas bitch-slow + evas_object_resize(wd->front.content, 0, 0); + evas_object_resize(wd->back.content, 0, 0); + evas_smart_objects_calculate(evas_object_evas_get(wd->obj)); + // FIXME: end hack + wd->animator = NULL; + if (wd->finish) wd->state = !wd->state; + _configure(wd->obj); + wd->animator = NULL; + evas_object_smart_callback_call(wd->obj, SIG_ANIMATE_DONE, NULL); + + return ECORE_CALLBACK_CANCEL; +} + +static void +_update_job(void *data) +{ + Widget_Data *wd = data; + double p; + Elm_Flip_Mode m = ELM_FLIP_ROTATE_X_CENTER_AXIS; + int rev = 0; + + wd->job = NULL; + switch (wd->intmode) + { + case ELM_FLIP_INTERACTION_ROTATE: + case ELM_FLIP_INTERACTION_CUBE: + p = _pos_get(wd, &rev, &m); + _flip_do(wd->obj, p, m, 1, rev); + break; + case ELM_FLIP_INTERACTION_PAGE: + /* + if (_state_update(st)) + { + evas_object_hide(st->front); + evas_object_hide(st->back); + } + */ + break; + default: + break; + } +} + +static void +_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) +{ + Evas_Object *fl = data; + Widget_Data *wd = elm_widget_data_get(fl); + Evas_Event_Mouse_Down *ev = event_info; + Evas_Coord x, y, w, h; + + if (!wd) return; + if (ev->button != 1) return; + if (wd->animator) + { + ecore_animator_del(wd->animator); + wd->animator = NULL; + } + wd->down = EINA_TRUE; + wd->started = EINA_FALSE; + evas_object_geometry_get(data, &x, &y, &w, &h); + wd->x = ev->canvas.x - x; + wd->y = ev->canvas.y - y; + wd->w = w; + wd->h = h; + wd->down_x = wd->x; + wd->down_y = wd->y; + printf("dn %i %i\n", wd->x, wd->y); +} + +static void +_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) +{ + Evas_Object *fl = data; + Widget_Data *wd = elm_widget_data_get(fl); + Evas_Event_Mouse_Up *ev = event_info; + Evas_Coord x, y, w, h; + double tm = 0.5; + + if (!wd) return; + if (ev->button != 1) return; + wd->down = 0; + evas_object_geometry_get(data, &x, &y, &w, &h); + wd->x = ev->canvas.x - x; + wd->y = ev->canvas.y - y; + wd->w = w; + wd->h = h; + wd->ox = wd->x; + wd->oy = wd->y; + printf("up %i %i\n", wd->x, wd->y); + if (wd->job) + { + ecore_job_del(wd->job); + wd->job = NULL; + } + wd->finish = EINA_FALSE; + if (wd->dir == 0) + { + tm = (double)wd->x / (double)wd->w; + if (wd->x < (wd->w / 2)) wd->finish = EINA_TRUE; + } + else if (wd->dir == 1) + { + if (wd->x > (wd->w / 2)) wd->finish = EINA_TRUE; + tm = 1.0 - ((double)wd->x / (double)wd->w); + } + else if (wd->dir == 2) + { + if (wd->y < (wd->h / 2)) wd->finish = EINA_TRUE; + tm = (double)wd->y / (double)wd->h; + } + else if (wd->dir == 3) + { + if (wd->y > (wd->h / 2)) wd->finish = EINA_TRUE; + tm = 1.0 - ((double)wd->y / (double)wd->h); + } + if (tm < 0.01) tm = 0.01; + else if (tm > 0.99) tm = 0.99; + if (!wd->finish) tm = 1.0 - tm; + tm *= 1.0; // FIXME: config for anim time + if (wd->animator) ecore_animator_del(wd->animator); + wd->animator = ecore_animator_timeline_add(tm, _event_anim, wd); + _event_anim(wd, 0.0); +} + +static void +_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) +{ + Evas_Object *fl = data; + Widget_Data *wd = elm_widget_data_get(fl); + Evas_Event_Mouse_Move *ev = event_info; + Evas_Coord x, y, w, h; + + if (!wd) return; + if (!wd->down) return; + evas_object_geometry_get(data, &x, &y, &w, &h); + wd->x = ev->cur.canvas.x - x; + wd->y = ev->cur.canvas.y - y; + wd->w = w; + wd->h = h; + if (!wd->started) + { + Evas_Coord dx, dy; + + dx = wd->x - wd->down_x; + dy = wd->y - wd->down_y; + if (((dx * dx) + (dy * dy)) > (_elm_config->finger_size * _elm_config->finger_size / 4)) + { + wd->dir = 0; + if ((wd->x > (w / 2)) && (dx < 0) && (abs(dx) > abs(dy))) wd->dir = 0; // left + else if ((wd->x < (w / 2)) && (dx >= 0) && (abs(dx) > abs(dy))) wd->dir = 1; // right + else if ((wd->y > (h / 2)) && (dy < 0) && (abs(dy) >= abs(dx))) wd->dir = 2; // up + else if ((wd->y < (h / 2)) && (dy >= 0) && (abs(dy) >= abs(dx))) wd->dir = 3; // down + wd->started = EINA_TRUE; + printf("START\n"); + flip_show_hide(data); + evas_smart_objects_calculate(evas_object_evas_get(data)); + _flip(data); + // FIXME: hack around evas rendering bug (only fix makes evas bitch-slow) + evas_object_map_enable_set(wd->front.content, 0); + evas_object_map_enable_set(wd->back.content, 0); +// evas_object_resize(wd->front.content, 0, 0); +// evas_object_resize(wd->back.content, 0, 0); + evas_smart_objects_calculate(evas_object_evas_get(data)); + _configure(obj); + // FIXME: end hack + } + else return; + } + printf("mv %i %i\n", wd->x, wd->y); + if (wd->job) ecore_job_del(wd->job); + wd->job = ecore_job_add(_update_job, wd); +} + /** * Add a new flip to the parent * @@ -415,7 +824,7 @@ elm_flip_add(Evas_Object *parent) Evas_Object *obj; Evas *e; Widget_Data *wd; - + ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); ELM_SET_WIDTYPE(widtype, "flip"); @@ -427,6 +836,8 @@ elm_flip_add(Evas_Object *parent) elm_widget_focus_next_hook_set(obj, _elm_flip_focus_next_hook); elm_widget_can_focus_set(obj, EINA_FALSE); + wd->obj = obj; + wd->clip = evas_object_rectangle_add(e); evas_object_static_clip_set(wd->clip, 1); evas_object_color_set(wd->clip, 255, 255, 255, 255); @@ -463,7 +874,8 @@ elm_flip_add(Evas_Object *parent) evas_object_smart_callbacks_descriptions_set(obj, _signals); wd->state = 1; - + wd->intmode = ELM_FLIP_INTERACTION_NONE; + _sizing_eval(obj); return obj; @@ -486,6 +898,7 @@ elm_flip_content_front_set(Evas_Object *obj, Evas_Object *content) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); + int i; if (!wd) return; if (wd->front.content == content) return; if (wd->front.content) evas_object_del(wd->back.content); @@ -504,6 +917,10 @@ elm_flip_content_front_set(Evas_Object *obj, Evas_Object *content) evas_smart_objects_calculate(evas_object_evas_get(obj)); flip_show_hide(obj); _configure(obj); + if (wd->intmode != ELM_FLIP_INTERACTION_NONE) + { + for (i = 0; i < 4; i++) evas_object_raise(wd->event[i]); + } } /** @@ -523,6 +940,7 @@ elm_flip_content_back_set(Evas_Object *obj, Evas_Object *content) { ELM_CHECK_WIDTYPE(obj, widtype); Widget_Data *wd = elm_widget_data_get(obj); + int i; if (!wd) return; if (wd->back.content == content) return; if (wd->back.content) evas_object_del(wd->back.content); @@ -541,6 +959,10 @@ elm_flip_content_back_set(Evas_Object *obj, Evas_Object *content) evas_smart_objects_calculate(evas_object_evas_get(obj)); flip_show_hide(obj); _configure(obj); + if (wd->intmode != ELM_FLIP_INTERACTION_NONE) + { + for (i = 0; i < 4; i++) evas_object_raise(wd->event[i]); + } } /** @@ -667,6 +1089,8 @@ elm_flip_perspective_set(Evas_Object *obj, Evas_Coord foc __UNUSED__, Evas_Coord if (!wd) return; } +// FIXME: add ambient and lighting control + /** * Runs the flip animation * @@ -682,9 +1106,6 @@ elm_flip_perspective_set(Evas_Object *obj, Evas_Coord foc __UNUSED__, Evas_Coord * ELM_FLIP_CUBE_UP * ELM_FLIP_CUBE_DOWN * - * FIXME: add - ELM_FLIP_CUBE_UP - * FIXME: add - ELM_FLIP_CUBE_DOWN - * * @ingroup Flip */ EAPI void @@ -710,3 +1131,72 @@ elm_flip_go(Evas_Object *obj, Elm_Flip_Mode mode) _configure(obj); // FIXME: end hack } + +EAPI void +elm_flip_interaction_set(Evas_Object *obj, Elm_Flip_Interaction mode) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->intmode == mode) return; + wd->intmode = mode; +} + +EAPI Elm_Flip_Interaction +elm_flip_interaction_get(const Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) ELM_FLIP_INTERACTION_NONE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_FLIP_INTERACTION_NONE; + return wd->intmode; +} + +EAPI void +elm_flip_interacton_direction_enabled_set(Evas_Object *obj, Elm_Flip_Direction dir, Eina_Bool enabled) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + int i = -1; + if (!wd) return; + enabled = !!enabled; + if (dir == ELM_FLIP_DIRECTION_UP) i = 0; + else if (dir == ELM_FLIP_DIRECTION_DOWN) i = 1; + else if (dir == ELM_FLIP_DIRECTION_LEFT) i = 2; + else if (dir == ELM_FLIP_DIRECTION_RIGHT) i = 3; + if (i < 0) return; + if (wd->dir_enabled[i] == enabled) return; + wd->dir_enabled[i] = enabled; + if (wd->dir_enabled[i]) + { + wd->event[i] = evas_object_rectangle_add(evas_object_evas_get(obj)); + elm_widget_sub_object_add(obj, wd->event[i]); + evas_object_clip_set(wd->event[i], evas_object_clip_get(obj)); + evas_object_color_set(wd->event[i], 0, 0, 0, 0); + evas_object_show(wd->event[i]); + evas_object_smart_member_add(wd->event[i], obj); + evas_object_event_callback_add(wd->event[i], EVAS_CALLBACK_MOUSE_DOWN, _down_cb, obj); + evas_object_event_callback_add(wd->event[i], EVAS_CALLBACK_MOUSE_UP, _up_cb, obj); + evas_object_event_callback_add(wd->event[i], EVAS_CALLBACK_MOUSE_MOVE, _move_cb, obj); + } + else + { + evas_object_del(wd->event[i]); + wd->event[i] = NULL; + } + _sizing_eval(obj); +} + +EAPI Eina_Bool +elm_flip_interacton_direction_enabled_get(Evas_Object *obj, Elm_Flip_Direction dir) +{ + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + int i = -1; + if (!wd) return EINA_FALSE; + if (dir == ELM_FLIP_DIRECTION_UP) i = 0; + else if (dir == ELM_FLIP_DIRECTION_DOWN) i = 1; + else if (dir == ELM_FLIP_DIRECTION_LEFT) i = 2; + else if (dir == ELM_FLIP_DIRECTION_RIGHT) i = 3; + if (i < 0) return EINA_FALSE; + return wd->dir_enabled[i]; +} -- 2.7.4