On Sat, Feb 25, 2012 at 2:58 AM, Enlightenment SVN
<no-re...@enlightenment.org> wrote:
> Log:
> elementary/elm_photocam: add multi-touch zoom gesture
>
> Author:       xhell
> Date:         2012-02-24 09:58:29 -0800 (Fri, 24 Feb 2012)
> New Revision: 68426
> Trac:         http://trac.enlightenment.org/e/changeset/68426
>
> Modified:
>  trunk/elementary/src/lib/elm_photocam.c 
> trunk/elementary/src/lib/elm_photocam.h
>
> Modified: trunk/elementary/src/lib/elm_photocam.c
> ===================================================================
> --- trunk/elementary/src/lib/elm_photocam.c     2012-02-24 17:05:44 UTC (rev 
> 68425)
> +++ trunk/elementary/src/lib/elm_photocam.c     2012-02-24 17:58:29 UTC (rev 
> 68426)
> @@ -44,11 +44,27 @@
>    Evas_Object *obj;
>    Evas_Object *scr;
>    Evas_Object *pan_smart;
> +   Evas_Object *gest;
> +   double       gest_start;
> +
>    Pan *pan;
>    Evas_Coord pan_x, pan_y, minw, minh;
>
>    double zoom;
>    Elm_Photocam_Zoom_Mode mode;
> +   Evas_Coord pvx, pvy, px, py, zoom_point_x, zoom_point_y;
> +   struct
> +   {
> +      int imx, imy;
> +      struct
> +      {
> +         int x_start, y_start;
> +         int x_end, y_end;
> +         double t_start;
> +         double t_end;
> +         Ecore_Animator *animator;
> +      } bounce;
> +   } gzoom;
>    const char *file;
>
>    Ecore_Job *calc_job;
> @@ -82,6 +98,7 @@
>    Eina_Bool on_hold : 1;
>    Eina_Bool paused : 1;
>    Eina_Bool do_region : 1;
> +   Eina_Bool zoom_gest : 1;
>  };
>
>  struct _Pan
> @@ -164,8 +181,11 @@
>    ay = 0;
>    gw = wd->size.w;
>    gh = wd->size.h;
> -   if (ow > gw) ax = (ow - gw) / 2;
> -   if (oh > gh) ay = (oh - gh) / 2;
> +   if (!wd->zoom_gest)
> +     {
> +        if (ow > gw) ax = (ow - gw) / 2;
> +        if (oh > gh) ay = (oh - gh) / 2;
> +     }
>    evas_object_move(wd->img, ox + 0 - px + ax, oy + 0 - py + ay);
>    evas_object_resize(wd->img, gw, gh);
>
> @@ -187,8 +207,11 @@
>    ay = 0;
>    gw = wd->size.w;
>    gh = wd->size.h;
> -   if (ow > gw) ax = (ow - gw) / 2;
> -   if (oh > gh) ay = (oh - gh) / 2;
> +   if (!wd->zoom_gest)
> +     {
> +        if (ow > gw) ax = (ow - gw) / 2;
> +        if (oh > gh) ay = (oh - gh) / 2;
> +     }
>    for (y = 0; y < g->gh; y++)
>      {
>         for (x = 0; x < g->gw; x++)
> @@ -703,6 +726,7 @@
>    if (wd->calc_job) ecore_job_del(wd->calc_job);
>    if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
>    if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
> +   if (wd->gzoom.bounce.animator) 
> ecore_animator_del(wd->gzoom.bounce.animator);
>    if (wd->long_timer) ecore_timer_del(wd->long_timer);
>    free(wd);
>  }
> @@ -886,11 +910,13 @@
>    Grid *g;
>    if (!sd) return;
>    evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
> -   img_place(sd->wd->obj, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
> +   img_place(sd->wd->obj, sd->wd->pan_x, sd->wd->pan_y,
> +             ox - sd->wd->gzoom.imx, oy - sd->wd->gzoom.imy, ow, oh);
>    EINA_LIST_FOREACH(sd->wd->grids, l, g)
>      {
>         grid_load(sd->wd->obj, g);
> -        grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, 
> oh);
> +        grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y,
> +                   ox - sd->wd->gzoom.imx, oy - sd->wd->gzoom.imy, ow, oh);
>      }
>  }
>
> @@ -1050,6 +1076,245 @@
>    return EINA_TRUE;
>  }
>
> +Eina_Bool
> +_bounce_eval(void *_wd)
> +{
> +   Widget_Data *wd = (Widget_Data *)_wd;
> +   double t, tt;
> +
> +   if (!wd) return ECORE_CALLBACK_CANCEL;
> +   if ((wd->gzoom.imx == wd->gzoom.bounce.x_end) &&
> +       (wd->gzoom.imy == wd->gzoom.bounce.y_end))
> +     {
> +        wd->gzoom.imx = 0;
> +        wd->gzoom.imy = 0;
> +        wd->zoom_gest = EINA_FALSE;
> +        wd->gzoom.bounce.animator = NULL;
> +        _freeze_off(NULL, wd->obj, NULL);
> +        return ECORE_CALLBACK_CANCEL;
> +     }
> +
> +   t = ecore_loop_time_get();
> +   tt = (t - wd->gzoom.bounce.t_start) / (wd->gzoom.bounce.t_end - 
> wd->gzoom.bounce.t_start);
> +   tt = 1.0 - tt;
> +   tt = 1.0 - (tt * tt);
> +
> +   if (t > wd->gzoom.bounce.t_end)
> +     {
> +        wd->gzoom.imx = 0;
> +        wd->gzoom.imy = 0;
> +        wd->zoom_gest = EINA_FALSE;
> +        _freeze_off(NULL, wd->obj, NULL);
> +        zoom_do(wd->obj, 1.0);
> +        wd->gzoom.bounce.animator = NULL;
> +        return ECORE_CALLBACK_CANCEL;
> +     }
> +
> +   if (wd->gzoom.imx != wd->gzoom.bounce.x_end)
> +     wd->gzoom.imx = wd->gzoom.bounce.x_start * (1.0 - tt) + 
> wd->gzoom.bounce.x_end * tt;
> +
> +   if (wd->gzoom.imy != wd->gzoom.bounce.y_end)
> +     wd->gzoom.imy = wd->gzoom.bounce.y_start * (1.0 - tt) + 
> wd->gzoom.bounce.y_end * tt;
> +
> +   zoom_do(wd->obj, 1.0 - (1.0 - tt));
> +   return ECORE_CALLBACK_RENEW;
> +}
> +
> +static void
> +_gzoom(Widget_Data *_wd, Evas_Coord px, Evas_Coord py, 
> Elm_Gesture_Zoom_Info* gest)
> +{
> +   Widget_Data *wd = (Widget_Data *)_wd;
> +   Evas_Coord rx, ry, rw, rh;
> +   int regx, regy, regw, regh, ix, iy, iw, ih;
> +   int xx, yy;
> +
> +   if (!wd) return;
> +   wd->mode = ELM_PHOTOCAM_ZOOM_MODE_MANUAL;
> +   wd->zoom = wd->gest_start / gest->zoom;
> +   wd->size.ow = wd->size.w;
> +   wd->size.oh = wd->size.h;
> +   elm_smart_scroller_child_pos_get(wd->scr, &rx, &ry);
> +   elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
> +   if ((rw <= 0) || (rh <= 0)) return;
> +
> +   wd->size.nw = (double)wd->size.imw / wd->zoom;
> +   wd->size.nh = (double)wd->size.imh / wd->zoom;
> +
> +   elm_photocam_image_region_get(wd->obj, &regx, &regy, &regw, &regh);
> +   evas_object_geometry_get(wd->img, &ix, &iy, &iw, &ih);
> +
> +   wd->pvx = gest->x;
> +   wd->pvy = gest->y;
> +
> +   xx = (px / wd->zoom) - wd->pvx;
> +   yy = (py / wd->zoom) - wd->pvy;
> +   wd->gzoom.imx = 0;
> +   wd->gzoom.imy = 0;
> +
> +   if ((xx < 0) || (rw > wd->size.nw))
> +     {
> +        wd->gzoom.imx = xx;
> +        xx = 0;
> +     }
> +   else if ((xx + rw) > wd->size.nw)
> +     {
> +        wd->gzoom.imx = xx + rw - wd->size.nw;
> +        xx = wd->size.nw - rw;
> +     }
> +
> +   if ((yy < 0) || (rh > wd->size.nh))
> +     {
> +        wd->gzoom.imy = yy;
> +        yy = 0;
> +     }
> +   else if ((yy + rh) > wd->size.nh)
> +     {
> +        wd->gzoom.imy = yy + rh - wd->size.nh;
> +        yy = wd->size.nh - rh;
> +     }
> +
> +   wd->size.spos.x = (double)(xx + (rw / 2)) / (double)(wd->size.nw);
> +   wd->size.spos.y = (double)(yy + (rh / 2)) / (double)(wd->size.nh);
> +
> +   zoom_do(wd->obj, 1.0);
> +}
> +
> +static Evas_Event_Flags
> +_gzoom_start(void *_wd, void *event_info)
> +{
> +   Widget_Data *wd = (Widget_Data *)_wd;
> +   Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
> +   Evas_Coord rw, rh;
> +   int x,y,w,h;
> +   double marginx = 0, marginy = 0;
> +
> +   if (wd->gzoom.bounce.animator)
> +     {
> +        ecore_animator_del(wd->gzoom.bounce.animator);
> +        wd->gzoom.bounce.animator = NULL;
> +     }
> +   wd->zoom_gest = EINA_TRUE;
> +   _freeze_on(NULL, wd->obj, NULL);
> +
> +   elm_photocam_image_region_get(wd->obj, &x, &y, &w, &h);
> +   elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
> +
> +   if (rw > wd->size.nw)
> +     marginx = (rw - wd->size.nw) / 2;
> +   if (rh > wd->size.nh)
> +     marginy = (rh - wd->size.nh) / 2;
> +
> +   wd->gest_start = wd->zoom;
> +
> +   wd->zoom_point_x = x + ((p->x - marginx) * wd->zoom) + wd->gzoom.imx;
> +   wd->zoom_point_y = y + ((p->y - marginy) * wd->zoom) + wd->gzoom.imy;
> +
> +   return EVAS_EVENT_FLAG_NONE;
> +}
> +
> +static Evas_Event_Flags
> +_gzoom_move(void *_wd, void *event_info)
> +{
> +   Widget_Data *wd = (Widget_Data *)_wd;
> +   Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
> +
> +   _gzoom(wd, wd->zoom_point_x, wd->zoom_point_y, p);
> +   return EVAS_EVENT_FLAG_NONE;
> +}
> +
> +static Evas_Event_Flags
> +_gzoom_end(void *_wd, void *event_info __UNUSED__)
> +{
> +   Widget_Data *wd = (Widget_Data *)_wd;
> +   Evas_Coord rw, rh;
> +
> +   elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
> +   wd->gest_start = 1.0;
> +
> +   if (wd->gzoom.imx || wd->gzoom.imy)
> +     {
> +        double t;
> +
> +        t = ecore_loop_time_get();
> +        wd->gzoom.bounce.x_start = wd->gzoom.imx;
> +        wd->gzoom.bounce.y_start = wd->gzoom.imy;
> +        wd->gzoom.bounce.x_end = 0;
> +        wd->gzoom.bounce.y_end = 0;
> +
> +        if (rw > wd->size.nw &&
> +            rh > wd->size.nh)
> +          {
> +             Evas_Coord pw, ph;
> +             double z;
> +
> +             if ((wd->size.imw < rw) && (wd->size.imh < rh))
> +               {
> +                  wd->zoom = 1;
> +                  wd->size.nw = wd->size.imw;
> +                  wd->size.nh = wd->size.imh;
> +               }
> +             else
> +               {
> +                  ph = (wd->size.imh * rw) / wd->size.imw;
> +                  if (ph > rh)
> +                    {
> +                       pw = (wd->size.imw * rh) / wd->size.imh;
> +                       ph = rh;
> +                    }
> +                  else
> +                    {
> +                       pw = rw;
> +                    }
> +                  if (wd->size.imw > wd->size.imh)
> +                    z = (double)wd->size.imw / pw;
> +                  else
> +                    z = (double)wd->size.imh / ph;
> +
> +                  wd->zoom = z;
> +                  wd->size.nw = pw;
> +                  wd->size.nh = ph;
> +               }
> +             wd->gzoom.bounce.x_end = (wd->size.nw - rw) / 2;
> +             wd->gzoom.bounce.y_end = (wd->size.nh - rh) / 2;
> +          }
> +        else
> +          {
> +             int xx, yy;
> +
> +             xx = (wd->zoom_point_x / wd->zoom) - wd->pvx;
> +             yy = (wd->zoom_point_y / wd->zoom) - wd->pvy;
> +
> +             if (xx < 0) xx = 0;
> +             if (yy < 0) yy = 0;
> +
> +             if (rw > wd->size.nw)
> +               wd->gzoom.bounce.x_end = (wd->size.nw -rw) / 2;
> +             if ((xx + rw) > wd->size.nw)
> +               xx = wd->size.nw - rw;
> +
> +             if (rh > wd->size.nh)
> +               wd->gzoom.bounce.y_end = (wd->size.nh - rh) / 2;
> +             if ((yy + rh) > wd->size.nh)
> +               yy = wd->size.nh - rh;
> +
> +             wd->size.spos.x = (double)(xx + (rw / 2)) / 
> (double)(wd->size.nw);
> +             wd->size.spos.y = (double)(yy + (rh / 2)) / 
> (double)(wd->size.nh);
> +          }
> +
> +        wd->gzoom.bounce.t_start = t;
> +        wd->gzoom.bounce.t_end = t + _elm_config->page_scroll_friction;
> +
> +        wd->gzoom.bounce.animator = ecore_animator_add(_bounce_eval, wd);
> +     }
> +   else
> +     {
> +        _freeze_off(NULL, wd->obj, NULL);
> +        wd->zoom_gest = EINA_FALSE;
> +     }
> +
> +   return EVAS_EVENT_FLAG_NONE;
> +}
> +
>  EAPI Evas_Object *
>  elm_photocam_add(Evas_Object *parent)
>  {
> @@ -1120,9 +1385,10 @@
>                                      _pan_set, _pan_get, _pan_max_get,
>                                      _pan_min_get, _pan_child_size_get);
>
> +   wd->zoom_gest = EINA_FALSE;
> +   wd->gest_start = 1.0;
>    wd->zoom = 1;
>    wd->mode = ELM_PHOTOCAM_ZOOM_MODE_MANUAL;
> -
>    wd->tsize = 512;
>
>    wd->img = evas_object_image_add(e);
> @@ -1172,6 +1438,11 @@
>    wd->size.imh = h;
>    wd->size.w = wd->size.imw / wd->zoom;
>    wd->size.h = wd->size.imh / wd->zoom;
> +   if (wd->gzoom.bounce.animator)
> +     {
> +        ecore_animator_del(wd->gzoom.bounce.animator);
> +        wd->gzoom.bounce.animator = NULL;
> +     }
>    if (wd->zoom_animator)
>      {
>         wd->nosmooth--;
> @@ -1194,11 +1465,11 @@
>                                 "elm,state,busy,start", "elm");
>         evas_object_smart_callback_call(obj, SIG_LOAD_DETAIL, NULL);
>      }
> -     {
> -        double tz = wd->zoom;
> -        wd->zoom = 0.0;
> -        elm_photocam_zoom_set(wd->obj, tz);
> -     }
> +   {
> +      double tz = wd->zoom;
> +      wd->zoom = 0.0;
> +      elm_photocam_zoom_set(wd->obj, tz);
> +   }
>    return evas_object_image_load_error_get(wd->img);
>  }
>
> @@ -1372,7 +1643,7 @@
>              free(g);
>           }
>      }
> -done:
> + done:
>    wd->t_start = ecore_loop_time_get();
>    wd->t_end = wd->t_start + _elm_config->zoom_friction;
>    if ((wd->size.w > 0) && (wd->size.h > 0))
> @@ -1442,11 +1713,11 @@
>    if (!wd) return;
>    if (wd->mode == mode) return;
>    wd->mode = mode;
> -     {
> -        double tz = wd->zoom;
> -        wd->zoom = 0.0;
> -        elm_photocam_zoom_set(wd->obj, tz);
> -     }
> +   {
> +      double tz = wd->zoom;
> +      wd->zoom = 0.0;
> +      elm_photocam_zoom_set(wd->obj, tz);
> +   }
>  }
>
>  EAPI Elm_Photocam_Zoom_Mode
> @@ -1540,6 +1811,12 @@
>    if (rh < 1) rh = 1;
>    if ((rx + rw) > wd->size.w) rx = wd->size.w - rw;
>    if ((ry + rh) > wd->size.h) ry = wd->size.h - rh;
> +   if (wd->gzoom.bounce.animator)
> +     {
> +        ecore_animator_del(wd->gzoom.bounce.animator);
> +        wd->gzoom.bounce.animator = NULL;
> +        zoom_do(obj, 1.0);
> +     }
>    if (wd->zoom_animator)
>      {
>         wd->nosmooth--;
> @@ -1567,6 +1844,12 @@
>    if (rh < 1) rh = 1;
>    if ((rx + rw) > wd->size.w) rx = wd->size.w - rw;
>    if ((ry + rh) > wd->size.h) ry = wd->size.h - rh;
> +   if (wd->gzoom.bounce.animator)
> +     {
> +        ecore_animator_del(wd->gzoom.bounce.animator);
> +        wd->gzoom.bounce.animator = NULL;
> +        zoom_do(obj, 1.0);
> +     }
>    if (wd->zoom_animator)
>      {
>         wd->nosmooth--;
> @@ -1589,6 +1872,12 @@
>    wd->paused = paused;
>    if (wd->paused)
>      {
> +        if (wd->gzoom.bounce.animator)
> +          {
> +             ecore_animator_del(wd->gzoom.bounce.animator);
> +             wd->gzoom.bounce.animator = NULL;
> +             zoom_do(obj, 1.0);
> +          }
>         if (wd->zoom_animator)
>           {
>              ecore_animator_del(wd->zoom_animator);
> @@ -1635,3 +1924,43 @@
>    elm_smart_scroller_bounce_allow_get(wd->scr, h_bounce, v_bounce);
>  }
>
> +EAPI void
> +elm_photocam_gesture_set(Evas_Object *obj, Eina_Bool gesture)
> +{
> +   ELM_CHECK_WIDTYPE(obj, widtype);
> +   Widget_Data *wd = elm_widget_data_get(obj);
> +   if (!wd) return;
> +   if ((wd->gest && !!gesture) || (!wd->gest && !gesture)) return;
> +
> +   if (wd->gest)
> +     {
> +        evas_object_del(wd->gest);
> +        wd->gest = NULL;
> +     }
> +
> +   if (gesture)
> +     {
> +        wd->gest = elm_gesture_layer_add(wd->obj);
> +        elm_gesture_layer_attach(wd->gest, wd->obj);
> +        elm_gesture_layer_cb_set(wd->gest, ELM_GESTURE_ZOOM, 
> ELM_GESTURE_STATE_START,
> +                                 _gzoom_start, wd);
> +        elm_gesture_layer_cb_set(wd->gest, ELM_GESTURE_ZOOM, 
> ELM_GESTURE_STATE_MOVE,
> +                                 _gzoom_move, wd);
> +        elm_gesture_layer_cb_set(wd->gest, ELM_GESTURE_ZOOM, 
> ELM_GESTURE_STATE_END,
> +                                 _gzoom_end, wd);
> +        elm_gesture_layer_cb_set(wd->gest, ELM_GESTURE_ZOOM, 
> ELM_GESTURE_STATE_ABORT,
> +                                 _gzoom_end, wd);
> +     }
> +}
> +
> +EAPI Eina_Bool
> +elm_photocam_gesture_get(const Evas_Object *obj)
> +{
> +   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
> +   Widget_Data *wd = elm_widget_data_get(obj);
> +   if (!wd) return EINA_FALSE;
> +
> +   if (wd->gest)
> +     return EINA_TRUE;
> +   return EINA_FALSE;
> +}
>
> Modified: trunk/elementary/src/lib/elm_photocam.h
> ===================================================================
> --- trunk/elementary/src/lib/elm_photocam.h     2012-02-24 17:05:44 UTC (rev 
> 68425)
> +++ trunk/elementary/src/lib/elm_photocam.h     2012-02-24 17:58:29 UTC (rev 
> 68426)
> @@ -255,5 +255,27 @@
>  EAPI void                   elm_photocam_bounce_get(const Evas_Object *obj, 
> Eina_Bool *h_bounce, Eina_Bool *v_bounce);
>

Hello,

>  /**
> + * @brief Set the gesture state for photocam.
> + *
> + * @param obj The photocam object
> + * @param gesture The gesture state to set
> + *
> + * This sets the gesture state to on(EINA_TRUE) or off (EINA_FALSE) for
> + * photocam. The default is off. This will start multi touch zooming.
> + */
> +EAPI void                  elm_photocam_gesture_set(Evas_Object *obj, 
> Eina_Bool gesture);

This feature is to enable/disable gesture feature on photocam.

1. how about renaming them to elm_photocam_gesture_enabled_set?
enabled_set/get or disabled_set/get is common naming for turning on
and off something in EFL.
If gesture is disabled by default, we can add
elm_photocam_gesture_enabled_set apis.

2. is it ok to add gesture related apis to widget?
Tom, can you give some comment here?

Thanks in advance.

Daniel Juyung Seo (SeoZ)

> +
> +/**
> + * @brief Get the gesture state for photocam.
> + *
> + * @param obj The photocam object
> + * @return The current gesture state
> + *
> + * This gets the current gesture state for the photocam object.
> + *
> + * @see elm_photocam_gesture_set()
> + */
> +EAPI Eina_Bool             elm_photocam_gesture_get(const Evas_Object *obj);
> +/**
>  * @}
>  */
>
>
> ------------------------------------------------------------------------------
> Virtualization & Cloud Management Using Capacity Planning
> Cloud computing makes use of virtualization - but cloud computing
> also focuses on allowing computing to be delivered as a service.
> http://www.accelacomm.com/jaw/sfnl/114/51521223/
> _______________________________________________
> enlightenment-svn mailing list
> enlightenment-...@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn

------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to