diff --git a/legacy/elementary/doc/examples.dox b/legacy/elementary/doc/examples.dox index 9b0813747e..fda24f3ec3 100644 --- a/legacy/elementary/doc/examples.dox +++ b/legacy/elementary/doc/examples.dox @@ -1855,99 +1855,76 @@ */ /** - * @page map_example_02 Map Example - Markers Usage + * @page map_example_02 Map Example - Overlay Usage * * This code places a Elementary map widget on a window, - * to exemplify part of the widget's API, related to markers. + * to exemplify part of the widget's API, related to overlays. * - * We'll start this example the same way + * We'll start this example in 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. + * Overlays can be placed over the map to represent anything we want. Let's + * say we want to represent some countries and cities with overlays. + * + * Before we create city or country overlays, let's create class overlays. * - * A marker class can be created as the following code does: - * @skipline marker_class_new - * @until style_set + * @skipline elm_map_overlay_class_add + * @until elm_map_overlay_icon_set + * These lines create a class overlay which represents cities. + * This class overlay will be used for grouping city overlays. + * Later city overlays in the same class are appended to this class overlay. + * if city overlays are near each other, they will be grouped. * - * 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. + * We can set the icon for the class so that the icon will be displayed + * when city overlays are grouped. + * We can set the zoom required to display the overlays that belongs + * to this class, so if the zoom is less than this value, nothing + * will be shown. + * + * Country class can be created in the same way. + * @skipline elm_map_overlay_class_add + * @until elm_map_overlay_icon_set * - * 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 + * Next we'll create some overlays representing cities and coutries. + * We set the data for the overlay so that can be used later when + * clicked callback is called. + * We'll append them into city class to be grouped. + * We'll append them in a list, to close up them later. + * To create a default overlay, we need to pass the coordinates. + * @skipline elm_map_overlay_add + * @until eina_list_append * - * For marker and group classes to represent a country, the same is done: - * @skipline marker_class_new - * @until displayed_set + * We subscribe a smart callback "overlay,clicked" to create bubble on + * the clicked overlay. + * @dontinclude map_example_02.c + * @skipline "overlay,clicked" * - * 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 + * Finally, on our @c main function, we ask the map to show all the overlays + * with the biggest zoom possible, passing the list of overlays added. + * @skipline elm_map_overlays_show * * 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; + * @until Overlay_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: + * To return an icon, all we need to do is to add a elm_icon and return it: * @dontinclude map_example_02.c - * @skipline _map_downloaded + * @skipline _icon_get( * @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 + * For the content, let's return something more elaborate. We will return * a box with an image representing the place, and the name of this place: - * @skipline static Evas_Object + * @skipline _box_get( * @until } * * See @ref map_example_02.c "map_example_02.c" for full source, @@ -1972,7 +1949,7 @@ * 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 + * We'll start this example in 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 diff --git a/legacy/elementary/src/bin/test_map.c b/legacy/elementary/src/bin/test_map.c index 8600469eda..4aa7d7d9fe 100644 --- a/legacy/elementary/src/bin/test_map.c +++ b/legacy/elementary/src/bin/test_map.c @@ -8,10 +8,10 @@ #define MARKER_MAX 1000 #define NAME_ENTRY_TEXT "Enter freeform address" -typedef struct Marker_Data +typedef struct Overlay_Data { const char *file; -} Marker_Data; +} Overlay_Data; typedef struct Map_Source { @@ -19,12 +19,11 @@ typedef struct Map_Source char *source_name; } Map_Source; -static Elm_Map_Marker_Class *itc1, *itc2, *itc_parking; -static Elm_Map_Group_Class *itc_group1, *itc_group2, *itc_group_parking, *route_group; +static Elm_Map_Overlay *route_start, *route_end, *route_clas; +static Elm_Map_Overlay *bubble_img; +static Elm_Map_Overlay *bubble_parking; static Evas_Object *menu, *fs_win; -/*static Elm_Map_Marker *markers[MARKER_MAX];*/ -static Elm_Map_Marker *route_from, *route_to; static Elm_Map_Route *route; static Elm_Map_Name *name; static Evas_Object *track; @@ -33,22 +32,19 @@ static Evas_Coord old_x, old_y; static Evas_Coord old_d; static Map_Source ms[SOURCE_MAX]; -Marker_Data data1 = {PACKAGE_DATA_DIR"/images/logo.png"}; -Marker_Data data2 = {PACKAGE_DATA_DIR"/images/logo_small.png"}; -Marker_Data data3 = {PACKAGE_DATA_DIR"/images/panel_01.jpg"}; -Marker_Data data4 = {PACKAGE_DATA_DIR"/images/plant_01.jpg"}; -Marker_Data data5 = {PACKAGE_DATA_DIR"/images/rock_01.jpg"}; -Marker_Data data6 = {PACKAGE_DATA_DIR"/images/rock_02.jpg"}; -Marker_Data data7 = {PACKAGE_DATA_DIR"/images/sky_01.jpg"}; -Marker_Data data8 = {PACKAGE_DATA_DIR"/images/sky_02.jpg"}; -Marker_Data data9 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"}; -Marker_Data data10 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"}; -Marker_Data data11= {PACKAGE_DATA_DIR"/images/wood_01.jpg"}; - -Marker_Data data_parking= {PACKAGE_DATA_DIR"/images/parking.png"}; - -static Evas_Object * _marker_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data); -static Evas_Object * _group_icon_get(Evas_Object *obj, void *data); +Overlay_Data data1 = {PACKAGE_DATA_DIR"/images/logo.png"}; +Overlay_Data data2 = {PACKAGE_DATA_DIR"/images/logo_small.png"}; +Overlay_Data data3 = {PACKAGE_DATA_DIR"/images/panel_01.jpg"}; +Overlay_Data data4 = {PACKAGE_DATA_DIR"/images/plant_01.jpg"}; +Overlay_Data data5 = {PACKAGE_DATA_DIR"/images/rock_01.jpg"}; +Overlay_Data data6 = {PACKAGE_DATA_DIR"/images/rock_02.jpg"}; +Overlay_Data data7 = {PACKAGE_DATA_DIR"/images/sky_01.jpg"}; +Overlay_Data data8 = {PACKAGE_DATA_DIR"/images/sky_02.jpg"}; +Overlay_Data data9 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"}; +Overlay_Data data10 = {PACKAGE_DATA_DIR"/images/sky_03.jpg"}; +Overlay_Data data11= {PACKAGE_DATA_DIR"/images/wood_01.jpg"}; +Overlay_Data parking= {PACKAGE_DATA_DIR"/images/parking.png"}; +Overlay_Data icon_data = {PACKAGE_DATA_DIR"/images/icon_14.png"}; static void #ifdef ELM_EMAP @@ -98,48 +94,60 @@ my_map_longpressed(void *data __UNUSED__, Evas_Object *obj, void *event_info) name = elm_map_utils_convert_coord_into_name(obj, lon, lat); } +static Evas_Object * +_route_icon_get(Evas_Object *obj) +{ + Evas_Object *icon = elm_icon_add(obj); + elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/bubble.png", NULL); + evas_object_show(icon); + + return icon; +} + static void my_map_clicked_double(void *data __UNUSED__, Evas_Object *obj, void *event_info) { printf("clicked,double\n"); double lon, lat; - double flon, flat, tlon, tlat; Evas_Event_Mouse_Down *down = (Evas_Event_Mouse_Down *)event_info; if (!down) return; if (elm_map_zoom_get(obj) < 5) return; elm_map_canvas_to_geo_convert(obj, down->canvas.x, down->canvas.y, &lon, &lat); printf("x:%d, y:%d, lon:%lf, lat:%lf\n", down->canvas.x, down->canvas.y, lon, lat); - if (!itc1) itc1 = elm_map_marker_class_new(obj); - elm_map_marker_class_del_cb_set(itc1, NULL); - if (!route_group) + if (!route_clas) { - route_group = elm_map_group_class_new(obj); - elm_map_group_class_icon_cb_set(route_group, _group_icon_get); - elm_map_group_class_data_set(route_group, (void *)PACKAGE_DATA_DIR"/images/bubble.png"); - elm_map_group_class_style_set(route_group, "empty"); - elm_map_group_class_zoom_displayed_set(route_group, 5); + route_clas = elm_map_overlay_class_add(obj); + elm_map_overlay_icon_set(route_clas, _route_icon_get(obj)); + elm_map_overlay_displayed_zoom_min_set(route_clas, 5); } - if (route_from && route_to) + if (route_start && route_end) { - elm_map_marker_remove(route_from); - route_from = NULL; - elm_map_marker_remove(route_to); - route_to = NULL; + printf("11\n"); + elm_map_overlay_del(route_start); + elm_map_overlay_del(route_end); elm_map_route_remove(route); + route_start = NULL; + route_end = NULL; + //route = NULL; } - if (!route_from) route_from = elm_map_marker_add(obj, lon, lat, itc1, route_group, NULL); - else route_to = elm_map_marker_add(obj, lon, lat, itc1, route_group, NULL); + if (!route_start) route_start = elm_map_overlay_add(obj, lon, lat); + else route_end = elm_map_overlay_add(obj, lon, lat); - if (route_from && route_to) + if (route_start && route_end) { - elm_map_marker_region_get(route_from, &flon, &flat); - elm_map_marker_region_get(route_to, &tlon, &tlat); - route = elm_map_route_add(obj, ELM_MAP_ROUTE_TYPE_MOTOCAR, ELM_MAP_ROUTE_METHOD_FASTEST, flon, flat, tlon, tlat); + double start_lon, start_lat, end_lon, end_lat; + elm_map_overlay_class_append(route_clas, route_start); + elm_map_overlay_class_append(route_clas, route_end); + elm_map_overlay_geo_get(route_start, &start_lon, &start_lat); + elm_map_overlay_geo_get(route_end, &end_lon, &end_lat); + route = elm_map_route_add(obj, ELM_MAP_ROUTE_TYPE_MOTOCAR, + ELM_MAP_ROUTE_METHOD_FASTEST, + start_lon, start_lat, end_lon, end_lat); elm_map_route_color_set(route, 255, 0, 0, 255); } } @@ -455,7 +463,7 @@ map_marker_add(void *data) int i; Elm_Map_Group_Class *g_clas; Elm_Map_Marker_Class *m_clas; - Marker_Data *d = &data7; + Overlay_Data *d = &data7; if (*markers) return; for (i =0; ifile, NULL); - evas_object_show(icon); - - Evas_Object *o = elm_button_add(obj); - elm_object_part_content_set(o, "icon", icon); - evas_object_show(o); - elm_box_pack_end(bx, o); - } - else - { - Evas_Object *o = evas_object_image_add(evas_object_evas_get(obj)); - evas_object_image_file_set(o, d->file, NULL); - evas_object_image_filled_set(o, EINA_TRUE); - evas_object_size_hint_min_set(o, 64, 64); - evas_object_show(o); - elm_box_pack_end(bx, o); - - Evas_Object *lbl = elm_label_add(obj); - elm_object_text_set(lbl, "Wolves Go !"); - evas_object_show(lbl); - elm_box_pack_end(bx, lbl); - } + img = evas_object_image_add(evas_object_evas_get(obj)); + evas_object_image_file_set(img, data->file, NULL); + evas_object_image_filled_set(img, EINA_TRUE); + evas_object_size_hint_min_set(img, 64, 64); + evas_object_show(img); + elm_box_pack_end(bx, img); + label = elm_label_add(obj); + elm_object_text_set(label, "Wolves go!!"); + evas_object_show(label); + elm_box_pack_end(bx, label); return bx; } static Evas_Object * -_icon_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data) +_icon_get(Evas_Object *obj, Overlay_Data *data) { - Marker_Data *d = data; - Evas_Object *icon = elm_icon_add(obj); - elm_icon_file_set(icon, d->file, NULL); - evas_object_show(icon); - - return icon; -} - -static Evas_Object * -_group_icon_get(Evas_Object *obj, void *data) -{ - char *file = data; - - Evas_Object *icon = elm_icon_add(obj); - elm_icon_file_set(icon, file, NULL); + elm_icon_file_set(icon, data->file, NULL); evas_object_show(icon); return icon; @@ -689,6 +667,62 @@ _map_mouse_up(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj __U } } +static void +_overlay_cb(void *data __UNUSED__, Evas_Object *map, void *ev) +{ + printf("Overlay clicked: "); + Elm_Map_Overlay *overlay = ev; + Evas_Object *bx; + + Overlay_Data *od = elm_map_overlay_data_get(overlay); + if (!od) + { + printf("No overlay data\n"); + } + else if (elm_map_overlay_type_get(overlay) == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + // prevent duplication + if (!bubble_img) bubble_img = elm_map_overlay_bubble_add(map); + + elm_map_overlay_bubble_follow(bubble_img, overlay); + bx = _box_get(map, od); + elm_map_overlay_bubble_content_clear(bubble_img); + elm_map_overlay_bubble_content_append(bubble_img, bx); + printf("overlay rendered\n"); + } + else printf("not default type\n"); +} + +static void +_parking_cb(void *data __UNUSED__, Evas_Object *map, Elm_Map_Overlay *ovl) +{ + printf("Parking clicked\n"); + if (elm_map_overlay_type_get(ovl) != ELM_MAP_OVERLAY_TYPE_DEFAULT) return; + + double lon, lat; + elm_map_overlay_geo_get(ovl, &lon, &lat); + if (!bubble_parking) + { + Evas_Object *bubble, *label; + bubble = elm_bubble_add(map); + elm_bubble_corner_set(bubble, "bottom_left"); + elm_object_text_set(bubble, "Overlay object"); + elm_object_part_text_set(bubble, "info", "Bubble is overlayed"); + + label = elm_label_add(bubble); + elm_object_text_set(label, "Parking Here !!"); + evas_object_show(label); + elm_object_content_set(bubble, label); + + evas_object_resize(bubble, 125, 50); + evas_object_show(bubble); + + bubble_parking = elm_map_overlay_add(map, lon + 0.0006, lat + 0.0006); + elm_map_overlay_content_set(bubble_parking, bubble); + } + elm_map_overlay_geo_set(bubble_parking, lon + 0.0006, lat + 0.0006); +} + void test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) { @@ -707,6 +741,11 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __ map = elm_map_add(win); if (map) { + Elm_Map_Overlay *ovl_1, *ovl_2, *ovl_3, *ovl_4, *ovl_5, *ovl6; + Elm_Map_Overlay *ovl_7, *ovl_8, *ovl_9, *ovl_10, *ovl_11; + Elm_Map_Overlay *parking1, *parking2, *parking3, *parking4, *parking5; + Elm_Map_Overlay *grp1, *grp2, *grp_parking; + srand(time(NULL)); source_names = elm_map_source_names_get(map); @@ -720,34 +759,6 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __ elm_win_resize_object_add(win, map); evas_object_data_set(map, "window", win); - itc1 = elm_map_marker_class_new(map); - elm_map_marker_class_get_cb_set(itc1, _marker_get); - elm_map_marker_class_del_cb_set(itc1, NULL); - - itc2 = elm_map_marker_class_new(map); - elm_map_marker_class_get_cb_set(itc2, _marker_get); - elm_map_marker_class_del_cb_set(itc2, NULL); - elm_map_marker_class_style_set(itc2, "radio2"); - - itc_parking = elm_map_marker_class_new(map); - elm_map_marker_class_get_cb_set(itc_parking, _marker_get); - elm_map_marker_class_del_cb_set(itc_parking, NULL); - elm_map_marker_class_icon_cb_set(itc_parking, _icon_get); - elm_map_marker_class_style_set(itc_parking, "empty"); - - itc_group1 = elm_map_group_class_new(map); - elm_map_group_class_data_set(itc_group1, (void *)PACKAGE_DATA_DIR"/images/plant_01.jpg"); - - itc_group2 = elm_map_group_class_new(map); - elm_map_group_class_style_set(itc_group2, "radio2"); - elm_map_group_class_zoom_displayed_set(itc_group1, 3); - - itc_group_parking = elm_map_group_class_new(map); - elm_map_group_class_icon_cb_set(itc_group_parking, _group_icon_get); - elm_map_group_class_data_set(itc_group_parking, (void *)PACKAGE_DATA_DIR"/images/parking.png"); - elm_map_group_class_style_set(itc_group_parking, "empty"); - elm_map_group_class_zoom_displayed_set(itc_group_parking, 5); - evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_DOWN, _map_mouse_down, map); evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_MOVE, @@ -755,21 +766,6 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __ evas_object_event_callback_add(map, EVAS_CALLBACK_MOUSE_UP, _map_mouse_up, map); - elm_map_marker_add(map, 2.352, 48.857, itc1, itc_group1, &data1); - elm_map_marker_add(map, 2.355, 48.857, itc1, itc_group1, &data3); - elm_map_marker_add(map, 3, 48.857, itc2, itc_group1, &data2); - elm_map_marker_add(map, 2.352, 49, itc2, itc_group1, &data1); - - elm_map_marker_add(map, 7.31451, 48.857127, itc1, itc_group1, &data10); - elm_map_marker_add(map, 7.314704, 48.857119, itc1, itc_group1, &data4); - elm_map_marker_add(map, 7.314704, 48.857119, itc2, itc_group1, &data5); - elm_map_marker_add(map, 7.31432, 48.856785, itc2, itc_group1, &data6); - elm_map_marker_add(map, 7.3148, 48.85725, itc1, itc_group2, &data7); - elm_map_marker_add(map, 7.316445, 48.8572210000694, itc1, itc_group1, &data8); - elm_map_marker_add(map, 7.316527000125, 48.85609, itc2, itc_group2, &data9); - elm_map_marker_add(map, 7.3165409990833, 48.856078, itc2, itc_group1, &data11); - elm_map_marker_add(map, 7.319812, 48.856561, itc2, itc_group2, &data10); - evas_object_smart_callback_add(map, "clicked", my_map_clicked, map); evas_object_smart_callback_add(map, "press", my_map_press, map); evas_object_smart_callback_add(map, "longpressed", my_map_longpressed, map); @@ -789,6 +785,71 @@ test_map(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __ evas_object_smart_callback_add(map, "route,loaded", my_map_route_loaded, map); evas_object_smart_callback_add(map, "name,load", my_map_name_load, map); evas_object_smart_callback_add(map, "name,loaded", my_map_name_loaded, map); + evas_object_smart_callback_add(map, "overlay,clicked", _overlay_cb, map); + + // Create Overlays + ovl_1 = elm_map_overlay_add(map, 2.352, 48.857); + ovl_2 = elm_map_overlay_add(map, 3, 48.857); + ovl_3 = elm_map_overlay_add(map, 2.352, 49); + ovl_4 = elm_map_overlay_add(map, 7.31451, 48.857127); + ovl_5 = elm_map_overlay_add(map, 7.314704, 48.857119); + ovl6 = elm_map_overlay_add(map, 7.31432, 48.856785); + ovl_7 = elm_map_overlay_add(map, 7.3148, 48.85725); + ovl_8 = elm_map_overlay_add(map, 7.316445, 48.8572210000694); + ovl_9 = elm_map_overlay_add(map, 7.316527000125, 48.85609); + ovl_10 = elm_map_overlay_add(map, 7.3165409990833, 48.856078); + ovl_11 = elm_map_overlay_add(map, 7.319812, 48.856561); + elm_map_overlay_data_set(ovl_1, &data1); + elm_map_overlay_data_set(ovl_2, &data2); + elm_map_overlay_data_set(ovl_3, &data3); + elm_map_overlay_data_set(ovl_4, &data4); + elm_map_overlay_data_set(ovl_5, &data5); + elm_map_overlay_data_set(ovl6, &data6); + elm_map_overlay_data_set(ovl_7, &data7); + elm_map_overlay_data_set(ovl_8, &data8); + elm_map_overlay_data_set(ovl_9, &data9); + elm_map_overlay_data_set(ovl_10, &data10); + elm_map_overlay_data_set(ovl_11, &data11); + + // Append overlays to groups + grp1 = elm_map_overlay_class_add(map); + elm_map_overlay_displayed_zoom_min_set(grp1, 3); + elm_map_overlay_class_append(grp1, ovl_1); + elm_map_overlay_class_append(grp1, ovl_2); + elm_map_overlay_class_append(grp1, ovl_3); + elm_map_overlay_class_append(grp1, ovl_4); + elm_map_overlay_class_append(grp1, ovl_5); + elm_map_overlay_class_append(grp1, ovl6); + + // Append overlays to groups + grp2 = elm_map_overlay_class_add(map); + elm_map_overlay_class_append(grp2, ovl_7); + elm_map_overlay_class_append(grp2, ovl_8); + elm_map_overlay_class_append(grp2, ovl_9); + elm_map_overlay_class_append(grp2, ovl_10); + elm_map_overlay_class_append(grp2, ovl_11); + + // Create overlays + parking1 = elm_map_overlay_add(map, 127.04871, 37.25730); + parking2 = elm_map_overlay_add(map, 127.05578, 37.25545); + parking3 = elm_map_overlay_add(map, 127.05515, 37.25439); + parking4 = elm_map_overlay_add(map, 127.05328, 37.25721); + parking5 = elm_map_overlay_add(map, 127.05431, 37.25873); + elm_map_overlay_icon_set(parking4, _icon_get(map, &icon_data)); + elm_map_overlay_get_cb_set(parking1, _parking_cb, NULL); + elm_map_overlay_get_cb_set(parking2, _parking_cb, NULL); + elm_map_overlay_get_cb_set(parking3, _parking_cb, NULL); + elm_map_overlay_get_cb_set(parking4, _parking_cb, NULL); + elm_map_overlay_get_cb_set(parking5, _parking_cb, NULL); + + // Append overlays to groups + grp_parking = elm_map_overlay_class_add(map); + elm_map_overlay_icon_set(grp_parking, _icon_get(map, &parking)); + elm_map_overlay_class_append(grp_parking, parking1); + elm_map_overlay_class_append(grp_parking, parking2); + elm_map_overlay_class_append(grp_parking, parking3); + elm_map_overlay_class_append(grp_parking, parking4); + elm_map_overlay_class_append(grp_parking, parking5); evas_object_show(map); } diff --git a/legacy/elementary/src/examples/map_example_01.c b/legacy/elementary/src/examples/map_example_01.c index 8fd577800c..3572498413 100644 --- a/legacy/elementary/src/examples/map_example_01.c +++ b/legacy/elementary/src/examples/map_example_01.c @@ -19,37 +19,31 @@ 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); + elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL); + zoom = elm_map_zoom_get(data); + elm_map_zoom_set(data, 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); + elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL); + zoom = elm_map_zoom_get(data); + elm_map_zoom_set(data, 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); + elm_map_zoom_mode_set(data, 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); + elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FILL); } static void @@ -117,8 +111,8 @@ elm_main(int argc __UNUSED__, char **argv __UNUSED__) 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); + elm_map_geo_region_show(map, -43.2, -22.9); evas_object_resize(win, 512, 512); evas_object_show(win); diff --git a/legacy/elementary/src/examples/map_example_02.c b/legacy/elementary/src/examples/map_example_02.c index 0a8a8c0e00..e0c9215398 100644 --- a/legacy/elementary/src/examples/map_example_02.c +++ b/legacy/elementary/src/examples/map_example_02.c @@ -1,5 +1,5 @@ /** - * Simple Elementary's map widget example, illustrating markers + * Simple Elementary's map widget example, illustrating overlays * usage. * * See stdout/stderr for output. Compile with: @@ -16,81 +16,93 @@ # define __UNUSED__ #endif -typedef struct _Marker_Data +typedef struct _Overlay_Data { const char *name; const char *file; -} Marker_Data; +} Overlay_Data; -Marker_Data data_argentina = {"Argentina", +Overlay_Data data_argentina = {"Argentina", PACKAGE_DATA_DIR"/images/rock_01.jpg"}; -Marker_Data data_chile = {"Chile", +Overlay_Data data_chile = {"Chile", PACKAGE_DATA_DIR"/images/rock_02.jpg"}; -Marker_Data data_sampa = {"São Paulo", +Overlay_Data data_sampa = {"São Paulo", PACKAGE_DATA_DIR"/images/sky_01.jpg"}; -Marker_Data data_rio = {"Rio de Janeiro", +Overlay_Data data_rio = {"Rio de Janeiro", PACKAGE_DATA_DIR"/images/sky_02.jpg"}; -Marker_Data data_brasilia = {"Brasília", +Overlay_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; +static Elm_Map_Overlay *bubble; +static Evas_Object * +_icon_get(Evas_Object *obj, const char *file) +{ + Evas_Object *icon = elm_icon_add(obj); + elm_icon_file_set(icon, file, NULL); + evas_object_show(icon); + return icon; +} + +static Evas_Object * +_city_icon_get(Evas_Object *obj) +{ + return _icon_get(obj, PACKAGE_DATA_DIR"/images/icon_07.png"); +} + +static Evas_Object * +_clas_city_icon_get(Evas_Object *obj) +{ + return _icon_get(obj, PACKAGE_DATA_DIR"/images/icon_05.png"); +} + +static Evas_Object * +_country_icon_get(Evas_Object *obj) +{ + return _icon_get(obj, PACKAGE_DATA_DIR"/images/icon_06.png"); +} + +static Evas_Object * +_clas_country_icon_get(Evas_Object *obj) +{ + return _icon_get(obj, PACKAGE_DATA_DIR"/images/icon_04.png"); +} + +static Evas_Object * +_box_get(Evas_Object *obj, Overlay_Data *data) +{ + Evas_Object *bx, *img, *label; 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); + img = evas_object_image_add(evas_object_evas_get(obj)); + evas_object_image_file_set(img, data->file, NULL); + evas_object_image_filled_set(img, EINA_TRUE); + evas_object_size_hint_min_set(img, 64, 64); + evas_object_show(img); + elm_box_pack_end(bx, img); + label = elm_label_add(obj); + elm_object_text_set(label, data->name); + evas_object_show(label); + elm_box_pack_end(bx, label); return bx; } -static Evas_Object * -_marker_city_content_get(Evas_Object *obj, Elm_Map_Marker *marker __UNUSED__, void *data __UNUSED__) +static void +_overlay_cb(void *data __UNUSED__, Evas_Object *map, void *ev) { - Evas_Object *icon = elm_icon_add(obj); - elm_icon_file_set(icon, PACKAGE_DATA_DIR"/images/icon_07.png", NULL); - evas_object_show(icon); + printf("Overlay clicked\n"); + Elm_Map_Overlay *overlay = ev; + Evas_Object *bx; - return icon; -} + // prevent duplication + if (!bubble) bubble = elm_map_overlay_bubble_add(map); -static Evas_Object * -_group_city_content_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_content_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_content_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; + elm_map_overlay_bubble_follow(bubble, overlay); + elm_map_overlay_bubble_content_clear(bubble); + bx = _box_get(map, elm_map_overlay_data_get(overlay)); + elm_map_overlay_bubble_content_append(bubble, bx); } static void @@ -152,13 +164,11 @@ EAPI_MAIN 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; + Eina_List *ovls = NULL; + Elm_Map_Overlay *ovl, *city_clas, *country_clas; win = elm_win_add(NULL, "map", ELM_WIN_BASIC); - elm_win_title_set(win, "Map Markers Example"); + elm_win_title_set(win, "Map Overlay Example"); evas_object_smart_callback_add(win, "delete,request", _on_done, NULL); bg = elm_bg_add(win); @@ -198,42 +208,47 @@ elm_main(int argc __UNUSED__, char **argv __UNUSED__) 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_content_get); - elm_map_marker_class_style_set(mc_city, "radio"); + evas_object_smart_callback_add(map, "overlay,clicked", _overlay_cb, NULL); - 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_content_get); - elm_map_group_class_zoom_displayed_set(gc_city, 3); + city_clas = elm_map_overlay_class_add(map); + elm_map_overlay_displayed_zoom_min_set(city_clas, 3); + elm_map_overlay_icon_set(city_clas, _clas_city_icon_get(map)); - 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_content_get); - elm_map_marker_class_style_set(mc_country, "empty"); + country_clas = elm_map_overlay_class_add(map); + elm_map_overlay_displayed_zoom_min_set(country_clas, 1); + elm_map_overlay_icon_set(country_clas, _clas_country_icon_get(map)); - 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_content_get); - elm_map_group_class_zoom_displayed_set(gc_country, 1); + ovl = elm_map_overlay_add(map, -43.2, -22.9); + elm_map_overlay_icon_set(ovl, _city_icon_get(map)); + elm_map_overlay_data_set(ovl, &data_rio); + elm_map_overlay_class_append(city_clas, ovl); + ovls = eina_list_append(ovls, ovl); - 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); + ovl = elm_map_overlay_add(map, -46.63, -23.55); + elm_map_overlay_icon_set(ovl, _city_icon_get(map)); + elm_map_overlay_data_set(ovl, &data_sampa); + elm_map_overlay_class_append(city_clas, ovl); + ovls = eina_list_append(ovls, ovl); - 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); + ovl = elm_map_overlay_add(map, -47.88, -15.78); + elm_map_overlay_icon_set(ovl, _city_icon_get(map)); + elm_map_overlay_data_set(ovl, &data_brasilia); + elm_map_overlay_class_append(city_clas, ovl); + ovls = eina_list_append(ovls, ovl); - elm_map_markers_list_show(markers); + ovl = elm_map_overlay_add(map, -65.23, -35.1); + elm_map_overlay_icon_set(ovl, _country_icon_get(map)); + elm_map_overlay_data_set(ovl, &data_argentina); + elm_map_overlay_class_append(country_clas, ovl); + ovls = eina_list_append(ovls, ovl); + + ovl = elm_map_overlay_add(map, -71.3, -31.75); + elm_map_overlay_icon_set(ovl, _country_icon_get(map)); + elm_map_overlay_data_set(ovl, &data_chile); + elm_map_overlay_class_append(country_clas, ovl); + ovls = eina_list_append(ovls, ovl); + + elm_map_overlays_show(ovls); evas_object_resize(win, 512, 512); evas_object_show(win); diff --git a/legacy/elementary/src/examples/map_example_03.c b/legacy/elementary/src/examples/map_example_03.c index 25f3b6975b..6a49b4511c 100644 --- a/legacy/elementary/src/examples/map_example_03.c +++ b/legacy/elementary/src/examples/map_example_03.c @@ -63,37 +63,31 @@ _bt_route(void *data, Evas_Object *obj __UNUSED__, void *ev __UNUSED__) 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); + elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL); + zoom = elm_map_zoom_get(data); + elm_map_zoom_set(data, 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); + elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_MANUAL); + zoom = elm_map_zoom_get(data); + elm_map_zoom_set(data, 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); + elm_map_zoom_mode_set(data, 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); + elm_map_zoom_mode_set(data, ELM_MAP_ZOOM_MODE_AUTO_FILL); } static void @@ -192,8 +186,8 @@ elm_main(int argc __UNUSED__, char **argv __UNUSED__) 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); + elm_map_geo_region_show(map, example_data.start_lon, example_data.start_lat); evas_object_resize(win, 512, 512); evas_object_show(win); diff --git a/legacy/elementary/src/lib/elm_map.c b/legacy/elementary/src/lib/elm_map.c index 82143010d3..0c90c6d822 100644 --- a/legacy/elementary/src/lib/elm_map.c +++ b/legacy/elementary/src/lib/elm_map.c @@ -12,6 +12,10 @@ typedef struct _Widget_Data Widget_Data; typedef struct _Pan Pan; typedef struct _Grid Grid; typedef struct _Grid_Item Grid_Item; +typedef struct _Overlay_Default Overlay_Default; +typedef struct _Overlay_Group Overlay_Group; +typedef struct _Overlay_Class Overlay_Class; +typedef struct _Overlay_Bubble Overlay_Bubble; typedef struct _Marker_Group Marker_Group; typedef struct _Marker_Bubble Marker_Bubble; typedef struct _Path_Node Path_Node; @@ -19,14 +23,16 @@ typedef struct _Path_Waypoint Path_Waypoint; typedef struct _Url_Data Url_Data; typedef struct _Route_Dump Route_Dump; typedef struct _Name_Dump Name_Dump; -typedef struct _Track_Dump Track_Dump; typedef struct _Delayed_Data Delayed_Data; typedef struct _Map_Sources_Tab Map_Sources_Tab; #define ROUND(z) (((z) < 0) ? (int)ceil((z) - 0.005) : (int)floor((z) + 0.005)) #define EVAS_MAP_POINT 4 #define DEFAULT_TILE_SIZE 256 +#define MAX_CONCURRENT_DOWNLOAD 10 + #define MARER_MAX_NUMBER 30 + #define CACHE_ROOT_PATH "/tmp/elm_map" #define CACHE_PATH CACHE_ROOT_PATH"/%d/%d/%d" #define CACHE_FILE_PATH "%s/%d.png" @@ -47,16 +53,8 @@ typedef struct _Map_Sources_Tab Map_Sources_Tab; #define NOMINATIM_ATTR_LON "lon" #define NOMINATIM_ATTR_LAT "lat" -#define MAX_CONCURRENT_DOWNLOAD 10 - -/* FIXME: This is unused currently -#define GPX_NAME "name>" -#define GPX_COORDINATES "trkpt " -#define GPX_LON "lon" -#define GPX_LAT "lat" -#define GPX_ELE "ele>" -#define GPX_TIME "time>" -*/ +#define OVERLAY_CLASS_ZOOM_MAX 255 +#define OVERLAY_GROUPING_SCALE 2 enum _Route_Xml_Attribute { @@ -91,6 +89,7 @@ struct _Delayed_Data int zoom; double lon, lat; Eina_List *markers; + Eina_List *overlays; }; // Map sources @@ -101,12 +100,12 @@ struct _Map_Sources_Tab const char *name; int zoom_min; int zoom_max; - ElmMapModuleUrlFunc url_cb; + Elm_Map_Module_Url_Func url_cb; Elm_Map_Route_Sources route_source; - ElmMapModuleRouteUrlFunc route_url_cb; - ElmMapModuleNameUrlFunc name_url_cb; - ElmMapModuleGeoIntoCoordFunc geo_into_coord; - ElmMapModuleCoordIntoGeoFunc coord_into_geo; + Elm_Map_Module_Route_Url_Func route_url_cb; + Elm_Map_Module_Name_Url_Func name_url_cb; + Elm_Map_Module_Geo_Into_Coord_Func geo_into_coord; + Elm_Map_Module_Coord_Into_Geo_Func coord_into_geo; }; struct _Url_Data @@ -117,14 +116,83 @@ struct _Url_Data char *fname; }; +struct _Overlay_Default +{ + Evas_Coord w, h; + + // Display priority is obj > icon > clas_obj > clas_icon > layout + Evas_Object *obj; + Evas_Object *icon; + + // if obj or icon exists, do not inherit from class + Evas_Object *clas_obj; // Duplicated from class icon + Evas_Object *clas_obj_ref; // Checking fro class icon is changed + Evas_Object *clas_icon; // Duplicated from class icon + Evas_Object *clas_icon_ref; // Checking for class icon is changed + + char *style; + Evas_Object *layout; + double lon, lat; + Evas_Coord x, y; +}; + +struct _Overlay_Group +{ + Overlay_Default *ovl; + Evas_Object *clas_icon; + Elm_Map_Overlay *clas; + Eina_List *members; +}; + +struct _Overlay_Class +{ + Elm_Map_Overlay *clas; + Evas_Object *obj; + char *style; + Evas_Object *icon; + Eina_List *members; + int zoom_max; +}; + +struct _Overlay_Bubble +{ + Widget_Data *wd; + Evas_Object *pobj; + Evas_Object *obj, *sc, *bx; + double lon, lat; + Evas_Coord x, y, w, h; +}; + +struct _Elm_Map_Overlay +{ + Widget_Data *wd; + + Eina_Bool paused : 1; + Eina_Bool hide : 1; + Evas_Coord zoom_min; + + void *data; // user set data + + Elm_Map_Overlay_Type type; + void *ovl; // Overlay Data for each type + + // These are not used if overlay type is class + Eina_Bool grp_in : 1; + Eina_Bool grp_boss : 1; + Overlay_Group *grp; + + Elm_Map_Overlay_Get_Cb cb; + void *cb_data; +}; + struct _Elm_Map_Marker_Class { const char *style; struct _Elm_Map_Marker_Class_Func { - ElmMapMarkerGetFunc get; - ElmMapMarkerDelFunc del; //if NULL the object will be destroyed with evas_object_del() - ElmMapMarkerIconGetFunc icon_get; + Elm_Map_Marker_Get_Func get; + Elm_Map_Marker_Del_Func del; //if NULL the object will be destroyed with evas_object_del() + Elm_Map_Marker_Icon_Get_Func icon_get; } func; }; @@ -139,7 +207,7 @@ struct _Elm_Map_Group_Class void *data; struct { - ElmMapGroupIconGetFunc icon_get; + Elm_Map_Group_Icon_Get_Func icon_get; } func; Eina_Bool hide : 1; @@ -372,6 +440,8 @@ struct _Widget_Data Eina_List *route; Eina_List *track; Eina_List *names; + + Eina_List *overlays; }; static char *_mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom); @@ -421,6 +491,7 @@ static const char SIG_ROUTE_LOAD[] = "route,load"; static const char SIG_ROUTE_LOADED[] = "route,loaded"; static const char SIG_NAME_LOAD[] = "name,load"; static const char SIG_NAME_LOADED[] = "name,loaded"; +static const char SIG_OVERLAY_CLICKED[] = "overlay,clicked"; static const Evas_Smart_Cb_Description _signals[] = { {SIG_CHANGED, ""}, {SIG_CLICKED, ""}, @@ -442,6 +513,7 @@ static const Evas_Smart_Cb_Description _signals[] = { {SIG_ROUTE_LOADED, ""}, {SIG_NAME_LOAD, ""}, {SIG_NAME_LOADED, ""}, + {SIG_OVERLAY_CLICKED, ""}, {NULL, NULL} }; @@ -452,15 +524,15 @@ module_list_cb(Eina_Module *m, void *data) Widget_Data *wd = data; Map_Sources_Tab *s; - ElmMapModuleSourceFunc source; - ElmMapModuleZoomMinFunc zoom_min; - ElmMapModuleZoomMaxFunc zoom_max; - ElmMapModuleUrlFunc url; - ElmMapModuleRouteSourceFunc route_source; - ElmMapModuleRouteUrlFunc route_url; - ElmMapModuleNameUrlFunc name_url; - ElmMapModuleGeoIntoCoordFunc geo_into_coord; - ElmMapModuleCoordIntoGeoFunc coord_into_geo; + Elm_Map_Module_Source_Func source; + Elm_Map_Module_Zoom_Min_Func zoom_min; + Elm_Map_Module_Zoom_Max_Func zoom_max; + Elm_Map_Module_Url_Func url; + Elm_Map_Module_Route_Source_Func route_source; + Elm_Map_Module_Route_Url_Func route_url; + Elm_Map_Module_Name_Url_Func name_url; + Elm_Map_Module_Geo_Into_Coord_Func geo_into_coord; + Elm_Map_Module_Coord_Into_Geo_Func coord_into_geo; const char *file; file = eina_module_file_get(m); @@ -650,6 +722,22 @@ _obj_place(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coor evas_object_show(obj); } +static void +_region_show(void *data) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + Delayed_Data *dd = data; + int x, y, w, h; + + elm_map_utils_convert_geo_into_coord(dd->wd->obj, dd->lon, dd->lat, + dd->wd->size.w, &x, &y); + _viewport_size_get(dd->wd, &w, &h); + x = x - (w / 2); + y = y - (h / 2); + elm_smart_scroller_child_region_show(dd->wd->scr, x, y, w, h); + evas_object_smart_changed(dd->wd->pan_smart); +} + static void _bubble_update(Marker_Bubble *bubble, Eina_List *contents) { @@ -1090,7 +1178,6 @@ _marker_place(Widget_Data *wd) } } - static void _grid_item_coord_get(Grid_Item *gi, int *x, int *y, int *w, int *h) { @@ -1834,6 +1921,710 @@ _mouse_wheel_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, voi } } +static void +_region_max_min_get(Eina_List *overlays, double *max_longitude, double *min_longitude, double *max_latitude, double *min_latitude) +{ + double max_lon = -180, min_lon = 180; + double max_lat = -90, min_lat = 90; + Elm_Map_Overlay *overlay; + EINA_LIST_FREE(overlays, overlay) + { + double lon, lat; + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + Overlay_Default *ovl = overlay->ovl; + lon = ovl->lon; + lat = ovl->lat; + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) + { + // FIXME: class center coord is alright?? + Overlay_Class *ovl = overlay->ovl; + double max_lo, min_lo, max_la, min_la; + _region_max_min_get(ovl->members, &max_lo, &min_lo, &max_la, + &min_la); + lon = (max_lo + min_lo) / 2; + lat = (max_la + min_la) / 2; + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE) + { + Overlay_Bubble *ovl = overlay->ovl; + lon = ovl->lon; + lat = ovl->lat; + } + else + { + WRN("Not supported overlay type: %d", overlay->type); + continue; + } + if (lon> max_lon) max_lon = lon; + if (lon< min_lon) min_lon = lon; + if (lat > max_lat) max_lat = lat; + if (lat < min_lat) min_lat = lat; + } + if (max_longitude) *max_longitude = max_lon; + if (min_longitude) *min_longitude = min_lon; + if (max_latitude) *max_latitude = max_lat; + if (min_latitude) *min_latitude = min_lat; +} + +static Evas_Object * +_icon_dup(Evas_Object *icon, Evas_Object *parent) +{ + if (!icon || !parent) return NULL; + // Evas_Object do not support object duplication?? + const char *file = NULL, *group = NULL; + Eina_Bool scale_up, scale_down; + + Evas_Object *dup = elm_icon_add(parent); + elm_icon_file_get(icon, &file, &group); + elm_icon_file_set(dup, file, group); + elm_icon_animated_set(dup, elm_icon_animated_get(icon)); + elm_icon_animated_play_set(dup, elm_icon_animated_play_get(icon)); + elm_icon_standard_set(dup, elm_icon_standard_get(icon)); + elm_icon_order_lookup_set(dup, elm_icon_order_lookup_get(icon)); + elm_icon_no_scale_set(dup, elm_icon_no_scale_get(icon)); + elm_icon_scale_get(icon, &scale_up, &scale_down); + elm_icon_scale_set(dup, scale_up, scale_down); + elm_icon_fill_outside_set(dup, elm_icon_fill_outside_get(icon)); + elm_icon_prescale_set(dup, elm_icon_prescale_get(icon)); + elm_icon_aspect_fixed_set(dup, elm_icon_aspect_fixed_get(icon)); + return dup; +} + +static Evas_Object * +_overlay_layout_new(Widget_Data *wd, const char *group) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(group, NULL); + Evas_Object *obj = elm_layout_add(wd->obj); + evas_object_smart_member_add(obj, wd->pan_smart); + evas_object_stack_above(obj, wd->sep_maps_markers); + elm_layout_theme_set(obj, "map/marker", group, elm_widget_style_get(wd->obj)); + return obj; +} + +static void +_overlay_layout_update(Widget_Data *wd, Evas_Object *layout, Evas_Object *icon, const char *text, const char *group) +{ + EINA_SAFETY_ON_NULL_RETURN(wd); + EINA_SAFETY_ON_NULL_RETURN(layout); + + Evas_Object *prev_icon = elm_object_part_content_get(layout, "elm.icon"); + if (icon && (prev_icon != icon)) + { + elm_layout_theme_set(layout, "map/marker", "empty", + elm_widget_style_get(wd->obj)); + elm_object_part_content_set(layout, "elm.icon", icon); + } + else if (text) + { + if (group) elm_layout_theme_set(layout, "map/marker", group, + elm_widget_style_get(wd->obj)); + edje_object_part_text_set(elm_layout_edje_get(layout), "elm.text", text); + } +} + +static void +_overlay_clicked_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *ev __UNUSED__) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + Elm_Map_Overlay *overlay = data; + + evas_object_smart_callback_call(overlay->wd->obj, SIG_OVERLAY_CLICKED, + overlay); + if (overlay->cb) overlay->cb(overlay->cb_data, overlay->wd->obj, + overlay); +} + +static void +_overlay_default_cb_add(Overlay_Default *ovl, Evas_Object_Event_Cb cb, void *data) +{ + EINA_SAFETY_ON_NULL_RETURN(ovl); + EINA_SAFETY_ON_NULL_RETURN(data); + + // FIXME: Add icon or object event callback + evas_object_event_callback_add(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN, cb, + data); +} + +static void +_overlay_default_cb_del(Overlay_Default *ovl, Evas_Object_Event_Cb cb) +{ + EINA_SAFETY_ON_NULL_RETURN(ovl); + // FIXME: Add icon or object event callback + evas_object_event_callback_del(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN, cb); +} + +static void +_overlay_default_hide(Overlay_Default *ovl) +{ + EINA_SAFETY_ON_NULL_RETURN(ovl); + if (ovl->obj) evas_object_hide(ovl->obj); + if (ovl->layout) evas_object_hide(ovl->layout); +} + +static void +_overlay_default_show(Widget_Data *wd, Overlay_Default *ovl) +{ + Evas_Object *disp; + Evas_Coord px, py; + Evas_Coord x, y, w, h; + + if (ovl->obj) + { + disp = ovl->obj; + evas_object_geometry_get(disp, NULL, NULL, &w, &h); + if (w <= 0 || h <= 0) evas_object_size_hint_min_get(disp, &w, &h); + } + else + { + disp = ovl->layout; + w = ovl->w; + h = ovl->h; + } + + _pan_geometry_get(wd, &px, &py); + _coord_rotate(ovl->x + px, ovl->y + py, wd->rotate.cx, wd->rotate.cy, + wd->rotate.d, &x, &y); + _obj_place(disp, x - (w / 2), y - (h / 2), w, h); +} + +static void +_overlay_default_update(Widget_Data *wd, Overlay_Default *ovl, Evas_Object *obj, Evas_Object *icon, Overlay_Class *ovl_clas, const char *text, const char *group) +{ + EINA_SAFETY_ON_NULL_RETURN(wd); + EINA_SAFETY_ON_NULL_RETURN(ovl); + + elm_map_utils_convert_geo_into_coord(wd->obj, ovl->lon, ovl->lat, + wd->size.w, &ovl->x, &ovl->y); + + if (obj) + { + if (ovl->obj == obj) return; + if (ovl->obj) evas_object_del(ovl->obj); + ovl->obj = obj; + } + else if (!(ovl->obj) && icon) + { + if (ovl->icon == icon) return; + if (ovl->icon) evas_object_del(ovl->icon); + ovl->icon = icon; + _overlay_layout_update(wd, ovl->layout, ovl->icon, NULL, NULL); + + } + else if (!(ovl->obj) && !(ovl->icon) && (ovl_clas) && + ((ovl_clas->obj) || (ovl_clas->icon))) + { + // Inherit icon from group overlay's ojbect or icon + + // FIXME: It is hard to duplicate evas object :-) + /* + if (ovl_clas->obj && (ovl_clas->obj != ovl->clas_obj_ref)) + { + if (ovl->clas_obj) evas_object_del(ovl->clas_obj); + ovl->clas_obj_ref = ovl_clas->obj; + ovl->clas_obj = _obj_dup(ovl->clas_obj_ref, ovl->layout); + _overlay_layout_update(wd, ovl->layout, ovl->clas_obj, NULL, NULL); + } + */ + if (ovl_clas->icon && (ovl_clas->icon != ovl->clas_icon_ref)) + { + if (ovl->clas_icon) evas_object_del(ovl->clas_icon); + ovl->clas_icon_ref = ovl_clas->icon; + ovl->clas_icon = _icon_dup(ovl->clas_icon_ref, ovl->layout); + _overlay_layout_update(wd, ovl->layout, ovl->clas_icon, NULL, NULL); + } + } + else if (!(ovl->obj) && !(ovl->icon) && !(ovl->clas_icon) && text) + { + _overlay_layout_update(wd, ovl->layout, NULL, text, group); + } +} + +static void +_overlay_default_free(Overlay_Default *ovl) +{ + EINA_SAFETY_ON_NULL_RETURN(ovl); + if (ovl->obj) evas_object_del(ovl->obj); + if (ovl->icon) evas_object_del(ovl->icon); + if (ovl->clas_icon) evas_object_del(ovl->clas_icon); + evas_object_event_callback_del(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN, + _overlay_clicked_cb); + if (ovl->layout) evas_object_del(ovl->layout); + free(ovl); +} + +static Overlay_Default * +_overlay_default_new(Widget_Data *wd, double lon, double lat, const char *group) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(group, NULL); + + Overlay_Default *ovl = ELM_NEW(Overlay_Default); + _edj_marker_size_get(wd, &(ovl->w), &(ovl->h)); + ovl->layout = _overlay_layout_new(wd, group); + ovl->lon = lon; + ovl->lat = lat; + return ovl; +} + +static void +_overlay_group_clicked_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *ev __UNUSED__) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + Overlay_Group *ovl = data; + + evas_object_smart_callback_call(ovl->clas->wd->obj, SIG_OVERLAY_CLICKED, + ovl->clas); + if (ovl->clas->cb) ovl->clas->cb(ovl->clas->cb_data, ovl->clas->wd->obj, + ovl->clas); +} + +static void +_overlay_group_cb_add(Overlay_Group *ovl) +{ + EINA_SAFETY_ON_NULL_RETURN(ovl); + _overlay_default_cb_add(ovl->ovl, _overlay_group_clicked_cb, ovl); +} + +static void +_overlay_group_cb_del(Overlay_Group *ovl) +{ + EINA_SAFETY_ON_NULL_RETURN(ovl); + _overlay_default_cb_del(ovl->ovl, _overlay_group_clicked_cb); +} + +static void +_overlay_group_update(Widget_Data *wd, Overlay_Group *grp, Eina_List *members) +{ + EINA_SAFETY_ON_NULL_RETURN(wd); + EINA_SAFETY_ON_NULL_RETURN(grp); + + Eina_List *l; + Elm_Map_Overlay *overlay; + Evas_Coord sum_x = 0, sum_y = 0, cnt = 0; + + if (grp->members) eina_list_free(grp->members); + grp->members = members; + + if (!grp->members || eina_list_count(grp->members) <= 0) + { + _overlay_default_hide(grp->ovl); + return; + } + EINA_LIST_FOREACH(grp->members, l, overlay) + { + Overlay_Default *df = overlay->ovl; + sum_x += df->x; + sum_y += df->y; + cnt++; + } + + Overlay_Class *ovl_clas = grp->clas->ovl; + + char text[128]; + snprintf(text, sizeof(text), "%d", cnt); + _overlay_default_update(wd, grp->ovl, NULL, NULL, ovl_clas, text, "radio2"); + + grp->ovl->x = sum_x / cnt; + grp->ovl->y = sum_y / cnt; +} + +static void +_overlay_group_free(Overlay_Group *grp, Elm_Map_Overlay *club_owner) +{ + EINA_SAFETY_ON_NULL_RETURN(grp); + + _overlay_default_cb_del(grp->ovl, _overlay_group_clicked_cb); + _overlay_default_free(grp->ovl); + if (grp->clas) elm_map_overlay_class_remove(grp->clas, club_owner); + if (grp->members) eina_list_free(grp->members); + free(grp); +} + +static Overlay_Group * +_overlay_group_new(Widget_Data *wd) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + + Overlay_Group *grp = ELM_NEW(Overlay_Group); + grp->ovl = ELM_NEW(Overlay_Default); + grp->ovl = _overlay_default_new(wd, -1, -1, "radio2"); + grp->ovl->w *= 2; + grp->ovl->h *= 2; + return grp; +} + +static void +_overlay_class_update(Widget_Data *wd, Overlay_Class *clas, Evas_Object *obj, Evas_Object *icon) +{ + EINA_SAFETY_ON_NULL_RETURN(wd); + EINA_SAFETY_ON_NULL_RETURN(clas); + + if (obj && (clas->obj != obj)) + { + if (clas->obj) evas_object_del(clas->obj); + clas->obj = icon; + } + else if (icon && (clas->icon != icon)) + { + if (clas->icon) evas_object_del(clas->icon); + clas->icon = icon; + } +} + +static void +_overlay_class_free(Overlay_Class *clas) +{ + EINA_SAFETY_ON_NULL_RETURN(clas); + if (clas->icon) evas_object_del(clas->icon); + if (clas->members) eina_list_free(clas->members); + free(clas); +} + +static Overlay_Class * +_overlay_class_new(Widget_Data *wd, Elm_Map_Overlay *clas) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + Overlay_Class *ovl = ELM_NEW(Overlay_Class); + ovl->clas = clas; + ovl->icon = NULL; + ovl->zoom_max = OVERLAY_CLASS_ZOOM_MAX; + return ovl; +} + +static void +_overlay_bubble_cb_add(Overlay_Bubble *ovl, Elm_Map_Overlay *overlay) +{ + EINA_SAFETY_ON_NULL_RETURN(ovl); + EINA_SAFETY_ON_NULL_RETURN(overlay); + evas_object_event_callback_add(ovl->obj, EVAS_CALLBACK_MOUSE_DOWN, + _overlay_clicked_cb, overlay); +} + +static void +_overlay_bubble_cb_del(Overlay_Bubble *ovl) +{ + EINA_SAFETY_ON_NULL_RETURN(ovl); + evas_object_event_callback_del(ovl->obj, EVAS_CALLBACK_MOUSE_DOWN, + _overlay_clicked_cb); +} + +static void +_overlay_bubble_hide(Overlay_Bubble *bubble) +{ + EINA_SAFETY_ON_NULL_RETURN(bubble); + if (bubble->obj) evas_object_hide(bubble->obj); +} + +static void +_overlay_bubble_update(Overlay_Bubble *bubble) +{ + EINA_SAFETY_ON_NULL_RETURN(bubble); + if ((!bubble->pobj) && (bubble->lon >= 0) && (bubble->lat >= 0)) + { + elm_map_utils_convert_geo_into_coord(bubble->wd->obj, bubble->lon, + bubble->lat, bubble->wd->size.w, + &bubble->x, &bubble->y); + } +} + +static void +_overlay_bubble_show(Overlay_Bubble *bubble) +{ + EINA_SAFETY_ON_NULL_RETURN(bubble); + Evas_Coord x, y; + + if ((bubble->x < 0) || (bubble->y < 0)) return; + Evas_Coord px, py; + _pan_geometry_get(bubble->wd, &px, &py); + _coord_rotate(bubble->x + px, bubble->y + py, bubble->wd->rotate.cx, + bubble->wd->rotate.cy, bubble->wd->rotate.d, &x, &y); + x = x - (bubble->w / 2); + y = y - (bubble->h / 2); + _obj_place(bubble->obj, x, y, bubble->w, bubble->h); + //evas_object_raise(bubble->obj); +} + +static void +_overlay_bubble_chase(Overlay_Bubble *bubble) +{ + EINA_SAFETY_ON_NULL_RETURN(bubble); + EINA_SAFETY_ON_NULL_RETURN(bubble->pobj); + + Evas_Coord x, y, w; + evas_object_geometry_get(bubble->pobj, &x, &y, &w, NULL); + x = x + (w / 2) - (bubble->w / 2); + y = y - bubble->h; + _obj_place(bubble->obj, x, y, bubble->w, bubble->h); + evas_object_raise(bubble->obj); +} + +static void +_overlay_bubble_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + _overlay_bubble_hide(data); +} + +static void +_overlay_bubble_chase_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + _overlay_bubble_chase(data); +} + +static void +_overlay_bubble_free(Overlay_Bubble* bubble) +{ + EINA_SAFETY_ON_NULL_RETURN(bubble); + + evas_object_del(bubble->bx); + evas_object_del(bubble->sc); + evas_object_del(bubble->obj); + if (bubble->pobj) + { + evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_HIDE, + _overlay_bubble_hide_cb, bubble); + evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_SHOW, + _overlay_bubble_chase_cb, bubble); + evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_MOVE, + _overlay_bubble_chase_cb, bubble); + } + free(bubble); +} + +static Overlay_Bubble* +_overlay_bubble_new(Widget_Data *wd) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + + Evas_Coord h; + const char *s; + Overlay_Bubble *bubble = ELM_NEW(Overlay_Bubble); + bubble->wd = wd; + + bubble->obj = edje_object_add(evas_object_evas_get(wd->obj)); + _elm_theme_object_set(wd->obj, bubble->obj , "map", "marker_bubble", + elm_widget_style_get(wd->obj)); + evas_object_event_callback_add(bubble->obj, EVAS_CALLBACK_MOUSE_UP, + _overlay_bubble_chase_cb, bubble); + + bubble->sc = elm_scroller_add(bubble->obj); + elm_widget_style_set(bubble->sc, "map_bubble"); + elm_scroller_content_min_limit(bubble->sc, EINA_FALSE, EINA_TRUE); + elm_scroller_policy_set(bubble->sc, ELM_SCROLLER_POLICY_AUTO, + ELM_SCROLLER_POLICY_OFF); + elm_scroller_bounce_set(bubble->sc, _elm_config->thumbscroll_bounce_enable, + EINA_FALSE); + edje_object_part_swallow(bubble->obj, "elm.swallow.content", bubble->sc); + + bubble->bx = elm_box_add(bubble->sc); + evas_object_size_hint_align_set(bubble->bx, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(bubble->bx, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_box_horizontal_set(bubble->bx, EINA_TRUE); + elm_object_content_set(bubble->sc, bubble->bx); + + s = edje_object_data_get(bubble->obj, "size_w"); + if (s) bubble->w = atoi(s); + else bubble->w = 0; + + edje_object_size_min_calc(bubble->obj, NULL, &(bubble->h)); + s = edje_object_data_get(bubble->obj, "size_h"); + if (s) h = atoi(s); + else h = 0; + if (bubble->h < h) bubble->h = h; + + bubble->lon = -1; + bubble->lat = -1; + bubble->x = -1; + bubble->y = -1; + return bubble; +} + +static void +_overlay_grouping(Eina_List *members, Elm_Map_Overlay *overlay) +{ + EINA_SAFETY_ON_NULL_RETURN(members); + EINA_SAFETY_ON_NULL_RETURN(overlay); + // Currently support only basic overlay type + EINA_SAFETY_ON_FALSE_RETURN(overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT); + + Eina_List *l; + Elm_Map_Overlay *overlay_memb; + Eina_List *club_members = NULL; + + // Grouping only supports overlay default + Overlay_Default *ovl = (Overlay_Default *)overlay->ovl; + EINA_LIST_FOREACH(members, l, overlay_memb) + { + Overlay_Default *ovl_memb = overlay_memb->ovl; + if ((overlay_memb->hide) || + (overlay_memb->zoom_min > overlay_memb->wd->zoom)) continue; + if (overlay == overlay_memb || overlay_memb->grp_in) continue; + if (ELM_RECTS_INTERSECT(ovl_memb->x, ovl_memb->y, ovl_memb->w, + ovl_memb->h, ovl->x, ovl->y, + ovl->w * OVERLAY_GROUPING_SCALE, + ovl->h * OVERLAY_GROUPING_SCALE)) + { + // Join group. + overlay_memb->grp_boss = EINA_FALSE; + overlay_memb->grp_in = EINA_TRUE; + club_members = eina_list_append(club_members, overlay_memb); + _overlay_group_update(overlay_memb->wd, overlay_memb->grp, NULL); + _overlay_group_cb_del(overlay_memb->grp); + } + } + + if (eina_list_count(club_members) >= 1) + { + // Mark as boss + overlay->grp_boss = EINA_TRUE; + overlay->grp_in = EINA_TRUE; + club_members = eina_list_append(club_members, overlay); + _overlay_group_update(overlay->wd, overlay->grp, club_members); + _overlay_group_cb_del(overlay->grp); + _overlay_group_cb_add(overlay->grp); + } +} + +static void +_overlay_display(Widget_Data *wd, Elm_Map_Overlay *overlay) +{ + Eina_Bool hide = EINA_FALSE; + + if ((overlay->grp_in) || (overlay->hide) || (overlay->zoom_min > wd->zoom)) + hide = EINA_TRUE; + if ((overlay->grp->clas) && ((overlay->grp->clas->hide) || + (overlay->grp->clas->zoom_min > wd->zoom))) + hide = EINA_TRUE; + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + if (hide) _overlay_default_hide(overlay->ovl); + else _overlay_default_show(wd, overlay->ovl); + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE) + { + if (hide) _overlay_bubble_hide(overlay->ovl); + else _overlay_bubble_show(overlay->ovl); + } +} + +static void +_overlay_place(Widget_Data *wd) +{ + EINA_SAFETY_ON_NULL_RETURN(wd); + + Eina_List *l, *ll; + Elm_Map_Overlay *overlay, *grp; + + if (eina_list_count(wd->overlays) == 0) return; + + // Reset overlays coord & grp except class type + EINA_LIST_FOREACH(wd->overlays, l, overlay) + { + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) continue; + if (overlay->paused) continue; + if ((overlay->grp) && (overlay->grp->clas) && + (overlay->grp->clas->paused)) continue; + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + Overlay_Class *ovl_grp = NULL; + if (overlay->grp->clas) ovl_grp = overlay->grp->clas->ovl; + _overlay_default_update(wd, overlay->ovl, NULL, NULL, ovl_grp, NULL, + NULL); + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE) + _overlay_bubble_update(overlay->ovl); + // Reset grp flags + overlay->grp_in = EINA_FALSE; + overlay->grp_boss = EINA_FALSE; + _overlay_group_update(wd, overlay->grp, NULL); + } + + // Classify into group idol or follwer + EINA_LIST_FOREACH(wd->overlays, l, grp) + { + Elm_Map_Overlay *idol; + Overlay_Class *ovl; + + if (grp->type != ELM_MAP_OVERLAY_TYPE_CLASS) continue; + if ((grp->hide) || (grp->zoom_min > wd->zoom)) continue; + + ovl = grp->ovl; + if (ovl->zoom_max < wd->zoom) continue; + EINA_LIST_FOREACH(ovl->members, ll, idol) + { + if (!idol->grp_in) _overlay_grouping(ovl->members, idol); + } + } + + // Place overlays + EINA_LIST_FOREACH(wd->overlays, l, overlay) + if (overlay->type != ELM_MAP_OVERLAY_TYPE_CLASS) + _overlay_display(wd, overlay); + + // Place group overlays + EINA_LIST_FOREACH(wd->overlays, l, overlay) + { + if (overlay->grp_boss) _overlay_default_show(wd, overlay->grp->ovl); + } +} + +static Evas_Object * +_overlay_obj_get(Elm_Map_Overlay *overlay) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL); + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + Overlay_Default *ovl = overlay->ovl; + return ovl->layout; + } + else + { + ERR("Not supported overlay type: %d", overlay->type); + return NULL; + } +} + +static void +_overlays_show(void *data) +{ + EINA_SAFETY_ON_NULL_RETURN(data); + Delayed_Data *dd = data; + + int zoom; + double max_lon, min_lon, max_lat, min_lat; + Evas_Coord vw, vh; + + _region_max_min_get(dd->overlays, &max_lon, &min_lon, &max_lat, &min_lat); + dd->lon = (max_lon + min_lon) / 2; + dd->lat = (max_lat + min_lat) / 2; + + zoom = dd->wd->src->zoom_min; + _viewport_size_get(dd->wd, &vw, &vh); + while (zoom <= dd->wd->src->zoom_max) + { + Evas_Coord size, max_x, max_y, min_x, min_y; + size = pow(2.0, zoom) * dd->wd->tsize; + elm_map_utils_convert_geo_into_coord(dd->wd->obj, min_lon, max_lat, + size, &min_x, &max_y); + elm_map_utils_convert_geo_into_coord(dd->wd->obj, max_lon, min_lat, + size, &max_x, &min_y); + if ((max_x - min_x) > vw || (max_y - min_y) > vh) break; + zoom++; + } + zoom--; + + zoom_do(dd->wd, zoom); + _region_show(dd); + evas_object_smart_changed(dd->wd->pan_smart); +} + static void _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) { @@ -1923,6 +2714,7 @@ _pan_calculate(Evas_Object *obj) _grid_place(sd->wd); _marker_place(sd->wd); + _overlay_place(sd->wd); _route_place(sd->wd); _track_place(sd->wd); _delayed_do(sd->wd); @@ -2004,6 +2796,7 @@ _del_hook(Evas_Object *obj) Elm_Map_Marker *marker; Elm_Map_Group_Class *group_clas; Elm_Map_Marker_Class *clas; + Elm_Map_Overlay *overlay; Delayed_Data *dd; int idx = 0; Map_Sources_Tab *s; @@ -2072,6 +2865,8 @@ _del_hook(Evas_Object *obj) free(clas); } + EINA_LIST_FREE(wd->overlays, overlay) elm_map_overlay_del(overlay); + if (wd->scr_timer) ecore_timer_del(wd->scr_timer); if (wd->long_timer) ecore_timer_del(wd->long_timer); @@ -2688,22 +3483,6 @@ _region_bring_in(void *data) evas_object_smart_changed(dd->wd->pan_smart); } -static void -_region_show(void *data) -{ - EINA_SAFETY_ON_NULL_RETURN(data); - Delayed_Data *dd = data; - int x, y, w, h; - - elm_map_utils_convert_geo_into_coord(dd->wd->obj, dd->lon, dd->lat, - dd->wd->size.w, &x, &y); - _viewport_size_get(dd->wd, &w, &h); - x = x - (w / 2); - y = y - (h / 2); - elm_smart_scroller_child_region_show(dd->wd->scr, x, y, w, h); - evas_object_smart_changed(dd->wd->pan_smart); -} - static void _marker_list_show(void *data) { @@ -3043,6 +3822,8 @@ elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode) Widget_Data *wd = elm_widget_data_get(obj); EINA_SAFETY_ON_NULL_RETURN(wd); + if ((mode == ELM_MAP_ZOOM_MODE_MANUAL) && (wd->mode == !!mode)) return; + Delayed_Data *data = ELM_NEW(Delayed_Data); data->mode = mode; data->func = _zoom_mode_set; @@ -3476,7 +4257,7 @@ elm_map_markers_list_show(Eina_List *markers) { #ifdef HAVE_ELEMENTARY_ECORE_CON EINA_SAFETY_ON_NULL_RETURN(markers); - EINA_SAFETY_ON_TRUE_RETURN(!eina_list_count(markers)); + EINA_SAFETY_ON_FALSE_RETURN(eina_list_count(markers)); Elm_Map_Marker *marker; marker = eina_list_data_get(markers); @@ -3595,7 +4376,7 @@ elm_map_group_class_style_set(Elm_Map_Group_Class *clas, const char *style) } EAPI void -elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, ElmMapGroupIconGetFunc icon_get) +elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, Elm_Map_Group_Icon_Get_Func icon_get) { #ifdef HAVE_ELEMENTARY_ECORE_CON EINA_SAFETY_ON_NULL_RETURN(clas); @@ -3692,7 +4473,7 @@ elm_map_marker_class_style_set(Elm_Map_Marker_Class *clas, const char *style) } EAPI void -elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerIconGetFunc icon_get) +elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Icon_Get_Func icon_get) { #ifdef HAVE_ELEMENTARY_ECORE_CON EINA_SAFETY_ON_NULL_RETURN(clas); @@ -3704,7 +4485,7 @@ elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerIconGet } EAPI void -elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get) +elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Get_Func get) { #ifdef HAVE_ELEMENTARY_ECORE_CON EINA_SAFETY_ON_NULL_RETURN(clas); @@ -3716,7 +4497,7 @@ elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc } EAPI void -elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del) +elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Del_Func del) { #ifdef HAVE_ELEMENTARY_ECORE_CON EINA_SAFETY_ON_NULL_RETURN(clas); @@ -4309,3 +5090,660 @@ elm_map_track_remove(Evas_Object *obj, Evas_Object *route) (void) route; #endif } + +EAPI Elm_Map_Overlay * +elm_map_overlay_add(Evas_Object *obj, double lon, double lat) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + + Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay); + overlay->wd = wd; + overlay->type = ELM_MAP_OVERLAY_TYPE_DEFAULT; + overlay->ovl = _overlay_default_new(wd, lon, lat, "radio"); + _overlay_default_cb_add(overlay->ovl, _overlay_clicked_cb, overlay); + overlay->grp = _overlay_group_new(wd); + wd->overlays = eina_list_append(wd->overlays, overlay); + + evas_object_smart_changed(wd->pan_smart); + return overlay; +#else + (void) obj; + (void) lon; + (void) lat; + return NULL; +#endif +} + +EAPI void +elm_map_overlay_del(Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + _overlay_default_cb_del(overlay->ovl, _overlay_clicked_cb); + _overlay_default_free(overlay->ovl); + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE) + { + _overlay_bubble_cb_del(overlay->ovl); + _overlay_bubble_free(overlay->ovl); + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) + _overlay_class_free(overlay->ovl); + + if (overlay->grp) + { + _overlay_group_cb_del(overlay->grp); + _overlay_group_free(overlay->grp, overlay); + } + + overlay->wd->overlays = eina_list_remove(overlay->wd->overlays, overlay); + evas_object_smart_changed(overlay->wd->pan_smart); + + free(overlay); +#else + (void) overlay; +#endif +} + +EAPI Elm_Map_Overlay_Type +elm_map_overlay_type_get(Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, ELM_MAP_OVERLAY_TYPE_NONE); + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, ELM_MAP_OVERLAY_TYPE_NONE); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) ELM_MAP_OVERLAY_TYPE_NONE; + + return overlay->type; +#else + (void) overlay; + return OVERLAY_TYPE_NONE; +#endif +} + +EAPI void +elm_map_overlay_data_set(Elm_Map_Overlay *overlay, void *data) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + overlay->data = data; +#else + (void) overlay; + (void) data; +#endif +} + +EAPI void * +elm_map_overlay_data_get(const Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL; + + return overlay->data; +#else + (void) overlay; + return NULL; +#endif +} + +EAPI void +elm_map_overlay_hide_set(Elm_Map_Overlay *overlay, Eina_Bool hide) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + if (overlay->hide == !!hide) return; + overlay->hide = hide; + + evas_object_smart_changed(overlay->wd->pan_smart); +#else + (void) overlay; + (void) hide; +#endif +} + +EAPI Eina_Bool +elm_map_overlay_hide_get(const Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, EINA_FALSE); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) EINA_FALSE; + + return overlay->hide; +#else + (void) overlay; + return EINA_FALSE; +#endif +} + +EAPI void +elm_map_overlay_displayed_zoom_min_set(Elm_Map_Overlay *overlay, int zoom) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + overlay->zoom_min = zoom; + evas_object_smart_changed(overlay->wd->pan_smart); +#else + (void) overlay; + (void) zoom; +#endif +} + +EAPI int +elm_map_overlay_displayed_zoom_min_get(const Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, 0); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) 0; + + return overlay->zoom_min; +#else + (void) overlay; + return 0; +#endif +} + +EAPI void +elm_map_overlay_paused_set(Elm_Map_Overlay *overlay, Eina_Bool paused) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + if (overlay->paused == !!paused) return; + overlay->paused = paused; + + evas_object_smart_changed(overlay->wd->pan_smart); +#else + (void) overlay; + (void) paused; +#endif +} + +EAPI Eina_Bool +elm_map_overlay_paused_get(const Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, EINA_FALSE); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) EINA_FALSE; + + return overlay->paused; +#else + (void) overlay; + return EINA_FALSE; +#endif +} + +EAPI void +elm_map_overlay_show(Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + Overlay_Default *ovl = overlay->ovl; + elm_map_geo_region_show(overlay->wd->obj, ovl->lon, ovl->lat); + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE) + { + Overlay_Bubble *ovl = overlay->ovl; + elm_map_geo_region_show(overlay->wd->obj, ovl->lon, ovl->lat); + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) + { + Overlay_Class *ovl = overlay->ovl; + double lon, lat, max_lo, min_lo, max_la, min_la; + _region_max_min_get(ovl->members, &max_lo, &min_lo, &max_la, &min_la); + lon = (max_lo + min_lo) / 2; + lat = (max_la + min_la) / 2; + elm_map_geo_region_show(overlay->wd->obj, lon, lat); + } + else ERR("Not supported overlay type: %d", overlay->type); + + evas_object_smart_changed(overlay->wd->pan_smart); +#else + (void) overlay; +#endif +} + +EAPI void +elm_map_overlays_show(Eina_List *overlays) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlays); + EINA_SAFETY_ON_FALSE_RETURN(eina_list_count(overlays)); + + Elm_Map_Overlay *overlay; + overlay = eina_list_data_get(overlays); + + Delayed_Data *data = ELM_NEW(Delayed_Data); + data->func = _overlays_show; + data->wd = overlay->wd; + data->overlays = eina_list_clone(overlays); + data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data); + evas_object_smart_changed(data->wd->pan_smart); +#else + (void) overlays; +#endif +} + +EAPI void +elm_map_overlay_geo_set(Elm_Map_Overlay *overlay, double lon, double lat) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + Overlay_Default *ovl = overlay->ovl; + ovl->lon = lon; + ovl->lat = lat; + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE) + { + Overlay_Bubble *ovl = overlay->ovl; + ovl->lon = lon; + ovl->lat = lat; + } + else ERR("Not supported overlay type: %d", overlay->type); + + evas_object_smart_changed(overlay->wd->pan_smart); +#else + (void) overlay; + (void) lon; + (void) lat; +#endif +} + +EAPI void +elm_map_overlay_geo_get(const Elm_Map_Overlay *overlay, double *lon, double *lat) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + const Overlay_Default *ovl = overlay->ovl; + if (lon) *lon = ovl->lon; + if (lat) *lat = ovl->lat; + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE) + { + const Overlay_Bubble *ovl = overlay->ovl; + if (lon) *lon = ovl->lon; + if (lat) *lat = ovl->lat; + } + else ERR("Not supported overlay type: %d", overlay->type); +#else + (void) overlay; + (void) lon; + (void) lat; +#endif +} + +EAPI void +elm_map_overlay_icon_set(Elm_Map_Overlay *overlay, Evas_Object *icon) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(icon); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + _overlay_default_update(overlay->wd, overlay->ovl, NULL, icon, + NULL, NULL, NULL); + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) + _overlay_class_update(overlay->wd, overlay->ovl, NULL, icon); + else ERR("Not supported overlay type: %d", overlay->type); + + evas_object_smart_changed(overlay->wd->pan_smart); +#else + (void) overlay; + (void) icon; +#endif +} + +EAPI const Evas_Object * +elm_map_overlay_icon_get(const Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL; + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + const Overlay_Default *ovl = overlay->ovl; + return elm_object_part_content_get(ovl->layout, "elm.icon"); + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) + { + const Overlay_Class *ovl = overlay->ovl; + return ovl->icon; + } + else + { + ERR("Not supported overlay type: %d", overlay->type); + return NULL; + } +#else + (void) overlay; + return NULL; +#endif +} + +EAPI void +elm_map_overlay_content_set(Elm_Map_Overlay *overlay, Evas_Object *obj) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(obj); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + _overlay_default_update(overlay->wd, overlay->ovl, obj, NULL, NULL, + NULL, NULL); + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) + _overlay_class_update(overlay->wd, overlay->ovl, obj, NULL); + else ERR("Not supported overlay type: %d", overlay->type); + + evas_object_smart_changed(overlay->wd->pan_smart); +#else + (void) overlay; + (void) obj; +#endif +} + +EAPI const Evas_Object * +elm_map_overlay_content_get(const Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL; + + if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + const Overlay_Default *ovl = overlay->ovl; + return elm_object_part_content_get(ovl->layout, "elm.icon"); + } + else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) + { + const Overlay_Class *ovl = overlay->ovl; + return ovl->icon; + } + else + { + ERR("Not supported overlay type: %d", overlay->type); + return NULL; + } +#else + (void) overlay; + return NULL; +#endif +} + +EAPI void +elm_map_overlay_get_cb_set(Elm_Map_Overlay *overlay, Elm_Map_Overlay_Get_Cb get_cb, void *data) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(overlay->wd); + ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype); + + overlay->cb = get_cb; + overlay->cb_data = data; +#else + (void) overlay; + (void) get_cb; + (void) data; +#endif +} + +EAPI Elm_Map_Overlay * +elm_map_overlay_class_add(Evas_Object *obj) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + + Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay); + overlay->wd = wd; + overlay->type = ELM_MAP_OVERLAY_TYPE_CLASS; + overlay->ovl = _overlay_class_new(wd, overlay); + overlay->grp = NULL; + wd->overlays = eina_list_append(wd->overlays, overlay); + + evas_object_smart_changed(wd->pan_smart); + return overlay; +#else + (void) obj; + return NULL; +#endif +} + +EAPI void +elm_map_overlay_class_append(Elm_Map_Overlay *group, Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(group); + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(group->wd); + ELM_CHECK_WIDTYPE(group->wd->obj, widtype); + EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS); + + if (overlay->type != ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + ERR("Currently group supports only default overlays"); + return; + } + + Overlay_Class *ovl = group->ovl; + if (eina_list_data_find(ovl->members, overlay)) + { + ERR("Already added overlay into group"); + return; + } + ovl->members = eina_list_append(ovl->members, overlay); + overlay->grp->clas = group; + + evas_object_smart_changed(group->wd->pan_smart); +#else + (void) group; + (void) overlay; +#endif +} + +EAPI void +elm_map_overlay_class_remove(Elm_Map_Overlay *group, Elm_Map_Overlay *overlay) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(group); + EINA_SAFETY_ON_NULL_RETURN(overlay); + EINA_SAFETY_ON_NULL_RETURN(group->wd); + ELM_CHECK_WIDTYPE(group->wd->obj, widtype); + EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS); + + if (overlay->type != ELM_MAP_OVERLAY_TYPE_DEFAULT) + { + ERR("Currently group supports only default overlays"); + return; + } + Overlay_Class *ovl = group->ovl; + ovl->members = eina_list_remove(ovl->members, overlay); + overlay->grp->clas = NULL; + _overlay_group_update(group->wd, overlay->grp, NULL); + + evas_object_smart_changed(group->wd->pan_smart); +#else + (void) group; + (void) overlay; +#endif +} + +EAPI void +elm_map_overlay_class_zoom_max_set(Elm_Map_Overlay *group, int zoom) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(group); + EINA_SAFETY_ON_NULL_RETURN(group->wd); + ELM_CHECK_WIDTYPE(group->wd->obj, widtype); + EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS); + + Overlay_Class *ovl = group->ovl; + if (ovl->zoom_max == !!zoom) return; + ovl->zoom_max = zoom; + + evas_object_smart_changed(group->wd->pan_smart); +#else + (void) group; + (void) zoom; +#endif +} + +EAPI int +elm_map_overlay_class_zoom_max_get(const Elm_Map_Overlay *group) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN_VAL(group, OVERLAY_CLASS_ZOOM_MAX); + EINA_SAFETY_ON_NULL_RETURN_VAL(group->wd, OVERLAY_CLASS_ZOOM_MAX); + ELM_CHECK_WIDTYPE(group->wd->obj, widtype) OVERLAY_CLASS_ZOOM_MAX; + EINA_SAFETY_ON_FALSE_RETURN_VAL(group->type == ELM_MAP_OVERLAY_TYPE_CLASS, OVERLAY_CLASS_ZOOM_MAX); + + const Overlay_Class *ovl = group->ovl; + return ovl->zoom_max; +#else + (void) group; + return OVERLAY_CLASS_ZOOM_MAX; +#endif +} + +EAPI Elm_Map_Overlay * +elm_map_overlay_bubble_add(Evas_Object *obj) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + ELM_CHECK_WIDTYPE(obj, widtype) NULL; + Widget_Data *wd = elm_widget_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL); + + Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay); + overlay->wd = wd; + overlay->type = ELM_MAP_OVERLAY_TYPE_BUBBLE; + overlay->ovl = _overlay_bubble_new(wd); + _overlay_bubble_cb_add(overlay->ovl, overlay); + overlay->grp = _overlay_group_new(wd); + wd->overlays = eina_list_append(wd->overlays, overlay); + + evas_object_smart_changed(wd->pan_smart); + return overlay; +#else + (void) obj; + return NULL; +#endif +} + +EAPI void +elm_map_overlay_bubble_follow(Elm_Map_Overlay *bubble, Elm_Map_Overlay *parent) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(bubble); + EINA_SAFETY_ON_NULL_RETURN(parent); + ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype); + EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE); + + Overlay_Bubble *ovl = bubble->ovl; + Evas_Object *pobj = _overlay_obj_get(parent); + if (!pobj) return; + + if (ovl->pobj) + { + evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_HIDE, + _overlay_bubble_hide_cb, ovl); + evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_SHOW, + _overlay_bubble_chase_cb, ovl); + evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_MOVE, + _overlay_bubble_chase_cb, ovl); + } + + ovl->pobj = pobj; + evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_HIDE, + _overlay_bubble_hide_cb, ovl); + evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_SHOW, + _overlay_bubble_chase_cb, ovl); + evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_MOVE, + _overlay_bubble_chase_cb, ovl); + + _overlay_bubble_chase(ovl); + evas_object_smart_changed(bubble->wd->pan_smart); +#else + (void) bubble; + (void) parent; +#endif +} + +EAPI void +elm_map_overlay_bubble_content_append(Elm_Map_Overlay *bubble, Evas_Object *content) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(bubble); + EINA_SAFETY_ON_NULL_RETURN(content); + ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype); + EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE); + + Overlay_Bubble *bb = bubble->ovl; + elm_box_pack_end(bb->bx, content); + + evas_object_smart_changed(bubble->wd->pan_smart); +#else + (void) bubble; + (void) content; +#endif +} + +EAPI void +elm_map_overlay_bubble_content_clear(Elm_Map_Overlay *bubble) +{ +#ifdef HAVE_ELEMENTARY_ECORE_CON + EINA_SAFETY_ON_NULL_RETURN(bubble); + ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype); + EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE); + + Overlay_Bubble *bb = bubble->ovl; + elm_box_clear(bb->bx); + + evas_object_smart_changed(bubble->wd->pan_smart); +#else + (void) bubble; +#endif +} diff --git a/legacy/elementary/src/lib/elm_map.h b/legacy/elementary/src/lib/elm_map.h index e3d3540f2c..c2cc6127ab 100644 --- a/legacy/elementary/src/lib/elm_map.h +++ b/legacy/elementary/src/lib/elm_map.h @@ -81,9 +81,9 @@ */ typedef enum { - ELM_MAP_ZOOM_MODE_MANUAL, /**< Zoom controlled manually by elm_map_zoom_set(). It's set by default. */ - ELM_MAP_ZOOM_MODE_AUTO_FIT, /**< Zoom until map fits inside the scroll frame with no pixels outside this area. */ - ELM_MAP_ZOOM_MODE_AUTO_FILL, /**< Zoom until map fills scroll, ensuring no pixels are left unfilled. */ + ELM_MAP_ZOOM_MODE_MANUAL, /**< Zoom controlled manually by elm_map_zoom_set(). It's set by default. */ + ELM_MAP_ZOOM_MODE_AUTO_FIT, /**< Zoom until map fits inside the scroll frame with no pixels outside this area. */ + ELM_MAP_ZOOM_MODE_AUTO_FILL, /**< Zoom until map fills scroll, ensuring no pixels are left unfilled. */ ELM_MAP_ZOOM_MODE_LAST } Elm_Map_Zoom_Mode; @@ -98,9 +98,9 @@ typedef enum */ typedef enum { - ELM_MAP_ROUTE_SOURCE_YOURS, /**< Routing service http://www.yournavigation.org/ . Set by default.*/ - ELM_MAP_ROUTE_SOURCE_MONAV, /**< MoNav offers exact routing without heuristic assumptions. Its routing core is based on Contraction Hierarchies. It's not working with Map yet. */ - ELM_MAP_ROUTE_SOURCE_ORS, /**< Open Route Service: http://www.openrouteservice.org/ . It's not working with Map yet. */ + ELM_MAP_ROUTE_SOURCE_YOURS, /**< Routing service http://www.yournavigation.org/ . Set by default.*/ + ELM_MAP_ROUTE_SOURCE_MONAV, /**< MoNav offers exact routing without heuristic assumptions. Its routing core is based on Contraction Hierarchies. It's not working with Map yet. */ + ELM_MAP_ROUTE_SOURCE_ORS, /**< Open Route Service: http://www.openrouteservice.org/ . It's not working with Map yet. */ ELM_MAP_ROUTE_SOURCE_LAST } Elm_Map_Route_Sources; @@ -119,9 +119,9 @@ typedef enum */ typedef enum { - ELM_MAP_ROUTE_TYPE_MOTOCAR, /**< Route should consider an automobile will be used. */ - ELM_MAP_ROUTE_TYPE_BICYCLE, /**< Route should consider a bicycle will be used by the user. */ - ELM_MAP_ROUTE_TYPE_FOOT, /**< Route should consider user will be walking. */ + ELM_MAP_ROUTE_TYPE_MOTOCAR, /**< Route should consider an automobile will be used. */ + ELM_MAP_ROUTE_TYPE_BICYCLE, /**< Route should consider a bicycle will be used by the user. */ + ELM_MAP_ROUTE_TYPE_FOOT, /**< Route should consider user will be walking. */ ELM_MAP_ROUTE_TYPE_LAST } Elm_Map_Route_Type; @@ -134,11 +134,31 @@ typedef enum */ typedef enum { - ELM_MAP_ROUTE_METHOD_FASTEST, /**< Route should prioritize time. */ + ELM_MAP_ROUTE_METHOD_FASTEST, /**< Route should prioritize time. */ ELM_MAP_ROUTE_METHOD_SHORTEST, /**< Route should prioritized distance. */ ELM_MAP_ROUTE_METHOD_LAST } Elm_Map_Route_Method; +/** + * Set overlay type to be used. This type is resolved + * when the overlay is created. + * You can get this value by elm_map_overlay_type_get(). + * + * @see elm_map_overlay_type_get() + * @see elm_map_overlay_add() + * @see elm_map_overlay_class_add() + * @see elm_map_overlay_bubble_add() + * + * @ingroup Map + */ +typedef enum _Elm_Map_Overlay_Type +{ + ELM_MAP_OVERLAY_TYPE_NONE = 0, + ELM_MAP_OVERLAY_TYPE_DEFAULT, + ELM_MAP_OVERLAY_TYPE_CLASS, + ELM_MAP_OVERLAY_TYPE_BUBBLE +} Elm_Map_Overlay_Type; + typedef enum { ELM_MAP_NAME_METHOD_SEARCH, @@ -146,27 +166,29 @@ typedef enum ELM_MAP_NAME_METHOD_LAST } Elm_Map_Name_Method; -typedef struct _Elm_Map_Marker Elm_Map_Marker; /**< A marker to be shown in a specific point of the map. Can be created with elm_map_marker_add() and deleted with elm_map_marker_remove(). */ +typedef struct _Elm_Map_Marker Elm_Map_Marker; /**< A marker to be shown in a specific point of the map. Can be created with elm_map_marker_add() and deleted with elm_map_marker_remove(). */ typedef struct _Elm_Map_Marker_Class Elm_Map_Marker_Class; /**< Each marker must be associated to a class. It's required to add a mark. The class defines the style of the marker when a marker is displayed alone (not grouped). A new class can be created with elm_map_marker_class_new(). */ -typedef struct _Elm_Map_Group_Class Elm_Map_Group_Class; /**< Each marker must be associated to a group class. It's required to add a mark. The group class defines the style of the marker when a marker is grouped to other markers. Markers with the same group are grouped if they are close. A new group class can be created with elm_map_marker_group_class_new(). */ -typedef struct _Elm_Map_Route Elm_Map_Route; /**< A route to be shown in the map. Can be created with elm_map_route_add() and deleted with elm_map_route_remove(). */ -typedef struct _Elm_Map_Name Elm_Map_Name; /**< A handle for specific coordinates. */ -typedef struct _Elm_Map_Track Elm_Map_Track; +typedef struct _Elm_Map_Group_Class Elm_Map_Group_Class; /**< Each marker must be associated to a group class. It's required to add a mark. The group class defines the style of the marker when a marker is grouped to other markers. Markers with the same group are grouped if they are close. A new group class can be created with elm_map_marker_group_class_new(). */ +typedef struct _Elm_Map_Route Elm_Map_Route; /**< A route to be shown in the map. Can be created with elm_map_route_add() and deleted with elm_map_route_remove(). */ +typedef struct _Elm_Map_Name Elm_Map_Name; /**< A handle for specific coordinates. */ +typedef struct _Elm_Map_Overlay Elm_Map_Overlay; /**< A overlay to be shown in a specific point of the map. This can be created by elm_map_overlay_add() and similar functions and deleted by elm_map_overlay_del(). */ -typedef Evas_Object *(*ElmMapMarkerGetFunc)(Evas_Object *obj, Elm_Map_Marker *marker, void *data); /**< Bubble content fetching class function for marker classes. When the user click on a marker, a bubble is displayed with a content. */ -typedef void (*ElmMapMarkerDelFunc)(Evas_Object *obj, Elm_Map_Marker *marker, void *data, Evas_Object *o); /**< Function to delete bubble content for marker classes. */ -typedef Evas_Object *(*ElmMapMarkerIconGetFunc)(Evas_Object *obj, Elm_Map_Marker *marker, void *data); /**< Icon fetching class function for marker classes. */ -typedef Evas_Object *(*ElmMapGroupIconGetFunc)(Evas_Object *obj, void *data); /**< Icon fetching class function for markers group classes. */ +typedef Evas_Object *(*Elm_Map_Marker_Get_Func)(Evas_Object *obj, Elm_Map_Marker *marker, void *data); /**< Bubble content fetching class function for marker classes. When the user click on a marker, a bubble is displayed with a content. */ +typedef void (*Elm_Map_Marker_Del_Func)(Evas_Object *obj, Elm_Map_Marker *marker, void *data, Evas_Object *o); /**< Function to delete bubble content for marker classes. */ +typedef Evas_Object *(*Elm_Map_Marker_Icon_Get_Func)(Evas_Object *obj, Elm_Map_Marker *marker, void *data); /**< Icon fetching class function for marker classes. */ +typedef Evas_Object *(*Elm_Map_Group_Icon_Get_Func)(Evas_Object *obj, void *data); /**< Icon fetching class function for markers group classes. */ -typedef char *(*ElmMapModuleSourceFunc)(void); -typedef int (*ElmMapModuleZoomMinFunc)(void); -typedef int (*ElmMapModuleZoomMaxFunc)(void); -typedef char *(*ElmMapModuleUrlFunc)(Evas_Object *obj, int x, int y, int zoom); -typedef int (*ElmMapModuleRouteSourceFunc)(void); -typedef char *(*ElmMapModuleRouteUrlFunc)(Evas_Object *obj, char *type_name, int method, double flon, double flat, double tlon, double tlat); -typedef char *(*ElmMapModuleNameUrlFunc)(Evas_Object *obj, int method, char *name, double lon, double lat); -typedef Eina_Bool (*ElmMapModuleGeoIntoCoordFunc)(const Evas_Object *obj, int zoom, double lon, double lat, int size, int *x, int *y); -typedef Eina_Bool (*ElmMapModuleCoordIntoGeoFunc)(const Evas_Object *obj, int zoom, int x, int y, int size, double *lon, double *lat); +typedef void (*Elm_Map_Overlay_Get_Cb)(void *data, Evas_Object *map, Elm_Map_Overlay *overlay); /**< Get callback function for the overlay. */ + +typedef char *(*Elm_Map_Module_Source_Func)(void); +typedef int (*Elm_Map_Module_Zoom_Min_Func)(void); +typedef int (*Elm_Map_Module_Zoom_Max_Func)(void); +typedef char *(*Elm_Map_Module_Url_Func)(Evas_Object *obj, int x, int y, int zoom); +typedef int (*Elm_Map_Module_Route_Source_Func)(void); +typedef char *(*Elm_Map_Module_Route_Url_Func)(Evas_Object *obj, char *type_name, int method, double flon, double flat, double tlon, double tlat); +typedef char *(*Elm_Map_Module_Name_Url_Func)(Evas_Object *obj, int method, char *name, double lon, double lat); +typedef Eina_Bool (*Elm_Map_Module_Geo_Into_Coord_Func)(const Evas_Object *obj, int zoom, double lon, double lat, int size, int *x, int *y); +typedef Eina_Bool (*Elm_Map_Module_Coord_Into_Geo_Func)(const Evas_Object *obj, int zoom, int x, int y, int size, double *lon, double *lat); /** * Add a new map widget to the given parent Elementary (container) object. @@ -345,7 +367,7 @@ EAPI void elm_map_paused_set(Evas_Object *obj, Eina_Bool paused * * @param obj The map object. * @return @c EINA_TRUE means map is pause. @c EINA_FALSE indicates - * it is not. If @p obj is @c NULL, @c EINA_FALSE is returned. + * it is not. * * This gets the current paused state for the map object. * @@ -389,7 +411,7 @@ EAPI void elm_map_paused_markers_set(Evas_Object *obj, Eina_Boo * * @param obj The map object. * @return @c EINA_TRUE means map @b won't display markers or @c EINA_FALSE - * indicates it will. If @p obj is @c NULL, @c EINA_FALSE is returned. + * indicates it will. * * This gets the current markers paused state for the map object. * @@ -661,12 +683,12 @@ EAPI void elm_map_marker_show(Elm_Map_Marker *marker); EAPI void elm_map_markers_list_show(Eina_List *markers); /** - * Get the Evas object returned by the ElmMapMarkerGetFunc callback + * Get the Evas object returned by the Elm_Map_Marker_Get_Func callback * * @param marker The marker which content should be returned. * @return Return the evas object if it exists, else @c NULL. * - * To set callback function #ElmMapMarkerGetFunc for the marker class, + * To set callback function #Elm_Map_Marker_Get_Func for the marker class, * elm_map_marker_class_get_cb_set() should be used. * * This content is what will be inside the bubble that will be displayed @@ -691,8 +713,8 @@ EAPI Evas_Object *elm_map_marker_object_get(const Elm_Map_Marker *marke * @param marker The marker to be updated. * * If a content is set to this marker, it will call function to delete it, - * #ElmMapMarkerDelFunc, and then will fetch the content again with - * #ElmMapMarkerGetFunc. + * #Elm_Map_Marker_Del_Func, and then will fetch the content again with + * #Elm_Map_Marker_Get_Func. * * These functions are set for the marker class with * elm_map_marker_class_get_cb_set() and elm_map_marker_class_del_cb_set(). @@ -706,7 +728,7 @@ EAPI void elm_map_marker_update(Elm_Map_Marker *marker); * * @param obj The map object. * - * A bubble is displayed with a content fetched with #ElmMapMarkerGetFunc + * A bubble is displayed with a content fetched with #Elm_Map_Marker_Get_Func * when the user clicks on a marker. * * This functions is set for the marker class with @@ -741,7 +763,7 @@ EAPI void elm_map_bubbles_close(Evas_Object *obj); * elm_map_group_class_zoom_grouped_set(). * - visibility - set if markers will be visible or not, set with * elm_map_group_class_hide_set(). - * - #ElmMapGroupIconGetFunc - used to fetch icon for markers group classes. + * - #Elm_Map_Group_Icon_Get_Func - used to fetch icon for markers group classes. * It can be set using elm_map_group_class_icon_cb_set(). * * @see elm_map_marker_add() @@ -791,7 +813,7 @@ EAPI void elm_map_group_class_style_set(Elm_Map_Group_Class *cl * * @ingroup Map */ -EAPI void elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, ElmMapGroupIconGetFunc icon_get); +EAPI void elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, Elm_Map_Group_Icon_Get_Func icon_get); /** * Set the data associated to the group class. @@ -877,11 +899,11 @@ EAPI void elm_map_group_class_hide_set(Evas_Object *obj, Elm_Ma * * Some properties and functions can be set by class, as: * - style, with elm_map_marker_class_style_set() - * - #ElmMapMarkerIconGetFunc - used to fetch icon for markers classes. + * - #Elm_Map_Marker_Icon_Get_Func - used to fetch icon for markers classes. * It can be set using elm_map_marker_class_icon_cb_set(). - * - #ElmMapMarkerGetFunc - used to fetch bubble content for marker classes. + * - #Elm_Map_Marker_Get_Func - used to fetch bubble content for marker classes. * Set using elm_map_marker_class_get_cb_set(). - * - #ElmMapMarkerDelFunc - used to delete bubble content for marker classes. + * - #Elm_Map_Marker_Del_Func - used to delete bubble content for marker classes. * Set using elm_map_marker_class_del_cb_set(). * * @see elm_map_marker_add() @@ -929,7 +951,7 @@ EAPI void elm_map_marker_class_style_set(Elm_Map_Marker_Class * * * @ingroup Map */ -EAPI void elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerIconGetFunc icon_get); +EAPI void elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Icon_Get_Func icon_get); /** * Set the bubble content callback function of a marker class. @@ -950,7 +972,7 @@ EAPI void elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class * * @ingroup Map */ -EAPI void elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get); +EAPI void elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Get_Func get); /** * Set the callback function used to delete bubble content of a marker class. @@ -976,7 +998,7 @@ EAPI void elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class * * @ingroup Map */ -EAPI void elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del); +EAPI void elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Del_Func del); /** * Get the list of available sources. @@ -1375,7 +1397,7 @@ EAPI void elm_map_wheel_disabled_set(Evas_Object *obj, Eina_Boo * * @param obj The map object. * @return @c EINA_TRUE means map is disabled. @c EINA_FALSE indicates - * it is enabled. If @p obj is @c NULL, @c EINA_FALSE is returned. + * it is enabled. * * Mouse wheel can be used for the user to zoom in or zoom out the map. * @@ -1410,6 +1432,496 @@ EAPI Evas_Object *elm_map_track_add(Evas_Object *obj, EMap_Route *emap) */ EAPI void elm_map_track_remove(Evas_Object *obj, Evas_Object *route); +/** + * Add a new overlay to the map object. This overlay has a default type. + * + * @param obj The map object to add a new overlay. + * @param lon The longitude of the overlay. + * @param lat The latitude of the overlay. + * @return The created overlay or @c NULL upon failure. + * + * A overlay will be created and shown in a specific point of the map, defined + * by @p lon and @p lat. + * + * The created overlay has a default style layout before content or + * icon is set. + * If content or icon is set, those are displayed instead of default style + * layout. + * You can set by using elm_map_overlay_content_set() or + * elm_map_overlay_icon_set(). If NULL is set, default style + * is shown again. + * + * Overlay created with this method can be deleted by elm_map_overlay_del(). + * + * @see elm_map_overlay_del() + * @see elm_map_overlay_class_add() + * @see elm_map_overlay_bubble_add() + * @see elm_map_overlay_content_set() + * @see elm_map_overlay_icon_set() + * + * @ingroup Map + */ +EAPI Elm_Map_Overlay * elm_map_overlay_add(Evas_Object *obj, double lon, double lat); + +/** + * Delete a overlay from the map. This function can delete all types + * of overlays. + * + * @param overlay The overlay to be deleted. + * + * @see elm_map_overlay_add() + * @see elm_map_overlay_class_add() + * @see elm_map_overlay_bubble_add() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_del(Elm_Map_Overlay *overlay); + +/** + * Get the overlay type. + * + * @param overlay The overlay to return type. + * @return Return the overlay type. + * + * This type is resolved when the overlay is created. + * + * @see elm_map_overlay_add() + * @see elm_map_overlay_class_add() + * @see elm_map_overlay_bubble_add() + * + * @ingroup Map + */ +EAPI Elm_Map_Overlay_Type elm_map_overlay_type_get(Elm_Map_Overlay *overlay); + + /** + * Set a pointer of user data for a overlay. + * + * @param overlay The overlay to own the user data. + * @param data A pointer of user data + * + * @see elm_map_overlay_data_get() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_data_set(Elm_Map_Overlay *overlay, void *data); + +/** + * Get the user data stored on a overlay. + * + * @param overlay The overlay to return the user data. + * @return A pointer to data stored using elm_map_overlay_data_set(), + * or @c NULL, if none has been set. + * + * @see elm_map_overlay_data_set() + * + * @ingroup Map + */ +EAPI void * elm_map_overlay_data_get(const Elm_Map_Overlay *overlay); + +/** + * Set if the overlay is hidden or not. + * + * @param overlay The overlay to be hidden. + * @param hide Use @c EINA_TRUE to hide the overlay or @c EINA_FALSE to show. + * + * @see elm_map_overlay_hide_get(). + * + * @ingroup Map + */ +EAPI void elm_map_overlay_hide_set(Elm_Map_Overlay *overlay, Eina_Bool hide); + +/** + * Get a value whether the overlay is hidden or not. + * + * @param overlay The overlay to return the hidden state. + * @return @c EINA_TRUE means the overlay is hidden. @c EINA_FALSE indicates + * it is not. + * + * This gets the current hidden state for the overlay. + * + * @see elm_map_overlay_hide_set(). + * + * @ingroup Map + */ +EAPI Eina_Bool elm_map_overlay_hide_get(const Elm_Map_Overlay *overlay); + +/** + * Set the minimum zoom from where the overlay is displayed. + * + * @param overlay The overlay to be set the minimum zoom. + * @param zoom The minimum zoom. + * + * The overlay only will be displayed when the map is displayed at @p zoom + * or bigger. + * + * @see elm_map_overlay_displayed_zoom_min_get(). + * + * @ingroup Map + */ +EAPI void elm_map_overlay_displayed_zoom_min_set(Elm_Map_Overlay *overlay, int zoom); + +/** + * Get the minimum zoom from where the overlay is displayed. + * + * @param overlay The overlay to return the minimum zoom. + * @return zoom The minimum zoom. + * + * @see elm_map_overlay_displayed_zoom_min_set(). + * + * @ingroup Map + */ +EAPI int elm_map_overlay_displayed_zoom_min_get(const Elm_Map_Overlay *overlay); + +/** + * Pause or unpause the overlay. + * + * @param overlay The overlay to be paused. + * @param paused Use @c EINA_TRUE to pause the @p overlay or @c EINA_FALSE + * to unpause it. + * + * This sets the paused state to on (@c EINA_TRUE) or off (@c EINA_FALSE) + * for the overlay. + * + * The default is off. + * + * This will stop moving the overlay coordinates instantly. + * even if map being scrolled or zoomed. + * + * @see elm_map_overlay_paused_get() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_paused_set(Elm_Map_Overlay *overlay, Eina_Bool paused); + +/** + * Get a value whether the overlay is paused or not. + * + * @param overlay The overlay to return paused state. + * @return @c EINA_TRUE means overlay is paused. @c EINA_FALSE indicates + * it is not. + * + * This gets the current paused state for the overlay. + * + * @see elm_map_overlay_paused_set(). + * + * @ingroup Map + */ +EAPI Eina_Bool elm_map_overlay_paused_get(const Elm_Map_Overlay *overlay); + +/** + * Set the content object of the overlay. + * + * @param overlay The overlay to be set the content. + * @param obj The evas object will be used to display the overlay. + * + * Only default and class type overlay support this function. + * + * The content should be resized or set size hints before set to the overlay. + * Do not modify this object (move, show, hide, del, etc.), + * after set. + * You can only resize this. + * + * This content is what will be inside the overlay that will be displayed. + * If a content is set, icon and default style layout are no more used before + * the content is deleted. + * + * If @p obj is @c NULL, content inside the overlay is deleted. + * + * @see elm_map_overlay_content_get(). + * + * @ingroup Map + */ +EAPI void elm_map_overlay_content_set(Elm_Map_Overlay *overlay, Evas_Object *obj); + +/** + * Get the content object. + * + * @param overlay The overlay to return the content. + * @return Return the evas object if it exists, else @c NULL. + * + * Only default and class type overlay support this function. + * + * Returned content is what being inside the overlay that being displayed. + * + * Do not modify this object (move, show, hide, del, etc.). + * You can only resize this. + * + * The content can be set by elm_map_overlay_content_set(). + * + * @see elm_map_overlay_content_set(). + * + * @ingroup Map + */ +EAPI const Evas_Object * elm_map_overlay_content_get(const Elm_Map_Overlay *overlay); + +/** + * Set a icon of the overlay. + * + * @param overlay The overlay to be set the icon. + * @param icon The icon will be used to display the overlay. + * + * Only default and class type overlay support this function. + * + * Do not modify this object (move, show, hide, resize, del, etc.), + * after set. + * + * If icon is set, default style layout will not be used. + * + * If @p icon is @c NULL, icon inside the overlay will be deleted. + * + * @see elm_map_overlay_icon_get(). + * + * @ingroup Map + */ +EAPI void elm_map_overlay_icon_set(Elm_Map_Overlay *overlay, Evas_Object *icon); + +/** + * Get the icon object. + * + * @param overlay The overlay to return the icon. + * @return Return the icon object if it exists, else @c NULL. + * + * Only default and class type overlay support this function. + * + * Returned icon is what being inside the overlay that being displayed. + * + * Do not modify this icon (move, show, hide, resize, del, etc.). + * + * The icon can be set by elm_map_overlay_icon_set(). + * + * @see elm_map_overlay_icon_set(). + * + * @ingroup Map + */ +EAPI const Evas_Object * elm_map_overlay_icon_get(const Elm_Map_Overlay *overlay); + +/** + * Set the geographic coordinates of the overlay. + * + * @param overlay The overlay to be set geographic coordinates. + * @param lon Longitude to be set. + * @param lat Latitude to be set. + * + * Only default and bubble type overlay support this function. + * + * This sets the center coordinates of the overlay. It can be + * get by elm_map_overlay_geo_get(). + * + * @see elm_map_overlay_geo_get() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_geo_set(Elm_Map_Overlay *overlay, double lon, double lat); + +/** + * Get the geographic coordinates of the overlay. + * + * @param overlay The overlay to return geographic coordinates. + * @param lon Pointer to store longitude. + * @param lat Pointer to store latitude. + * + * Only default and bubble type overlay support this function. + * + * This returns the center coordinates of the overlay. It can be + * set by elm_map_overlay_geo_set(). + * + * @see elm_map_overlay_geo_set() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_geo_get(const Elm_Map_Overlay *overlay, double *lon, double *lat); + +/** + * Show the given overlay at the center of the map, immediately. + * + * @param overlay The overlay to be center at. + * + * This causes map to @b redraw its viewport's contents to the + * region containing the given @p overlay's coordinates, that will be + * moved to the center of the map. + * + * @see elm_map_overlays_show() if more than one overlay need to be displayed. + * + * @ingroup Map + */ +EAPI void elm_map_overlay_show(Elm_Map_Overlay *overlay); + +/** + * Move and zoom the map to display a list of overlays. + * + * @param overlays A list of #Elm_Map_Overlay handles. + * + * The map will be centered on the center point of the overlays in the list. + * Then the map will be zoomed in order to fit the overlays using the maximum + * zoom which allows display of all the overlays. + * + * @warning All the overlays should belong to the same map object. + * + * @see elm_map_overlay_show() to show a single overlay. + * + * @ingroup Map + */ +EAPI void elm_map_overlays_show(Eina_List *overlays); + +/** + * Set the get callback function of the overlay. + * + * @param overlay The overlay to own the get callback function. + * @param get_cb The callback function. + * + * You can delete this callback function by setting @c NULL. + * + * @ingroup Map + */ +EAPI void elm_map_overlay_get_cb_set(Elm_Map_Overlay *overlay, Elm_Map_Overlay_Get_Cb get_cb, void *data); + + +/** + * Add a new class overlay to the map object. + * This overlay has a class type. + * + * @param obj The map object to add a new overlay. + * @return The created overlay or @c NULL upon failure. + * + * This overlay is not shown before overlay members are appended. + * if overlay members in the same class are close, group overlays + * are created. If they are far away, group overlays are hidden. + * When group overlays are shown, they have default style layouts at first. + * + * You can changed the state (hidden, paused, etc.) or set the content + * or icon of the group overlays. + * Also these changes have a influence on the overlays in the same class + * even if each overlay is alone and is not grouped. + * + * @see elm_map_overlay_del() + * @see elm_map_overlay_add() + * @see elm_map_overlay_bubble_add() + * + * @ingroup Map + */ +EAPI Elm_Map_Overlay * elm_map_overlay_class_add(Evas_Object *obj); + +/** + * Add a new overlay member to the class overlay. + * + * @param clas The class overlay to add a new overlay. + * @param overlay The overlay to be added to the class overlay. + * + * @see elm_map_overlay_class_remove() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_class_append(Elm_Map_Overlay *clas, Elm_Map_Overlay *overlay); + +/** + * Remove a overlay from the class. + * + * @param clas The class overlay to delete the overlay. + * @param overlay The overlay to be deleted from the class overlay. + * + * @see elm_map_overlay_class_append() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_class_remove(Elm_Map_Overlay *clas, Elm_Map_Overlay *overlay); + +/** + * Set the maximum zoom from where the overlay members in the class can be + * grouped. + * + * @param clas The overlay class has overlay members. + * @param zoom The maximum zoom. + * + * Overlay members in the class only will be grouped when the map + * is displayed at less than @p zoom. + * + * @see elm_map_overlay_class_zoom_max_get(). + * + * @ingroup Map + */ +EAPI +EAPI void elm_map_overlay_class_zoom_max_set(Elm_Map_Overlay *clas, int zoom); + +/** + * Get the zoom from where the overlay members in the class are no more grouped. + * + * @param clas The overlay class has overlay members. + * + * @return The maximum zoom. + * + * @see elm_map_overlay_class_zoom_max_set(). + * + * @ingroup Map + */ +EAPI int elm_map_overlay_class_zoom_max_get(const Elm_Map_Overlay *clas); + +/** + * Add a new bubble overlay to the map object. + * This overlay has a bubble type. + * + * @param obj The map object to add a new overlay. + * @return The created overlay or @c NULL upon failure. + * + * A bubble will not be displayed before geogrphic coordinates are set or + * any other overlays are followed. + * + * This overlay has a bubble style layout and icon or content can not + * be set. + * + * Overlay created with this method can be deleted with elm_map_overlay_del(). + * + * @see elm_map_overlay_del() + * @see elm_map_overlay_add() + * @see elm_map_overlay_class_add() + * @see elm_map_overlay_geo_set() + * @see elm_map_overlay_bubble_follow() + * + * @ingroup Map + */ +EAPI Elm_Map_Overlay * elm_map_overlay_bubble_add(Evas_Object *obj); + +/** + * Follow a other overlay. + * + * @param bubble The bubble overlay to follow a parent overlay. + * @param parent The parent overlay to be followed by the bubble overlay. + * + * Bubble overlay will follow the parent overlay's movement (hide, show, move). + * + * @see elm_map_overlay_bubble_add() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_bubble_follow(Elm_Map_Overlay *bubble, Elm_Map_Overlay *parent); + +/** + * Add a content object to the bubble overlay. + * + * @param bubble The bubble overlay to add a content. + * @param content The content to be added to the bubble overlay. + * + * Added contents will be displayed inside the bubble overlay. + * + * @see elm_map_overlay_bubble_content_clear() + * + * @ingroup Map + */ +EAPI void elm_map_overlay_bubble_content_append(Elm_Map_Overlay *bubble, Evas_Object *content); + +/** + * Clear all contents inside the bubble overlay. + * + * @param bubble The bubble overlay to clear the contents. + * + * This will delete all contents inside the bubble overlay. + * + * @see elm_map_overlay_bubble_content_append() + * + * @ingroup Map + */ + +EAPI void elm_map_overlay_bubble_content_clear(Elm_Map_Overlay *bubble); + /** * @} */