From b676045cf877409db34bd13ca3e41da89bf09b87 Mon Sep 17 00:00:00 2001 From: Bruno Dilly Date: Thu, 4 Aug 2011 22:35:12 +0000 Subject: [PATCH] Elementary: Map examples SVN revision: 62115 --- doc/examples.dox | 290 ++++++++++++++++++++++++++++++++++++++++++ src/examples/Makefile.am | 9 ++ src/examples/map_example_01.c | 131 +++++++++++++++++++ src/examples/map_example_02.c | 254 ++++++++++++++++++++++++++++++++++++ src/examples/map_example_03.c | 206 ++++++++++++++++++++++++++++++ 5 files changed, 890 insertions(+) create mode 100644 src/examples/map_example_01.c create mode 100644 src/examples/map_example_02.c create mode 100644 src/examples/map_example_03.c diff --git a/doc/examples.dox b/doc/examples.dox index 5f3d631..8155882 100644 --- a/doc/examples.dox +++ b/doc/examples.dox @@ -40,6 +40,12 @@ * @ref clock_example * * @ref mapbuf_example + + * @ref map_example_01 + * + * @ref map_example_02 + * + * @ref map_example_03 * * @ref diskselector_example_01 * @@ -1850,6 +1856,290 @@ */ /** + * @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 43 20 S, 22 90 W . + * 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 43 20 S will + * be represented + * by the value -43.20 . 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 + * "name,loaded" 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 diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am index 7d1de28..f56d4ac 100644 --- a/src/examples/Makefile.am +++ b/src/examples/Makefile.am @@ -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 index 0000000..1441b46 --- /dev/null +++ b/src/examples/map_example_01.c @@ -0,0 +1,131 @@ +/** + * Simple Elementary's map widget 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 +#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 index 0000000..72e590d --- /dev/null +++ b/src/examples/map_example_02.c @@ -0,0 +1,254 @@ +/** + * Simple Elementary's map widget 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 +#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 index 0000000..25ea7cc --- /dev/null +++ b/src/examples/map_example_03.c @@ -0,0 +1,206 @@ +/** + * Simple Elementary's map widget 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 +#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() -- 2.7.4