Elementary: Map examples
authorbdilly <bdilly@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 4 Aug 2011 22:35:12 +0000 (22:35 +0000)
committerbdilly <bdilly@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 4 Aug 2011 22:35:12 +0000 (22:35 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/elementary@62115 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

doc/examples.dox
src/examples/Makefile.am
src/examples/map_example_01.c [new file with mode: 0644]
src/examples/map_example_02.c [new file with mode: 0644]
src/examples/map_example_03.c [new file with mode: 0644]

index 5f3d631..8155882 100644 (file)
  * @ref clock_example
  *
  * @ref mapbuf_example
+
+ * @ref map_example_01
+ *
+ * @ref map_example_02
+ *
+ * @ref map_example_03
  *
  * @ref diskselector_example_01
  *
  */
 
 /**
+ * @page map_example_01 Map Example - Creation and Zoom
+ *
+ * This code places a Elementary map widget on a window,
+ * to exemplify part of the widget's API.
+ *
+ * Let's start adding a map to our window:
+ * @dontinclude map_example_01.c
+ * @skipline elm_map_add
+ * @until evas_object_show
+ *
+ * It's enough to display a world map inside our window. But usually you'll
+ * need to let user interact with the map. We need to place some buttons,
+ * so the user could control the map. It's done on the followin code.
+ * If you don't know about boxes, or buttons, check their examples,
+ * @ref box_example_01 "Box Example 1" and
+ * @ref button_example_01 "Button Example 1".
+ * @skipline elm_box_add
+ * @until _bt_zoom_fill
+ *
+ * We are adding callback functions that will be called when the user clicks
+ * over these buttons. Let's study such functions, starting from the function
+ * that will zoom in the map:
+ * @dontinclude map_example_01.c
+ * @skipline static void
+ * @until }
+ *
+ * First thing done is assure zoom mode is set to manual. It's the default
+ * mode, but the other buttons will change this, so before setting a new
+ * zoom value, we need to change the zoom mode.
+ *
+ * Then, we get the current zoom value, increment that, and set the new
+ * value to the map. If it's bigger than max zoom value allowed, it will
+ * remain on the maximum allowed, nothing bad will happen. This way we
+ * don't need to check first if it won't be bigger than max.
+ *
+ * Zoom out function is basically the same thing, but zoom will be decremented
+ * instead of incremented:
+ * @skipline static void
+ * @until }
+ *
+ * The "X" button, when pressed, will call a function that will
+ * zoom the map until it fits
+ * inside the scroll frame with no pixels outside this area:
+ * @skipline static void
+ * @until }
+ *
+ * And the "#" button, will call a function that will zoom until map fills
+ * scroll, ensuring no pixels are left unfilled:
+ * @skipline static void
+ * @until }
+ *
+ * But we can also set map to show something different from default
+ * world map, changing the zoom level and region shown. Let's pick a
+ * wonderful city coordinates, one placed at <tt> 43 20 S, 22 90 W </tt>.
+ * Since map uses double variables to represent latitude and longitude,
+ * to represent north or east, we should represent it as positive values,
+ * and south or west as negative. Also, the value will be represented as
+ * degree.min. So, for example, our longitude <tt> 43 20 S </tt> will
+ * be represented
+ * by the value <tt> -43.20 </tt>. A zoom set to @c 12 should be enough
+ * to show a city.
+ * @skipline region_show
+ * @until zoom_set
+ *
+ * See @ref map_example_01.c "map_example_01.c" for full source,
+ * whose window should
+ * look like this picture:
+ *
+ * @image html screenshots/map_example_01.png
+ * @image latex screenshots/map_example_01.eps width=\textwidth
+ *
+ * @example map_example_01.c
+ */
+
+/**
+ * @page map_example_02 Map Example - Markers Usage
+ *
+ * This code places a Elementary map widget on a window,
+ * to exemplify part of the widget's API, related to markers.
+ *
+ * We'll start this example the same way
+ * @ref map_example_01 "Map Example 1". Adding a map with buttons to control
+ * zoom, so if you didn't read it yet, just do it now.
+ * @dontinclude map_example_02.c
+ * @skipline elm_map_add
+ * @until zoom_fill
+ *
+ * Markers can be placed over the map to represent anything we want. Let's
+ * say we want to represent some countries and cities with markers. To add
+ * a mark we need a marker class and also a group class.
+ *
+ * A marker class can be created as the following code does:
+ * @skipline marker_class_new
+ * @until style_set
+ *
+ * These lines create a new class, set a function to return the object
+ * to be displayed inside the bubble that opens when a user clicks over
+ * the mark, set the function to retrieve an icon to be placed inside
+ * the marker, and defines the style of this marker. It can be @c empty
+ * that will just show the icon, @c radio, that will place a blue circle,
+ * and @c radio2 that will place a green circle.
+ *
+ * The group classes can be created in a very similar way, but you won't
+ * set callback functions to get stuff to be placed inside the bubble,
+ * since clicking over a group marker will just get the content
+ * of all the markers composing the group and place on this bubble.
+ * The limit of markers to get can be set with function
+ * elm_map_max_marker_per_group_set() but we won't need on this example.
+ * But we can set the zoom required to display the marks that belongs
+ * to this group class, so if the zoom is less than this value, nothing
+ * will be show. The group marker style will be used when markers are
+ * near each other, and the count of markers grouped will be placed
+ * inside the group marker.
+ * @skipline group_class_new
+ * @until displayed_set
+ *
+ * For marker and group classes to represent a country, the same is done:
+ * @skipline marker_class_new
+ * @until displayed_set
+ *
+ * Next we'll create some markers representing cities and coutries.
+ * We'll append them in a list, to close up them later. To create a marker
+ * we need to pass the coordinates, marker class, group class and optionally,
+ * data:
+ * @skipline marker_add
+ * @until data_chile
+ * @until append
+ *
+ * We have created a specific structure for this example to store the name
+ * of the place and a path to a image file to represent it.
+ * @dontinclude map_example_02.c
+ * @skipline typedef
+ * @until Marker_Data;
+ *
+ * We'll create instances for each place:
+ * @skipline argentina
+ * @until sky_03
+ *
+ * Finally, on our @c main function, we ask the map to show all the markers
+ * with the biggest zoom possible, passing the list of markers added:
+ * @skipline list_show
+ *
+ * Actually the zoom is not what we want, so after the download of the map
+ * is concluded, let's set another zoom level. For this we add a callback
+ * for @c "downloaded" signal:
+ * @skipline callback_add
+ *
+ * The callback function will simply set the zoom level we want and remove
+ * the callback, otherwise it would be called all the time, after the map
+ * is downloaded:
+ * @dontinclude map_example_02.c
+ * @skipline _map_downloaded
+ * @until }
+ *
+ * We added two kinds of callback functions when we added the markers.
+ * One will return the content of the bubbles, and other the icon to be
+ * placed inside the marker.
+ *
+ * To return an icon, all we need to do is add a elm_icon and return it:
+ * @dontinclude map_example_02.c
+ * @skip static Evas_Object
+ * @skip }
+ * @skipline static Evas_Object
+ * @until }
+ *
+ * For the content, let's return something more elaboreate. We will return
+ * a box with an image representing the place, and the name of this place:
+ * @skipline static Evas_Object
+ * @until }
+ *
+ * See @ref map_example_02.c "map_example_02.c" for full source,
+ * whose window should
+ * look like this picture:
+ *
+ * @image html screenshots/map_example_02.png
+ * @image latex screenshots/map_example_02.eps width=\textwidth
+ *
+ * @example map_example_02.c
+ */
+
+/**
+ * @page map_example_03 Map Example - Route and Name Usage
+ *
+ * This code places a Elementary map widget on a window,
+ * to exemplify part of the widget's API, related routes and names.
+ *
+ * In this example, we will suppose we need to set a route for the user
+ * from his current point (a gps could provide us this information)
+ * to somewhere else. So we would have coordinates of this
+ * start point, and would like that he enters the address of his
+ * destination in a entry, and we'll trace a route on the map.
+ *
+ * We'll start this example the same way
+ * @ref map_example_01 "Map Example 1". Adding a map with buttons to control
+ * zoom, so if you didn't read it yet, just do it now. Actually there is
+ * a change, that we're aligning buttons to the top, since we wan't a
+ * vertical control box this time.
+ * @dontinclude map_example_03.c
+ * @skipline elm_map_add
+ * @until zoom_fill
+ * @until align_set
+ *
+ * Next we set the box to be vertical and change it's size, weight
+ * and alignment, so it will occupy the top of the window, from left
+ * to right:
+ * @skipline horizontal_set
+ * @until align_set
+ *
+ * We'll add an entry with a preliminar address, that I know will
+ * find a coordinate, to examplify names work. But you can try
+ * lots of addresses. From city or country names to pubs, or whatever
+ * you want. To try is enough to run the example, type the address and
+ * press "Route" button. This button will call a function that will
+ * get the typed address and find the route.
+ * @skipline entry_add
+ * @until align_set
+ * @until align_set
+ *
+ * The button pass an structure
+ * instance we make for this example, with all the fields we'll need.
+ * @dontinclude map_example_03.c
+ * @skipline _Example_Data
+ * @until example_data;
+ *
+ * Let's initialize it's fields:
+ * @skipline example_data.map
+ * @until example_data.start_lat
+ *
+ * @c map and @c entry are our elementary objects, @c route is set to @c NULL,
+ * since we don't have one yet, and the coordinates of the start point is set
+ * (longitude and latitude).
+ *
+ * Also, let's show this start point at the center of the map, and set a zoom
+ * nice enough to close it:
+ * @skipline region_show
+ * @until zoom_set
+ *
+ * These lines were already explained on @ref map_example_02 "Map Example 2".
+ *
+ * Now we'll see the "Route" button callback function:
+ * @dontinclude map_example_03.c
+ * @skip static void
+ * @skip }
+ * @skipline static void
+ * @until }
+ *
+ * First we get the address string from our entry. Then we use @c name
+ * conversion
+ * util functions, so we could get coordinates for this address. These
+ * functions return an #Elm_Map_Name handle for us.
+ * Function elm_map_utils_convert_name_into_coord() will do this job for us,
+ * but it's an assyncronous function, since it requires this
+ * information from the server.
+ *
+ * That's the reason we need to wait for
+ * <tt> "name,loaded" </tt> signal. We add a callback function for this:
+ * @dontinclude map_example_03.c
+ * @skipline static void
+ * @until }
+ *
+ * This function will check if a previous route was traced, and if it was,
+ * it will remove it. Next we'll get destination coordinates from our
+ * @c name, and use them to add a new route.
+ *
+ * To trace a route we need to know how the user will go through the path.
+ * Let's suppose he'll be walking, but doesn't like to walk, so we
+ * need to choose the shortest path intead of the route that would
+ * made him spend less time. Coordinates of the point from where he will
+ * start and of the destination point need to be passed as well.
+ *
+ * Finally we'll set a color different from solid red (default), to show
+ * our route. We set it green.
+ *
+ * See @ref map_example_03.c "map_example_03.c" for full source,
+ * whose window should
+ * look like this picture:
+ *
+ * @image html screenshots/map_example_03.png
+ * @image latex screenshots/map_example_03.eps width=\textwidth
+ *
+ * @example map_example_03.c
+ */
+
+/**
  * @page diskselector_example_01 Diskselector widget example
  *
  * This code places 4 Elementary diskselector widgets on a window, each of
index 7d1de28..f56d4ac 100644 (file)
@@ -62,6 +62,9 @@ SRCS = \
        calendar_example_04.c \
        calendar_example_05.c \
        calendar_example_06.c \
+       map_example_01.c \
+       map_example_02.c \
+       map_example_03.c \
        toolbar_example_01.c \
        toolbar_example_02.c \
        toolbar_example_03.c \
@@ -163,6 +166,9 @@ pkglib_PROGRAMS += \
        calendar_example_04 \
        calendar_example_05 \
        calendar_example_06 \
+       map_example_01 \
+       map_example_02 \
+       map_example_03 \
        toolbar_example_01 \
        toolbar_example_02 \
        toolbar_example_03 \
@@ -243,6 +249,9 @@ SCREENSHOTS = \
        calendar_example_04:calendar_example_04.png:0.0 \
        calendar_example_05:calendar_example_05.png:0.0 \
        calendar_example_06:calendar_example_06.png:0.0 \
+       map_example_01:map_example_01.png:2 \
+       map_example_02:map_example_02.png:2.5 \
+       map_example_03:map_example_03.png:2 \
        toolbar_example_01:toolbar_example_01.png:0.0 \
        toolbar_example_02:toolbar_example_02.png:1 \
        toolbar_example_03:toolbar_example_03.png:1 \
diff --git a/src/examples/map_example_01.c b/src/examples/map_example_01.c
new file mode 100644 (file)
index 0000000..1441b46
--- /dev/null
@@ -0,0 +1,131 @@
+/**
+ * Simple Elementary's <b>map widget</b> example, illustrating its
+ * creation.
+ *
+ * See stdout/stderr for output. Compile with:
+ *
+ * @verbatim
+ * gcc -g `pkg-config --cflags --libs elementary` map_example_01.c -o map_example_01
+ * @endverbatim
+ */
+
+#include <Elementary.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#else
+# define __UNUSED__
+#endif
+
+static void
+_bt_zoom_in(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
+{
+   Evas_Object *map = data;
+   int zoom;
+
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(map);
+   elm_map_zoom_set(map, zoom + 1);
+}
+
+static void
+_bt_zoom_out(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
+{
+   Evas_Object *map = data;
+   int zoom;
+
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(map);
+   elm_map_zoom_set(map, zoom - 1);
+}
+
+static void
+_bt_zoom_fit(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *map = data;
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FIT);
+}
+
+static void
+_bt_zoom_fill(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *map = data;
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FILL);
+}
+
+static void
+_on_done(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   elm_exit();
+}
+
+/* FIXME: it shouldn't be required. For unknown reason map won't call
+ * pan_calculate until shot delay time, but then it will take a screenshot
+ * when the map isn't loaded yet (actually it won't be downloaded, because
+ * after the SS it will kill the example). */
+static Eina_Bool
+_nasty_hack(void *data)
+{
+   Evas_Object *o = data;
+   Evas *e = evas_object_evas_get(o);
+   evas_smart_objects_calculate(e);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+EAPI int
+elm_main(int argc __UNUSED__, char **argv __UNUSED__)
+{
+   Evas_Object *win, *bg, *map, *box, *bt;
+
+   win = elm_win_add(NULL, "map", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Map Creation Example");
+   evas_object_smart_callback_add(win, "delete,request", _on_done, NULL);
+
+   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);
+
+   map = elm_map_add(win);
+   elm_win_resize_object_add(win, map);
+   evas_object_size_hint_weight_set(map, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(map);
+
+   box = elm_box_add(win);
+   evas_object_show(box);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "+");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_in, map);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "-");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_out, map);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "X");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fit, map);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "#");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fill, map);
+
+   elm_map_geo_region_show(map, -43.2, -22.9);
+   elm_map_zoom_set(map, 12);
+
+   evas_object_resize(win, 512, 512);
+   evas_object_show(win);
+
+   ecore_timer_add(0.5, _nasty_hack, win);
+
+   elm_run();
+   return 0;
+}
+ELM_MAIN()
diff --git a/src/examples/map_example_02.c b/src/examples/map_example_02.c
new file mode 100644 (file)
index 0000000..72e590d
--- /dev/null
@@ -0,0 +1,254 @@
+/**
+ * Simple Elementary's <b>map widget</b> example, illustrating markers
+ * usage.
+ *
+ * See stdout/stderr for output. Compile with:
+ *
+ * @verbatim
+ * gcc -g `pkg-config --cflags --libs elementary` map_example_02.c -o map_example_02
+ * @endverbatim
+ */
+
+#include <Elementary.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#else
+# define __UNUSED__
+#endif
+
+typedef struct _Marker_Data
+{
+   const char *name;
+   const char *file;
+} Marker_Data;
+
+Marker_Data data_argentina = {"Argentina",
+     PACKAGE_DATA_DIR"/images/rock_01.jpg"};
+Marker_Data data_chile = {"Chile",
+     PACKAGE_DATA_DIR"/images/rock_02.jpg"};
+Marker_Data data_sampa = {"São Paulo",
+     PACKAGE_DATA_DIR"/images/sky_01.jpg"};
+Marker_Data data_rio = {"Rio de Janeiro",
+     PACKAGE_DATA_DIR"/images/sky_02.jpg"};
+Marker_Data data_brasilia = {"Brasília",
+     PACKAGE_DATA_DIR"/images/sky_03.jpg"};
+
+static Evas_Object *
+_marker_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data)
+{
+   Evas_Object *bx, *im, *lbl;
+   Marker_Data *md = data;
+
+   bx = elm_box_add(obj);
+   evas_object_show(bx);
+
+   im = elm_image_add(obj);
+   elm_image_file_set(im, md->file, NULL);
+   evas_object_size_hint_min_set(im, 64, 64);
+   evas_object_show(im);
+   elm_box_pack_end(bx, im);
+
+   lbl = elm_label_add(obj);
+   elm_object_text_set(lbl, md->name);
+   evas_object_show(lbl);
+   elm_box_pack_end(bx, lbl);
+
+   return bx;
+}
+
+static Evas_Object *
+_marker_city_icon_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data __UNUSED__)
+{
+   Evas_Object *icon = elm_icon_add(obj);
+   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_07.png", NULL);
+   evas_object_show(icon);
+
+   return icon;
+}
+
+static Evas_Object *
+_group_city_icon_get(Evas_Object *obj, void *data __UNUSED__)
+{
+   Evas_Object *icon = elm_icon_add(obj);
+   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_05.png", NULL);
+   evas_object_show(icon);
+   return icon;
+}
+
+static Evas_Object *
+_marker_country_icon_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data __UNUSED__)
+{
+   Evas_Object *icon = elm_icon_add(obj);
+   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_06.png", NULL);
+   evas_object_show(icon);
+   return icon;
+}
+
+static Evas_Object *
+_group_country_icon_get(Evas_Object *obj, void *data __UNUSED__)
+{
+   Evas_Object *icon = elm_icon_add(obj);
+   elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_04.png", NULL);
+   evas_object_show(icon);
+   return icon;
+}
+
+static void
+_map_downloaded(void *data __UNUSED__, Evas_Object *obj, void *ev __UNUSED__)
+{
+   elm_map_zoom_set(obj, 3);
+   evas_object_smart_callback_del(obj, "downloaded", _map_downloaded);
+}
+
+static void
+_bt_zoom_in(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
+{
+   Evas_Object *map = data;
+   int zoom;
+
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(map);
+   elm_map_zoom_set(map, zoom + 1);
+}
+
+static void
+_bt_zoom_out(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
+{
+   Evas_Object *map = data;
+   int zoom;
+
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(map);
+   elm_map_zoom_set(map, zoom - 1);
+}
+
+static void
+_bt_zoom_fit(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *map = data;
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FIT);
+}
+
+static void
+_bt_zoom_fill(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *map = data;
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FILL);
+}
+
+static void
+_on_done(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   elm_exit();
+}
+
+/* FIXME: it shouldn't be required. For unknown reason map won't call
+ * pan_calculate until shot delay time, but then it will take a screenshot
+ * when the map isn't loaded yet (actually it won't be downloaded, because
+ * after the SS it will kill the example). */
+static Eina_Bool
+_nasty_hack(void *data)
+{
+   Evas_Object *o = data;
+   Evas *e = evas_object_evas_get(o);
+   evas_smart_objects_calculate(e);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+EAPI int
+elm_main(int argc __UNUSED__, char **argv __UNUSED__)
+{
+   Evas_Object *win, *bg, *map, *box, *bt;
+   static Elm_Map_Marker_Class *mc_city, *mc_country;
+   static Elm_Map_Group_Class *gc_city, *gc_country;
+   Eina_List *markers = NULL;
+   Elm_Map_Marker *m;
+
+   win = elm_win_add(NULL, "map", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Map Markers Example");
+   evas_object_smart_callback_add(win, "delete,request", _on_done, NULL);
+
+   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);
+
+   map = elm_map_add(win);
+   elm_win_resize_object_add(win, map);
+   evas_object_size_hint_weight_set(map, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(map);
+
+   box = elm_box_add(win);
+   evas_object_show(box);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "+");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_in, map);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "-");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_out, map);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "X");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fit, map);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "#");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fill, map);
+
+   mc_city = elm_map_marker_class_new(map);
+   elm_map_marker_class_get_cb_set(mc_city, _marker_get);
+   elm_map_marker_class_icon_cb_set(mc_city, _marker_city_icon_get);
+   elm_map_marker_class_style_set(mc_city, "radio");
+
+   gc_city = elm_map_group_class_new(map);
+   elm_map_group_class_style_set(gc_city, "radio2");
+   elm_map_group_class_icon_cb_set(gc_city, _group_city_icon_get);
+   elm_map_group_class_zoom_displayed_set(gc_city, 3);
+
+   mc_country = elm_map_marker_class_new(map);
+   elm_map_marker_class_get_cb_set(mc_country, _marker_get);
+   elm_map_marker_class_icon_cb_set(mc_country, _marker_country_icon_get);
+   elm_map_marker_class_style_set(mc_country, "empty");
+
+   gc_country = elm_map_group_class_new(map);
+   elm_map_group_class_style_set(gc_country, "empty");
+   elm_map_group_class_icon_cb_set(gc_country, _group_country_icon_get);
+   elm_map_group_class_zoom_displayed_set(gc_country, 1);
+
+   m = elm_map_marker_add(map, -43.2, -22.9, mc_city, gc_city, &data_rio);
+   markers = eina_list_append(markers, m);
+   m = elm_map_marker_add(map, -46.63, -23.55, mc_city, gc_city, &data_sampa);
+   markers = eina_list_append(markers, m);
+   m = elm_map_marker_add(map, -47.88, -15.78, mc_city, gc_city,
+                          &data_brasilia);
+   markers = eina_list_append(markers, m);
+
+   m = elm_map_marker_add(map, -65.23, -35.1, mc_country, gc_country,
+                      &data_argentina);
+   markers = eina_list_append(markers, m);
+   m = elm_map_marker_add(map, -71.3, -31.75, mc_country, gc_country,
+                      &data_chile);
+   markers = eina_list_append(markers, m);
+
+   elm_map_markers_list_show(markers);
+   evas_object_smart_callback_add(map, "downloaded", _map_downloaded, NULL);
+
+   evas_object_resize(win, 512, 512);
+   evas_object_show(win);
+
+   ecore_timer_add(1, _nasty_hack, win);
+
+   elm_run();
+   return 0;
+}
+ELM_MAIN()
diff --git a/src/examples/map_example_03.c b/src/examples/map_example_03.c
new file mode 100644 (file)
index 0000000..25ea7cc
--- /dev/null
@@ -0,0 +1,206 @@
+/**
+ * Simple Elementary's <b>map widget</b> example, illustrating route and
+ * name usage.
+ *
+ * See stdout/stderr for output. Compile with:
+ *
+ * @verbatim
+ * gcc -g `pkg-config --cflags --libs elementary` map_example_03.c -o map_example_03
+ * @endverbatim
+ */
+
+#include <Elementary.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#else
+# define __UNUSED__
+#endif
+
+typedef struct _Example_Data
+{
+   Evas_Object *map, *entry;
+   Elm_Map_Route *route;
+   double start_lon, start_lat, dest_lon, dest_lat;
+   Elm_Map_Name *name;
+} Example_Data;
+
+static Example_Data example_data;
+
+static void
+_name_loaded(void *data, Evas_Object *obj, void *ev __UNUSED__)
+{
+   Example_Data *example_data = data;
+   Evas_Object *map = obj;
+
+   if (example_data->route)
+     elm_map_route_remove(example_data->route);
+
+   elm_map_name_region_get(example_data->name, &(example_data->dest_lon),
+                           &(example_data->dest_lat));
+
+   example_data->route = elm_map_route_add(map, ELM_MAP_ROUTE_TYPE_FOOT,
+                     ELM_MAP_ROUTE_METHOD_SHORTEST,
+                     example_data->start_lon, example_data->start_lat,
+                     example_data->dest_lon, example_data->dest_lat);
+   elm_map_route_color_set(example_data->route, 0, 255, 0, 255);
+}
+
+static void
+_bt_route(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
+{
+   Example_Data *example_data = data;
+   Evas_Object *map;
+   char *address;
+
+   map = example_data->map;
+   address = (char *)elm_object_text_get(example_data->entry);
+
+   example_data->name = elm_map_utils_convert_name_into_coord(map, address);
+
+   evas_object_smart_callback_add(map, "name,loaded", _name_loaded, data);
+}
+
+static void
+_bt_zoom_in(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
+{
+   Evas_Object *map = data;
+   int zoom;
+
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(map);
+   elm_map_zoom_set(map, zoom + 1);
+}
+
+static void
+_bt_zoom_out(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
+{
+   Evas_Object *map = data;
+   int zoom;
+
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_MANUAL);
+   zoom = elm_map_zoom_get(map);
+   elm_map_zoom_set(map, zoom - 1);
+}
+
+static void
+_bt_zoom_fit(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *map = data;
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FIT);
+}
+
+static void
+_bt_zoom_fill(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *map = data;
+   elm_map_zoom_mode_set(map, ELM_MAP_ZOOM_MODE_AUTO_FILL);
+}
+
+static void
+_on_done(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   elm_exit();
+}
+
+/* FIXME: it shouldn't be required. For unknown reason map won't call
+ * pan_calculate until shot delay time, but then it will take a screenshot
+ * when the map isn't loaded yet (actually it won't be downloaded, because
+ * after the SS it will kill the example). */
+static Eina_Bool
+_nasty_hack(void *data)
+{
+   Evas_Object *o = data;
+   Evas *e = evas_object_evas_get(o);
+   evas_smart_objects_calculate(e);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+EAPI int
+elm_main(int argc __UNUSED__, char **argv __UNUSED__)
+{
+   Evas_Object *win, *bg, *map, *box, *bt, *entry;
+
+   win = elm_win_add(NULL, "map", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Map Route Example");
+   evas_object_smart_callback_add(win, "delete,request", _on_done, NULL);
+
+   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);
+
+   map = elm_map_add(win);
+   elm_win_resize_object_add(win, map);
+   evas_object_size_hint_weight_set(map, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(map);
+
+   box = elm_box_add(win);
+   evas_object_show(box);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "+");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_in, map);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "-");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_out, map);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "X");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fit, map);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "#");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_zoom_fill, map);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0);
+
+   elm_box_horizontal_set(box, EINA_TRUE);
+   elm_win_resize_object_add(win, box);
+   evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(box, EVAS_HINT_FILL, 0);
+
+   entry = elm_entry_add(win);
+   elm_entry_scrollable_set(entry, EINA_TRUE);
+   elm_entry_single_line_set(entry, EINA_TRUE);
+   elm_object_text_set(entry, "Jockey Club Brasileiro");
+   evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0);
+   elm_box_pack_end(box, entry);
+   evas_object_show(entry);
+
+   bt = elm_button_add(win);
+   elm_object_text_set(bt, "Route");
+   elm_box_pack_end(box, bt);
+   evas_object_show(bt);
+   evas_object_smart_callback_add(bt, "clicked", _bt_route, &example_data);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0);
+
+   example_data.map = map;
+   example_data.entry = entry;
+   example_data.route = NULL;
+   example_data.start_lon = -43.175;
+   example_data.start_lat = -22.97;
+
+   elm_map_geo_region_show(map, example_data.start_lon, example_data.start_lat);
+   elm_map_zoom_set(map, 12);
+
+   evas_object_resize(win, 512, 512);
+   evas_object_show(win);
+
+   ecore_timer_add(0.5, _nasty_hack, win);
+
+   elm_run();
+   return 0;
+}
+ELM_MAIN()