elm_map: Add new elm_map_region_zoom_bring_in() API
authorbluezery <ohpowel@gmail.com>
Wed, 28 May 2014 08:08:00 +0000 (17:08 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Wed, 28 May 2014 08:08:01 +0000 (17:08 +0900)
Summary:
By using this API, we  can do region show & bring in concurrently.
This needs some tuning more because some main layouting logic in map
needs to be modified to support more smooth animation.
I will spare my time to do that later.
@feature

Reviewers: Hermet, raster, stefan_schmidt

Reviewed By: raster

CC: Jaehyun
Differential Revision: https://phab.enlightenment.org/D887

src/bin/test_map.c
src/lib/elm_map.c
src/lib/elm_map.eo
src/lib/elm_widget_map.h

index 07da09a3e39b4ec8d7c43457accbd8a5dad701af..108eb7a7fa7b0e7e28698ffb4414caae868717ca 100644 (file)
@@ -487,6 +487,12 @@ _bring_seoul(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNU
    elm_map_region_bring_in(data, 126.977969, 37.566535);
 }
 
+static void
+_bring_zoom_suwon(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   elm_map_region_zoom_bring_in(data, 16, 126.977969, 37.566535);
+}
+
 static void
 _paused_set(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
@@ -770,6 +776,7 @@ _submenu_move_add(void *data, Elm_Object_Item *parent)
    if ((!data) || (!parent)) return;
    elm_menu_item_add(menu, parent, NULL, "Show Urmatt", _show_urmatt, data);
    elm_menu_item_add(menu, parent, NULL, "Bring Seoul", _bring_seoul, data);
+   elm_menu_item_add(menu, parent, NULL, "Zoom & Bring Suwon", _bring_zoom_suwon, data);
 
 }
 
index 393ba8d897416d55e5e59f026dae65c8e6ca7121..d6608740956a68730e16ef3b9794b411a0582533 100644 (file)
@@ -26,6 +26,8 @@
 #define DEFAULT_TILE_SIZE      256
 #define MARER_MAX_NUMBER       30
 #define OVERLAY_GROUPING_SCALE 2
+#define ZOOM_ANIM_CNT          75
+#define ZOOM_BRING_CNT         80
 
 #define CACHE_ROOT             "/elm_map"
 #define CACHE_TILE_ROOT        CACHE_ROOT "/%d/%d/%d"
@@ -1135,7 +1137,7 @@ _zoom_anim_cb(void *data)
 {
    ELM_MAP_DATA_GET(data, sd);
 
-   if (sd->ani.cnt <= 0)
+   if (sd->ani.zoom_cnt <= 0)
      {
         sd->zoom_animator = NULL;
         evas_object_smart_changed(sd->pan_obj);
@@ -1145,8 +1147,8 @@ _zoom_anim_cb(void *data)
      }
    else
      {
-        sd->ani.zoom += sd->ani.diff;
-        sd->ani.cnt--;
+        sd->ani.zoom += sd->ani.zoom_diff;
+        sd->ani.zoom_cnt--;
         _zoom_do(sd, sd->ani.zoom);
 
         return ECORE_CALLBACK_RENEW;
@@ -1160,13 +1162,83 @@ _zoom_with_animation(Elm_Map_Data *sd,
 {
    if (cnt == 0) return;
 
-   sd->ani.cnt = cnt;
+   sd->ani.zoom_cnt = cnt;
    sd->ani.zoom = sd->zoom;
-   sd->ani.diff = (double)(zoom - sd->zoom) / cnt;
+   sd->ani.zoom_diff = (double)(zoom - sd->zoom) / cnt;
    ecore_animator_del(sd->zoom_animator);
    sd->zoom_animator = ecore_animator_add(_zoom_anim_cb, sd->obj);
 }
 
+static Eina_Bool
+_zoom_bring_anim_cb(void *data)
+{
+   ELM_MAP_DATA_GET(data, sd);
+
+   if ((sd->ani.zoom_cnt <= 0) && (sd->ani.region_cnt <= 0))
+     {
+        sd->zoom_animator = NULL;
+
+        evas_object_smart_changed(sd->pan_obj);
+        _calc_job(sd);
+
+        return ECORE_CALLBACK_CANCEL;
+     }
+   else
+     {
+        Evas_Coord x, y, w, h;
+        if (sd->ani.zoom_cnt > 0)
+          {
+             sd->ani.zoom += sd->ani.zoom_diff;
+             _zoom_do(sd, sd->ani.zoom);
+             sd->ani.zoom_cnt--;
+          }
+        if (sd->ani.region_cnt > 0)
+          {
+             sd->ani.lon += sd->ani.lon_diff;
+             sd->ani.lat += sd->ani.lat_diff;
+
+             _region_to_coord_convert
+                (sd, sd->ani.lon, sd->ani.lat, sd->size.w, &x, &y);
+             _viewport_coord_get(sd, NULL, NULL, &w, &h);
+             x = x - (w / 2);
+             y = y - (h / 2);
+             eo_do(sd->obj, elm_interface_scrollable_content_region_show(x, y, w, h));
+             sd->ani.region_cnt--;
+          }
+
+        return ECORE_CALLBACK_RENEW;
+     }
+}
+
+static void
+_zoom_bring_with_animation(Elm_Map_Data *sd,
+                           double zoom,
+                           double lon,
+                           double lat,
+                           int zoom_cnt,
+                           int region_cnt)
+{
+   double tlon, tlat;
+   Evas_Coord vx, vy, vw, vh;
+   if ((zoom_cnt == 0) && (region_cnt == 0)) return;
+
+   sd->ani.zoom_cnt = zoom_cnt;
+   sd->ani.zoom = sd->zoom;
+   sd->ani.zoom_diff = (double)(zoom - sd->zoom) / zoom_cnt;
+
+   sd->ani.region_cnt = region_cnt;
+   _viewport_coord_get(sd, &vx, &vy, &vw, &vh);
+   _coord_to_region_convert
+     (sd, vx + vw / 2, vy + vh / 2, sd->size.w, &tlon, &tlat);
+   sd->ani.lon = tlon;
+   sd->ani.lat = tlat;
+   sd->ani.lon_diff = (lon - tlon) / region_cnt;
+   sd->ani.lat_diff = (lat - tlat) / region_cnt;
+
+   ecore_animator_del(sd->zoom_animator);
+   sd->zoom_animator = ecore_animator_add(_zoom_bring_anim_cb, sd->obj);
+}
+
 static void
 _sizing_eval(Evas_Object *obj)
 {
@@ -4222,6 +4294,12 @@ _elm_map_region_show(Eo *obj EINA_UNUSED, Elm_Map_Data *sd, double lon, double l
    evas_object_smart_changed(sd->pan_obj);
 }
 
+EOLIAN static void
+_elm_map_region_zoom_bring_in(Eo *obj EINA_UNUSED, Elm_Map_Data *sd, int zoom, double lon, double lat)
+{
+   _zoom_bring_with_animation(sd, zoom, lon, lat, ZOOM_ANIM_CNT, ZOOM_BRING_CNT);
+}
+
 EOLIAN static void
 _elm_map_region_get(Eo *obj EINA_UNUSED, Elm_Map_Data *sd, double *lon, double *lat)
 {
index ca7810bcfb99697f68df95836decc0a44fa1f2ae..847a2518c02f0ded5fc0903cb2fe204b641630ed 100644 (file)
@@ -632,6 +632,26 @@ class Elm_Map (Elm_Widget, Elm_Interface_Scrollable)
             @in double lat; /*@ Latitude to center at. */
          }
       }
+      region_zoom_bring_in {
+         /*@
+         Animatedly set the zoom level of the map and bring in given coordinates
+         to the center of the map.
+
+         This causes map to zoom into specific zoom level and also move to the
+         given @p lat and @p lon coordinates and show it (by scrolling) in the
+         center of the viewport concurrently.
+
+         @see elm_map_region_bring_in()
+         @see elm_map_zoom_set()
+
+         @ingroup Map */
+
+         params {
+            @in int zoom;   /*@ The zoom level to set. */
+            @in double lon; /*@ Longitude to center at. */
+            @in double lat; /*@ Latitude to center at. */
+         }
+      }
       track_remove {
          /*@
          Remove a track from the map
index 1e2f0548e79a62f176dcc24ed15d447eb1fb2403..46e59358c654f502071515e51e5c7d312400af56 100644 (file)
@@ -432,8 +432,11 @@ struct _Elm_Map_Data
    struct
    {
       double zoom;
-      double diff;
-      int    cnt;
+      double zoom_diff;
+      double lon, lat;
+      double lon_diff, lat_diff;
+      int    zoom_cnt;
+      int    region_cnt;
    } ani;
 
    Ecore_Timer                          *zoom_timer;