2 # include "elementary_config.h"
5 #include "Elementary.h"
7 #include "els_scroller.h"
9 #ifdef HAVE_ELEMENTARY_ECORE_CON
11 typedef struct _Widget_Data Widget_Data;
12 typedef struct _Pan Pan;
13 typedef struct _Grid Grid;
14 typedef struct _Grid_Item Grid_Item;
16 typedef struct _Marker_Group Marker_Group;
17 typedef struct _Event Event;
19 typedef struct _Overlay_Default Overlay_Default;
20 typedef struct _Overlay_Group Overlay_Group;
21 typedef struct _Overlay_Class Overlay_Class;
22 typedef struct _Overlay_Bubble Overlay_Bubble;
23 typedef struct _Overlay_Route Overlay_Route;
24 typedef struct _Marker_Group Marker_Group;
25 typedef struct _Marker_Bubble Marker_Bubble;
26 >>>>>>> remotes/origin/upstream
27 typedef struct _Path_Node Path_Node;
28 typedef struct _Path_Waypoint Path_Waypoint;
29 typedef struct _Url_Data Url_Data;
30 typedef struct _Route_Dump Route_Dump;
31 typedef struct _Name_Dump Name_Dump;
33 typedef struct _Track_Dump Track_Dump;
35 #define CACHE_ROOT_PATH "/tmp/elm_map"
36 #define CACHE_PATH CACHE_ROOT_PATH"/%d/%d/%d"
37 #define CACHE_FILE_PATH "%s/%d.png"
38 #define DEST_ROUTE_XML_FILE "/tmp/elm_map-route-XXXXXX"
39 #define DEST_NAME_XML_FILE "/tmp/elm_map-name-XXXXXX"
41 #define ROUTE_YOURS_URL "http://www.yournavigation.org/api/dev/route.php"
42 #define ROUTE_TYPE_MOTORCAR "motocar"
43 #define ROUTE_TYPE_BICYCLE "bicycle"
44 #define ROUTE_TYPE_FOOT "foot"
45 #define YOURS_DISTANCE "distance"
46 #define YOURS_DESCRIPTION "description"
47 #define YOURS_COORDINATES "coordinates"
49 // TODO: fix monav & ors url
50 #define ROUTE_MONAV_URL "http://"
51 #define ROUTE_ORS_URL "http:///"
53 #define NAME_NOMINATIM_URL "http://nominatim.openstreetmap.org"
54 #define NOMINATIM_RESULT "result"
55 #define NOMINATIM_PLACE "place"
56 #define NOMINATIM_ATTR_LON "lon"
57 #define NOMINATIM_ATTR_LAT "lat"
59 #define PINCH_ZOOM_MIN 0.25
60 #define PINCH_ZOOM_MAX 4.0
61 #define MAX_CONCURRENT_DOWNLOAD 10
63 #define GPX_NAME "name>"
64 #define GPX_COORDINATES "trkpt "
67 #define GPX_ELE "ele>"
68 #define GPX_TIME "time>"
71 // Currently the size of a tile must be 256*256
72 // and the size of the map must be pow(2.0, z)*tile_size
73 typedef struct _Map_Sources_Tab
75 typedef struct _Delayed_Data Delayed_Data;
76 typedef struct _Source_Tile Source_Tile;
77 typedef struct _Source_Route Source_Route;
78 typedef struct _Source_Name Source_Name;
80 typedef char *(*Elm_Map_Module_Source_Name_Func)(void);
81 typedef int (*Elm_Map_Module_Tile_Zoom_Min_Func)(void);
82 typedef int (*Elm_Map_Module_Tile_Zoom_Max_Func)(void);
83 typedef char *(*Elm_Map_Module_Tile_Url_Func)(Evas_Object *obj, int x, int y, int zoom);
84 typedef Eina_Bool (*Elm_Map_Module_Tile_Geo_to_Coord_Func)(const Evas_Object *obj, int zoom, double lon, double lat, int size, int *x, int *y);
85 typedef Eina_Bool (*Elm_Map_Module_Tile_Coord_to_Geo_Func)(const Evas_Object *obj, int zoom, int x, int y, int size, double *lon, double *lat);
86 typedef char *(*Elm_Map_Module_Route_Url_Func)(Evas_Object *obj, const char *type_name, int method, double flon, double flat, double tlon, double tlat);
87 typedef char *(*Elm_Map_Module_Name_Url_Func)(Evas_Object *obj, int method, const char *name, double lon, double lat);
89 #define ROUND(z) (((z) < 0) ? (int)ceil((z) - 0.005) : (int)floor((z) + 0.005))
90 #define EVAS_MAP_POINT 4
91 #define DEFAULT_TILE_SIZE 256
92 #define MAX_CONCURRENT_DOWNLOAD 10
93 #define MARER_MAX_NUMBER 30
94 #define OVERLAY_CLASS_ZOOM_MAX 255
95 #define OVERLAY_GROUPING_SCALE 2
97 #define CACHE_ROOT "/tmp/elm_map"
98 #define CACHE_TILE_ROOT CACHE_ROOT"/%d/%d/%d"
99 #define CACHE_TILE_PATH "%s/%d.png"
100 #define CACHE_ROUTE_ROOT CACHE_ROOT"/route"
101 #define CACHE_NAME_ROOT CACHE_ROOT"/name"
103 #define ROUTE_YOURS_URL "http://www.yournavigation.org/api/dev/route.php"
104 #define ROUTE_TYPE_MOTORCAR "motocar"
105 #define ROUTE_TYPE_BICYCLE "bicycle"
106 #define ROUTE_TYPE_FOOT "foot"
107 #define YOURS_DISTANCE "distance"
108 #define YOURS_DESCRIPTION "description"
109 #define YOURS_COORDINATES "coordinates"
111 #define NAME_NOMINATIM_URL "http://nominatim.openstreetmap.org"
112 #define NOMINATIM_RESULT "result"
113 #define NOMINATIM_PLACE "place"
114 #define NOMINATIM_ATTR_LON "lon"
115 #define NOMINATIM_ATTR_LAT "lat"
117 enum _Route_Xml_Attribute
121 ROUTE_XML_DESCRIPTION,
122 ROUTE_XML_COORDINATES,
124 } Route_Xml_Attibute;
126 enum _Name_Xml_Attribute
135 enum _Track_Xml_Attribute
138 TRACK_XML_COORDINATES,
140 } Track_Xml_Attibute;
144 void (*func)(void *data);
146 Elm_Map_Zoom_Mode mode;
154 // FIXME: Currently tile size must be 256*256
155 // and the map size is pow(2.0, z) * (tile size)
157 >>>>>>> remotes/origin/upstream
163 ElmMapModuleUrlFunc url_cb;
164 Elm_Map_Route_Sources route_source;
165 ElmMapModuleRouteUrlFunc route_url_cb;
166 ElmMapModuleNameUrlFunc name_url_cb;
167 ElmMapModuleGeoIntoCoordFunc geo_into_coord;
168 ElmMapModuleCoordIntoGeoFunc coord_into_geo;
171 //Zemm min is supposed to be 0
172 static char *_mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
173 static char *_osmarender_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
174 static char *_cyclemap_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
175 static char *_mapquest_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
176 static char *_mapquest_aerial_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
178 static char *_yours_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
180 static char *_monav_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
181 static char *_ors_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
183 static char *_nominatim_url_cb(Evas_Object *obj, int method, char *name, double lon, double lat);
185 static Map_Sources_Tab default_map_sources_tab[] =
187 {"Mapnik", 0, 18, _mapnik_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb, NULL, NULL},
188 {"Osmarender", 0, 17, _osmarender_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb, NULL, NULL},
189 {"CycleMap", 0, 16, _cyclemap_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb, NULL, NULL},
190 {"MapQuest", 0, 18, _mapquest_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb, NULL, NULL},
191 {"MapQuest Open Aerial", 0, 11, _mapquest_aerial_url_cb, ELM_MAP_ROUTE_SOURCE_YOURS, _yours_url_cb, _nominatim_url_cb, NULL, NULL},
193 Elm_Map_Module_Tile_Url_Func url_cb;
194 Elm_Map_Module_Tile_Geo_to_Coord_Func geo_to_coord;
195 Elm_Map_Module_Tile_Coord_to_Geo_Func coord_to_geo;
202 Elm_Map_Module_Route_Url_Func url_cb;
209 Elm_Map_Module_Name_Url_Func url_cb;
210 >>>>>>> remotes/origin/upstream
215 Ecore_Con_Url *con_url;
222 struct _Elm_Map_Marker_Class
227 struct _Elm_Map_Marker_Class_Func
229 ElmMapMarkerGetFunc get;
230 ElmMapMarkerDelFunc del; //if NULL the object will be destroyed with evas_object_del()
231 ElmMapMarkerIconGetFunc icon_get;
235 { //this part is private, do not modify these values
237 Evas_Coord edje_w, edje_h;
241 struct _Elm_Map_Marker
244 Elm_Map_Marker_Class *clas;
245 Elm_Map_Group_Class *clas_group;
246 double longitude, latitude;
251 Marker_Group **groups;
252 Evas_Object *content;
254 struct _Overlay_Default
258 // Display priority is obj > icon > clas_obj > clas_icon > layout
262 // if obj or icon exists, do not inherit from class
263 Evas_Object *clas_obj; // Duplicated from class icon
264 Evas_Object *clas_obj_ref; // Checking fro class icon is changed
265 Evas_Object *clas_icon; // Duplicated from class icon
266 Evas_Object *clas_icon_ref; // Checking for class icon is changed
274 struct _Overlay_Group
276 Overlay_Default *ovl;
277 Evas_Object *clas_icon;
278 Elm_Map_Overlay *clas;
282 struct _Overlay_Class
284 Elm_Map_Overlay *clas;
292 struct _Overlay_Bubble
296 Evas_Object *obj, *sc, *bx;
298 Evas_Coord x, y, w, h;
301 struct _Overlay_Route
305 Eina_Bool inbound : 1;
319 struct _Elm_Map_Overlay
323 Eina_Bool paused : 1;
327 void *data; // user set data
329 Elm_Map_Overlay_Type type;
330 void *ovl; // Overlay Data for each type
332 // These are not used if overlay type is class
333 Eina_Bool grp_in : 1;
334 Eina_Bool grp_boss : 1;
337 Elm_Map_Overlay_Get_Cb cb;
341 struct _Elm_Map_Marker_Class
344 struct _Elm_Map_Marker_Class_Func
346 Elm_Map_Marker_Get_Func get;
347 Elm_Map_Marker_Del_Func del; //if NULL the object will be destroyed with evas_object_del()
348 Elm_Map_Marker_Icon_Get_Func icon_get;
350 >>>>>>> remotes/origin/upstream
353 struct _Elm_Map_Group_Class
358 int zoom_displayed; // display the group if the zoom is >= to zoom_display
359 int zoom_grouped; // group the markers only if the zoom is <= to zoom_groups
364 ElmMapGroupIconGetFunc icon_get;
368 { //this part is private, do not modify these values
370 Evas_Coord edje_w, edje_h;
371 Evas_Coord edje_max_w, edje_max_h;
373 Eina_List *objs_used;
374 Eina_List *objs_notused;
380 int zoom_displayed; // display the group if the zoom is >= to zoom_display
381 int zoom_grouped; // group the markers only if the zoom is <= to zoom_groups
386 Elm_Map_Group_Icon_Get_Func icon_get;
392 struct _Marker_Bubble
396 Evas_Object *obj, *sc, *bx;
399 struct _Elm_Map_Marker
402 Elm_Map_Marker_Class *clas;
403 Elm_Map_Group_Class *group_clas;
404 double longitude, latitude;
409 Eina_Bool grouped : 1;
410 Eina_Bool leader : 1; // if marker is group leader
413 Marker_Bubble *bubble;
414 Evas_Object *content;
416 >>>>>>> remotes/origin/upstream
423 Eina_Matrixsparse_Cell *cell;
424 Elm_Map_Group_Class *clas;
427 long long sum_x, sum_y;
431 Evas_Object *obj, *bubble, *sc, *bx, *rect;
433 Eina_Bool bringin : 1;
434 Eina_Bool update_nbelems : 1;
435 Eina_Bool update_resize : 1;
436 Eina_Bool update_raise : 1;
437 Eina_Bool delete_object : 1;
439 Elm_Map_Group_Class *clas;
446 Marker_Bubble *bubble;
447 >>>>>>> remotes/origin/upstream
450 struct _Elm_Map_Route
457 Ecore_Con_Url *con_url;
462 double flon, flat, tlon, tlat;
464 Eina_List *nodes, *path;
469 Elm_Map_Route_Type type;
470 Elm_Map_Route_Method method;
471 double flon, flat, tlon, tlat;
474 Ecore_File_Download_Job *job;
479 >>>>>>> remotes/origin/upstream
485 const char *waypoints;
486 double distance; /* unit : km */
501 Eina_Bool inbound : 1;
506 >>>>>>> remotes/origin/upstream
521 struct _Path_Waypoint
533 Ecore_Con_Url *con_url;
538 Ecore_Event_Handler *handler;
545 Ecore_File_Download_Job *job;
565 >>>>>>> remotes/origin/upstream
583 Eina_Bool file_have : 1;
584 Ecore_File_Download_Job *job;
593 int x, y; // Tile coordinate
594 Eina_Bool file_have : 1;
596 Ecore_File_Download_Job *job;
597 >>>>>>> remotes/origin/upstream
604 int tsize; // size of tile (tsize x tsize pixels)
605 int zoom; // zoom level tiles want for optimal display (1, 2, 4, 8)
606 int iw, ih; // size of image in pixels
607 int w, h; // size of grid image in pixels (represented by grid)
608 int gw, gh; // size of grid in tiles
609 Eina_Matrixsparse *grid;
613 int zoom; // zoom level tiles want for optimal display (1, 2, 4, 8)
614 int tw, th; // size of grid in tiles
615 Eina_Matrixsparse *grid;
620 Evas_Object_Smart_Clipped_Data __clipped_data;
624 >>>>>>> remotes/origin/upstream
630 Evas_Object *pan_smart;
633 Evas_Object *sep_maps_markers; //map objects are below this object and marker objects are on top
635 Evas_Coord pan_x, pan_y, minw, minh;
640 Elm_Map_Zoom_Mode mode;
643 Ecore_Timer *scr_timer;
644 Ecore_Timer *long_timer;
645 Ecore_Animator *zoom_animator;
659 Evas_Coord x, y ,w ,h;
664 Eina_Bool resized : 1;
665 Eina_Bool on_hold : 1;
666 Eina_Bool paused : 1;
667 Eina_Bool paused_markers : 1;
675 Ecore_Job *markers_place_job;
676 Eina_Matrixsparse **markers;
677 Eina_List *cells_displayed; // list of Eina_Matrixsparse_Cell
678 Evas_Coord markers_max_num;
679 int marker_max_w, marker_max_h;
681 Eina_List *opened_bubbles; //opened bubbles, list of Map_Group *
683 Eina_List *groups_clas; // list of Elm_Map_Group_Class*
684 Eina_List *markers_clas; // list of Elm_Map_Markers_Class*
686 Elm_Map_Route_Sources route_source;
687 Eina_List *s_event_list;
692 const char *user_agent;
695 Evas_Event_Mouse_Down ev;
706 Evas_Object *sep_maps_markers; // Tiles are below this and overlays are on top
709 Eina_Array *src_tile_mods;
710 Source_Tile *src_tile;
711 Eina_List *src_tiles;
712 const char **src_tile_names;
714 Eina_Array *src_route_mods;
715 Source_Route *src_route;
716 Eina_List *src_routes;
717 const char **src_route_names;
719 Eina_Array *src_name_mods;
720 Source_Name *src_name;
721 Eina_List *src_names;
722 const char **src_name_names;
724 int zoom_min, zoom_max;
732 double prev_lon, prev_lat;
736 int w, h; // Current pixel width, heigth of a grid
737 int tile; // Current pixel size of a grid item
739 Elm_Map_Zoom_Mode mode;
746 Ecore_Timer *zoom_timer;
747 Ecore_Animator *zoom_animator;
752 Eina_List *download_list;
753 Ecore_Idler *download_idler;
755 const char *user_agent;
757 Evas_Coord pan_x, pan_y;
758 Eina_List *delayed_jobs;
760 Ecore_Timer *scr_timer;
761 Ecore_Timer *long_timer;
762 Evas_Event_Mouse_Down ev;
763 Eina_Bool on_hold : 1;
764 Eina_Bool paused : 1;
767 >>>>>>> remotes/origin/upstream
776 Eina_Bool wheel_disabled : 1;
777 Eina_Bool scr_started : 1;
780 Eina_List *map_sources_tab;
781 const char **source_names;
783 Ecore_Timer *zoom_timer;
784 Map_Sources_Tab *src;
785 const char *gpx_file;
786 int zoom_min, zoom_max;
787 Eina_List *download_list;
793 Evas_Object_Smart_Clipped_Data __clipped_data;
811 Evas_Coord x, y, w, h;
828 enum _Route_Xml_Attribute
832 ROUTE_XML_DESCRIPTION,
833 ROUTE_XML_COORDINATES,
835 } Route_Xml_Attibute;
845 enum _Name_Xml_Attribute
862 enum _Track_Xml_Attribute
865 TRACK_XML_COORDINATES,
867 } Track_Xml_Attibute;
869 static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_NULL;
870 static const char *widtype = NULL;
871 static int idnum = 1;
873 static const char SIG_CHANGED[] = "changed";
874 static const char SIG_CLICKED[] = "clicked";
875 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
876 static const char SIG_LOADED_DETAIL[] = "loaded,detail";
877 static const char SIG_LOAD_DETAIL[] = "load,detail";
878 static const char SIG_LONGPRESSED[] = "longpressed";
879 static const char SIG_PRESS[] = "press";
880 static const char SIG_SCROLL[] = "scroll";
881 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
882 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
883 static const char SIG_ZOOM_CHANGE[] = "zoom,change";
884 static const char SIG_ZOOM_START[] = "zoom,start";
885 static const char SIG_ZOOM_STOP[] = "zoom,stop";
886 static const char SIG_DOWNLOADED[] = "downloaded";
887 static const char SIG_ROUTE_LOAD[] = "route,load";
888 static const char SIG_ROUTE_LOADED[] = "route,loaded";
889 static const char SIG_NAME_LOAD[] = "name,load";
890 static const char SIG_NAME_LOADED[] = "name,loaded";
891 static const Evas_Smart_Cb_Description _signals[] = {
894 {SIG_CLICKED_DOUBLE, ""},
895 {SIG_LOADED_DETAIL, ""},
896 {SIG_LOAD_DETAIL, ""},
897 {SIG_LONGPRESSED, ""},
900 {SIG_SCROLL_DRAG_START, ""},
901 {SIG_SCROLL_DRAG_STOP, ""},
902 {SIG_ZOOM_CHANGE, ""},
903 {SIG_ZOOM_START, ""},
905 {SIG_DOWNLOADED, ""},
906 {SIG_ROUTE_LOAD, ""},
907 {SIG_ROUTE_LOADED, ""},
909 {SIG_NAME_LOADED, ""},
913 static void _pan_calculate(Evas_Object *obj);
915 static void _rect_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
916 static void _del_hook(Evas_Object *obj);
917 static void _theme_hook(Evas_Object *obj);
918 static void _on_focus_hook(void *data, Evas_Object *obj);
919 static void _sizing_eval(Evas_Object *obj);
920 static void _calc_job(void *data);
921 static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
922 Evas_Callback_Type type, void *event_info);
923 static void grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
924 static void grid_load(Evas_Object *obj, Grid *g);
926 static void _process_download_list(Evas_Object *obj);
927 static void _add_download_list(Evas_Object *obj, Grid_Item *gi);
929 static void _group_object_create(Marker_Group *group);
930 static void _group_object_free(Marker_Group *group);
931 static void _group_open_cb(void *data, Evas_Object *obj, const char *emission, const char *soure);
932 static void _group_bringin_cb(void *data, Evas_Object *obj, const char *emission, const char *soure);
933 static void _group_bubble_create(Marker_Group *group);
934 static void _group_bubble_free(Marker_Group *group);
935 static void _group_bubble_place(Marker_Group *group);
937 static int _group_bubble_content_update(Marker_Group *group);
938 static void _group_bubble_content_free(Marker_Group *group);
939 static void marker_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
940 static void _bubble_sc_hints_changed_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
942 static void _mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
943 static void _mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info);
945 static void route_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
946 static void track_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh);
949 module_list_cb(Eina_Module *m, void *data)
951 ELM_CHECK_WIDTYPE(data, widtype) EINA_FALSE;
952 Widget_Data *wd = elm_widget_data_get(data);
954 ElmMapModuleSourceFunc source;
955 ElmMapModuleZoomMinFunc zoom_min;
956 ElmMapModuleZoomMaxFunc zoom_max;
957 ElmMapModuleUrlFunc url;
958 ElmMapModuleRouteSourceFunc route_source;
959 ElmMapModuleRouteUrlFunc route_url;
960 ElmMapModuleNameUrlFunc name_url;
961 ElmMapModuleGeoIntoCoordFunc geo_into_coord;
962 ElmMapModuleCoordIntoGeoFunc coord_into_geo;
965 if (!wd) return EINA_FALSE;
967 file = eina_module_file_get(m);
968 if (!eina_module_load(m))
970 ERR("could not load module \"%s\": %s", file, eina_error_msg_get(eina_error_get()));
974 source = eina_module_symbol_get(m, "map_module_source_get");
975 zoom_min = eina_module_symbol_get(m, "map_module_zoom_min_get");
976 zoom_max = eina_module_symbol_get(m, "map_module_zoom_max_get");
977 url = eina_module_symbol_get(m, "map_module_url_get");
978 route_source = eina_module_symbol_get(m, "map_module_route_source_get");
979 route_url = eina_module_symbol_get(m, "map_module_route_url_get");
980 name_url = eina_module_symbol_get(m, "map_module_name_url_get");
981 geo_into_coord = eina_module_symbol_get(m, "map_module_geo_into_coord");
982 coord_into_geo = eina_module_symbol_get(m, "map_module_coord_into_geo");
983 if ((!source) || (!zoom_min) || (!zoom_max) || (!url) || (!route_source) || (!route_url) || (!name_url) || (!geo_into_coord) || (!coord_into_geo))
985 WRN("could not find map_module_source_get() in module \"%s\": %s", file, eina_error_msg_get(eina_error_get()));
986 eina_module_unload(m);
989 s = calloc(1, sizeof(Map_Sources_Tab));
990 EINA_SAFETY_ON_NULL_RETURN_VAL(s, EINA_FALSE);
992 s->zoom_min = zoom_min();
993 s->zoom_max = zoom_max();
995 s->route_source = route_source();
996 s->route_url_cb = route_url;
997 s->name_url_cb = name_url;
998 s->geo_into_coord = geo_into_coord;
999 s->coord_into_geo = coord_into_geo;
1000 wd->map_sources_tab = eina_list_append(wd->map_sources_tab, s);
1006 module_init(void *data)
1008 ELM_CHECK_WIDTYPE(data, widtype);
1009 Widget_Data *wd = elm_widget_data_get(data);
1012 wd->modules = eina_module_list_get(wd->modules, MODULES_PATH, 1, &module_list_cb, data);
1016 source_init(void *data)
1018 ELM_CHECK_WIDTYPE(data, widtype);
1019 Widget_Data *wd = elm_widget_data_get(data);
1025 for (idx = 0; idx < sizeof(default_map_sources_tab)/sizeof(Map_Sources_Tab); idx++)
1027 s = calloc(1, sizeof(Map_Sources_Tab));
1028 EINA_SAFETY_ON_NULL_RETURN(s);
1029 s->name = default_map_sources_tab[idx].name;
1030 s->zoom_min = default_map_sources_tab[idx].zoom_min;
1031 s->zoom_max = default_map_sources_tab[idx].zoom_max;
1032 s->url_cb = default_map_sources_tab[idx].url_cb;
1033 s->route_source = default_map_sources_tab[idx].route_source;
1034 s->route_url_cb = default_map_sources_tab[idx].route_url_cb;
1035 s->name_url_cb = default_map_sources_tab[idx].name_url_cb;
1036 s->geo_into_coord = default_map_sources_tab[idx].geo_into_coord;
1037 s->coord_into_geo = default_map_sources_tab[idx].coord_into_geo;
1038 wd->map_sources_tab = eina_list_append(wd->map_sources_tab, s);
1039 if (!idx) wd->src = s;
1043 int n = eina_list_count(wd->map_sources_tab);
1044 wd->source_names = malloc(sizeof(char *) * (n + 1));
1045 if (!wd->source_names)
1047 ERR("init source names failed.");
1051 EINA_LIST_FOREACH(wd->map_sources_tab, l, s)
1053 wd->source_names[idx] = strdup(s->name);
1054 INF("source : %s", wd->source_names[idx]);
1055 if (s->zoom_min < wd->zoom_min) wd->zoom_min = s->zoom_min;
1056 if (s->zoom_max > wd->zoom_max) wd->zoom_max = s->zoom_max;
1059 wd->source_names[idx] = NULL;
1063 obj_rotate_zoom(void *data, Evas_Object *obj)
1065 ELM_CHECK_WIDTYPE(data, widtype);
1066 Widget_Data *wd = elm_widget_data_get(data);
1068 if ((!wd->pinch.cx) && (!wd->pinch.cy))
1070 wd->pinch.cx = wd->rotate.cx;
1071 wd->pinch.cy = wd->rotate.cy;
1074 evas_map_util_points_populate_from_object_full(wd->map, obj, 0);
1075 evas_object_image_size_get(obj, &iw, &ih);
1076 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
1077 if ((ow < iw) || (oh < ih))
1079 ow *= (double)iw / ow;
1080 oh *= (double)ih / oh;
1081 evas_map_point_image_uv_set(wd->map, 1, ow, 0);
1082 evas_map_point_image_uv_set(wd->map, 2, ow, oh);
1083 evas_map_point_image_uv_set(wd->map, 3, 0, oh);
1085 evas_map_util_zoom(wd->map, wd->pinch.level, wd->pinch.level, wd->pinch.cx, wd->pinch.cy);
1086 evas_map_util_rotate(wd->map, wd->rotate.d, wd->rotate.cx, wd->rotate.cy);
1087 evas_object_map_enable_set(obj, EINA_TRUE);
1088 evas_object_map_set(obj, wd->map);
1093 track_place(Evas_Object *obj, Grid *g __UNUSED__, Evas_Coord px, Evas_Coord py, Evas_Coord ox __UNUSED__, Evas_Coord oy __UNUSED__, Evas_Coord ow, Evas_Coord oh)
1095 track_place(Evas_Object *obj __UNUSED__, Grid *g __UNUSED__, Evas_Coord px __UNUSED__, Evas_Coord py __UNUSED__, Evas_Coord ox __UNUSED__, Evas_Coord oy __UNUSED__, Evas_Coord ow __UNUSED__, Evas_Coord oh __UNUSED__)
1099 ELM_CHECK_WIDTYPE(obj, widtype);
1100 Widget_Data *wd = elm_widget_data_get(obj);
1103 int xmin, xmax, ymin, ymax;
1106 Evas_Coord size = pow(2.0, wd->zoom)*wd->tsize;
1108 EINA_LIST_FOREACH(wd->track, l, route)
1110 elm_map_utils_convert_geo_into_coord(wd->obj, elm_route_lon_min_get(route), elm_route_lat_max_get(route), size, &xmin, &ymin);
1111 elm_map_utils_convert_geo_into_coord(wd->obj, elm_route_lon_max_get(route), elm_route_lat_min_get(route), size, &xmax, &ymax);
1113 if( !(xmin < px && xmax < px) && !(xmin > px+ow && xmax > px+ow))
1115 if( !(ymin < py && ymax < py) && !(ymin > py+oh && ymax > py+oh))
1118 evas_object_move(route, xmin - px + ox, ymin - py + oy);
1119 evas_object_resize(route, xmax - xmin, ymax - ymin);
1121 evas_object_raise(route);
1122 obj_rotate_zoom(obj, route);
1123 evas_object_show(route);
1128 //the route is not display
1129 evas_object_hide(route);
1134 route_place(Evas_Object *obj, Grid *g __UNUSED__, Evas_Coord px, Evas_Coord py, Evas_Coord ox __UNUSED__, Evas_Coord oy __UNUSED__, Evas_Coord ow, Evas_Coord oh)
1136 ELM_CHECK_WIDTYPE(obj, widtype);
1137 Widget_Data *wd = elm_widget_data_get(obj);
1138 Eina_List *lr, *lp, *ln;
1147 Evas_Coord size = pow(2.0, wd->zoom)*wd->tsize;
1149 EINA_LIST_FOREACH(wd->route, lr, r)
1151 EINA_LIST_FOREACH(r->path, lp, p)
1153 evas_object_polygon_points_clear(p);
1156 evas_object_geometry_get(wd->rect, &rx, &ry, NULL, NULL);
1157 nodes = eina_list_count(r->nodes);
1159 EINA_LIST_FOREACH(r->nodes, ln, n)
1161 if ((!wd->zoom) || ((n->idx) &&
1162 ((n->idx % (int)ceil((double)nodes/(double)size*100.0))))) continue;
1165 elm_map_utils_convert_geo_into_coord(wd->obj, n->pos.lon, n->pos.lat, size, &x, &y);
1166 if ((x >= px - ow) && (x <= (px + ow*2)) &&
1167 (y >= py - oh) && (y <= (py + oh*2)))
1172 p = eina_list_nth(r->path, n->idx);
1173 a = (double)(y - r->y) / (double)(x - r->x);
1174 if ((abs(a) >= 1) || (r->x == x))
1176 evas_object_polygon_point_add(p, r->x - 3, r->y);
1177 evas_object_polygon_point_add(p, r->x + 3, r->y);
1178 evas_object_polygon_point_add(p, x + 3, y);
1179 evas_object_polygon_point_add(p, x - 3, y);
1183 evas_object_polygon_point_add(p, r->x, r->y - 3);
1184 evas_object_polygon_point_add(p, r->x, r->y + 3);
1185 evas_object_polygon_point_add(p, x, y + 3);
1186 evas_object_polygon_point_add(p, x, y - 3);
1189 evas_object_color_set(p, r->color.r, r->color.g, r->color.b, r->color.a);
1190 evas_object_raise(p);
1191 obj_rotate_zoom(obj, p);
1192 evas_object_show(p);
1196 else r->inbound = EINA_FALSE;
1200 elm_map_utils_convert_geo_into_coord(wd->obj, n->pos.lon, n->pos.lat, size, &x, &y);
1201 if ((x >= px - ow) && (x <= (px + ow*2)) &&
1202 (y >= py - oh) && (y <= (py + oh*2)))
1206 r->inbound = EINA_TRUE;
1208 else r->inbound = EINA_FALSE;
1211 r->inbound = EINA_FALSE;
1216 rect_place(Evas_Object *obj, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
1218 ELM_CHECK_WIDTYPE(obj, widtype);
1219 Widget_Data *wd = elm_widget_data_get(obj);
1220 Evas_Coord ax, ay, gw, gh, hh, ww;
1223 evas_object_geometry_get(wd->rect, NULL, NULL, &ww, &hh);
1230 if ((ww == gw) && (hh == gh)) return;
1232 if (ow > gw) ax = (ow - gw) / 2;
1233 if (oh > gh) ay = (oh - gh) / 2;
1234 evas_object_move(wd->rect,
1237 evas_object_resize(wd->rect, gw, gh);
1241 wd->show.show = EINA_FALSE;
1242 elm_smart_scroller_child_region_show(wd->scr, wd->show.x, wd->show.y, wd->show.w, wd->show.h);
1247 marker_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
1249 ELM_CHECK_WIDTYPE(obj, widtype);
1250 Widget_Data *wd = elm_widget_data_get(obj);
1251 Evas_Coord ax, ay, gw, gh, tx, ty;
1252 Eina_List *l, *markers;
1253 Eina_Matrixsparse_Cell *cell;
1254 Marker_Group *group;
1258 int g_xx, g_yy, g_hh, g_ww;
1266 if (ow > gw) ax = (ow - gw) / 2;
1267 if (oh > gh) ay = (oh - gh) / 2;
1269 if (wd->zoom != wd->marker_zoom)
1271 EINA_LIST_FREE(wd->cells_displayed, cell)
1273 EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
1275 if (group->obj) _group_object_free(group);
1279 wd->marker_zoom = wd->zoom;
1281 if ((wd->paused_markers)
1282 && ((wd->size.nw != wd->size.w) || (wd->size.nh != wd->size.h)) )
1285 g_xx = wd->pan_x / wd->tsize;
1286 if (g_xx < 0) g_xx = 0;
1287 g_yy = wd->pan_y / wd->tsize;
1288 if (g_yy < 0) g_yy = 0;
1289 g_ww = (ow / wd->tsize) + 1;
1290 if (g_xx + g_ww >= g->gw) g_ww = g->gw - g_xx - 1;
1291 g_hh = (oh / wd->tsize) + 1;
1292 if (g_yy + g_hh >= g->gh) g_hh = g->gh - g_yy - 1;
1294 //hide groups no more displayed
1295 EINA_LIST_FREE(wd->cells_displayed, cell)
1297 eina_matrixsparse_cell_position_get(cell, (unsigned long *)&y, (unsigned long *)&x);
1298 if ((y < g_yy) || (y > g_yy + g_hh) || (x < g_xx) || (x > g_xx + g_ww))
1300 EINA_LIST_FOREACH(eina_matrixsparse_cell_data_get(cell), l, group)
1302 if (group->obj) _group_object_free(group);
1307 if (!wd->marker_zoom)
1313 for (y = g_yy; y <= g_yy + g_hh; y++)
1315 for (x = g_xx; x <= g_xx + g_ww; x++)
1317 if (!wd->markers[wd->zoom]) continue;
1318 eina_matrixsparse_cell_idx_get(wd->markers[wd->zoom], y, x, &cell);
1319 if (!cell) continue;
1320 wd->cells_displayed = eina_list_append(wd->cells_displayed, cell);
1321 markers = eina_matrixsparse_cell_data_get(cell);
1322 EINA_LIST_FOREACH(markers, l, group)
1324 if (!group->markers) continue;
1325 if (group->clas->zoom_displayed > wd->zoom) continue;
1332 if (eina_list_count(group->markers) == 1)
1334 Elm_Map_Marker *m = eina_list_data_get(group->markers);
1335 ww = m->clas->priv.edje_w;
1336 hh = m->clas->priv.edje_h;
1339 if (ww <= 0) ww = 1;
1340 if (hh <= 0) hh = 1;
1342 if ((gw != g->w) && (g->w > 0))
1345 xx = ((long long )gw * xx) / g->w;
1346 ww = (((long long)gw * (tx + ww)) / g->w) - xx;
1348 if ((gh != g->h) && (g->h > 0))
1351 yy = ((long long)gh * yy) / g->h;
1352 hh = (((long long)gh * (ty + hh)) / g->h) - yy;
1355 if ((!group->clas->hide)
1356 && (xx-px+ax+ox >= ox) && (xx-px+ax+ox<= ox+ow)
1357 && (yy-py+ay+oy >= oy) && (yy-py+ay+oy<= oy+oh))
1359 if (!group->obj) _group_object_create(group);
1361 if (group->update_nbelems)
1363 group->update_nbelems = EINA_FALSE;
1364 if (eina_list_count(group->markers) > 1)
1366 snprintf(buf, sizeof(buf), "%d", eina_list_count(group->markers));
1367 edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", buf);
1370 edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", "");
1372 evas_object_move(group->obj,
1373 xx - px + ax + ox - ww/2,
1374 yy - py + ay + oy - hh/2);
1375 if ((!wd->paused_markers) || (group->update_resize))
1377 group->update_resize = EINA_FALSE;
1378 evas_object_resize(group->obj, ww, hh);
1379 obj_rotate_zoom(obj, group->obj);
1381 if (group->update_raise)
1383 group->update_raise = EINA_FALSE;
1384 evas_object_raise(group->obj);
1385 obj_rotate_zoom(obj, group->obj);
1386 evas_object_show(group->obj);
1388 if (group->bubble) _group_bubble_place(group);
1390 else if (group->obj)
1392 _group_object_free(group);
1400 grid_place(Evas_Object *obj, Grid *g, Evas_Coord px, Evas_Coord py, Evas_Coord ox, Evas_Coord oy, Evas_Coord ow, Evas_Coord oh)
1402 ELM_CHECK_WIDTYPE(obj, widtype);
1403 Widget_Data *wd = elm_widget_data_get(obj);
1404 Evas_Coord ax, ay, gw, gh, tx, ty;
1412 if (ow > gw) ax = (ow - gw) / 2;
1413 if (oh > gh) ay = (oh - gh) / 2;
1415 Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
1416 Eina_Matrixsparse_Cell *cell;
1418 EINA_ITERATOR_FOREACH(it, cell)
1420 Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
1426 if ((gw != g->w) && (g->w > 0))
1429 xx = ((long long )gw * xx) / g->w;
1430 ww = (((long long)gw * (tx + ww)) / g->w) - xx;
1432 if ((gh != g->h) && (g->h > 0))
1435 yy = ((long long)gh * yy) / g->h;
1436 hh = (((long long)gh * (ty + hh)) / g->h) - yy;
1438 evas_object_move(gi->img,
1442 evas_object_resize(gi->img, ww, hh);
1444 obj_rotate_zoom(obj, gi->img);
1445 /*evas_object_move(gi->txt,
1449 evas_object_resize(gi->txt, ww, hh);
1452 eina_iterator_free(it);
1456 _tile_update(Grid_Item *gi)
1458 evas_object_image_file_set(gi->img, gi->file, NULL);
1459 Evas_Load_Error err = evas_object_image_load_error_get(gi->img);
1460 if (err != EVAS_LOAD_ERROR_NONE)
1462 ERR("Image loading error (%s): %s", gi->file, evas_load_error_str(err));
1463 ecore_file_remove(gi->file);
1464 gi->file_have = EINA_FALSE;
1468 obj_rotate_zoom(gi->wd->obj, gi->img);
1469 evas_object_show(gi->img);
1470 gi->file_have = EINA_TRUE;
1471 //evas_object_text_text_set(gi->txt, gi->file);
1472 //evas_object_show(gi->txt);
1477 _tile_downloaded(void *data, const char *file __UNUSED__, int status)
1479 Grid_Item *gi = data;
1485 DBG("Download success from %s to %s", gi->source, gi->file);
1487 gi->wd->finish_num++;
1491 WRN("Download failed from %s to %s (%d) ", gi->source, gi->file, status);
1492 ecore_file_remove(gi->file);
1493 gi->file_have = EINA_FALSE;
1496 gi->wd->download_num--;
1497 evas_object_smart_callback_call(gi->wd->obj, SIG_DOWNLOADED, NULL);
1498 if (!gi->wd->download_num)
1500 edje_object_signal_emit(elm_smart_scroller_edje_object_get(gi->wd->scr), "elm,state,busy,stop", "elm");
1501 evas_object_smart_callback_call(gi->wd->obj, SIG_LOADED_DETAIL, NULL);
1503 _process_download_list(gi->wd->obj);
1507 _process_download_list(Evas_Object *obj)
1509 ELM_CHECK_WIDTYPE(obj, widtype);
1510 Widget_Data *wd = elm_widget_data_get(obj);
1512 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh, tx, ty, gw, gh, xx, yy, ww, hh;
1515 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
1516 evas_output_viewport_get(evas_object_evas_get(wd->obj), &cvx, &cvy, &cvw, &cvh);
1521 EINA_LIST_REVERSE_FOREACH_SAFE(wd->download_list, l, ll, gi)
1528 if ((gw != gi->g->w) && (gi->g->w > 0))
1531 xx = ((long long )gw * xx) / gi->g->w;
1532 ww = (((long long)gw * (tx + ww)) / gi->g->w) - xx;
1534 if ((gh != gi->g->h) && (gi->g->h > 0))
1537 yy = ((long long)gh * yy) / gi->g->h;
1538 hh = (((long long)gh * (ty + hh)) / gi->g->h) - yy;
1540 if (!ELM_RECTS_INTERSECT(xx - wd->pan_x + ox,
1541 yy - wd->pan_y + oy,
1543 cvx, cvy, cvw, cvh) ||
1544 (gi->zoom != wd->zoom))
1546 wd->download_list = eina_list_remove(wd->download_list, gi);
1550 if (gi->wd->download_num >= MAX_CONCURRENT_DOWNLOAD) break;
1552 Eina_Bool ret = ecore_file_download_full(gi->source, gi->file, _tile_downloaded, NULL, gi, &(gi->job), wd->ua);
1553 if (!ret || !gi->job) ERR("Can't start to download from %s to %s", gi->source, gi->file);
1556 gi->wd->download_num++;
1558 wd->download_list = eina_list_remove(wd->download_list, gi);
1559 if (wd->download_num == 1)
1560 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,state,busy,start", "elm");
1566 _add_download_list(Evas_Object *obj, Grid_Item *gi)
1568 ELM_CHECK_WIDTYPE(obj, widtype);
1569 Widget_Data *wd = elm_widget_data_get(obj);
1571 wd->download_list = eina_list_remove(wd->download_list, gi);
1572 wd->download_list = eina_list_append(wd->download_list, gi);
1573 _process_download_list(obj);
1577 grid_create_all(Evas_Object *obj)
1579 ELM_CHECK_WIDTYPE(obj, widtype);
1580 Widget_Data *wd = elm_widget_data_get(obj);
1584 EINA_SAFETY_ON_NULL_RETURN(wd);
1585 EINA_SAFETY_ON_NULL_RETURN(wd->src);
1587 for (zoom = wd->src->zoom_min; zoom <= wd->src->zoom_max; zoom++)
1589 g = calloc(1, sizeof(Grid));
1590 EINA_SAFETY_ON_NULL_RETURN(g);
1592 g->tsize = wd->tsize;
1594 int size = pow(2.0, g->zoom);
1597 g->w = g->tsize * g->gw;
1598 g->h = g->tsize * g->gh;
1600 g->grid = eina_matrixsparse_new(g->gh, g->gw, NULL, NULL);
1601 wd->grids = eina_list_append(wd->grids, g);
1606 grid_clear_all(Evas_Object *obj)
1608 ELM_CHECK_WIDTYPE(obj, widtype);
1609 Widget_Data *wd = elm_widget_data_get(obj);
1613 EINA_SAFETY_ON_NULL_RETURN(wd);
1615 EINA_LIST_FREE(wd->grids, g)
1617 Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
1618 Eina_Matrixsparse_Cell *cell;
1620 EINA_ITERATOR_FOREACH(it, cell)
1622 gi = eina_matrixsparse_cell_data_get(cell);
1623 evas_object_del(gi->img);
1624 //evas_object_del(gi->txt);
1628 DBG("DOWNLOAD abort %s", gi->file);
1629 ecore_file_download_abort(gi->job);
1630 ecore_file_remove(gi->file);
1631 gi->file_have = EINA_FALSE;
1635 if (gi->file) eina_stringshare_del(gi->file);
1636 if (gi->source) eina_stringshare_del(gi->source);
1639 eina_matrixsparse_free(g->grid);
1640 eina_iterator_free(it);
1644 EINA_LIST_FREE(wd->download_list, gi);
1645 if (!ecore_file_recursive_rm("/tmp/elm_map/")) WRN("Deletion of /tmp/elm_map/ failed");
1650 grid_unload(Evas_Object *obj, Grid *g)
1652 ELM_CHECK_WIDTYPE(obj, widtype);
1653 Widget_Data *wd = elm_widget_data_get(obj);
1656 Eina_Matrixsparse_Cell *cell;
1659 EINA_SAFETY_ON_NULL_RETURN(wd);
1661 it = eina_matrixsparse_iterator_new(g->grid);
1662 EINA_ITERATOR_FOREACH(it, cell)
1664 gi = eina_matrixsparse_cell_data_get(cell);
1668 evas_object_hide(gi->img);
1669 //evas_object_hide(gi->txt);
1670 evas_object_image_file_set(gi->img, NULL, NULL);
1674 DBG("DOWNLOAD abort %s", gi->file);
1675 ecore_file_download_abort(gi->job);
1676 ecore_file_remove(gi->file);
1681 eina_iterator_free(it);
1686 grid_load(Evas_Object *obj, Grid *g)
1688 ELM_CHECK_WIDTYPE(obj, widtype);
1689 Widget_Data *wd = elm_widget_data_get(obj);
1692 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh, tx, ty, gw, gh, xx, yy, ww, hh;
1694 Eina_Matrixsparse_Cell *cell;
1697 EINA_SAFETY_ON_NULL_RETURN(wd);
1698 EINA_SAFETY_ON_NULL_RETURN(wd->src);
1700 evas_object_geometry_get(wd->pan_smart, &ox, &oy, &ow, &oh);
1701 evas_output_viewport_get(evas_object_evas_get(wd->obj), &cvx, &cvy, &cvw, &cvh);
1706 if ((gw <= 0) || (gh <= 0)) return;
1709 if ((gw != g->w) && (g->w > 0))
1710 size = ((long long)gw * size) / g->w;
1711 if (size < (g->tsize / 2)) return; // else we will load to much tiles
1713 it = eina_matrixsparse_iterator_new(g->grid);
1715 EINA_ITERATOR_FOREACH(it, cell)
1717 gi = eina_matrixsparse_cell_data_get(cell);
1724 if ((gw != g->w) && (g->w > 0))
1727 xx = ((long long )gw * xx) / g->w;
1728 ww = (((long long)gw * (tx + ww)) / g->w) - xx;
1730 if ((gh != g->h) && (g->h > 0))
1733 yy = ((long long)gh * yy) / g->h;
1734 hh = (((long long)gh * (ty + hh)) / g->h) - yy;
1737 if (!ELM_RECTS_INTERSECT(xx - wd->pan_x + ox,
1738 yy - wd->pan_y + oy,
1740 cvx, cvy, cvw, cvh))
1744 evas_object_hide(gi->img);
1745 //evas_object_hide(gi->txt);
1746 evas_object_image_file_set(gi->img, NULL, NULL);
1750 DBG("Download abort %s", gi->file);
1751 ecore_file_download_abort(gi->job);
1752 ecore_file_remove(gi->file);
1758 eina_iterator_free(it);
1760 xx = wd->pan_x / size - 1;
1763 yy = wd->pan_y / size - 1;
1767 if (xx + ww >= g->gw) ww = g->gw - xx - 1;
1770 if (yy + hh >= g->gh) hh = g->gh - yy - 1;
1772 for (y = yy; y <= yy + hh; y++)
1774 for (x = xx; x <= xx + ww; x++)
1776 gi = eina_matrixsparse_data_idx_get(g->grid, y, x);
1781 char buf2[PATH_MAX];
1784 gi = calloc(1, sizeof(Grid_Item));
1785 EINA_SAFETY_ON_NULL_RETURN(gi);
1790 gi->file_have = EINA_FALSE;
1793 gi->src.x = x * g->tsize;
1794 gi->src.y = y * g->tsize;
1795 gi->src.w = g->tsize;
1796 gi->src.h = g->tsize;
1798 gi->out.x = gi->src.x;
1799 gi->out.y = gi->src.y;
1800 gi->out.w = gi->src.w;
1801 gi->out.h = gi->src.h;
1803 gi->img = evas_object_image_add(evas_object_evas_get(obj));
1804 evas_object_image_scale_hint_set(gi->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
1805 evas_object_image_filled_set(gi->img, 1);
1807 evas_object_smart_member_add(gi->img, wd->pan_smart);
1808 elm_widget_sub_object_add(obj, gi->img);
1809 evas_object_pass_events_set(gi->img, EINA_TRUE);
1810 evas_object_stack_below(gi->img, wd->sep_maps_markers);
1812 /* gi->txt = evas_object_text_add(evas_object_evas_get(obj));
1813 evas_object_text_font_set(gi->txt, "Vera", 12);
1814 evas_object_color_set(gi->txt, 100, 100, 100, 255);
1815 evas_object_smart_member_add(gi->txt,
1817 elm_widget_sub_object_add(obj, gi->txt);
1818 evas_object_pass_events_set(gi->txt, EINA_TRUE);
1820 snprintf(buf, sizeof(buf), CACHE_PATH, wd->id, g->zoom, x);
1821 snprintf(buf2, sizeof(buf2), CACHE_FILE_PATH, buf, y);
1822 if (!ecore_file_exists(buf)) ecore_file_mkpath(buf);
1824 eina_stringshare_replace(&gi->file, buf2);
1825 source = wd->src->url_cb(obj, x, y, g->zoom);
1826 if ((!source) || (strlen(source)==0))
1828 eina_stringshare_replace(&gi->source, NULL);
1829 WRN("Getting source url failed: %s", gi->file);
1831 else eina_stringshare_replace(&gi->source, source);
1832 if (source) free(source);
1834 eina_matrixsparse_data_idx_set(g->grid, y, x, gi);
1839 DBG("File exists: %s", gi->file);
1844 DBG("Added to download list: %s", gi->file);
1845 _add_download_list(obj, gi);
1848 Eina_Bool wheel_disabled : 1;
1850 unsigned int markers_max_num;
1851 Eina_Bool paused_markers : 1;
1852 Eina_List *group_classes;
1853 Eina_List *marker_classes;
1860 Eina_List *overlays;
1863 static char *_mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
1864 static char *_osmarender_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
1865 static char *_cyclemap_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
1866 static char *_mapquest_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
1867 static char *_mapquest_aerial_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom);
1868 static char *_yours_url_cb(Evas_Object *obj __UNUSED__, const char *type_name, int method, double flon, double flat, double tlon, double tlat);
1869 static char *_nominatim_url_cb(Evas_Object *obj, int method, const char *name, double lon, double lat);
1871 static char *_monav_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
1872 static char *_ors_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat);
1875 const Source_Tile src_tiles[] =
1877 {"Mapnik", 0, 18, _mapnik_url_cb, NULL, NULL},
1878 {"Osmarender", 0, 17, _osmarender_url_cb, NULL, NULL},
1879 {"CycleMap", 0, 16, _cyclemap_url_cb, NULL, NULL},
1880 {"MapQuest", 0, 18, _mapquest_url_cb, NULL, NULL},
1881 {"MapQuest Open Aerial", 0, 11, _mapquest_aerial_url_cb, NULL, NULL},
1884 // FIXME: Fix more open sources
1885 const Source_Route src_routes[] =
1887 {"Yours", _yours_url_cb} // http://www.yournavigation.org/
1888 //{"Monav", _monav_url_cb},
1889 //{"ORS", _ors_url_cb}, // http://www.openrouteservice.org
1892 // FIXME: Add more open sources
1893 const Source_Name src_names[] =
1895 {"Nominatim", _nominatim_url_cb}
1898 static const char *widtype = NULL;
1899 static Evas_Smart_Class parent_sc = EVAS_SMART_CLASS_INIT_NULL;
1900 static Evas_Smart_Class sc;
1901 static Evas_Smart *smart;
1902 static int idnum = 1;
1904 static const char SIG_CLICKED[] = "clicked";
1905 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
1906 static const char SIG_PRESS[] = "press";
1907 static const char SIG_LONGPRESSED[] = "longpressed";
1908 static const char SIG_SCROLL[] = "scroll";
1909 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
1910 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
1911 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
1912 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
1913 static const char SIG_ZOOM_START[] = "zoom,start";
1914 static const char SIG_ZOOM_STOP[] = "zoom,stop";
1915 static const char SIG_ZOOM_CHANGE[] = "zoom,change";
1916 static const char SIG_TILE_LOAD[] = "tile,load";
1917 static const char SIG_TILE_LOADED[] = "tile,loaded";
1918 static const char SIG_TILE_LOADED_FAIL[] = "tile,loaded,fail";
1919 static const char SIG_ROUTE_LOAD[] = "route,load";
1920 static const char SIG_ROUTE_LOADED[] = "route,loaded";
1921 static const char SIG_ROUTE_LOADED_FAIL[] = "route,loaded,fail";
1922 static const char SIG_NAME_LOAD[] = "name,load";
1923 static const char SIG_NAME_LOADED[] = "name,loaded";
1924 static const char SIG_NAME_LOADED_FAIL[] = "name,loaded,fail";
1925 static const char SIG_OVERLAY_CLICKED[] = "overlay,clicked";
1926 static const Evas_Smart_Cb_Description _signals[] = {
1928 {SIG_CLICKED_DOUBLE, ""},
1930 {SIG_LONGPRESSED, ""},
1932 {SIG_SCROLL_DRAG_START, ""},
1933 {SIG_SCROLL_DRAG_STOP, ""},
1934 {SIG_SCROLL_ANIM_START, ""},
1935 {SIG_SCROLL_ANIM_STOP, ""},
1936 {SIG_ZOOM_START, ""},
1937 {SIG_ZOOM_STOP, ""},
1938 {SIG_ZOOM_CHANGE, ""},
1939 {SIG_TILE_LOAD, ""},
1940 {SIG_TILE_LOADED, ""},
1941 {SIG_TILE_LOADED_FAIL, ""},
1942 {SIG_ROUTE_LOAD, ""},
1943 {SIG_ROUTE_LOADED, ""},
1944 {SIG_ROUTE_LOADED_FAIL, ""},
1945 {SIG_NAME_LOAD, ""},
1946 {SIG_NAME_LOADED, ""},
1947 {SIG_NAME_LOADED_FAIL, ""},
1948 {SIG_OVERLAY_CLICKED, ""},
1953 _edj_marker_size_get(Widget_Data *wd, Evas_Coord *w, Evas_Coord *h)
1955 EINA_SAFETY_ON_NULL_RETURN(wd);
1956 EINA_SAFETY_ON_NULL_RETURN(w);
1957 EINA_SAFETY_ON_NULL_RETURN(h);
1962 edj = edje_object_add(evas_object_evas_get(wd->obj));
1963 _elm_theme_object_set(wd->obj, edj, "map/marker", "radio",
1964 elm_widget_style_get(wd->obj));
1965 s = edje_object_data_get(edj, "size_w");
1966 if (s) *w = atoi(s);
1968 s = edje_object_data_get(edj, "size_h");
1969 if (s) *h = atoi(s);
1971 evas_object_del(edj);
1975 _coord_rotate(Evas_Coord x, Evas_Coord y, Evas_Coord cx, Evas_Coord cy, double degree, Evas_Coord *xx, Evas_Coord *yy)
1977 EINA_SAFETY_ON_NULL_RETURN(xx);
1978 EINA_SAFETY_ON_NULL_RETURN(yy);
1980 double r = (degree * M_PI) / 180.0;
1982 if (xx) *xx = ((x - cx) * cos(r)) + ((y - cy) * cos(r + M_PI_2)) + cx;
1983 if (yy) *yy = ((x - cx) * sin(r)) + ((y - cy) * sin(r + M_PI_2)) + cy;
1987 _obj_rotate(Widget_Data *wd, Evas_Object *obj)
1989 Evas_Coord w, h, ow, oh;
1990 evas_map_util_points_populate_from_object(wd->map, obj);
1992 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
1993 evas_object_image_size_get(obj, &w, &h);
1994 if ((w > ow) || (h > oh))
1996 evas_map_point_image_uv_set(wd->map, 0, 0, 0);
1997 evas_map_point_image_uv_set(wd->map, 1, w, 0);
1998 evas_map_point_image_uv_set(wd->map, 2, w, h);
1999 evas_map_point_image_uv_set(wd->map, 3, 0, h);
2001 evas_map_util_rotate(wd->map, wd->rotate.d, wd->rotate.cx, wd->rotate.cy);
2003 evas_object_map_set(obj, wd->map);
2004 evas_object_map_enable_set(obj, EINA_TRUE);
2008 _obj_place(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
2010 EINA_SAFETY_ON_NULL_RETURN(obj);
2012 evas_object_move(obj, x, y);
2013 evas_object_resize(obj, w, h);
2014 evas_object_show(obj);
2018 _coord_to_region_convert(Widget_Data *wd, Evas_Coord x, Evas_Coord y, Evas_Coord size, double *lon, double *lat)
2020 EINA_SAFETY_ON_NULL_RETURN(wd);
2022 int zoom = floor(log(size / wd->size.tile) / log(2));
2023 if ((wd->src_tile) && (wd->src_tile->coord_to_geo))
2025 if (wd->src_tile->coord_to_geo(wd->obj, zoom, x, y, size, lon, lat))
2029 if (lon) *lon = (x / (double)size * 360.0) - 180;
2032 double n = ELM_PI - (2.0 * ELM_PI * y / size);
2033 *lat = 180.0 / ELM_PI * atan(0.5 * (exp(n) - exp(-n)));
2038 _region_to_coord_convert(Widget_Data *wd, double lon, double lat, Evas_Coord size, Evas_Coord *x, Evas_Coord *y)
2040 EINA_SAFETY_ON_NULL_RETURN(wd);
2042 int zoom = floor(log(size / 256) / log(2));
2043 if ((wd->src_tile) && (wd->src_tile->geo_to_coord))
2045 if (wd->src_tile->geo_to_coord(wd->obj, zoom, lon, lat, size, x, y)) return;
2048 if (x) *x = floor((lon + 180.0) / 360.0 * size);
2050 *y = floor((1.0 - log(tan(lat * ELM_PI / 180.0) + (1.0 / cos(lat * ELM_PI / 180.0)))
2051 / ELM_PI) / 2.0 * size);
2055 _viewport_size_get(Widget_Data *wd, Evas_Coord *vw, Evas_Coord *vh)
2057 EINA_SAFETY_ON_NULL_RETURN(wd);
2059 Evas_Coord x, y, w, h;
2060 evas_object_geometry_get(wd->pan_smart, &x, &y, &w, &h);
2061 if (vw) *vw = (x * 2) + w;
2062 if (vh) *vh = (y * 2) + h;
2066 _pan_geometry_get(Widget_Data *wd, Evas_Coord *px, Evas_Coord *py)
2068 EINA_SAFETY_ON_NULL_RETURN(wd);
2070 Evas_Coord x, y, vx, vy, vw, vh;
2071 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
2072 evas_object_geometry_get(wd->pan_smart, &vx, &vy, &vw, &vh);
2075 if (vw > wd->size.w) x += (((vw - wd->size.w) / 2) + vx);
2077 if (vh > wd->size.h) y += (((vh - wd->size.h) / 2) + vy);
2084 _region_show(void *data)
2086 EINA_SAFETY_ON_NULL_RETURN(data);
2087 Delayed_Data *dd = data;
2090 _region_to_coord_convert(dd->wd, dd->lon, dd->lat, dd->wd->size.w, &x, &y);
2091 _viewport_size_get(dd->wd, &w, &h);
2094 elm_smart_scroller_child_region_show(dd->wd->scr, x, y, w, h);
2095 evas_object_smart_changed(dd->wd->pan_smart);
2099 _bubble_update(Marker_Bubble *bubble, Eina_List *contents)
2101 EINA_SAFETY_ON_NULL_RETURN(bubble);
2102 EINA_SAFETY_ON_NULL_RETURN(contents);
2107 elm_box_clear(bubble->bx);
2108 EINA_LIST_FOREACH(contents, l, c) elm_box_pack_end(bubble->bx, c);
2112 _bubble_place(Marker_Bubble *bubble)
2114 EINA_SAFETY_ON_NULL_RETURN(bubble);
2116 Evas_Coord x, y, w, h;
2117 Evas_Coord xx, yy, ww, hh;
2120 if ((!bubble->obj) || (!bubble->pobj)) return;
2121 evas_object_geometry_get(bubble->pobj, &x, &y, &w, NULL);
2123 s = edje_object_data_get(bubble->obj, "size_w");
2124 if (s) ww = atoi(s);
2127 edje_object_size_min_calc(bubble->obj, NULL, &hh);
2128 s = edje_object_data_get(bubble->obj, "size_h");
2133 xx = x + (w / 2) - (ww / 2);
2136 _obj_place(bubble->obj, xx, yy, ww, hh);
2137 evas_object_raise(bubble->obj);
2141 _bubble_sc_hints_changed_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2143 Marker_Bubble *bubble = data;
2144 EINA_SAFETY_ON_NULL_RETURN(bubble);
2145 _bubble_place(data);
2149 _bubble_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2151 Marker_Bubble *bubble = data;
2152 EINA_SAFETY_ON_NULL_RETURN(bubble);
2153 _bubble_place(bubble);
2157 _bubble_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2159 Marker_Bubble *bubble = data;
2160 EINA_SAFETY_ON_NULL_RETURN(bubble);
2161 evas_object_hide(bubble->obj);
2165 _bubble_show_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2167 Marker_Bubble *bubble = data;
2168 EINA_SAFETY_ON_NULL_RETURN(bubble);
2169 _bubble_place(bubble);
2173 _bubble_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2175 Marker_Bubble *bubble = data;
2176 EINA_SAFETY_ON_NULL_RETURN(bubble);
2177 _bubble_place(bubble);
2181 _bubble_free(Marker_Bubble* bubble)
2183 EINA_SAFETY_ON_NULL_RETURN(bubble);
2185 evas_object_del(bubble->bx);
2186 evas_object_del(bubble->sc);
2187 evas_object_del(bubble->obj);
2191 static Marker_Bubble*
2192 _bubble_create(Evas_Object *pobj, Widget_Data *wd)
2194 EINA_SAFETY_ON_NULL_RETURN_VAL(pobj, NULL);
2195 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
2197 Marker_Bubble *bubble = ELM_NEW(Marker_Bubble);
2198 EINA_SAFETY_ON_NULL_RETURN_VAL(bubble, NULL);
2201 bubble->pobj = pobj;
2202 evas_object_event_callback_add(pobj, EVAS_CALLBACK_HIDE, _bubble_hide_cb,
2204 evas_object_event_callback_add(pobj, EVAS_CALLBACK_SHOW, _bubble_show_cb,
2206 evas_object_event_callback_add(pobj, EVAS_CALLBACK_MOVE, _bubble_move_cb,
2209 bubble->obj = edje_object_add(evas_object_evas_get(pobj));
2210 _elm_theme_object_set(wd->obj, bubble->obj , "map", "marker_bubble",
2211 elm_widget_style_get(wd->obj));
2212 evas_object_event_callback_add(bubble->obj, EVAS_CALLBACK_MOUSE_UP,
2213 _bubble_mouse_up_cb, bubble);
2215 bubble->sc = elm_scroller_add(bubble->obj);
2216 elm_widget_style_set(bubble->sc, "map_bubble");
2217 elm_scroller_content_min_limit(bubble->sc, EINA_FALSE, EINA_TRUE);
2218 elm_scroller_policy_set(bubble->sc, ELM_SCROLLER_POLICY_AUTO,
2219 ELM_SCROLLER_POLICY_OFF);
2220 elm_scroller_bounce_set(bubble->sc, _elm_config->thumbscroll_bounce_enable,
2222 edje_object_part_swallow(bubble->obj, "elm.swallow.content", bubble->sc);
2223 evas_object_event_callback_add(bubble->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2224 _bubble_sc_hints_changed_cb, bubble);
2226 bubble->bx = elm_box_add(bubble->sc);
2227 evas_object_size_hint_align_set(bubble->bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
2228 evas_object_size_hint_weight_set(bubble->bx, EVAS_HINT_EXPAND,
2230 elm_box_horizontal_set(bubble->bx, EINA_TRUE);
2231 elm_object_content_set(bubble->sc, bubble->bx);
2237 _marker_group_update(Marker_Group* group, Elm_Map_Group_Class *clas, Eina_List *markers)
2239 EINA_SAFETY_ON_NULL_RETURN(group);
2240 EINA_SAFETY_ON_NULL_RETURN(clas);
2241 EINA_SAFETY_ON_NULL_RETURN(markers);
2242 Widget_Data *wd = clas->wd;
2243 EINA_SAFETY_ON_NULL_RETURN(wd);
2247 Elm_Map_Marker *marker;
2249 int sum_x = 0, sum_y = 0;
2251 EINA_LIST_FOREACH(markers, l, marker)
2258 group->x = sum_x / cnt;
2259 group->y = sum_y / cnt;
2260 _edj_marker_size_get(wd, &group->w, &group->h);
2264 group->markers = markers;
2266 if (clas->style) elm_layout_theme_set(group->obj, "map/marker", clas->style,
2267 elm_widget_style_get(wd->obj));
2268 else elm_layout_theme_set(group->obj, "map/marker", "radio",
2269 elm_widget_style_get(wd->obj));
2272 if (clas->func.icon_get)
2274 Evas_Object *icon = NULL;
2276 icon = elm_object_part_content_get(group->obj, "elm.icon");
2277 if (icon) evas_object_del(icon);
2279 icon = clas->func.icon_get(wd->obj, clas->data);
2280 elm_object_part_content_set(group->obj, "elm.icon", icon);
2282 snprintf(buf, sizeof(buf), "%d", cnt);
2283 edje_object_part_text_set(elm_layout_edje_get(group->obj), "elm.text", buf);
2287 Eina_List *contents = NULL;
2289 EINA_LIST_FOREACH(group->markers, l, marker)
2291 Evas_Object *c = marker->clas->func.get(marker->wd->obj,
2292 marker, marker->data);
2293 if (c) contents = eina_list_append(contents, c);
2295 _bubble_update(group->bubble, contents);
2300 _marker_group_bubble_open_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *soure __UNUSED__)
2302 EINA_SAFETY_ON_NULL_RETURN(data);
2303 Marker_Group *group = data;
2305 Elm_Map_Marker *marker;
2306 Eina_List *contents = NULL;
2308 if (!group->bubble) group->bubble = _bubble_create(group->obj, group->wd);
2310 EINA_LIST_FOREACH(group->markers, l, marker)
2312 if (group->wd->markers_max_num <= eina_list_count(contents)) break;
2313 Evas_Object *c = marker->clas->func.get(marker->wd->obj,
2314 marker, marker->data);
2315 if (c) contents = eina_list_append(contents, c);
2317 _bubble_update(group->bubble, contents);
2318 _bubble_place(group->bubble);
2322 _marker_group_bringin_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *soure __UNUSED__)
2324 EINA_SAFETY_ON_NULL_RETURN(data);
2327 Marker_Group *group = data;
2328 _coord_to_region_convert(group->wd, group->x, group->y, group->wd->size.w,
2330 elm_map_region_bring_in(group->wd->obj, lon, lat);
2334 _marker_group_free(Marker_Group* group)
2336 EINA_SAFETY_ON_NULL_RETURN(group);
2338 if (group->bubble) _bubble_free(group->bubble);
2340 eina_list_free(group->markers);
2341 evas_object_del(group->obj);
2346 static Marker_Group*
2347 _marker_group_create(Widget_Data *wd)
2349 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
2351 Marker_Group *group = ELM_NEW(Marker_Group);
2354 group->obj = elm_layout_add(wd->obj);
2355 evas_object_smart_member_add(group->obj, wd->pan_smart);
2356 evas_object_stack_above(group->obj, wd->sep_maps_markers);
2357 elm_layout_theme_set(group->obj, "map/marker", "radio",
2358 elm_widget_style_get(wd->obj));
2359 edje_object_signal_callback_add(elm_layout_edje_get(group->obj),
2360 "open", "elm", _marker_group_bubble_open_cb,
2362 edje_object_signal_callback_add(elm_layout_edje_get(group->obj),
2363 "bringin", "elm", _marker_group_bringin_cb,
2369 _marker_bringin_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *soure __UNUSED__)
2371 Elm_Map_Marker *marker = data;
2372 EINA_SAFETY_ON_NULL_RETURN(marker);
2373 elm_map_region_bring_in(marker->wd->obj, marker->longitude, marker->latitude);
2377 _marker_bubble_open_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *soure __UNUSED__)
2379 EINA_SAFETY_ON_NULL_RETURN(data);
2380 Elm_Map_Marker *marker = data;
2382 if (!marker->bubble) marker->bubble = _bubble_create(marker->obj, marker->wd);
2383 evas_object_smart_changed(marker->wd->pan_smart);
2387 _marker_update(Elm_Map_Marker *marker)
2389 EINA_SAFETY_ON_NULL_RETURN(marker);
2390 Elm_Map_Marker_Class *clas = marker->clas;
2391 EINA_SAFETY_ON_NULL_RETURN(clas);
2393 if (clas->style) elm_layout_theme_set(marker->obj, "map/marker", clas->style,
2394 elm_widget_style_get(marker->wd->obj));
2395 else elm_layout_theme_set(marker->obj, "map/marker", "radio",
2396 elm_widget_style_get(marker->wd->obj));
2398 if (clas->func.icon_get)
2400 Evas_Object *icon = NULL;
2402 icon = elm_object_part_content_get(marker->obj, "elm.icon");
2403 if (icon) evas_object_del(icon);
2405 icon = clas->func.icon_get(marker->wd->obj, marker, marker->data);
2406 elm_object_part_content_set(marker->obj, "elm.icon", icon);
2408 _region_to_coord_convert(marker->wd, marker->longitude, marker->latitude,
2409 marker->wd->size.w, &(marker->x), &(marker->y));
2413 if (marker->content) evas_object_del(marker->content);
2414 if (marker->clas->func.get)
2415 marker->content = marker->clas->func.get(marker->wd->obj, marker,
2417 if (marker->content)
2419 Eina_List *contents = NULL;
2420 contents = eina_list_append(contents, marker->content);
2421 _bubble_update(marker->bubble, contents);
2429 _marker_place(Widget_Data *wd)
2431 EINA_SAFETY_ON_NULL_RETURN(wd);
2435 Elm_Map_Marker *marker;
2436 Elm_Map_Group_Class *group_clas;
2441 if (wd->paused_markers || (!eina_list_count(wd->markers))) return;
2443 _pan_geometry_get(wd, &px, &py);
2445 _edj_marker_size_get(wd, &gw, &gh);
2449 EINA_LIST_FOREACH(wd->markers, l, marker)
2451 _marker_update(marker);
2452 marker->grouped = EINA_FALSE;
2453 marker->leader = EINA_FALSE;
2456 EINA_LIST_FOREACH(wd->group_classes, l, group_clas)
2459 EINA_LIST_FOREACH(group_clas->markers, ll, marker)
2463 Eina_List *markers = NULL;
2465 if (marker->grouped) continue;
2466 if (group_clas->zoom_grouped < wd->zoom)
2468 marker->grouped = EINA_FALSE;
2472 EINA_LIST_FOREACH(group_clas->markers, lll, mm)
2474 if (marker == mm || mm->grouped) continue;
2475 if (ELM_RECTS_INTERSECT(mm->x, mm->y, mm->w, mm->h,
2476 marker->x, marker->y, gw, gh))
2478 // mm is group follower.
2479 mm->leader = EINA_FALSE;
2480 mm->grouped = EINA_TRUE;
2481 markers = eina_list_append(markers, mm);
2484 if (eina_list_count(markers) >= 1)
2486 // marker is group leader.
2487 marker->leader = EINA_TRUE;
2488 marker->grouped = EINA_TRUE;
2489 markers = eina_list_append(markers, marker);
2491 if (!marker->group) marker->group = _marker_group_create(wd);
2492 _marker_group_update(marker->group, group_clas, markers);
2497 EINA_LIST_FOREACH(wd->markers, l, marker)
2500 if (marker->grouped ||
2501 (marker->group_clas &&
2502 (marker->group_clas->hide ||
2503 marker->group_clas->zoom_displayed > wd->zoom)))
2504 evas_object_hide(marker->obj);
2508 _coord_rotate(marker->x + px, marker->y + py, wd->rotate.cx,
2509 wd->rotate.cy, wd->rotate.d, &x, &y);
2510 _obj_place(marker->obj, x - (marker->w / 2), y - (marker->h / 2),
2511 marker->w, marker->h);
2515 EINA_LIST_FOREACH(wd->markers, l, marker)
2517 Marker_Group *group = marker->group;
2518 if (!group) continue;
2520 if (!marker->leader || (group->clas->hide) ||
2521 (group->clas->zoom_displayed > wd->zoom))
2522 evas_object_hide(group->obj);
2526 _coord_rotate(group->x + px, group->y + py, wd->rotate.cx,
2527 wd->rotate.cy, wd->rotate.d, &x, &y);
2528 _obj_place(group->obj, x - (group->w / 2), y - (group->h / 2),
2529 group->w, group->h);
2530 >>>>>>> remotes/origin/upstream
2537 _smooth_update(Evas_Object *obj)
2539 ELM_CHECK_WIDTYPE(obj, widtype);
2540 Widget_Data *wd = elm_widget_data_get(obj);
2545 EINA_LIST_FOREACH(wd->grids, l, g)
2547 Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
2548 Eina_Matrixsparse_Cell *cell;
2550 EINA_ITERATOR_FOREACH(it, cell)
2552 Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
2553 evas_object_image_smooth_scale_set(gi->img, (!wd->nosmooth));
2555 eina_iterator_free(it);
2560 _scr_timeout(void *data)
2562 ELM_CHECK_WIDTYPE(data, widtype) ECORE_CALLBACK_CANCEL;
2563 Widget_Data *wd = elm_widget_data_get(data);
2565 if (!wd) return ECORE_CALLBACK_CANCEL;
2567 if (!wd->nosmooth) _smooth_update(data);
2568 wd->scr_timer = NULL;
2569 return ECORE_CALLBACK_CANCEL;
2573 _scr(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2575 ELM_CHECK_WIDTYPE(data, widtype);
2576 Widget_Data *wd = elm_widget_data_get(data);
2582 if (wd->nosmooth == 1) _smooth_update(data);
2584 if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
2585 wd->scr_timer = ecore_timer_add(0.5, _scr_timeout, data);
2589 zoom_do(Evas_Object *obj)
2591 ELM_CHECK_WIDTYPE(obj, widtype);
2592 Widget_Data *wd = elm_widget_data_get(obj);
2593 Evas_Coord xx, yy, ow, oh;
2596 wd->size.w = wd->size.nw;
2597 wd->size.h = wd->size.nh;
2599 elm_smart_scroller_child_viewport_size_get(wd->scr, &ow, &oh);
2601 if (wd->center_on.enabled)
2603 elm_map_utils_convert_geo_into_coord(obj, wd->center_on.lon, wd->center_on.lat, wd->size.w, &xx, &yy);
2609 xx = (wd->size.spos.x * wd->size.w) - (ow / 2);
2610 yy = (wd->size.spos.y * wd->size.h) - (oh / 2);
2615 else if (xx > (wd->size.w - ow)) xx = wd->size.w - ow;
2617 else if (yy > (wd->size.h - oh)) yy = wd->size.h - oh;
2619 wd->show.show = EINA_TRUE;
2625 if (wd->calc_job) ecore_job_del(wd->calc_job);
2626 wd->calc_job = ecore_job_add(_calc_job, wd);
2630 _zoom_timeout(void *data)
2632 ELM_CHECK_WIDTYPE(data, widtype) ECORE_CALLBACK_CANCEL;
2633 Widget_Data *wd = elm_widget_data_get(data);
2635 if (!wd) return ECORE_CALLBACK_CANCEL;
2636 wd->zoom_timer = NULL;
2637 wd->pinch.level = 1.0;
2639 evas_object_smart_callback_call(data, SIG_ZOOM_STOP, NULL);
2640 return ECORE_CALLBACK_CANCEL;
2644 _zoom_anim(void *data)
2646 ELM_CHECK_WIDTYPE(data, widtype) ECORE_CALLBACK_CANCEL;
2647 Evas_Object *obj = data;
2648 Widget_Data *wd = elm_widget_data_get(obj);
2650 if (!wd) return ECORE_CALLBACK_CANCEL;
2651 if (wd->zoom_method == ZOOM_METHOD_IN) wd->t += 0.1 ;
2652 else if (wd->zoom_method == ZOOM_METHOD_OUT) wd->t -= 0.05;
2655 wd->zoom_animator = NULL;
2657 evas_object_smart_callback_call(data, SIG_ZOOM_STOP, NULL);
2658 return ECORE_CALLBACK_CANCEL;
2663 wd->zoom_animator = NULL;
2664 wd->pinch.level = 2.0;
2665 if (wd->zoom_timer) ecore_timer_del(wd->zoom_timer);
2666 wd->zoom_timer = ecore_timer_add(0.35, _zoom_timeout, obj);
2667 return ECORE_CALLBACK_CANCEL;
2669 else if (wd->t <= 0.5)
2671 wd->zoom_animator = NULL;
2672 wd->pinch.level = 0.5;
2673 if (wd->zoom_timer) ecore_timer_del(wd->zoom_timer);
2674 wd->zoom_timer = ecore_timer_add(1.35, _zoom_timeout, obj);
2675 return ECORE_CALLBACK_CANCEL;
2677 else if (wd->t != 1.0)
2679 Evas_Coord x, y, w, h;
2680 float half_w, half_h;
2681 evas_object_geometry_get(data, &x, &y, &w, &h);
2682 half_w = (float)w * 0.5;
2683 half_h = (float)h * 0.5;
2684 wd->pinch.cx = x + half_w;
2685 wd->pinch.cy = y + half_h;
2686 wd->pinch.level = wd->t;
2687 if (wd->calc_job) ecore_job_del(wd->calc_job);
2688 wd->calc_job = ecore_job_add(_calc_job, wd);
2690 _grid_item_coord_get(Grid_Item *gi, int *x, int *y, int *w, int *h)
2692 EINA_SAFETY_ON_NULL_RETURN(gi);
2694 if (x) *x = gi->x * gi->wd->size.tile;
2695 if (y) *y = gi->y * gi->wd->size.tile;
2696 if (w) *w = gi->wd->size.tile;
2697 if (h) *h = gi->wd->size.tile;
2701 _grid_item_intersect(Grid_Item *gi)
2703 EINA_SAFETY_ON_NULL_RETURN_VAL(gi, EINA_FALSE);
2707 Evas_Coord x, y, w, h;
2709 _pan_geometry_get(gi->wd, &px, &py);
2710 _viewport_size_get(gi->wd, &vw, &vh);
2711 _grid_item_coord_get(gi, &x, &y, &w, &h);
2712 return ELM_RECTS_INTERSECT(x + px, y + py, w, h, 0, 0, vw, vh);
2716 _grid_item_update(Grid_Item *gi)
2718 evas_object_image_file_set(gi->img, gi->file, NULL);
2719 if (!gi->wd->zoom_timer && !gi->wd->scr_timer)
2720 evas_object_image_smooth_scale_set(gi->img, EINA_TRUE);
2721 else evas_object_image_smooth_scale_set(gi->img, EINA_FALSE);
2723 Evas_Load_Error err = evas_object_image_load_error_get(gi->img);
2724 if (err != EVAS_LOAD_ERROR_NONE)
2726 ERR("Image loading error (%s): %s", gi->file, evas_load_error_str(err));
2727 ecore_file_remove(gi->file);
2728 gi->file_have = EINA_FALSE;
2733 Evas_Coord x, y, w, h;
2735 _pan_geometry_get(gi->wd, &px, &py);
2736 _grid_item_coord_get(gi, &x, &y, &w, &h);
2738 _obj_place(gi->img, x + px, y + py, w, h);
2739 _obj_rotate(gi->wd, gi->img);
2740 gi->file_have = EINA_TRUE;
2745 _grid_item_load(Grid_Item *gi)
2747 EINA_SAFETY_ON_NULL_RETURN(gi);
2748 if (gi->file_have) _grid_item_update(gi);
2751 gi->wd->download_list = eina_list_remove(gi->wd->download_list, gi);
2752 gi->wd->download_list = eina_list_append(gi->wd->download_list, gi);
2757 _grid_item_unload(Grid_Item *gi)
2759 EINA_SAFETY_ON_NULL_RETURN(gi);
2762 evas_object_hide(gi->img);
2763 evas_object_image_file_set(gi->img, NULL, NULL);
2767 ecore_file_download_abort(gi->job);
2768 ecore_file_remove(gi->file);
2772 else gi->wd->download_list = eina_list_remove(gi->wd->download_list, gi);
2777 _grid_item_create(Grid *g, Evas_Coord x, Evas_Coord y)
2779 EINA_SAFETY_ON_NULL_RETURN_VAL(g, NULL);
2781 char buf2[PATH_MAX];
2785 gi = ELM_NEW(Grid_Item);
2791 gi->file_have = EINA_FALSE;
2794 gi->img = evas_object_image_add(evas_object_evas_get(g->wd->obj));
2795 evas_object_image_smooth_scale_set(gi->img, EINA_FALSE);
2796 evas_object_image_scale_hint_set(gi->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
2797 evas_object_image_filled_set(gi->img, 1);
2798 evas_object_smart_member_add(gi->img, g->wd->pan_smart);
2799 evas_object_pass_events_set(gi->img, EINA_TRUE);
2800 evas_object_stack_below(gi->img, g->wd->sep_maps_markers);
2802 snprintf(buf, sizeof(buf), CACHE_TILE_ROOT, g->wd->id, g->zoom, x);
2803 snprintf(buf2, sizeof(buf2), CACHE_TILE_PATH, buf, y);
2804 if (!ecore_file_exists(buf)) ecore_file_mkpath(buf);
2806 eina_stringshare_replace(&gi->file, buf2);
2807 url = g->wd->src_tile->url_cb(g->wd->obj, x, y, g->zoom);
2808 if ((!url) || (!strlen(url)))
2810 eina_stringshare_replace(&gi->url, NULL);
2811 ERR("Getting source url failed: %s", gi->file);
2813 else eina_stringshare_replace(&gi->url, url);
2815 eina_matrixsparse_data_idx_set(g->grid, y, x, gi);
2820 _grid_item_free(Grid_Item *gi)
2822 EINA_SAFETY_ON_NULL_RETURN(gi);
2823 _grid_item_unload(gi);
2824 if (gi->g && gi->g->grid) eina_matrixsparse_data_idx_set(gi->g->grid,
2825 gi->y, gi->x, NULL);
2826 if (gi->url) eina_stringshare_del(gi->url);
2827 if (gi->file) eina_stringshare_del(gi->file);
2828 if (gi->img) evas_object_del(gi->img);
2829 if (gi->file_have) ecore_file_remove(gi->file);
2834 _downloaded_cb(void *data, const char *file __UNUSED__, int status)
2836 Grid_Item *gi = data;
2840 DBG("Download success from %s to %s", gi->url, gi->file);
2841 _grid_item_update(gi);
2842 gi->wd->finish_num++;
2843 evas_object_smart_callback_call(gi->wd->obj, SIG_TILE_LOADED, NULL);
2847 WRN("Download failed from %s to %s (%d) ", gi->url, gi->file, status);
2848 ecore_file_remove(gi->file);
2849 gi->file_have = EINA_FALSE;
2850 evas_object_smart_callback_call(gi->wd->obj, SIG_TILE_LOADED_FAIL, NULL);
2854 gi->wd->download_num--;
2855 if (!gi->wd->download_num)
2856 edje_object_signal_emit(elm_smart_scroller_edje_object_get(gi->wd->scr),
2857 "elm,state,busy,stop", "elm");
2861 _download_job(void *data)
2863 EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_CANCEL);
2864 Widget_Data *wd = data;
2869 if (!eina_list_count(wd->download_list))
2871 wd->download_idler = NULL;
2872 return ECORE_CALLBACK_CANCEL;
2875 EINA_LIST_REVERSE_FOREACH_SAFE(wd->download_list, l, ll, gi)
2877 if (gi->g->zoom != wd->zoom || !_grid_item_intersect(gi))
2879 wd->download_list = eina_list_remove(wd->download_list, gi);
2882 if (wd->download_num >= MAX_CONCURRENT_DOWNLOAD)
2883 return ECORE_CALLBACK_RENEW;
2885 Eina_Bool ret = ecore_file_download_full(gi->url, gi->file,
2886 _downloaded_cb, NULL,
2887 gi, &(gi->job), wd->ua);
2888 if ((!ret) || (!gi->job))
2889 ERR("Can't start to download from %s to %s", gi->url, gi->file);
2892 wd->download_list = eina_list_remove(wd->download_list, gi);
2895 evas_object_smart_callback_call(gi->wd->obj, SIG_TILE_LOAD,
2897 if (wd->download_num == 1)
2898 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
2899 "elm,state,busy,start", "elm");
2902 >>>>>>> remotes/origin/upstream
2904 return ECORE_CALLBACK_RENEW;
2909 _long_press(void *data)
2911 ELM_CHECK_WIDTYPE(data, widtype) ECORE_CALLBACK_CANCEL;
2912 Widget_Data *wd = elm_widget_data_get(data);
2914 if (!wd) return ECORE_CALLBACK_CANCEL;
2915 wd->long_timer = NULL;
2916 evas_object_smart_callback_call(data, SIG_LONGPRESSED, &wd->ev);
2917 return ECORE_CALLBACK_CANCEL;
2921 _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2923 ELM_CHECK_WIDTYPE(data, widtype);
2924 Widget_Data *wd = elm_widget_data_get(data);
2925 Evas_Event_Mouse_Down *ev = event_info;
2927 if (ev->button != 1) return;
2928 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
2929 else wd->on_hold = EINA_FALSE;
2930 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
2931 evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, ev);
2933 evas_object_smart_callback_call(data, SIG_PRESS, ev);
2934 if (wd->long_timer) ecore_timer_del(wd->long_timer);
2936 wd->long_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, data);
2940 _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2942 ELM_CHECK_WIDTYPE(data, widtype);
2943 Widget_Data *wd = elm_widget_data_get(data);
2944 EINA_SAFETY_ON_NULL_RETURN(wd);
2946 Evas_Event_Mouse_Up *ev = event_info;
2947 EINA_SAFETY_ON_NULL_RETURN(ev);
2949 if (ev->button != 1) return;
2950 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
2951 else wd->on_hold = EINA_FALSE;
2954 ecore_timer_del(wd->long_timer);
2955 wd->long_timer = NULL;
2957 if (!wd->on_hold) evas_object_smart_callback_call(data, SIG_CLICKED, ev);
2958 wd->on_hold = EINA_FALSE;
2962 _mouse_wheel_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2964 ELM_CHECK_WIDTYPE(data, widtype);
2965 Widget_Data *wd = elm_widget_data_get(data);
2966 EINA_SAFETY_ON_NULL_RETURN(wd);
2971 Evas_Event_Mouse_Wheel *ev = (Evas_Event_Mouse_Wheel*) event_info;
2972 Evas_Coord x, y, w, h;
2974 evas_object_geometry_get(data, &x, &y, &w, &h);
2976 if (wd->calc_job) ecore_job_del(wd->calc_job);
2977 wd->calc_job = ecore_job_add(_calc_job, wd);
2979 wd->wheel_diff -= ev->z;
2980 wd->pinch.level = wd->pinch.diff * pow(2.0, (double)wd->wheel_diff/10);
2981 wd->pinch.cx = x + ((double)w * 0.5);
2982 wd->pinch.cy = y + ((double)h * 0.5);
2984 if (wd->pinch.level > 1.99 || wd->pinch.level < 1.01)
2987 if (wd->pinch.level > 1.99)
2990 wd->pinch.diff = wd->pinch.level / 2.0;
2991 wd->pinch.level = wd->pinch.level / 2.0;
2993 else if (wd->pinch.level < 1.01)
2996 wd->pinch.diff = wd->pinch.level * 2.0;
2997 wd->pinch.level = wd->pinch.level * 2.0;
3000 Elm_Map_Zoom_Mode temp;
3002 wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
3003 wd->paused = EINA_TRUE;
3004 elm_map_zoom_set(data, wd->zoom + zoom_diff);
3005 wd->paused = EINA_FALSE;
3010 if (wd->calc_job) ecore_job_del(wd->calc_job);
3011 wd->calc_job = ecore_job_add(_calc_job, wd);
3014 _grid_viewport_get(Grid *g, int *x, int *y, int *w, int *h)
3016 EINA_SAFETY_ON_NULL_RETURN(g);
3018 Evas_Coord px, py, vw, vh;
3020 _pan_geometry_get(g->wd, &px, &py);
3021 _viewport_size_get(g->wd, &vw, &vh);
3025 xx = (-px / g->wd->size.tile) - 1;
3028 yy = (-py / g->wd->size.tile) - 1;
3031 ww = (vw / g->wd->size.tile) + 3;
3032 if (xx + ww >= g->tw) ww = g->tw - xx;
3034 hh = (vh / g->wd->size.tile) + 3;
3035 if (yy + hh >= g->th) hh = g->th - yy;
3044 _grid_unload(Grid *g)
3046 EINA_SAFETY_ON_NULL_RETURN(g);
3048 Eina_Matrixsparse_Cell *cell;
3051 it = eina_matrixsparse_iterator_new(g->grid);
3052 EINA_ITERATOR_FOREACH(it, cell)
3054 gi = eina_matrixsparse_cell_data_get(cell);
3055 _grid_item_unload(gi);
3057 eina_iterator_free(it);
3063 EINA_SAFETY_ON_NULL_RETURN(g);
3064 int x, y, xx, yy, ww, hh;
3066 Eina_Matrixsparse_Cell *cell;
3069 it = eina_matrixsparse_iterator_new(g->grid);
3070 EINA_ITERATOR_FOREACH(it, cell)
3072 gi = eina_matrixsparse_cell_data_get(cell);
3073 if (!_grid_item_intersect(gi)) _grid_item_unload(gi);
3075 eina_iterator_free(it);
3077 _grid_viewport_get(g, &xx, &yy, &ww, &hh);
3078 for (y = yy; y < yy + hh; y++)
3080 for (x = xx; x < xx + ww; x++)
3082 gi = eina_matrixsparse_data_idx_get(g->grid, y, x);
3083 if (!gi) gi = _grid_item_create(g, x, y);
3084 _grid_item_load(gi);
3085 >>>>>>> remotes/origin/upstream
3092 _rect_resize_cb(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3094 ELM_CHECK_WIDTYPE(data, widtype);
3095 Widget_Data *wd = elm_widget_data_get(data);
3098 evas_object_geometry_get(wd->rect, &x, &y, &w, &h);
3099 evas_object_geometry_get(wd->pan_smart, &x, &y, &w, &h);
3100 evas_object_resize(wd->rect, w, h);
3101 evas_object_move(wd->rect, x, y);
3105 _del_hook(Evas_Object *obj)
3107 ELM_CHECK_WIDTYPE(obj, widtype);
3108 Widget_Data *wd = elm_widget_data_get(obj);
3109 Elm_Map_Group_Class *group_clas;
3110 Elm_Map_Marker_Class *marker_clas;
3115 Ecore_Event_Handler *h;
3121 EINA_LIST_FREE(wd->groups_clas, group_clas)
3123 if (group_clas->style)
3124 eina_stringshare_del(group_clas->style);
3128 EINA_LIST_FREE(wd->markers_clas, marker_clas)
3130 if (marker_clas->style)
3131 eina_stringshare_del(marker_clas->style);
3135 EINA_LIST_FOREACH(wd->route, l, r)
3137 EINA_LIST_FREE(r->path, p)
3142 EINA_LIST_FREE(r->waypoint, w)
3144 if (w->point) eina_stringshare_del(w->point);
3148 EINA_LIST_FREE(r->nodes, n)
3150 if (n->pos.address) eina_stringshare_del(n->pos.address);
3154 EINA_LIST_FREE(r->handlers, h)
3156 ecore_event_handler_del(h);
3159 if (r->con_url) ecore_con_url_free(r->con_url);
3160 if (r->info.nodes) eina_stringshare_del(r->info.nodes);
3161 if (r->info.waypoints) eina_stringshare_del(r->info.waypoints);
3164 EINA_LIST_FREE(wd->names, na)
3166 if (na->address) free(na->address);
3167 if (na->handler) ecore_event_handler_del(na->handler);
3170 ecore_file_remove(na->ud.fname);
3172 na->ud.fname = NULL;
3176 EINA_LIST_FREE(wd->track, route)
3178 evas_object_del(route);
3181 if (wd->map) evas_map_free(wd->map);
3182 if (wd->source_names) free(wd->source_names);
3183 if (wd->calc_job) ecore_job_del(wd->calc_job);
3184 if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
3185 if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
3186 if (wd->long_timer) ecore_timer_del(wd->long_timer);
3187 if (wd->user_agent) eina_stringshare_del(wd->user_agent);
3188 if (wd->ua) eina_hash_free(wd->ua);
3189 if (wd->markers) free(wd->markers);
3195 _del_pre_hook(Evas_Object *obj)
3197 ELM_CHECK_WIDTYPE(obj, widtype);
3198 Widget_Data *wd = elm_widget_data_get(obj);
3199 Marker_Group *group;
3200 Elm_Map_Marker *marker;
3202 Eina_Bool free_marker = EINA_TRUE;
3206 grid_clear_all(obj);
3207 for (i = 0; i <= wd->zoom_max; i++)
3209 if (!wd->markers[i]) continue;
3210 Eina_Iterator *it = eina_matrixsparse_iterator_new(wd->markers[i]);
3212 _grid_place(Widget_Data *wd)
3214 EINA_SAFETY_ON_NULL_RETURN(wd);
3218 EINA_LIST_FOREACH(wd->grids, l, g)
3220 if (wd->zoom == g->zoom) _grid_load(g);
3221 else _grid_unload(g);
3223 if (!wd->download_idler) wd->download_idler = ecore_idler_add(_download_job, wd);
3227 _grid_all_create(Widget_Data *wd)
3229 EINA_SAFETY_ON_NULL_RETURN(wd);
3230 EINA_SAFETY_ON_NULL_RETURN(wd->src_tile);
3233 for (zoom = wd->src_tile->zoom_min; zoom <= wd->src_tile->zoom_max; zoom++)
3240 tnum = pow(2.0, g->zoom);
3243 g->grid = eina_matrixsparse_new(g->th, g->tw, NULL, NULL);
3244 wd->grids = eina_list_append(wd->grids, g);
3249 _grid_all_clear(Widget_Data *wd)
3251 EINA_SAFETY_ON_NULL_RETURN(wd);
3254 EINA_LIST_FREE(wd->grids, g)
3256 Eina_Matrixsparse_Cell *cell;
3257 Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
3258 EINA_ITERATOR_FOREACH(it, cell)
3261 gi = eina_matrixsparse_cell_data_get(cell);
3262 if (gi) _grid_item_free(gi);
3264 eina_iterator_free(it);
3266 eina_matrixsparse_free(g->grid);
3272 _track_place(Widget_Data *wd)
3275 EINA_SAFETY_ON_NULL_RETURN(wd);
3279 int xmin, xmax, ymin, ymax;
3280 Evas_Coord px, py, ow, oh;
3283 _viewport_size_get(wd, &ow, &oh);
3285 Evas_Coord size = wd->size.w;
3287 EINA_LIST_FOREACH(wd->track, l, route)
3289 double lon_min, lon_max;
3290 double lat_min, lat_max;
3291 elm_route_longitude_min_max_get(route, &lon_min, &lon_max);
3292 elm_route_latitude_min_max_get(route, &lat_min, &lat_max);
3293 _region_to_coord_convert(wd, lon_min, lat_max, size, &xmin, &ymin);
3294 _region_to_coord_convert(wd, lon_max, lat_min, size, &xmax, &ymax);
3296 if( !(xmin < px && xmax < px) && !(xmin > px+ow && xmax > px+ow))
3298 if( !(ymin < py && ymax < py) && !(ymin > py+oh && ymax > py+oh))
3301 evas_object_move(route, xmin - px, ymin - py);
3302 evas_object_resize(route, xmax - xmin, ymax - ymin);
3304 evas_object_raise(route);
3305 _obj_rotate(wd, route);
3306 evas_object_show(route);
3311 //the route is not display
3312 evas_object_hide(route);
3320 _delayed_do(Widget_Data *wd)
3323 dd = eina_list_nth(wd->delayed_jobs, 0);
3324 if (dd && !dd->wd->zoom_animator)
3327 wd->delayed_jobs = eina_list_remove(wd->delayed_jobs, dd);
3333 _smooth_update(Widget_Data *wd)
3335 EINA_SAFETY_ON_NULL_RETURN(wd);
3339 EINA_LIST_FOREACH(wd->grids, l, g)
3341 Eina_Iterator *it = eina_matrixsparse_iterator_new(g->grid);
3342 >>>>>>> remotes/origin/upstream
3343 Eina_Matrixsparse_Cell *cell;
3345 EINA_ITERATOR_FOREACH(it, cell)
3348 l = eina_matrixsparse_cell_data_get(cell);
3349 EINA_LIST_FREE(l, group)
3351 EINA_LIST_FREE(group->markers, marker)
3353 evas_object_event_callback_del_full(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
3354 _bubble_sc_hints_changed_cb, group);
3355 if (free_marker) free(marker);
3359 free_marker = EINA_FALSE;
3361 eina_iterator_free(it);
3362 eina_matrixsparse_free(wd->markers[i]);
3365 evas_object_del(wd->sep_maps_markers);
3366 evas_object_del(wd->pan_smart);
3367 wd->pan_smart = NULL;
3371 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
3373 ELM_CHECK_WIDTYPE(obj, widtype);
3374 Widget_Data *wd = elm_widget_data_get(obj);
3377 if (elm_widget_focus_get(obj))
3379 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,action,focus", "elm");
3380 evas_object_focus_set(wd->obj, EINA_TRUE);
3384 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,action,unfocus", "elm");
3385 evas_object_focus_set(wd->obj, EINA_FALSE);
3387 Grid_Item *gi = eina_matrixsparse_cell_data_get(cell);
3388 if (_grid_item_intersect(gi))
3389 evas_object_image_smooth_scale_set(gi->img, EINA_TRUE);
3391 eina_iterator_free(it);
3396 _zoom_timeout(void *data)
3398 EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_CANCEL);
3399 Widget_Data *wd = data;
3401 wd->zoom_timer = NULL;
3402 evas_object_smart_callback_call(wd->obj, SIG_ZOOM_STOP, NULL);
3403 return ECORE_CALLBACK_CANCEL;
3407 zoom_do(Widget_Data *wd, double zoom)
3409 EINA_SAFETY_ON_NULL_RETURN(wd);
3410 if (zoom > wd->zoom_max) zoom = wd->zoom_max;
3411 else if (zoom < wd->zoom_min) zoom = wd->zoom_min;
3413 Evas_Coord px, py, vw, vh;
3416 wd->zoom = ROUND(zoom);
3417 wd->zoom_detail = zoom;
3420 wd->size.tile = pow(2.0, (zoom - wd->zoom)) * wd->tsize;
3421 wd->size.w = pow(2.0, wd->zoom) * wd->size.tile;
3422 wd->size.h = wd->size.w;;
3424 // Fix to zooming with (viewport center px, py) as the center to prevent
3425 // from zooming with (0,0) as the cetner. (scroller default behavior)
3426 _pan_geometry_get(wd, &px, &py);
3427 _viewport_size_get(wd, &vw, &vh);
3428 if ((vw > 0) && (vh > 0) && (ow > 0) && (oh > 0))
3432 if (vw > ow) sx = 0.5;
3433 else sx = (double)(-px + (vw / 2)) / ow;
3434 if (vh > oh) sy = 0.5;
3435 else sy = (double)(-py + (vh / 2)) / oh;
3437 if (sx > 1.0) sx = 1.0;
3438 if (sy > 1.0) sy = 1.0;
3440 xx = (sx * wd->size.w) - (vw / 2);
3441 yy = (sy * wd->size.h) - (vh / 2);
3443 else if (xx > (wd->size.w - vw)) xx = wd->size.w - vw;
3445 else if (yy > (wd->size.h - vh)) yy = wd->size.h - vh;
3446 elm_smart_scroller_child_region_show(wd->scr, xx, yy, vw, vh);
3448 if (wd->zoom_timer) ecore_timer_del(wd->zoom_timer);
3449 else evas_object_smart_callback_call(wd->obj, SIG_ZOOM_START, NULL);
3450 wd->zoom_timer = ecore_timer_add(0.25, _zoom_timeout, wd);
3451 evas_object_smart_callback_call(wd->obj, SIG_ZOOM_CHANGE, NULL);
3453 evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
3454 evas_object_smart_changed(wd->pan_smart);
3458 _zoom_anim(void *data)
3460 Widget_Data *wd = data;
3461 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, ECORE_CALLBACK_CANCEL);
3463 if (wd->ani.cnt <= 0)
3465 wd->zoom_animator = NULL;
3466 evas_object_smart_changed(wd->pan_smart);
3467 return ECORE_CALLBACK_CANCEL;
3471 wd->ani.zoom += wd->ani.diff;
3473 zoom_do(wd, wd->ani.zoom);
3474 return ECORE_CALLBACK_RENEW;
3475 >>>>>>> remotes/origin/upstream
3481 _theme_hook(Evas_Object *obj)
3483 ELM_CHECK_WIDTYPE(obj, widtype);
3484 Widget_Data *wd = elm_widget_data_get(obj);
3487 elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", elm_widget_style_get(obj));
3488 // edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
3493 _sizing_eval(Evas_Object *obj)
3495 ELM_CHECK_WIDTYPE(obj, widtype);
3496 Widget_Data *wd = elm_widget_data_get(obj);
3497 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
3500 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
3501 evas_object_size_hint_min_set(obj, minw, minh);
3502 evas_object_size_hint_max_set(obj, maxw, maxh);
3506 _calc_job(void *data)
3508 Widget_Data *wd = data;
3509 Evas_Coord minw, minh;
3516 wd->resized = EINA_FALSE;
3517 if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
3519 double tz = wd->zoom;
3521 elm_map_zoom_set(wd->obj, tz);
3524 if ((minw != wd->minw) || (minh != wd->minh))
3528 evas_object_smart_callback_call(wd->pan_smart, SIG_CHANGED, NULL);
3529 _sizing_eval(wd->obj);
3531 wd->calc_job = NULL;
3532 evas_object_smart_changed(wd->pan_smart);
3536 _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
3538 Pan *sd = evas_object_smart_data_get(obj);
3540 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
3543 evas_object_smart_changed(obj);
3547 _pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
3549 Pan *sd = evas_object_smart_data_get(obj);
3551 if (x) *x = sd->wd->pan_x;
3552 if (y) *y = sd->wd->pan_y;
3556 _pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
3558 Pan *sd = evas_object_smart_data_get(obj);
3561 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3562 ow = sd->wd->minw - ow;
3564 oh = sd->wd->minh - oh;
3571 _pan_min_get(Evas_Object *obj __UNUSED__, Evas_Coord *x, Evas_Coord *y)
3578 _pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
3580 Pan *sd = evas_object_smart_data_get(obj);
3582 if (w) *w = sd->wd->minw;
3583 if (h) *h = sd->wd->minh;
3587 _pan_add(Evas_Object *obj)
3590 Evas_Object_Smart_Clipped_Data *cd;
3592 cd = evas_object_smart_data_get(obj);
3594 sd = calloc(1, sizeof(Pan));
3596 sd->__clipped_data = *cd;
3598 evas_object_smart_data_set(obj, sd);
3602 _pan_del(Evas_Object *obj)
3604 Pan *sd = evas_object_smart_data_get(obj);
3610 _pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
3612 Pan *sd = evas_object_smart_data_get(obj);
3615 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
3616 if ((ow == w) && (oh == h)) return;
3617 sd->wd->resized = EINA_TRUE;
3618 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3619 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
3623 _pan_calculate(Evas_Object *obj)
3625 Pan *sd = evas_object_smart_data_get(obj);
3626 Evas_Coord ox, oy, ow, oh;
3630 EINA_SAFETY_ON_NULL_RETURN(sd);
3631 EINA_SAFETY_ON_NULL_RETURN(sd->wd);
3633 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
3634 rect_place(sd->wd->obj, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
3635 EINA_LIST_FOREACH(sd->wd->grids, l, g)
3637 if (sd->wd->zoom == g->zoom) grid_load(sd->wd->obj, g);
3638 else if (sd->wd->zoom-1 != g->zoom && sd->wd->zoom+1 != g->zoom) grid_unload(sd->wd->obj, g); // remain only adjacent grids
3639 grid_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
3640 if (sd->wd->zoom == g->zoom) marker_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
3641 if (!sd->wd->zoom_animator) route_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
3642 if (!sd->wd->zoom_animator) track_place(sd->wd->obj, g, sd->wd->pan_x, sd->wd->pan_y, ox, oy, ow, oh);
3647 _pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
3649 Pan *sd = evas_object_smart_data_get(obj);
3651 if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
3652 sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
3656 _hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
3658 ELM_CHECK_WIDTYPE(obj, widtype);
3659 Widget_Data *wd = elm_widget_data_get(obj);
3662 elm_smart_scroller_hold_set(wd->scr, 1);
3666 _hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
3668 ELM_CHECK_WIDTYPE(obj, widtype);
3669 Widget_Data *wd = elm_widget_data_get(obj);
3672 elm_smart_scroller_hold_set(wd->scr, 0);
3676 _freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
3678 ELM_CHECK_WIDTYPE(obj, widtype);
3679 Widget_Data *wd = elm_widget_data_get(obj);
3682 elm_smart_scroller_freeze_set(wd->scr, 1);
3686 _freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
3688 ELM_CHECK_WIDTYPE(obj, widtype);
3689 Widget_Data *wd = elm_widget_data_get(obj);
3692 elm_smart_scroller_freeze_set(wd->scr, 0);
3696 _scr_anim_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3698 evas_object_smart_callback_call(data, "scroll,anim,start", NULL);
3702 _scr_anim_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3704 evas_object_smart_callback_call(data, "scroll,anim,stop", NULL);
3708 _scr_drag_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3710 Widget_Data *wd = elm_widget_data_get(data);
3711 EINA_SAFETY_ON_NULL_RETURN(wd);
3712 wd->center_on.enabled = EINA_FALSE;
3714 // FIXME: els_scoller sometimes give start event again & again... it confuses app. (els_scr bug?)
3715 if (!wd->scr_started)
3717 wd->scr_started = EINA_TRUE;
3718 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_START, NULL);
3723 _scr_drag_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3725 Widget_Data *wd = elm_widget_data_get(data);
3726 EINA_SAFETY_ON_NULL_RETURN(wd);
3727 wd->center_on.enabled = EINA_FALSE;
3729 // FIXME: els_scoller sometimes give start event again & again... it confuses app. (els_scr bug?)
3730 if (wd->scr_started)
3732 wd->scr_started = EINA_FALSE;
3733 evas_object_smart_callback_call(data, SIG_SCROLL_DRAG_STOP, NULL);
3738 _scr_scroll(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3740 evas_object_smart_callback_call(data, SIG_SCROLL, NULL);
3745 _group_object_create(Marker_Group *group)
3747 const char *style = "radio";
3748 Evas_Object *icon = NULL;
3750 if (group->obj) return;
3751 if ((!group->clas->priv.objs_notused) || (eina_list_count(group->markers) == 1))
3753 //set icon and style
3754 if (eina_list_count(group->markers) == 1)
3756 Elm_Map_Marker *m = eina_list_data_get(group->markers);
3758 style = m->clas->style;
3760 if (m->clas->func.icon_get)
3761 icon = m->clas->func.icon_get(group->wd->obj, m, m->data);
3763 group->delete_object = EINA_TRUE;
3767 if (group->clas->style)
3768 style = group->clas->style;
3770 if (group->clas->func.icon_get)
3771 icon = group->clas->func.icon_get(group->wd->obj, group->clas->data);
3773 group->delete_object = EINA_FALSE;
3776 group->obj = elm_layout_add(group->wd->obj);
3777 elm_layout_theme_set(group->obj, "map/marker", style, elm_widget_style_get(group->wd->obj));
3779 if (icon) elm_object_part_content_set(group->obj, "elm.icon", icon);
3781 evas_object_smart_member_add(group->obj, group->wd->pan_smart);
3782 elm_widget_sub_object_add(group->wd->obj, group->obj);
3783 evas_object_stack_above(group->obj, group->wd->sep_maps_markers);
3785 if (!group->delete_object)
3786 group->clas->priv.objs_used = eina_list_append(group->clas->priv.objs_used, group->obj);
3790 group->delete_object = EINA_FALSE;
3792 group->obj = eina_list_data_get(group->clas->priv.objs_notused);
3793 group->clas->priv.objs_used = eina_list_append(group->clas->priv.objs_used, group->obj);
3794 group->clas->priv.objs_notused = eina_list_remove(group->clas->priv.objs_notused, group->obj);
3795 evas_object_show(group->obj);
3798 edje_object_signal_callback_add(elm_layout_edje_get(group->obj), "open", "elm", _group_open_cb, group);
3799 edje_object_signal_callback_add(elm_layout_edje_get(group->obj), "bringin", "elm", _group_bringin_cb, group);
3801 group->update_nbelems = EINA_TRUE;
3802 group->update_resize = EINA_TRUE;
3803 group->update_raise = EINA_TRUE;
3805 if (group->open) _group_bubble_create(group);
3809 _group_object_free(Marker_Group *group)
3811 if (!group->obj) return;
3812 if (!group->delete_object)
3814 group->clas->priv.objs_notused = eina_list_append(group->clas->priv.objs_notused, group->obj);
3815 group->clas->priv.objs_used = eina_list_remove(group->clas->priv.objs_used, group->obj);
3816 evas_object_hide(group->obj);
3818 edje_object_signal_callback_del(elm_layout_edje_get(group->obj), "open", "elm", _group_open_cb);
3819 edje_object_signal_callback_del(elm_layout_edje_get(group->obj), "bringin", "elm", _group_bringin_cb);
3822 evas_object_del(group->obj);
3825 _group_bubble_free(group);
3829 _group_bubble_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3831 Marker_Group *group = data;
3833 if (!evas_object_above_get(group->rect)) return;
3834 evas_object_raise(group->bubble);
3835 evas_object_raise(group->sc);
3836 evas_object_raise(group->rect);
3840 _group_bubble_create(Marker_Group *group)
3842 if (group->bubble) return;
3844 group->wd->opened_bubbles = eina_list_append(group->wd->opened_bubbles, group);
3845 group->bubble = edje_object_add(evas_object_evas_get(group->obj));
3846 _elm_theme_object_set(group->wd->obj, group->bubble, "map", "marker_bubble",
3847 elm_widget_style_get(group->wd->obj));
3848 evas_object_smart_member_add(group->bubble,
3850 elm_widget_sub_object_add(group->wd->obj, group->bubble);
3852 _group_bubble_content_free(group);
3853 if (!_group_bubble_content_update(group))
3855 //no content, we can delete the bubble
3856 _group_bubble_free(group);
3860 group->rect = evas_object_rectangle_add(evas_object_evas_get(group->obj));
3861 evas_object_color_set(group->rect, 0, 0, 0, 0);
3862 evas_object_repeat_events_set(group->rect, EINA_TRUE);
3863 evas_object_smart_member_add(group->rect, group->wd->obj);
3864 elm_widget_sub_object_add(group->wd->obj, group->rect);
3866 evas_object_event_callback_add(group->rect, EVAS_CALLBACK_MOUSE_UP, _group_bubble_mouse_up_cb, group);
3868 _group_bubble_place(group);
3871 static void _bubble_sc_hints_changed_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
3873 _group_bubble_place(data);
3877 _group_bubble_content_update(Marker_Group *group)
3880 Elm_Map_Marker *marker;
3883 if (!group->bubble) return 1;
3887 group->sc = elm_scroller_add(group->bubble);
3888 elm_widget_style_set(group->sc, "map_bubble");
3889 elm_scroller_content_min_limit(group->sc, EINA_FALSE, EINA_TRUE);
3890 elm_scroller_policy_set(group->sc, ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_OFF);
3891 elm_scroller_bounce_set(group->sc, _elm_config->thumbscroll_bounce_enable, EINA_FALSE);
3892 edje_object_part_swallow(group->bubble, "elm.swallow.content", group->sc);
3893 evas_object_show(group->sc);
3894 evas_object_smart_member_add(group->sc,
3896 elm_widget_sub_object_add(group->wd->obj, group->sc);
3898 group->bx = elm_box_add(group->bubble);
3899 evas_object_size_hint_align_set(group->bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
3900 evas_object_size_hint_weight_set(group->bx, 0.5, 0.5);
3901 elm_box_horizontal_set(group->bx, EINA_TRUE);
3902 evas_object_show(group->bx);
3904 elm_object_content_set(group->sc, group->bx);
3906 evas_object_event_callback_add(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
3907 _bubble_sc_hints_changed_cb, group);
3910 EINA_LIST_FOREACH(group->markers, l, marker)
3912 if (i >= group->wd->markers_max_num) break;
3913 if ((!marker->content) && (marker->clas->func.get))
3914 marker->content = marker->clas->func.get(group->wd->obj, marker, marker->data);
3915 else if (marker->content)
3916 elm_box_unpack(group->bx, marker->content);
3917 if (marker->content)
3919 elm_box_pack_end(group->bx, marker->content);
3927 _group_bubble_content_free(Marker_Group *group)
3930 Elm_Map_Marker *marker;
3932 if (!group->sc) return;
3933 EINA_LIST_FOREACH(group->markers, l, marker)
3935 if ((marker->content) && (marker->clas->func.del))
3936 marker->clas->func.del(group->wd->obj, marker, marker->data, marker->content);
3937 else if (marker->content)
3938 evas_object_del(marker->content);
3939 marker->content = NULL;
3941 evas_object_del(group->sc);
3946 _group_bubble_free(Marker_Group *group)
3948 if (!group->bubble) return;
3949 group->wd->opened_bubbles = eina_list_remove(group->wd->opened_bubbles, group);
3950 evas_object_event_callback_del_full(group->sc, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
3951 _bubble_sc_hints_changed_cb, group);
3952 evas_object_del(group->bubble);
3953 evas_object_del(group->rect);
3954 group->bubble = NULL;
3955 _group_bubble_content_free(group);
3959 _group_bubble_place(Marker_Group *group)
3962 Evas_Coord xx, yy, ww, hh;
3965 if ((!group->bubble) || (!group->obj)) return;
3967 evas_object_geometry_get(group->obj, &x, &y, &w, NULL);
3968 edje_object_size_min_calc(group->bubble, NULL, &hh);
3970 s = edje_object_data_get(group->bubble, "size_w");
3971 if (s) ww = atoi(s);
3973 xx = x + w / 2 - ww / 2;
3976 evas_object_move(group->bubble, xx, yy);
3977 evas_object_resize(group->bubble, ww, hh);
3978 obj_rotate_zoom(group->wd->obj, group->bubble);
3979 evas_object_show(group->bubble);
3981 evas_object_move(group->rect, xx, yy);
3982 evas_object_resize(group->rect, ww, hh);
3983 obj_rotate_zoom(group->wd->obj, group->rect);
3984 evas_object_show(group->rect);
3988 _group_bringin_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *soure __UNUSED__)
3990 Marker_Group *group = data;
3991 Elm_Map_Marker *marker = eina_list_data_get(group->markers);
3992 if (!marker) return;
3993 group->bringin = EINA_TRUE;
3994 elm_map_geo_region_bring_in(group->wd->obj, marker->longitude, marker->latitude);
3998 _group_open_cb(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *soure __UNUSED__)
4000 Marker_Group *group = data;
4004 group->bringin = EINA_FALSE;
4010 group->open = EINA_FALSE;
4011 _group_bubble_free(group);
4014 group->open = EINA_TRUE;
4015 _group_bubble_create(group);
4019 _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
4021 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
4022 Widget_Data *wd = elm_widget_data_get(obj);
4026 Evas_Coord step_x = 0;
4027 Evas_Coord step_y = 0;
4030 Evas_Coord page_x = 0;
4031 Evas_Coord page_y = 0;
4033 if (!wd) return EINA_FALSE;
4034 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
4035 Evas_Event_Key_Down *ev = event_info;
4036 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
4038 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
4039 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
4040 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
4041 elm_smart_scroller_child_viewport_size_get(wd->scr, &v_w, &v_h);
4043 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
4047 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
4051 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
4055 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
4059 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
4062 y -= -(page_y * v_h) / 100;
4066 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
4069 y += -(page_y * v_h) / 100;
4073 else if (!strcmp(ev->keyname, "KP_Add"))
4075 zoom = elm_map_zoom_get(obj) + 1;
4076 elm_map_zoom_mode_set(obj, ELM_MAP_ZOOM_MODE_MANUAL);
4077 elm_map_zoom_set(obj, zoom);
4080 else if (!strcmp(ev->keyname, "KP_Subtract"))
4082 zoom = elm_map_zoom_get(obj) - 1;
4083 elm_map_zoom_mode_set(obj, ELM_MAP_ZOOM_MODE_MANUAL);
4084 elm_map_zoom_set(obj, zoom);
4087 else return EINA_FALSE;
4089 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
4090 elm_smart_scroller_child_pos_set(wd->scr, x, y);
4096 cb_dump_name_attrs(void *data, const char *key, const char *value)
4098 Name_Dump *dump = (Name_Dump*)data;
4099 if (!dump) return EINA_FALSE;
4101 if (!strncmp(key, NOMINATIM_ATTR_LON, sizeof(NOMINATIM_ATTR_LON))) dump->lon = atof(value);
4102 else if (!strncmp(key, NOMINATIM_ATTR_LAT, sizeof(NOMINATIM_ATTR_LAT))) dump->lat = atof(value);
4109 cb_route_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
4111 Route_Dump *dump = data;
4112 if (!dump) return EINA_FALSE;
4116 case EINA_SIMPLE_XML_OPEN:
4117 case EINA_SIMPLE_XML_OPEN_EMPTY:
4121 attrs = eina_simple_xml_tag_attributes_find(value, length);
4124 if (!strncmp(value, YOURS_DISTANCE, length)) dump->id = ROUTE_XML_DISTANCE;
4125 else if (!strncmp(value, YOURS_DESCRIPTION, length)) dump->id = ROUTE_XML_DESCRIPTION;
4126 else if (!strncmp(value, YOURS_COORDINATES, length)) dump->id = ROUTE_XML_COORDINATES;
4127 else dump->id = ROUTE_XML_NONE;
4131 case EINA_SIMPLE_XML_DATA:
4133 char *buf = malloc(length);
4134 if (!buf) return EINA_FALSE;
4135 snprintf(buf, length, "%s", value);
4136 if (dump->id == ROUTE_XML_DISTANCE) dump->distance = atof(buf);
4137 else if (!(dump->description) && (dump->id == ROUTE_XML_DESCRIPTION)) dump->description = strdup(buf);
4138 else if (dump->id == ROUTE_XML_COORDINATES) dump->coordinates = strdup(buf);
4150 cb_name_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
4152 Name_Dump *dump = data;
4153 if (!dump) return EINA_FALSE;
4157 case EINA_SIMPLE_XML_OPEN:
4158 case EINA_SIMPLE_XML_OPEN_EMPTY:
4161 attrs = eina_simple_xml_tag_attributes_find(value, length);
4164 if (!strncmp(value, NOMINATIM_RESULT, sizeof(NOMINATIM_RESULT) - 1)) dump->id = NAME_XML_NAME;
4165 else dump->id = NAME_XML_NONE;
4167 eina_simple_xml_attributes_parse
4168 (attrs, length - (attrs - value), cb_dump_name_attrs, dump);
4172 case EINA_SIMPLE_XML_DATA:
4174 char *buf = malloc(length + 1);
4175 if (!buf) return EINA_FALSE;
4176 snprintf(buf, length + 1, "%s", value);
4177 if (dump->id == NAME_XML_NAME) dump->address = strdup(buf);
4189 _parse_kml(void *data)
4191 Elm_Map_Route *r = (Elm_Map_Route*)data;
4192 if (!r || !r->ud.fname) return;
4196 unsigned int ele, idx;
4200 Route_Dump dump = {0, r->ud.fname, 0.0, NULL, NULL};
4202 f = fopen(r->ud.fname, "rb");
4207 fseek(f, 0, SEEK_END);
4213 fseek(f, 0, SEEK_SET);
4217 if (fread(buf, 1, sz, f))
4219 eina_simple_xml_parse(buf, sz, EINA_TRUE, cb_route_dump, &dump);
4226 if (dump.distance) r->info.distance = dump.distance;
4227 if (dump.description)
4229 eina_stringshare_replace(&r->info.waypoints, dump.description);
4230 str = eina_str_split_full(dump.description, "\n", 0, &ele);
4231 r->info.waypoint_count = ele;
4232 for (idx = 0 ; idx < ele ; idx++)
4234 Path_Waypoint *wp = ELM_NEW(Path_Waypoint);
4238 wp->point = eina_stringshare_add(str[idx]);
4239 DBG("%s", str[idx]);
4240 r->waypoint = eina_list_append(r->waypoint, wp);
4249 else WRN("description is not found !");
4251 if (dump.coordinates)
4253 eina_stringshare_replace(&r->info.nodes, dump.coordinates);
4254 str = eina_str_split_full(dump.coordinates, "\n", 0, &ele);
4255 r->info.node_count = ele;
4256 for (idx = 0 ; idx < ele ; idx++)
4258 sscanf(str[idx], "%lf,%lf", &lon, &lat);
4259 Path_Node *n = ELM_NEW(Path_Node);
4266 DBG("%lf:%lf", lon, lat);
4267 n->pos.address = NULL;
4268 r->nodes = eina_list_append(r->nodes, n);
4270 path = evas_object_polygon_add(evas_object_evas_get(r->wd->obj));
4271 evas_object_smart_member_add(path, r->wd->pan_smart);
4272 r->path = eina_list_append(r->path, path);
4285 _parse_name(void *data)
4287 Elm_Map_Name *n = (Elm_Map_Name*)data;
4288 if (!n || !n->ud.fname) return;
4292 Name_Dump dump = {0, NULL, 0.0, 0.0};
4294 f = fopen(n->ud.fname, "rb");
4299 fseek(f, 0, SEEK_END);
4305 fseek(f, 0, SEEK_SET);
4309 if (fread(buf, 1, sz, f))
4311 eina_simple_xml_parse(buf, sz, EINA_TRUE, cb_name_dump, &dump);
4320 INF("[%lf : %lf] ADDRESS : %s", n->lon, n->lat, dump.address);
4321 n->address = strdup(dump.address);
4328 Grid *_get_current_grid(Widget_Data *wd)
4330 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
4332 Grid *g = NULL, *ret = NULL;
4333 EINA_LIST_FOREACH(wd->grids, l, g)
4335 if (wd->zoom == g->zoom)
4345 _route_complete_cb(void *data, int ev_type __UNUSED__, void *event)
4347 Ecore_Con_Event_Url_Complete *ev = event;
4348 Elm_Map_Route *r = (Elm_Map_Route*)data;
4349 Widget_Data *wd = r->wd;
4351 if ((!r) || (!ev)) return EINA_TRUE;
4352 Elm_Map_Route *rr = ecore_con_url_data_get(r->con_url);
4353 ecore_con_url_data_set(r->con_url, NULL);
4354 if (r!=rr) return EINA_TRUE;
4356 if (r->ud.fd) fclose(r->ud.fd);
4362 Evas_Coord ox, oy, ow, oh;
4363 evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
4364 g = _get_current_grid(wd);
4365 route_place(wd->obj, g, wd->pan_x, wd->pan_y, ox, oy, ow, oh);
4367 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
4368 "elm,state,busy,stop", "elm");
4369 evas_object_smart_callback_call(wd->obj, SIG_ROUTE_LOADED, NULL);
4374 _name_complete_cb(void *data, int ev_type __UNUSED__, void *event)
4376 Ecore_Con_Event_Url_Complete *ev = event;
4377 Elm_Map_Name *n = (Elm_Map_Name*)data;
4378 Widget_Data *wd = n->wd;
4380 if ((!n) || (!ev)) return EINA_TRUE;
4381 Elm_Map_Name *nn = ecore_con_url_data_get(n->con_url);
4382 ecore_con_url_data_set(n->con_url, NULL);
4383 if (n!=nn) return EINA_TRUE;
4385 if (n->ud.fd) fclose(n->ud.fd);
4388 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
4389 "elm,state,busy,stop", "elm");
4390 evas_object_smart_callback_call(wd->obj, SIG_NAME_LOADED, NULL);
4394 static Elm_Map_Name *
4395 _utils_convert_name(const Evas_Object *obj, int method, char *address, double lon, double lat)
4397 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
4398 Widget_Data *wd = elm_widget_data_get(obj);
4403 if ((!wd) || (!wd->src)) return NULL;
4404 Elm_Map_Name *name = ELM_NEW(Elm_Map_Name);
4405 if (!name) return NULL;
4407 snprintf(buf, sizeof(buf), DEST_NAME_XML_FILE);
4415 name->con_url = ecore_con_url_new(NULL);
4416 name->ud.fname = strdup(buf);
4417 INF("xml file : %s", name->ud.fname);
4419 name->ud.fd = fdopen(fd, "w+");
4420 if ((!name->con_url) || (!name->ud.fd))
4422 ecore_con_url_free(name->con_url);
4428 name->handler = ecore_event_handler_add (ECORE_CON_EVENT_URL_COMPLETE, _name_complete_cb, name);
4429 name->method = method;
4430 if (method == ELM_MAP_NAME_METHOD_SEARCH) name->address = strdup(address);
4431 else if (method == ELM_MAP_NAME_METHOD_REVERSE) name->address = NULL;
4435 source = wd->src->name_url_cb(wd->obj, method, address, lon, lat);
4436 INF("name url = %s", source);
4438 wd->names = eina_list_append(wd->names, name);
4439 ecore_con_url_url_set(name->con_url, source);
4440 ecore_con_url_fd_set(name->con_url, fileno(name->ud.fd));
4441 ecore_con_url_data_set(name->con_url, name);
4443 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
4444 "elm,state,busy,start", "elm");
4445 evas_object_smart_callback_call(wd->obj, SIG_NAME_LOAD, NULL);
4446 ecore_con_url_get(name->con_url);
4447 if (source) free(source);
4453 static Evas_Event_Flags
4454 zoom_start_cb(void *data, void *event_info __UNUSED__)
4456 Widget_Data *wd = data;
4457 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
4459 // FIXME: scroller can be jumping strangely when resizing & scrolling at the sametime (els_scr bug?)
4460 elm_smart_scroller_hold_set(wd->scr, 1);
4461 elm_smart_scroller_freeze_set(wd->scr, 1);
4462 _scr_drag_start(wd->obj, NULL, NULL);
4464 wd->pinch.diff += 0.001;
4466 return EVAS_EVENT_FLAG_NONE;
4469 static Evas_Event_Flags
4470 zoom_end_cb(void *data, void *event_info __UNUSED__)
4472 Widget_Data *wd = data;
4473 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
4475 // FIXME: scroller can be jumping strangely when resizing & scrolling at the sametime (els_scr bug?)
4476 elm_smart_scroller_hold_set(wd->scr, 0);
4477 elm_smart_scroller_freeze_set(wd->scr, 0);
4478 _scr_drag_stop(wd->obj, NULL, NULL);
4480 wd->pinch.diff = wd->pinch.level;
4482 return EVAS_EVENT_FLAG_NONE;
4485 static Evas_Event_Flags
4486 zoom_cb(void *data, void *event_info)
4488 Widget_Data *wd = data;
4489 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
4495 Elm_Gesture_Zoom_Info *ei = event_info;
4496 evas_object_geometry_get(wd->obj, &x, &y, &w, &h);
4498 wd->pinch.level = wd->pinch.diff * ei->zoom;
4499 wd->pinch.cx = x + ((double)w * 0.5);
4500 wd->pinch.cy = y + ((double)h * 0.5);
4502 if (wd->pinch.level > 1.999 || wd->pinch.level < 1.001)
4504 if (wd->pinch.level > 1.999)
4507 wd->pinch.diff = wd->pinch.level / 2.0;
4508 wd->pinch.level = wd->pinch.level / 2.0;
4510 else if (wd->pinch.level < 1.001)
4513 wd->pinch.diff = wd->pinch.level * 2.0;
4514 wd->pinch.level = wd->pinch.level * 2.0;
4516 Elm_Map_Zoom_Mode temp;
4517 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE, NULL, wd); // ei->zoom is refreshed
4519 wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
4520 wd->paused = EINA_TRUE;
4521 elm_map_zoom_set(wd->obj, wd->zoom + zoom_diff);
4522 wd->paused = EINA_FALSE;
4524 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE, zoom_cb, wd); // ei->zoom is refreshed
4528 if (wd->calc_job) ecore_job_del(wd->calc_job);
4529 wd->calc_job = ecore_job_add(_calc_job, wd);
4531 evas_object_smart_callback_call(wd->obj, SIG_ZOOM_CHANGE, NULL);
4534 // FIXME: scroller can be jumping strangely when resizing & scrolling at the sametime (els_scr bug?)
4535 _scr_scroll(wd->obj, NULL, NULL);
4537 return EVAS_EVENT_FLAG_NONE;
4540 static Evas_Event_Flags
4541 rotate_cb(void *data, void *event_info)
4543 Widget_Data *wd = data;
4544 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
4549 Elm_Gesture_Rotate_Info *ei = event_info;
4550 evas_object_geometry_get(wd->obj, &x, &y, &w, &h);
4552 wd->rotate.d = wd->rotate.a + ei->angle - ei->base_angle;
4553 wd->rotate.cx = x + ((double)w * 0.5);
4554 wd->rotate.cy = y + ((double)h * 0.5);
4556 if (wd->calc_job) ecore_job_del(wd->calc_job);
4557 wd->calc_job = ecore_job_add(_calc_job, wd);
4559 return EVAS_EVENT_FLAG_NONE;
4562 static Evas_Event_Flags
4563 rotate_end_cb(void *data, void *event_info __UNUSED__)
4565 Widget_Data *wd = data;
4566 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
4568 wd->rotate.a = wd->rotate.d;
4570 return EVAS_EVENT_FLAG_NONE;
4574 _region_get(Widget_Data *wd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *w, Evas_Coord *h)
4576 EINA_SAFETY_ON_NULL_RETURN(wd);
4577 Evas_Coord sx, sy, tx, ty, tcx, tcy, sw, sh, tw, th, rw, rh;
4579 elm_smart_scroller_child_pos_get(wd->scr, &sx, &sy);
4580 elm_smart_scroller_child_viewport_size_get(wd->scr, &sw, &sh);
4581 rw = wd->size.w * wd->pinch.level;
4582 rh = wd->size.h * wd->pinch.level;
4584 if (wd->size.w < sw)
4588 tx = sx + (sw - tw)/2;
4593 tcx = (sx + tw/2) * wd->pinch.level;
4597 if (wd->size.h < sh)
4600 ty = sy + (sh - th)/2;
4606 tcy = (sy + th/2) * wd->pinch.level;
4619 _coord_rotate(const Evas_Coord x, const Evas_Coord y, const Evas_Coord cx, const Evas_Coord cy, const double degree, Evas_Coord *xx, Evas_Coord *yy)
4621 EINA_SAFETY_ON_NULL_RETURN(xx);
4622 EINA_SAFETY_ON_NULL_RETURN(yy);
4624 double r = (degree * M_PI) / 180.0;
4625 double tx, ty, ttx, tty;
4632 tx = ttx + (ty * cos(r + M_PI_2));
4633 ty = tty + (ty * sin(r + M_PI_2));
4640 zoom_with_animation(Widget_Data *wd, double zoom, int cnt)
4642 EINA_SAFETY_ON_NULL_RETURN(wd);
4643 if (cnt == 0) return;
4646 wd->ani.zoom = wd->zoom;
4647 wd->ani.diff = (double)(zoom - wd->zoom) / cnt;
4648 if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
4649 wd->zoom_animator = ecore_animator_add(_zoom_anim, wd);
4653 _sizing_eval(Widget_Data *wd)
4655 EINA_SAFETY_ON_NULL_RETURN(wd);
4657 Evas_Coord maxw = -1, maxh = -1;
4659 evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
4660 evas_object_size_hint_max_set(wd->obj, maxw, maxh);
4664 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
4670 _scr_timeout(void *data)
4672 EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_CANCEL);
4673 Widget_Data *wd = data;
4675 wd->scr_timer = NULL;
4676 evas_object_smart_callback_call(wd->obj, SIG_SCROLL_DRAG_STOP, NULL);
4677 return ECORE_CALLBACK_CANCEL;
4681 _scr(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
4683 EINA_SAFETY_ON_NULL_RETURN(data);
4684 Widget_Data *wd = data;
4686 if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
4687 else evas_object_smart_callback_call(wd->obj, SIG_SCROLL_DRAG_START, NULL);
4688 wd->scr_timer = ecore_timer_add(0.25, _scr_timeout, wd);
4689 evas_object_smart_callback_call(wd->obj, SIG_SCROLL, NULL);
4693 _scr_anim_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
4695 EINA_SAFETY_ON_NULL_RETURN(data);
4696 Widget_Data *wd = data;
4697 evas_object_smart_callback_call(wd->obj, SIG_SCROLL_ANIM_START, NULL);
4701 _scr_anim_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
4703 EINA_SAFETY_ON_NULL_RETURN(data);
4704 Widget_Data *wd = data;
4705 evas_object_smart_callback_call(wd->obj, SIG_SCROLL_ANIM_STOP, NULL);
4709 _long_press(void *data)
4711 EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_CANCEL);
4712 Widget_Data *wd = data;
4714 wd->long_timer = NULL;
4715 evas_object_smart_callback_call(wd->obj, SIG_LONGPRESSED, &wd->ev);
4716 return ECORE_CALLBACK_CANCEL;
4720 _mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
4722 EINA_SAFETY_ON_NULL_RETURN(data);
4723 Widget_Data *wd = data;
4724 Evas_Event_Mouse_Down *ev = event_info;
4726 if (ev->button != 1) return;
4728 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
4729 else wd->on_hold = EINA_FALSE;
4731 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
4732 evas_object_smart_callback_call(wd->obj, SIG_CLICKED_DOUBLE, ev);
4733 else evas_object_smart_callback_call(wd->obj, SIG_PRESS, ev);
4735 if (wd->long_timer) ecore_timer_del(wd->long_timer);
4737 wd->long_timer = ecore_timer_add(_elm_config->longpress_timeout, _long_press, wd);
4741 _mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
4743 EINA_SAFETY_ON_NULL_RETURN(data);
4744 Widget_Data *wd = data;
4746 Evas_Event_Mouse_Up *ev = event_info;
4747 EINA_SAFETY_ON_NULL_RETURN(ev);
4749 if (ev->button != 1) return;
4750 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) wd->on_hold = EINA_TRUE;
4751 else wd->on_hold = EINA_FALSE;
4754 ecore_timer_del(wd->long_timer);
4755 wd->long_timer = NULL;
4757 if (!wd->on_hold) evas_object_smart_callback_call(wd->obj, SIG_CLICKED, ev);
4758 wd->on_hold = EINA_FALSE;
4762 _mouse_wheel_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
4764 EINA_SAFETY_ON_NULL_RETURN(data);
4765 Widget_Data *wd = data;
4769 Evas_Event_Mouse_Wheel *ev = (Evas_Event_Mouse_Wheel*) event_info;
4770 zoom_do(wd, wd->zoom_detail - ((double)ev->z / 10));
4775 _region_max_min_get(Eina_List *overlays, double *max_longitude, double *min_longitude, double *max_latitude, double *min_latitude)
4777 double max_lon = -180, min_lon = 180;
4778 double max_lat = -90, min_lat = 90;
4779 Elm_Map_Overlay *overlay;
4780 EINA_LIST_FREE(overlays, overlay)
4783 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
4785 Overlay_Default *ovl = overlay->ovl;
4789 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
4791 // FIXME: class center coord is alright??
4792 Overlay_Class *ovl = overlay->ovl;
4793 double max_lo, min_lo, max_la, min_la;
4794 _region_max_min_get(ovl->members, &max_lo, &min_lo, &max_la,
4796 lon = (max_lo + min_lo) / 2;
4797 lat = (max_la + min_la) / 2;
4799 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
4801 Overlay_Bubble *ovl = overlay->ovl;
4807 WRN("Not supported overlay type: %d", overlay->type);
4810 if (lon> max_lon) max_lon = lon;
4811 if (lon< min_lon) min_lon = lon;
4812 if (lat > max_lat) max_lat = lat;
4813 if (lat < min_lat) min_lat = lat;
4815 if (max_longitude) *max_longitude = max_lon;
4816 if (min_longitude) *min_longitude = min_lon;
4817 if (max_latitude) *max_latitude = max_lat;
4818 if (min_latitude) *min_latitude = min_lat;
4821 static Evas_Object *
4822 _icon_dup(Evas_Object *icon, Evas_Object *parent)
4824 if (!icon || !parent) return NULL;
4825 // Evas_Object do not support object duplication??
4826 const char *file = NULL, *group = NULL;
4827 Eina_Bool size_up, size_down;
4830 dupp = elm_icon_add(parent);
4831 elm_icon_file_get(icon, &file, &group);
4832 elm_icon_file_set(dupp, file, group);
4833 elm_icon_animated_set(dupp, elm_icon_animated_get(icon));
4834 elm_icon_animated_play_set(dupp, elm_icon_animated_play_get(icon));
4835 elm_icon_standard_set(dupp, elm_icon_standard_get(icon));
4836 elm_icon_order_lookup_set(dupp, elm_icon_order_lookup_get(icon));
4837 elm_icon_no_scale_set(dupp, elm_icon_no_scale_get(icon));
4838 elm_icon_resizable_get(icon, &size_up, &size_down);
4839 elm_icon_resizable_set(dupp, size_up, size_down);
4840 elm_icon_fill_outside_set(dupp, elm_icon_fill_outside_get(icon));
4841 elm_icon_prescale_set(dupp, elm_icon_prescale_get(icon));
4842 elm_icon_aspect_fixed_set(dupp, elm_icon_aspect_fixed_get(icon));
4846 static Evas_Object *
4847 _overlay_layout_new(Widget_Data *wd, const char *group)
4849 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
4850 EINA_SAFETY_ON_NULL_RETURN_VAL(group, NULL);
4851 Evas_Object *obj = elm_layout_add(wd->obj);
4852 evas_object_smart_member_add(obj, wd->pan_smart);
4853 evas_object_stack_above(obj, wd->sep_maps_markers);
4854 elm_layout_theme_set(obj, "map/marker", group, elm_widget_style_get(wd->obj));
4859 _overlay_layout_update(Widget_Data *wd, Evas_Object *layout, Evas_Object *icon, const char *text, const char *group)
4861 EINA_SAFETY_ON_NULL_RETURN(wd);
4862 EINA_SAFETY_ON_NULL_RETURN(layout);
4864 Evas_Object *prev_icon = elm_object_part_content_get(layout, "elm.icon");
4865 if (icon && (prev_icon != icon))
4867 elm_layout_theme_set(layout, "map/marker", "empty",
4868 elm_widget_style_get(wd->obj));
4869 elm_object_part_content_set(layout, "elm.icon", icon);
4873 if (group) elm_layout_theme_set(layout, "map/marker", group,
4874 elm_widget_style_get(wd->obj));
4875 edje_object_part_text_set(elm_layout_edje_get(layout), "elm.text", text);
4880 _overlay_clicked_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
4882 EINA_SAFETY_ON_NULL_RETURN(data);
4883 Elm_Map_Overlay *overlay = data;
4885 evas_object_smart_callback_call(overlay->wd->obj, SIG_OVERLAY_CLICKED,
4887 if (overlay->cb) overlay->cb(overlay->cb_data, overlay->wd->obj,
4892 _overlay_default_cb_add(Overlay_Default *ovl, Evas_Object_Event_Cb cb, void *data)
4894 EINA_SAFETY_ON_NULL_RETURN(ovl);
4895 EINA_SAFETY_ON_NULL_RETURN(data);
4897 // FIXME: Add icon or object event callback
4898 evas_object_event_callback_add(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN, cb,
4903 _overlay_default_cb_del(Overlay_Default *ovl, Evas_Object_Event_Cb cb)
4905 EINA_SAFETY_ON_NULL_RETURN(ovl);
4906 // FIXME: Add icon or object event callback
4907 evas_object_event_callback_del(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN, cb);
4911 _overlay_default_hide(Overlay_Default *ovl)
4913 EINA_SAFETY_ON_NULL_RETURN(ovl);
4914 if (ovl->obj) evas_object_hide(ovl->obj);
4915 if (ovl->layout) evas_object_hide(ovl->layout);
4919 _overlay_default_show(Widget_Data *wd, Overlay_Default *ovl)
4923 Evas_Coord x, y, w, h;
4928 evas_object_geometry_get(disp, NULL, NULL, &w, &h);
4929 if (w <= 0 || h <= 0) evas_object_size_hint_min_get(disp, &w, &h);
4938 _pan_geometry_get(wd, &px, &py);
4939 _coord_rotate(ovl->x + px, ovl->y + py, wd->rotate.cx, wd->rotate.cy,
4940 wd->rotate.d, &x, &y);
4941 _obj_place(disp, x - (w / 2), y - (h / 2), w, h);
4945 _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)
4947 EINA_SAFETY_ON_NULL_RETURN(wd);
4948 EINA_SAFETY_ON_NULL_RETURN(ovl);
4950 _region_to_coord_convert(wd, ovl->lon, ovl->lat, wd->size.w, &ovl->x, &ovl->y);
4954 if (ovl->obj == obj) return;
4955 if (ovl->obj) evas_object_del(ovl->obj);
4958 else if (!(ovl->obj) && icon)
4960 if (ovl->icon == icon) return;
4961 if (ovl->icon) evas_object_del(ovl->icon);
4963 _overlay_layout_update(wd, ovl->layout, ovl->icon, NULL, NULL);
4966 else if (!(ovl->obj) && !(ovl->icon) && (ovl_clas) &&
4967 ((ovl_clas->obj) || (ovl_clas->icon)))
4969 // Inherit icon from group overlay's ojbect or icon
4971 // FIXME: It is hard to duplicate evas object :-)
4973 if (ovl_clas->obj && (ovl_clas->obj != ovl->clas_obj_ref))
4975 if (ovl->clas_obj) evas_object_del(ovl->clas_obj);
4976 ovl->clas_obj_ref = ovl_clas->obj;
4977 ovl->clas_obj = _obj_dup(ovl->clas_obj_ref, ovl->layout);
4978 _overlay_layout_update(wd, ovl->layout, ovl->clas_obj, NULL, NULL);
4981 if (ovl_clas->icon && (ovl_clas->icon != ovl->clas_icon_ref))
4983 if (ovl->clas_icon) evas_object_del(ovl->clas_icon);
4984 ovl->clas_icon_ref = ovl_clas->icon;
4985 ovl->clas_icon = _icon_dup(ovl->clas_icon_ref, ovl->layout);
4986 _overlay_layout_update(wd, ovl->layout, ovl->clas_icon, NULL, NULL);
4989 else if (!(ovl->obj) && !(ovl->icon) && !(ovl->clas_icon) && text)
4991 _overlay_layout_update(wd, ovl->layout, NULL, text, group);
4996 _overlay_default_free(Overlay_Default *ovl)
4998 EINA_SAFETY_ON_NULL_RETURN(ovl);
4999 if (ovl->obj) evas_object_del(ovl->obj);
5000 if (ovl->icon) evas_object_del(ovl->icon);
5001 if (ovl->clas_icon) evas_object_del(ovl->clas_icon);
5002 evas_object_event_callback_del(ovl->layout, EVAS_CALLBACK_MOUSE_DOWN,
5003 _overlay_clicked_cb);
5004 if (ovl->layout) evas_object_del(ovl->layout);
5008 static Overlay_Default *
5009 _overlay_default_new(Widget_Data *wd, double lon, double lat, const char *group)
5011 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
5012 EINA_SAFETY_ON_NULL_RETURN_VAL(group, NULL);
5014 Overlay_Default *ovl = ELM_NEW(Overlay_Default);
5015 _edj_marker_size_get(wd, &(ovl->w), &(ovl->h));
5016 ovl->layout = _overlay_layout_new(wd, group);
5023 _overlay_group_clicked_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *ev __UNUSED__)
5025 EINA_SAFETY_ON_NULL_RETURN(data);
5026 Overlay_Group *ovl = data;
5028 evas_object_smart_callback_call(ovl->clas->wd->obj, SIG_OVERLAY_CLICKED,
5030 if (ovl->clas->cb) ovl->clas->cb(ovl->clas->cb_data, ovl->clas->wd->obj,
5035 _overlay_group_cb_add(Overlay_Group *ovl)
5037 EINA_SAFETY_ON_NULL_RETURN(ovl);
5038 _overlay_default_cb_add(ovl->ovl, _overlay_group_clicked_cb, ovl);
5042 _overlay_group_cb_del(Overlay_Group *ovl)
5044 EINA_SAFETY_ON_NULL_RETURN(ovl);
5045 _overlay_default_cb_del(ovl->ovl, _overlay_group_clicked_cb);
5049 _overlay_group_update(Widget_Data *wd, Overlay_Group *grp, Eina_List *members)
5051 EINA_SAFETY_ON_NULL_RETURN(wd);
5052 EINA_SAFETY_ON_NULL_RETURN(grp);
5055 Elm_Map_Overlay *overlay;
5056 Evas_Coord sum_x = 0, sum_y = 0, cnt = 0;
5058 if (grp->members) eina_list_free(grp->members);
5059 grp->members = members;
5061 if (!grp->members || eina_list_count(grp->members) <= 0)
5063 _overlay_default_hide(grp->ovl);
5066 EINA_LIST_FOREACH(grp->members, l, overlay)
5068 Overlay_Default *df = overlay->ovl;
5074 Overlay_Class *ovl_clas = grp->clas->ovl;
5077 snprintf(text, sizeof(text), "%d", cnt);
5078 _overlay_default_update(wd, grp->ovl, NULL, NULL, ovl_clas, text, "radio2");
5080 grp->ovl->x = sum_x / cnt;
5081 grp->ovl->y = sum_y / cnt;
5085 _overlay_group_free(Overlay_Group *grp, Elm_Map_Overlay *club_owner)
5087 EINA_SAFETY_ON_NULL_RETURN(grp);
5089 _overlay_default_cb_del(grp->ovl, _overlay_group_clicked_cb);
5090 _overlay_default_free(grp->ovl);
5091 if (grp->clas) elm_map_overlay_class_remove(grp->clas, club_owner);
5092 if (grp->members) eina_list_free(grp->members);
5096 static Overlay_Group *
5097 _overlay_group_new(Widget_Data *wd)
5099 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
5101 Overlay_Group *grp = ELM_NEW(Overlay_Group);
5102 grp->ovl = ELM_NEW(Overlay_Default);
5103 grp->ovl = _overlay_default_new(wd, -1, -1, "radio2");
5110 _overlay_class_update(Widget_Data *wd, Overlay_Class *clas, Evas_Object *obj, Evas_Object *icon)
5112 EINA_SAFETY_ON_NULL_RETURN(wd);
5113 EINA_SAFETY_ON_NULL_RETURN(clas);
5115 if (obj && (clas->obj != obj))
5117 if (clas->obj) evas_object_del(clas->obj);
5120 else if (icon && (clas->icon != icon))
5122 if (clas->icon) evas_object_del(clas->icon);
5128 _overlay_class_free(Overlay_Class *clas)
5130 EINA_SAFETY_ON_NULL_RETURN(clas);
5131 if (clas->icon) evas_object_del(clas->icon);
5132 if (clas->members) eina_list_free(clas->members);
5136 static Overlay_Class *
5137 _overlay_class_new(Widget_Data *wd, Elm_Map_Overlay *clas)
5139 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
5140 Overlay_Class *ovl = ELM_NEW(Overlay_Class);
5143 ovl->zoom_max = OVERLAY_CLASS_ZOOM_MAX;
5148 _overlay_bubble_cb_add(Overlay_Bubble *ovl, Elm_Map_Overlay *overlay)
5150 EINA_SAFETY_ON_NULL_RETURN(ovl);
5151 EINA_SAFETY_ON_NULL_RETURN(overlay);
5152 evas_object_event_callback_add(ovl->obj, EVAS_CALLBACK_MOUSE_DOWN,
5153 _overlay_clicked_cb, overlay);
5157 _overlay_bubble_cb_del(Overlay_Bubble *ovl)
5159 EINA_SAFETY_ON_NULL_RETURN(ovl);
5160 evas_object_event_callback_del(ovl->obj, EVAS_CALLBACK_MOUSE_DOWN,
5161 _overlay_clicked_cb);
5165 _overlay_bubble_hide(Overlay_Bubble *bubble)
5167 EINA_SAFETY_ON_NULL_RETURN(bubble);
5168 if (bubble->obj) evas_object_hide(bubble->obj);
5172 _overlay_bubble_update(Overlay_Bubble *bubble)
5174 EINA_SAFETY_ON_NULL_RETURN(bubble);
5175 if ((!bubble->pobj) && (bubble->lon >= 0) && (bubble->lat >= 0))
5177 _region_to_coord_convert(bubble->wd, bubble->lon, bubble->lat,
5178 bubble->wd->size.w, &bubble->x, &bubble->y);
5183 _overlay_bubble_show(Overlay_Bubble *bubble)
5185 EINA_SAFETY_ON_NULL_RETURN(bubble);
5188 if ((bubble->x < 0) || (bubble->y < 0)) return;
5190 _pan_geometry_get(bubble->wd, &px, &py);
5191 _coord_rotate(bubble->x + px, bubble->y + py, bubble->wd->rotate.cx,
5192 bubble->wd->rotate.cy, bubble->wd->rotate.d, &x, &y);
5193 x = x - (bubble->w / 2);
5194 y = y - (bubble->h / 2);
5195 _obj_place(bubble->obj, x, y, bubble->w, bubble->h);
5196 //evas_object_raise(bubble->obj);
5200 _overlay_bubble_chase(Overlay_Bubble *bubble)
5202 EINA_SAFETY_ON_NULL_RETURN(bubble);
5203 EINA_SAFETY_ON_NULL_RETURN(bubble->pobj);
5206 evas_object_geometry_get(bubble->pobj, &x, &y, &w, NULL);
5207 x = x + (w / 2) - (bubble->w / 2);
5209 _obj_place(bubble->obj, x, y, bubble->w, bubble->h);
5210 evas_object_raise(bubble->obj);
5214 _overlay_bubble_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
5216 EINA_SAFETY_ON_NULL_RETURN(data);
5217 _overlay_bubble_hide(data);
5221 _overlay_bubble_chase_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
5223 EINA_SAFETY_ON_NULL_RETURN(data);
5224 _overlay_bubble_chase(data);
5228 _overlay_bubble_free(Overlay_Bubble* bubble)
5230 EINA_SAFETY_ON_NULL_RETURN(bubble);
5232 evas_object_del(bubble->bx);
5233 evas_object_del(bubble->sc);
5234 evas_object_del(bubble->obj);
5237 evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_HIDE,
5238 _overlay_bubble_hide_cb, bubble);
5239 evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_SHOW,
5240 _overlay_bubble_chase_cb, bubble);
5241 evas_object_event_callback_del_full(bubble->pobj, EVAS_CALLBACK_MOVE,
5242 _overlay_bubble_chase_cb, bubble);
5247 static Overlay_Bubble*
5248 _overlay_bubble_new(Widget_Data *wd)
5250 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
5254 Overlay_Bubble *bubble = ELM_NEW(Overlay_Bubble);
5257 bubble->obj = edje_object_add(evas_object_evas_get(wd->obj));
5258 _elm_theme_object_set(wd->obj, bubble->obj , "map", "marker_bubble",
5259 elm_widget_style_get(wd->obj));
5260 evas_object_event_callback_add(bubble->obj, EVAS_CALLBACK_MOUSE_UP,
5261 _overlay_bubble_chase_cb, bubble);
5263 bubble->sc = elm_scroller_add(bubble->obj);
5264 elm_widget_style_set(bubble->sc, "map_bubble");
5265 elm_scroller_content_min_limit(bubble->sc, EINA_FALSE, EINA_TRUE);
5266 elm_scroller_policy_set(bubble->sc, ELM_SCROLLER_POLICY_AUTO,
5267 ELM_SCROLLER_POLICY_OFF);
5268 elm_scroller_bounce_set(bubble->sc, _elm_config->thumbscroll_bounce_enable,
5270 edje_object_part_swallow(bubble->obj, "elm.swallow.content", bubble->sc);
5272 bubble->bx = elm_box_add(bubble->sc);
5273 evas_object_size_hint_align_set(bubble->bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
5274 evas_object_size_hint_weight_set(bubble->bx, EVAS_HINT_EXPAND,
5276 elm_box_horizontal_set(bubble->bx, EINA_TRUE);
5277 elm_object_content_set(bubble->sc, bubble->bx);
5279 s = edje_object_data_get(bubble->obj, "size_w");
5280 if (s) bubble->w = atoi(s);
5283 edje_object_size_min_calc(bubble->obj, NULL, &(bubble->h));
5284 s = edje_object_data_get(bubble->obj, "size_h");
5287 if (bubble->h < h) bubble->h = h;
5297 _overlay_route_hide(Overlay_Route *r)
5299 EINA_SAFETY_ON_NULL_RETURN(r);
5302 EINA_LIST_FOREACH(r->paths, l, p) evas_object_hide(p);
5306 _overlay_route_show(Overlay_Route *r)
5308 EINA_SAFETY_ON_NULL_RETURN(r);
5309 EINA_SAFETY_ON_NULL_RETURN(r->wd);
5318 Evas_Coord ow, oh, px, py, size;
5321 _viewport_size_get(wd, &ow, &oh);
5326 EINA_LIST_FOREACH(r->paths, l, p) evas_object_polygon_points_clear(p);
5328 cnt = eina_list_count(r->nodes);
5329 EINA_LIST_FOREACH(r->nodes, l, n)
5331 if ((!wd->zoom) || ((n->idx) &&
5332 ((n->idx % (int)ceil((double)cnt/(double)size*100.0))))) continue;
5335 _region_to_coord_convert(wd, n->pos.lon, n->pos.lat, size,
5337 if ((x >= px - ow) && (x <= (px + ow*2)) &&
5338 (y >= py - oh) && (y <= (py + oh*2)))
5343 p = eina_list_nth(r->paths, n->idx);
5344 a = (double)(y - r->y) / (double)(x - r->x);
5345 if ((abs(a) >= 1) || (r->x == x))
5347 evas_object_polygon_point_add(p, r->x - 3, r->y);
5348 evas_object_polygon_point_add(p, r->x + 3, r->y);
5349 evas_object_polygon_point_add(p, x + 3, y);
5350 evas_object_polygon_point_add(p, x - 3, y);
5354 evas_object_polygon_point_add(p, r->x, r->y - 3);
5355 evas_object_polygon_point_add(p, r->x, r->y + 3);
5356 evas_object_polygon_point_add(p, x, y + 3);
5357 evas_object_polygon_point_add(p, x, y - 3);
5360 evas_object_color_set(p, r->color.r, r->color.g, r->color.b,
5362 evas_object_raise(p);
5364 evas_object_show(p);
5369 else r->inbound = EINA_FALSE;
5373 _region_to_coord_convert(wd, n->pos.lon, n->pos.lat, size,
5375 if ((x >= px - ow) && (x <= (px + ow*2)) &&
5376 (y >= py - oh) && (y <= (py + oh*2)))
5380 r->inbound = EINA_TRUE;
5382 else r->inbound = EINA_FALSE;
5385 r->inbound = EINA_FALSE;
5389 _overlay_route_free(Overlay_Route* route)
5391 EINA_SAFETY_ON_NULL_RETURN(route);
5395 EINA_LIST_FREE(route->paths, p) evas_object_del(p);
5396 EINA_LIST_FREE(route->nodes, n)
5398 if (n->pos.address) eina_stringshare_del(n->pos.address);
5404 static Overlay_Route *
5405 _overlay_route_new(Widget_Data *wd, const Elm_Map_Route *route)
5407 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
5408 EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
5413 Overlay_Route *ovl = ELM_NEW(Overlay_Route);
5415 ovl->inbound = EINA_FALSE;
5421 EINA_LIST_FOREACH(route->nodes, l, n)
5426 node = ELM_NEW(Path_Node);
5428 node->pos.lon = n->pos.lon;
5429 node->pos.lat = n->pos.lat;
5430 if (n->pos.address) node->pos.address = strdup(n->pos.address);
5431 ovl->nodes = eina_list_append(ovl->nodes, node);
5433 path = evas_object_polygon_add(evas_object_evas_get(wd->obj));
5434 evas_object_smart_member_add(path, wd->pan_smart);
5435 ovl->paths = eina_list_append(ovl->paths, path);
5441 _overlay_grouping(Eina_List *members, Elm_Map_Overlay *overlay)
5443 EINA_SAFETY_ON_NULL_RETURN(members);
5444 EINA_SAFETY_ON_NULL_RETURN(overlay);
5445 // Currently support only basic overlay type
5446 EINA_SAFETY_ON_FALSE_RETURN(overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT);
5449 Elm_Map_Overlay *overlay_memb;
5450 Eina_List *club_members = NULL;
5452 // Grouping only supports overlay default
5453 Overlay_Default *ovl = (Overlay_Default *)overlay->ovl;
5454 EINA_LIST_FOREACH(members, l, overlay_memb)
5456 Overlay_Default *ovl_memb = overlay_memb->ovl;
5457 if ((overlay_memb->hide) ||
5458 (overlay_memb->zoom_min > overlay_memb->wd->zoom)) continue;
5459 if (overlay == overlay_memb || overlay_memb->grp_in) continue;
5460 if (ELM_RECTS_INTERSECT(ovl_memb->x, ovl_memb->y, ovl_memb->w,
5461 ovl_memb->h, ovl->x, ovl->y,
5462 ovl->w * OVERLAY_GROUPING_SCALE,
5463 ovl->h * OVERLAY_GROUPING_SCALE))
5466 overlay_memb->grp_boss = EINA_FALSE;
5467 overlay_memb->grp_in = EINA_TRUE;
5468 club_members = eina_list_append(club_members, overlay_memb);
5469 _overlay_group_update(overlay_memb->wd, overlay_memb->grp, NULL);
5470 _overlay_group_cb_del(overlay_memb->grp);
5474 if (eina_list_count(club_members) >= 1)
5477 overlay->grp_boss = EINA_TRUE;
5478 overlay->grp_in = EINA_TRUE;
5479 club_members = eina_list_append(club_members, overlay);
5480 _overlay_group_update(overlay->wd, overlay->grp, club_members);
5481 _overlay_group_cb_del(overlay->grp);
5482 _overlay_group_cb_add(overlay->grp);
5487 _overlay_display(Widget_Data *wd, Elm_Map_Overlay *overlay)
5489 Eina_Bool hide = EINA_FALSE;
5491 if ((overlay->grp_in) || (overlay->hide) || (overlay->zoom_min > wd->zoom))
5493 if ((overlay->grp->clas) && ((overlay->grp->clas->hide) ||
5494 (overlay->grp->clas->zoom_min > wd->zoom)))
5497 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
5499 if (hide) _overlay_default_hide(overlay->ovl);
5500 else _overlay_default_show(wd, overlay->ovl);
5502 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
5504 if (hide) _overlay_bubble_hide(overlay->ovl);
5505 else _overlay_bubble_show(overlay->ovl);
5507 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_ROUTE)
5509 if (hide) _overlay_route_hide(overlay->ovl);
5510 else _overlay_route_show(overlay->ovl);
5515 _overlay_place(Widget_Data *wd)
5517 EINA_SAFETY_ON_NULL_RETURN(wd);
5520 Elm_Map_Overlay *overlay, *grp;
5522 if (eina_list_count(wd->overlays) == 0) return;
5524 // Reset overlays coord & grp except class type
5525 EINA_LIST_FOREACH(wd->overlays, l, overlay)
5528 if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS) continue;
5529 if (overlay->paused) continue;
5530 if ((overlay->grp) && (overlay->grp->clas) &&
5531 (overlay->grp->clas->paused)) continue;
5532 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
5534 Overlay_Class *ovl_grp = NULL;
5535 if (overlay->grp->clas) ovl_grp = overlay->grp->clas->ovl;
5536 _overlay_default_update(wd, overlay->ovl, NULL, NULL, ovl_grp,
5539 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
5540 _overlay_bubble_update(overlay->ovl);
5542 overlay->grp_in = EINA_FALSE;
5543 overlay->grp_boss = EINA_FALSE;
5544 _overlay_group_update(wd, overlay->grp, NULL);
5547 // Classify into group idol or follwer
5548 EINA_LIST_FOREACH(wd->overlays, l, grp)
5550 Elm_Map_Overlay *idol;
5553 if (grp->type != ELM_MAP_OVERLAY_TYPE_CLASS) continue;
5554 if ((grp->hide) || (grp->zoom_min > wd->zoom)) continue;
5557 if (ovl->zoom_max < wd->zoom) continue;
5558 EINA_LIST_FOREACH(ovl->members, ll, idol)
5560 if (!idol->grp_in) _overlay_grouping(ovl->members, idol);
5565 EINA_LIST_FOREACH(wd->overlays, l, overlay)
5566 if (overlay->type != ELM_MAP_OVERLAY_TYPE_CLASS)
5567 _overlay_display(wd, overlay);
5569 // Place group overlays
5570 EINA_LIST_FOREACH(wd->overlays, l, overlay)
5572 if (overlay->grp_boss) _overlay_default_show(wd, overlay->grp->ovl);
5576 static Evas_Object *
5577 _overlay_obj_get(Elm_Map_Overlay *overlay)
5579 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL);
5580 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
5582 Overlay_Default *ovl = overlay->ovl;
5587 ERR("Not supported overlay type: %d", overlay->type);
5593 _overlays_show(void *data)
5595 EINA_SAFETY_ON_NULL_RETURN(data);
5596 Delayed_Data *dd = data;
5599 double max_lon, min_lon, max_lat, min_lat;
5602 _region_max_min_get(dd->overlays, &max_lon, &min_lon, &max_lat, &min_lat);
5603 dd->lon = (max_lon + min_lon) / 2;
5604 dd->lat = (max_lat + min_lat) / 2;
5606 zoom = dd->wd->src_tile->zoom_min;
5607 _viewport_size_get(dd->wd, &vw, &vh);
5608 while (zoom <= dd->wd->src_tile->zoom_max)
5610 Evas_Coord size, max_x, max_y, min_x, min_y;
5611 size = pow(2.0, zoom) * dd->wd->tsize;
5612 _region_to_coord_convert(dd->wd, min_lon, max_lat, size, &min_x, &max_y);
5613 _region_to_coord_convert(dd->wd, max_lon, min_lat, size, &max_x, &min_y);
5614 if ((max_x - min_x) > vw || (max_y - min_y) > vh) break;
5619 zoom_do(dd->wd, zoom);
5621 evas_object_smart_changed(dd->wd->pan_smart);
5625 _pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
5627 Pan *sd = evas_object_smart_data_get(obj);
5628 EINA_SAFETY_ON_NULL_RETURN(sd);
5629 if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
5633 evas_object_smart_changed(obj);
5637 _pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
5639 Pan *sd = evas_object_smart_data_get(obj);
5640 EINA_SAFETY_ON_NULL_RETURN(sd);
5641 if (x) *x = sd->wd->pan_x;
5642 if (y) *y = sd->wd->pan_y;
5646 _pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
5648 Pan *sd = evas_object_smart_data_get(obj);
5649 EINA_SAFETY_ON_NULL_RETURN(sd);
5651 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
5652 ow = sd->wd->size.w - ow;
5653 oh = sd->wd->size.h - oh;
5661 _pan_min_get(Evas_Object *obj __UNUSED__, Evas_Coord *x, Evas_Coord *y)
5668 _pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
5670 Pan *sd = evas_object_smart_data_get(obj);
5671 EINA_SAFETY_ON_NULL_RETURN(sd);
5672 if (w) *w = sd->wd->size.w;
5673 if (h) *h = sd->wd->size.h;
5677 _pan_add(Evas_Object *obj)
5680 Evas_Object_Smart_Clipped_Data *cd;
5682 cd = evas_object_smart_data_get(obj);
5683 EINA_SAFETY_ON_NULL_RETURN(cd);
5685 sd->__clipped_data = *cd;
5687 evas_object_smart_data_set(obj, sd);
5691 _pan_resize(Evas_Object *obj, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__)
5693 Pan *sd = evas_object_smart_data_get(obj);
5694 EINA_SAFETY_ON_NULL_RETURN(sd);
5696 _sizing_eval(sd->wd);
5697 elm_map_zoom_mode_set(sd->wd->obj, sd->wd->mode);
5698 evas_object_smart_changed(obj);
5702 _pan_calculate(Evas_Object *obj)
5704 Pan *sd = evas_object_smart_data_get(obj);
5705 EINA_SAFETY_ON_NULL_RETURN(sd);
5708 evas_object_geometry_get(sd->wd->pan_smart, NULL, NULL, &w, &h);
5709 if (w <= 0 || h <= 0) return;
5711 _grid_place(sd->wd);
5712 _marker_place(sd->wd);
5713 _overlay_place(sd->wd);
5714 _track_place(sd->wd);
5715 _delayed_do(sd->wd);
5719 _pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
5721 EINA_SAFETY_ON_NULL_RETURN(obj);
5722 evas_object_smart_changed(obj);
5726 _hold_on(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
5728 EINA_SAFETY_ON_NULL_RETURN(data);
5729 Widget_Data *wd = data;
5730 elm_smart_scroller_hold_set(wd->scr, 1);
5734 _hold_off(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
5736 EINA_SAFETY_ON_NULL_RETURN(data);
5737 Widget_Data *wd = data;
5738 elm_smart_scroller_hold_set(wd->scr, 0);
5742 _freeze_on(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
5744 EINA_SAFETY_ON_NULL_RETURN(data);
5745 Widget_Data *wd = data;
5746 elm_smart_scroller_freeze_set(wd->scr, 1);
5750 _freeze_off(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
5752 EINA_SAFETY_ON_NULL_RETURN(data);
5753 Widget_Data *wd = data;
5754 elm_smart_scroller_freeze_set(wd->scr, 0);
5758 _elm_map_marker_remove(Elm_Map_Marker *marker)
5760 #ifdef HAVE_ELEMENTARY_ECORE_CON
5761 EINA_SAFETY_ON_NULL_RETURN(marker);
5762 Widget_Data *wd = marker->wd;
5763 EINA_SAFETY_ON_NULL_RETURN(wd);
5765 if ((marker->content) && (marker->clas->func.del))
5766 marker->clas->func.del(wd->obj, marker, marker->data, marker->content);
5768 if (marker->bubble) _bubble_free(marker->bubble);
5769 if (marker->group) _marker_group_free(marker->group);
5771 if (marker->group_clas)
5772 marker->group_clas->markers = eina_list_remove(marker->group_clas->markers, marker);
5773 wd->markers = eina_list_remove(wd->markers, marker);
5775 evas_object_del(marker->obj);
5778 evas_object_smart_changed(wd->pan_smart);
5785 cb_dump_name_attrs(void *data, const char *key, const char *value)
5787 Name_Dump *dump = (Name_Dump*)data;
5788 if (!dump) return EINA_FALSE;
5790 if (!strncmp(key, NOMINATIM_ATTR_LON, sizeof(NOMINATIM_ATTR_LON))) dump->lon = atof(value);
5791 else if (!strncmp(key, NOMINATIM_ATTR_LAT, sizeof(NOMINATIM_ATTR_LAT))) dump->lat = atof(value);
5797 cb_route_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
5799 Route_Dump *dump = data;
5800 if (!dump) return EINA_FALSE;
5804 case EINA_SIMPLE_XML_OPEN:
5805 case EINA_SIMPLE_XML_OPEN_EMPTY:
5809 attrs = eina_simple_xml_tag_attributes_find(value, length);
5812 if (!strncmp(value, YOURS_DISTANCE, length)) dump->id = ROUTE_XML_DISTANCE;
5813 else if (!strncmp(value, YOURS_DESCRIPTION, length)) dump->id = ROUTE_XML_DESCRIPTION;
5814 else if (!strncmp(value, YOURS_COORDINATES, length)) dump->id = ROUTE_XML_COORDINATES;
5815 else dump->id = ROUTE_XML_NONE;
5819 case EINA_SIMPLE_XML_DATA:
5821 char *buf = malloc(length);
5822 if (!buf) return EINA_FALSE;
5823 snprintf(buf, length, "%s", value);
5824 if (dump->id == ROUTE_XML_DISTANCE) dump->distance = atof(buf);
5825 else if (!(dump->description) && (dump->id == ROUTE_XML_DESCRIPTION)) dump->description = strdup(buf);
5826 else if (dump->id == ROUTE_XML_COORDINATES) dump->coordinates = strdup(buf);
5838 cb_name_dump(void *data, Eina_Simple_XML_Type type, const char *value, unsigned offset __UNUSED__, unsigned length)
5840 Name_Dump *dump = data;
5841 if (!dump) return EINA_FALSE;
5845 case EINA_SIMPLE_XML_OPEN:
5846 case EINA_SIMPLE_XML_OPEN_EMPTY:
5849 attrs = eina_simple_xml_tag_attributes_find(value, length);
5852 if (!strncmp(value, NOMINATIM_RESULT, sizeof(NOMINATIM_RESULT) - 1)) dump->id = NAME_XML_NAME;
5853 else dump->id = NAME_XML_NONE;
5855 eina_simple_xml_attributes_parse
5856 (attrs, length - (attrs - value), cb_dump_name_attrs, dump);
5860 case EINA_SIMPLE_XML_DATA:
5862 char *buf = malloc(length + 1);
5863 if (!buf) return EINA_FALSE;
5864 snprintf(buf, length + 1, "%s", value);
5865 if (dump->id == NAME_XML_NAME) dump->address = strdup(buf);
5877 _kml_parse(Elm_Map_Route *r)
5879 EINA_SAFETY_ON_NULL_RETURN(r);
5880 EINA_SAFETY_ON_NULL_RETURN(r->fname);
5884 unsigned int ele, idx;
5887 Route_Dump dump = {0, r->fname, 0.0, NULL, NULL};
5889 f = fopen(r->fname, "rb");
5894 fseek(f, 0, SEEK_END);
5900 fseek(f, 0, SEEK_SET);
5904 if (fread(buf, 1, sz, f))
5906 eina_simple_xml_parse(buf, sz, EINA_TRUE, cb_route_dump,
5914 if (dump.distance) r->info.distance = dump.distance;
5915 if (dump.description)
5917 eina_stringshare_replace(&r->info.waypoints, dump.description);
5918 str = eina_str_split_full(dump.description, "\n", 0, &ele);
5919 r->info.waypoint_count = ele;
5920 for (idx = 0; idx < ele; idx++)
5922 Path_Waypoint *wp = ELM_NEW(Path_Waypoint);
5926 wp->point = eina_stringshare_add(str[idx]);
5927 DBG("%s", str[idx]);
5928 r->waypoint = eina_list_append(r->waypoint, wp);
5937 else WRN("description is not found !");
5939 if (dump.coordinates)
5941 eina_stringshare_replace(&r->info.nodes, dump.coordinates);
5942 str = eina_str_split_full(dump.coordinates, "\n", 0, &ele);
5943 r->info.node_count = ele;
5944 for (idx = 0; idx < ele; idx++)
5946 sscanf(str[idx], "%lf,%lf", &lon, &lat);
5947 Path_Node *n = ELM_NEW(Path_Node);
5954 DBG("%lf:%lf", lon, lat);
5955 n->pos.address = NULL;
5956 r->nodes = eina_list_append(r->nodes, n);
5969 _name_parse(Elm_Map_Name *n)
5971 EINA_SAFETY_ON_NULL_RETURN(n);
5972 EINA_SAFETY_ON_NULL_RETURN(n->fname);
5976 Name_Dump dump = {0, NULL, 0.0, 0.0};
5978 f = fopen(n->fname, "rb");
5983 fseek(f, 0, SEEK_END);
5989 fseek(f, 0, SEEK_SET);
5993 if (fread(buf, 1, sz, f))
5995 eina_simple_xml_parse(buf, sz, EINA_TRUE, cb_name_dump, &dump);
6004 INF("[%lf : %lf] ADDRESS : %s", n->lon, n->lat, dump.address);
6005 n->address = strdup(dump.address);
6012 Grid *_get_current_grid(Widget_Data *wd)
6014 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
6016 Grid *g = NULL, *ret = NULL;
6017 EINA_LIST_FOREACH(wd->grids, l, g)
6019 if (wd->zoom == g->zoom)
6029 _route_cb(void *data, const char *file, int status)
6031 EINA_SAFETY_ON_NULL_RETURN(data);
6032 EINA_SAFETY_ON_NULL_RETURN(file);
6034 Elm_Map_Route *route = data;
6035 Widget_Data *wd = route->wd;
6036 EINA_SAFETY_ON_NULL_RETURN(wd);
6042 INF("Route request success from (%lf, %lf) to (%lf, %lf)",
6043 route->flon, route->flat, route->tlon, route->tlat);
6044 if (route->cb) route->cb(route->data, wd->obj, route);
6045 evas_object_smart_callback_call(wd->obj, SIG_ROUTE_LOADED, NULL);
6049 ERR("Route request failed: %d", status);
6050 if (route->cb) route->cb(route->data, wd->obj, NULL);
6051 evas_object_smart_callback_call(wd->obj, SIG_ROUTE_LOADED_FAIL, NULL);
6054 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
6055 "elm,state,busy,stop", "elm");
6059 _name_cb(void *data, const char *file, int status)
6061 EINA_SAFETY_ON_NULL_RETURN(data);
6062 EINA_SAFETY_ON_NULL_RETURN(file);
6064 Elm_Map_Name *name = data;
6065 Widget_Data *wd = name->wd;
6066 EINA_SAFETY_ON_NULL_RETURN(wd);
6072 INF("Name request success address:%s, lon:%lf, lat:%lf",
6073 name->address, name->lon, name->lat);
6074 if (name->cb) name->cb(name->data, wd->obj, name);
6075 evas_object_smart_callback_call(wd->obj, SIG_NAME_LOADED, NULL);
6079 ERR("Name request failed: %d", status);
6080 if (name->cb) name->cb(name->data, wd->obj, NULL);
6081 evas_object_smart_callback_call(wd->obj, SIG_NAME_LOADED_FAIL, NULL);
6083 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
6084 "elm,state,busy,stop", "elm");
6089 static Elm_Map_Name *
6090 _name_request(const Evas_Object *obj, int method, const char *address, double lon, double lat, Elm_Map_Name_Cb name_cb, void *data)
6092 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
6093 Widget_Data *wd = elm_widget_data_get(obj);
6094 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
6095 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src_name, NULL);
6099 char fname[PATH_MAX];
6101 if (!ecore_file_exists(CACHE_NAME_ROOT)) ecore_file_mkpath(CACHE_NAME_ROOT);
6103 url = wd->src_name->url_cb(wd->obj, method, address, lon, lat);
6106 ERR("Name URL is NULL");
6110 Elm_Map_Name *name = ELM_NEW(Elm_Map_Name);
6112 snprintf(fname, sizeof(fname), CACHE_NAME_ROOT"/%d", rand());
6113 name->fname = strdup(fname);
6114 name->method = method;
6115 if (method == ELM_MAP_NAME_METHOD_SEARCH) name->address = strdup(address);
6116 else if (method == ELM_MAP_NAME_METHOD_REVERSE)
6124 if (!ecore_file_download_full(url, name->fname, _name_cb, NULL, name,
6125 &(name->job), wd->ua) || !(name->job))
6127 ERR("Can't request Name from %s to %s", url, name->fname);
6128 if (name->address) free(name->address);
6133 INF("Name requested from %s to %s", url, name->fname);
6136 wd->names = eina_list_append(wd->names, name);
6137 evas_object_smart_callback_call(wd->obj, SIG_NAME_LOAD, name);
6138 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
6139 "elm,state,busy,start", "elm");
6143 static Evas_Event_Flags
6144 _pinch_zoom_start_cb(void *data, void *event_info __UNUSED__)
6146 EINA_SAFETY_ON_NULL_RETURN_VAL(data, EVAS_EVENT_FLAG_NONE);
6147 Widget_Data *wd = data;
6149 wd->pinch_zoom = wd->zoom_detail;
6150 return EVAS_EVENT_FLAG_NONE;
6153 static Evas_Event_Flags
6154 _pinch_zoom_cb(void *data, void *event_info)
6156 Widget_Data *wd = data;
6157 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
6161 Elm_Gesture_Zoom_Info *ei = event_info;
6162 zoom_do(wd, wd->pinch_zoom + ei->zoom - 1);
6164 return EVAS_EVENT_FLAG_NONE;
6167 static Evas_Event_Flags
6168 _pinch_rotate_cb(void *data, void *event_info)
6170 Widget_Data *wd = data;
6171 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
6176 Elm_Gesture_Rotate_Info *ei = event_info;
6177 evas_object_geometry_get(wd->obj, &x, &y, &w, &h);
6179 wd->rotate.d = wd->rotate.a + ei->angle - ei->base_angle;
6180 wd->rotate.cx = x + ((double)w * 0.5);
6181 wd->rotate.cy = y + ((double)h * 0.5);
6183 evas_object_smart_changed(wd->pan_smart);
6185 return EVAS_EVENT_FLAG_NONE;
6188 static Evas_Event_Flags
6189 _pinch_rotate_end_cb(void *data, void *event_info __UNUSED__)
6191 Widget_Data *wd = data;
6192 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EVAS_EVENT_FLAG_NONE);
6194 wd->rotate.a = wd->rotate.d;
6196 return EVAS_EVENT_FLAG_NONE;
6200 _source_tile_mod_cb(Eina_Module *m, void *data)
6202 EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
6204 Widget_Data *wd = data;
6206 Elm_Map_Module_Source_Name_Func name_cb;
6207 Elm_Map_Module_Tile_Zoom_Min_Func zoom_min;
6208 Elm_Map_Module_Tile_Zoom_Max_Func zoom_max;
6209 Elm_Map_Module_Tile_Url_Func url_cb;
6210 Elm_Map_Module_Tile_Geo_to_Coord_Func geo_to_coord;
6211 Elm_Map_Module_Tile_Coord_to_Geo_Func coord_to_geo;
6214 file = eina_module_file_get(m);
6215 if (!eina_module_load(m))
6217 ERR("Could not load module \"%s\": %s", file,
6218 eina_error_msg_get(eina_error_get()));
6222 name_cb = eina_module_symbol_get(m, "map_module_source_name_get");
6223 zoom_min = eina_module_symbol_get(m, "map_module_tile_zoom_min_get");
6224 zoom_max = eina_module_symbol_get(m, "map_module_tile_zoom_max_get");
6225 url_cb = eina_module_symbol_get(m, "map_module_tile_url_get");
6226 geo_to_coord = eina_module_symbol_get(m, "map_module_tile_geo_to_coord");
6227 coord_to_geo = eina_module_symbol_get(m, "map_module_tile_coord_to_geo");
6229 if ((!name_cb) || (!zoom_min) || (!zoom_max) || (!url_cb) ||
6230 (!geo_to_coord) || (!coord_to_geo))
6232 WRN("Could not find map module functions from module \"%s\": %s",
6233 file, eina_error_msg_get(eina_error_get()));
6234 eina_module_unload(m);
6237 s = ELM_NEW(Source_Tile);
6238 s->name = name_cb();
6239 s->zoom_min = zoom_min();
6240 s->zoom_max = zoom_max();
6242 s->geo_to_coord = geo_to_coord;
6243 s->coord_to_geo = coord_to_geo;
6244 wd->src_tiles = eina_list_append(wd->src_tiles, s);
6250 _source_tile_load(Widget_Data *wd)
6256 // Load from hard coded data
6257 for (idx = 0; idx < (sizeof(src_tiles) / sizeof(Source_Tile)); idx++)
6259 s= ELM_NEW(Source_Tile);
6260 s->name = src_tiles[idx].name;
6261 s->zoom_min = src_tiles[idx].zoom_min;
6262 s->zoom_max = src_tiles[idx].zoom_max;
6263 s->url_cb = src_tiles[idx].url_cb;
6264 s->geo_to_coord = src_tiles[idx].geo_to_coord;
6265 s->coord_to_geo = src_tiles[idx].coord_to_geo;
6266 wd->src_tiles = eina_list_append(wd->src_tiles, s);
6269 // Load from modules
6270 wd->src_tile_mods = eina_module_list_get(wd->src_tile_mods, MODULES_PATH, 1,
6271 &_source_tile_mod_cb, wd);
6273 // Set default source
6274 wd->src_tile = eina_list_nth(wd->src_tiles, 0);
6276 // Make name strings
6278 wd->src_tile_names = calloc((eina_list_count(wd->src_tiles) + 1),
6280 EINA_LIST_FOREACH(wd->src_tiles, l, s)
6282 eina_stringshare_replace(&wd->src_tile_names[idx], s->name);
6283 INF("source : %s", wd->src_tile_names[idx]);
6289 _source_tile_unload(Widget_Data *wd)
6294 for (idx = 0; wd->src_tile_names[idx]; idx++)
6295 eina_stringshare_del(wd->src_tile_names[idx]);
6296 EINA_LIST_FREE(wd->src_tiles, s) free(s);
6297 eina_module_list_free(wd->src_tile_mods);
6301 _source_tile_set(Widget_Data *wd, const char *source_name)
6303 EINA_SAFETY_ON_NULL_RETURN(wd);
6304 EINA_SAFETY_ON_NULL_RETURN(source_name);
6308 if (wd->src_tile && !strcmp(wd->src_tile->name, source_name)) return;
6310 EINA_LIST_FOREACH(wd->src_tiles, l, s)
6312 if (!strcmp(s->name, source_name))
6320 ERR("source name (%s) is not found", source_name);
6324 if (wd->src_tile->zoom_max < wd->zoom)
6325 wd->zoom = wd->src_tile->zoom_max;
6326 else if (wd->src_tile->zoom_min > wd->zoom)
6327 wd->zoom = wd->src_tile->zoom_min;
6329 if (wd->src_tile->zoom_max < wd->zoom_max)
6330 wd->zoom_max = wd->src_tile->zoom_max;
6331 if (wd->src_tile->zoom_min > wd->zoom_min)
6332 wd->zoom_min = wd->src_tile->zoom_min;
6334 _grid_all_clear(wd);
6335 _grid_all_create(wd);
6336 zoom_do(wd, wd->zoom);
6340 _source_route_mod_cb(Eina_Module *m, void *data)
6342 EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
6344 Widget_Data *wd = data;
6346 Elm_Map_Module_Source_Name_Func name_cb;
6347 Elm_Map_Module_Route_Url_Func url_cb;
6350 file = eina_module_file_get(m);
6351 if (!eina_module_load(m))
6353 ERR("Could not load module \"%s\": %s", file,
6354 eina_error_msg_get(eina_error_get()));
6358 name_cb = eina_module_symbol_get(m, "map_module_source_name_get");
6359 url_cb = eina_module_symbol_get(m, "map_module_route_url_get");
6361 if ((!name_cb) || (!url_cb))
6363 WRN("Could not find map module functions from module \"%s\": %s",
6364 file, eina_error_msg_get(eina_error_get()));
6365 eina_module_unload(m);
6368 s = ELM_NEW(Source_Tile);
6369 s->name = name_cb();
6371 wd->src_routes = eina_list_append(wd->src_routes, s);
6373 eina_module_unload(m);
6378 _source_route_load(Widget_Data *wd)
6384 // Load from hard coded data
6385 for (idx = 0; idx < (sizeof(src_routes) / sizeof(Source_Route)); idx++)
6387 s= ELM_NEW(Source_Route);
6388 s->name = src_routes[idx].name;
6389 s->url_cb = src_routes[idx].url_cb;
6390 wd->src_routes = eina_list_append(wd->src_routes, s);
6393 // Load from modules
6394 wd->src_route_mods = eina_module_list_get(wd->src_route_mods, MODULES_PATH,
6395 1, &_source_route_mod_cb, wd);
6397 // Set default source
6398 wd->src_route = eina_list_nth(wd->src_routes, 0);
6400 // Make name strings
6402 wd->src_route_names = calloc((eina_list_count(wd->src_routes) + 1),
6404 EINA_LIST_FOREACH(wd->src_routes, l, s)
6406 eina_stringshare_replace(&wd->src_route_names[idx], s->name);
6407 INF("source : %s", wd->src_route_names[idx]);
6413 _source_route_unload(Widget_Data *wd)
6418 for (idx = 0; wd->src_route_names[idx]; idx++)
6419 eina_stringshare_del(wd->src_route_names[idx]);
6420 EINA_LIST_FREE(wd->src_routes, s) free(s);
6421 eina_module_list_free(wd->src_route_mods);
6425 _source_route_set(Widget_Data *wd, const char *source_name)
6427 EINA_SAFETY_ON_NULL_RETURN(wd);
6428 EINA_SAFETY_ON_NULL_RETURN(source_name);
6432 if (wd->src_route && !strcmp(wd->src_route->name, source_name)) return;
6434 EINA_LIST_FOREACH(wd->src_routes, l, s)
6436 if (!strcmp(s->name, source_name))
6444 ERR("source name (%s) is not found", source_name);
6450 _source_name_mod_cb(Eina_Module *m, void *data)
6452 EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
6454 Widget_Data *wd = data;
6456 Elm_Map_Module_Source_Name_Func name_cb;
6457 Elm_Map_Module_Name_Url_Func url_cb;
6460 file = eina_module_file_get(m);
6461 if (!eina_module_load(m))
6463 ERR("Could not load module \"%s\": %s", file,
6464 eina_error_msg_get(eina_error_get()));
6468 name_cb = eina_module_symbol_get(m, "map_module_source_name_get");
6469 url_cb = eina_module_symbol_get(m, "map_module_name_url_get");
6471 if ((!name_cb) || (!url_cb))
6473 WRN("Could not find map module functions from module \"%s\": %s",
6474 file, eina_error_msg_get(eina_error_get()));
6475 eina_module_unload(m);
6478 s = ELM_NEW(Source_Tile);
6479 s->name = name_cb();
6481 wd->src_names = eina_list_append(wd->src_names, s);
6483 eina_module_unload(m);
6488 _source_name_load(Widget_Data *wd)
6494 // Load from hard coded data
6495 for (idx = 0; idx < (sizeof(src_names) / sizeof(Source_Name)); idx++)
6497 s= ELM_NEW(Source_Name);
6498 s->name = src_names[idx].name;
6499 s->url_cb = src_names[idx].url_cb;
6500 wd->src_names = eina_list_append(wd->src_names, s);
6503 // Load from modules
6504 wd->src_name_mods = eina_module_list_get(wd->src_name_mods, MODULES_PATH, 1,
6505 &_source_name_mod_cb, wd);
6507 // Set default source
6508 wd->src_name = eina_list_nth(wd->src_names, 0);
6510 // Make name strings
6512 wd->src_name_names = calloc((eina_list_count(wd->src_names) + 1),
6514 EINA_LIST_FOREACH(wd->src_names, l, s)
6516 eina_stringshare_replace(&wd->src_name_names[idx], s->name);
6517 INF("source : %s", wd->src_name_names[idx]);
6523 _source_name_unload(Widget_Data *wd)
6528 for (idx = 0; wd->src_name_names[idx]; idx++)
6529 eina_stringshare_del(wd->src_name_names[idx]);
6530 EINA_LIST_FREE(wd->src_names, s) free(s);
6531 eina_module_list_free(wd->src_name_mods);
6535 _source_name_set(Widget_Data *wd, const char *source_name)
6537 EINA_SAFETY_ON_NULL_RETURN(wd);
6538 EINA_SAFETY_ON_NULL_RETURN(source_name);
6543 if (wd->src_name && !strcmp(wd->src_name->name, source_name)) return;
6545 EINA_LIST_FOREACH(wd->src_names, l, s)
6547 if (!strcmp(s->name, source_name))
6555 ERR("source name (%s) is not found", source_name);
6561 _source_all_load(Widget_Data *wd)
6563 EINA_SAFETY_ON_NULL_RETURN(wd);
6564 _source_tile_load(wd);
6565 _source_route_load(wd);
6566 _source_name_load(wd);
6570 _source_all_unload(Widget_Data *wd)
6572 EINA_SAFETY_ON_NULL_RETURN(wd);
6573 _source_tile_unload(wd);
6574 _source_route_unload(wd);
6575 _source_name_unload(wd);
6579 _zoom_mode_set(void *data)
6581 EINA_SAFETY_ON_NULL_RETURN(data);
6582 Delayed_Data *dd = data;
6584 dd->wd->mode = dd->mode;
6585 if (dd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
6595 zoom = dd->wd->zoom_detail;
6596 _viewport_size_get(dd->wd, &vw, &vh);
6598 if (dd->mode == ELM_MAP_ZOOM_MODE_AUTO_FIT)
6600 if ((w < vw) && (h < vh))
6603 while ((w < vw) && (h < vh))
6606 w = pow(2.0, zoom) * dd->wd->tsize;
6607 h = pow(2.0, zoom) * dd->wd->tsize;
6613 while ((w > vw) || (h > vh))
6616 w = pow(2.0, zoom) * dd->wd->tsize;
6617 h = pow(2.0, zoom) * dd->wd->tsize;
6622 else if (dd->mode == ELM_MAP_ZOOM_MODE_AUTO_FILL)
6624 if ((w < vw) || (h < vh))
6627 while ((w < vw) || (h < vh))
6630 w = pow(2.0, zoom) * dd->wd->tsize;
6631 h = pow(2.0, zoom) * dd->wd->tsize;
6637 while ((w > vw) && (h > vh))
6640 w = pow(2.0, zoom) * dd->wd->tsize;
6641 h = pow(2.0, zoom) * dd->wd->tsize;
6645 zoom_with_animation(dd->wd, zoom, 10);
6650 _zoom_set(void *data)
6652 EINA_SAFETY_ON_NULL_RETURN(data);
6653 Delayed_Data *dd = data;
6655 if (dd->wd->paused) zoom_do(dd->wd, dd->zoom);
6656 else zoom_with_animation(dd->wd, dd->zoom, 10);
6657 evas_object_smart_changed(dd->wd->pan_smart);
6661 _region_bring_in(void *data)
6663 EINA_SAFETY_ON_NULL_RETURN(data);
6664 Delayed_Data *dd = data;
6667 _region_to_coord_convert(dd->wd, dd->lon, dd->lat, dd->wd->size.w, &x, &y);
6668 _viewport_size_get(dd->wd, &w, &h);
6671 elm_smart_scroller_region_bring_in(dd->wd->scr, x, y, w, h);
6672 evas_object_smart_changed(dd->wd->pan_smart);
6676 _marker_list_show(void *data)
6678 EINA_SAFETY_ON_NULL_RETURN(data);
6679 Delayed_Data *dd = data;
6681 double max_lon = -180, min_lon = 180;
6682 double max_lat = -90, min_lat = 90;
6684 Elm_Map_Marker *marker;
6686 EINA_LIST_FREE(dd->markers, marker)
6688 if (marker->longitude > max_lon) max_lon = marker->longitude;
6689 if (marker->longitude < min_lon) min_lon = marker->longitude;
6690 if (marker->latitude > max_lat) max_lat = marker->latitude;
6691 if (marker->latitude < min_lat) min_lat = marker->latitude;
6693 dd->lon = (max_lon + min_lon) / 2;
6694 dd->lat = (max_lat + min_lat) / 2;
6696 zoom = dd->wd->src_tile->zoom_min;
6697 _viewport_size_get(dd->wd, &vw, &vh);
6698 while (zoom <= dd->wd->src_tile->zoom_max)
6700 Evas_Coord size, max_x, max_y, min_x, min_y;
6701 size = pow(2.0, zoom) * dd->wd->tsize;
6702 _region_to_coord_convert(dd->wd, min_lon, max_lat, size, &min_x, &max_y);
6703 _region_to_coord_convert(dd->wd, max_lon, min_lat, size, &max_x, &min_y);
6704 if ((max_x - min_x) > vw || (max_y - min_y) > vh) break;
6709 zoom_do(dd->wd, zoom);
6711 evas_object_smart_changed(dd->wd->pan_smart);
6715 _mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
6718 // ((x+y+zoom)%3)+'a' is requesting map images from distributed tile servers (eg., a, b, c)
6719 snprintf(buf, sizeof(buf), "http://%c.tile.openstreetmap.org/%d/%d/%d.png",
6720 ((x + y + zoom) % 3) + 'a', zoom, x, y);
6725 _osmarender_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
6728 snprintf(buf, sizeof(buf),
6729 "http://%c.tah.openstreetmap.org/Tiles/tile/%d/%d/%d.png",
6730 ((x + y + zoom) % 3) + 'a', zoom, x, y);
6735 _cyclemap_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
6738 snprintf(buf, sizeof(buf),
6739 "http://%c.tile.opencyclemap.org/cycle/%d/%d/%d.png",
6740 (( x + y + zoom) % 3) + 'a', zoom, x, y);
6745 _mapquest_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
6748 snprintf(buf, sizeof(buf),
6749 "http://otile%d.mqcdn.com/tiles/1.0.0/osm/%d/%d/%d.png",
6750 ((x + y + zoom) % 4) + 1, zoom, x, y);
6755 _mapquest_aerial_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
6758 snprintf(buf, sizeof(buf), "http://oatile%d.mqcdn.com/naip/%d/%d/%d.png",
6759 ((x + y + zoom) % 4) + 1, zoom, x, y);
6763 static char *_yours_url_cb(Evas_Object *obj __UNUSED__, const char *type_name, int method, double flon, double flat, double tlon, double tlat)
6766 snprintf(buf, sizeof(buf),
6767 "%s?flat=%lf&flon=%lf&tlat=%lf&tlon=%lf&v=%s&fast=%d&instructions=1",
6768 ROUTE_YOURS_URL, flat, flon, tlat, tlon, type_name, method);
6773 // TODO: fix monav api
6775 static char *_monav_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
6778 snprintf(buf, sizeof(buf),
6779 "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
6780 ROUTE_MONAV_URL, flat, flon, tlat, tlon, type_name, method);
6786 // TODO: fix ors api
6788 static char *_ors_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
6791 snprintf(buf, sizeof(buf),
6792 "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
6793 ROUTE_ORS_URL, flat, flon, tlat, tlon, type_name, method);
6800 _nominatim_url_cb(Evas_Object *obj, int method, const char *name, double lon, double lat)
6802 ELM_CHECK_WIDTYPE(obj, widtype) strdup("");
6803 Widget_Data *wd = elm_widget_data_get(obj);
6804 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, strdup(""));
6807 unsigned int ele, idx;
6808 char search_url[PATH_MAX];
6811 if (method == ELM_MAP_NAME_METHOD_SEARCH)
6813 search_url[0] = '\0';
6814 str = eina_str_split_full(name, " ", 0, &ele);
6815 for (idx = 0; idx < ele; idx++)
6817 eina_strlcat(search_url, str[idx], sizeof(search_url));
6818 if (!(idx == (ele-1)))
6819 eina_strlcat(search_url, "+", sizeof(search_url));
6821 snprintf(buf, sizeof(buf),
6822 "%s/search?q=%s&format=xml&polygon=0&addressdetails=0",
6823 NAME_NOMINATIM_URL, search_url);
6831 else if (method == ELM_MAP_NAME_METHOD_REVERSE)
6832 snprintf(buf, sizeof(buf),
6833 "%s/reverse?format=xml&lat=%lf&lon=%lf&zoom=%d&addressdetails=0",
6834 NAME_NOMINATIM_URL, lat, lon, (int)wd->zoom);
6835 else strcpy(buf, "");
6841 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
6843 ELM_CHECK_WIDTYPE(obj, widtype);
6844 Widget_Data *wd = elm_widget_data_get(obj);
6845 EINA_SAFETY_ON_NULL_RETURN(wd);
6847 if (elm_widget_focus_get(obj))
6849 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,action,focus", "elm");
6850 evas_object_focus_set(wd->obj, EINA_TRUE);
6854 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), "elm,action,unfocus", "elm");
6855 evas_object_focus_set(wd->obj, EINA_FALSE);
6860 _del_hook(Evas_Object *obj)
6862 ELM_CHECK_WIDTYPE(obj, widtype);
6863 Widget_Data *wd = elm_widget_data_get(obj);
6864 EINA_SAFETY_ON_NULL_RETURN(wd);
6866 if (wd->map) evas_map_free(wd->map);
6871 _del_pre_hook(Evas_Object *obj)
6873 ELM_CHECK_WIDTYPE(obj, widtype);
6874 Widget_Data *wd = elm_widget_data_get(obj);
6875 EINA_SAFETY_ON_NULL_RETURN(wd);
6881 Elm_Map_Marker *marker;
6882 Elm_Map_Group_Class *group_clas;
6883 Elm_Map_Marker_Class *clas;
6884 Elm_Map_Overlay *overlay;
6887 EINA_LIST_FOREACH_SAFE(wd->routes, l, ll, r) elm_map_route_del(r);
6888 eina_list_free(wd->routes);
6890 EINA_LIST_FOREACH_SAFE(wd->names, l, ll, na) elm_map_name_del(na);
6891 eina_list_free(wd->names);
6893 EINA_LIST_FOREACH_SAFE(wd->overlays, l, ll, overlay)
6894 elm_map_overlay_del(overlay);
6895 eina_list_free(wd->overlays);
6897 EINA_LIST_FREE(wd->track, track) evas_object_del(track);
6899 EINA_LIST_FOREACH_SAFE(wd->markers, l, ll, marker)
6900 _elm_map_marker_remove(marker);
6901 eina_list_free(wd->markers);
6903 EINA_LIST_FREE(wd->group_classes, group_clas)
6905 eina_list_free(group_clas->markers);
6906 if (group_clas->style) eina_stringshare_del(group_clas->style);
6909 EINA_LIST_FREE(wd->marker_classes, clas)
6911 if (clas->style) eina_stringshare_del(clas->style);
6915 if (wd->scr_timer) ecore_timer_del(wd->scr_timer);
6916 if (wd->long_timer) ecore_timer_del(wd->long_timer);
6918 if (wd->delayed_jobs) EINA_LIST_FREE(wd->delayed_jobs, dd) free(dd);
6920 if (wd->user_agent) eina_stringshare_del(wd->user_agent);
6921 if (wd->ua) eina_hash_free(wd->ua);
6923 if (wd->zoom_timer) ecore_timer_del(wd->zoom_timer);
6924 if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
6926 _grid_all_clear(wd);
6927 // Removal of download list should be after grid clear.
6928 if (wd->download_idler) ecore_idler_del(wd->download_idler);
6929 eina_list_free(wd->download_list);
6931 _source_all_unload(wd);
6933 if (!ecore_file_recursive_rm(CACHE_ROOT))
6934 ERR("Deletion of %s failed", CACHE_ROOT);
6938 _theme_hook(Evas_Object *obj)
6940 ELM_CHECK_WIDTYPE(obj, widtype);
6941 Widget_Data *wd = elm_widget_data_get(obj);
6942 EINA_SAFETY_ON_NULL_RETURN(wd);
6944 elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", elm_widget_style_get(obj));
6949 _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
6951 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
6952 Widget_Data *wd = elm_widget_data_get(obj);
6953 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
6957 Evas_Coord step_x, step_y, page_x, page_y;
6959 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
6960 Evas_Event_Key_Down *ev = event_info;
6961 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
6963 elm_smart_scroller_child_pos_get(wd->scr, &x, &y);
6964 elm_smart_scroller_step_size_get(wd->scr, &step_x, &step_y);
6965 elm_smart_scroller_page_size_get(wd->scr, &page_x, &page_y);
6966 _viewport_size_get(wd, NULL, &vh);
6968 if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
6972 else if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
6976 else if ((!strcmp(ev->keyname, "Up")) || (!strcmp(ev->keyname, "KP_Up")))
6980 else if ((!strcmp(ev->keyname, "Down")) || (!strcmp(ev->keyname, "KP_Down")))
6984 else if ((!strcmp(ev->keyname, "Prior")) || (!strcmp(ev->keyname, "KP_Prior")))
6987 y -= -(page_y * vh) / 100;
6991 else if ((!strcmp(ev->keyname, "Next")) || (!strcmp(ev->keyname, "KP_Next")))
6994 y += -(page_y * vh) / 100;
6998 else if (!strcmp(ev->keyname, "KP_Add"))
7000 zoom_with_animation(wd, wd->zoom + 1, 10);
7003 else if (!strcmp(ev->keyname, "KP_Subtract"))
7005 zoom_with_animation(wd, wd->zoom - 1, 10);
7008 else return EINA_FALSE;
7010 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
7011 elm_smart_scroller_child_pos_set(wd->scr, x, y);
7015 >>>>>>> remotes/origin/upstream
7019 elm_map_add(Evas_Object *parent)
7021 #ifdef HAVE_ELEMENTARY_ECORE_CON
7025 Evas_Coord minw, minh;
7027 static Evas_Smart *smart = NULL;
7028 Eina_Bool bounce = _elm_config->thumbscroll_bounce_enable;
7030 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
7032 ELM_SET_WIDTYPE(widtype, "map");
7033 elm_widget_type_set(obj, "map");
7034 elm_widget_sub_object_add(parent, obj);
7035 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
7036 elm_widget_data_set(obj, wd);
7037 elm_widget_del_hook_set(obj, _del_hook);
7038 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
7039 elm_widget_theme_hook_set(obj, _theme_hook);
7040 elm_widget_can_focus_set(obj, EINA_TRUE);
7041 elm_widget_event_hook_set(obj, _event_hook);
7043 wd->scr = elm_smart_scroller_add(e);
7044 elm_smart_scroller_widget_set(wd->scr, obj);
7045 elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", "default");
7046 evas_object_smart_callback_add(wd->scr, "scroll", _scr, obj);
7047 evas_object_smart_callback_add(wd->scr, "drag", _scr, obj);
7048 elm_widget_resize_object_set(obj, wd->scr);
7049 elm_smart_scroller_wheel_disabled_set(wd->scr, EINA_TRUE);
7051 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, obj);
7052 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, obj);
7053 evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
7054 evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
7055 evas_object_smart_callback_add(wd->scr, "scroll", _scr_scroll, obj);
7057 elm_smart_scroller_bounce_allow_set(wd->scr, bounce, bounce);
7059 wd->zoom_min = 0xFF;
7060 wd->zoom_max = 0X00;
7064 wd->map = evas_map_new(4);
7065 if (!wd->map) return NULL;
7067 wd->markers_max_num = 30;
7068 wd->pinch.level = 1.0;
7069 wd->pinch.diff = 1.0;
7070 wd->markers = calloc(wd->zoom_max + 1, sizeof(void*));
7072 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
7073 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
7074 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
7075 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
7079 static Evas_Smart_Class sc;
7081 evas_object_smart_clipped_smart_set(&_pan_sc);
7083 sc.name = "elm_map_pan";
7084 sc.version = EVAS_SMART_CLASS_VERSION;
7087 sc.resize = _pan_resize;
7088 sc.move = _pan_move;
7089 sc.calculate = _pan_calculate;
7090 smart = evas_smart_class_new(&sc);
7094 wd->pan_smart = evas_object_smart_add(e, smart);
7095 wd->pan = evas_object_smart_data_get(wd->pan_smart);
7099 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
7100 _pan_set, _pan_get, _pan_max_get,
7101 _pan_min_get, _pan_child_size_get);
7103 wd->rect = evas_object_rectangle_add(e);
7104 evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_RESIZE,
7105 _rect_resize_cb, obj);
7106 evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_DOWN,
7108 evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_UP,
7110 evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_WHEEL,
7111 _mouse_wheel_cb, obj);
7113 evas_object_smart_member_add(wd->rect, wd->pan_smart);
7114 elm_widget_sub_object_add(obj, wd->rect);
7115 evas_object_show(wd->rect);
7116 evas_object_color_set(wd->rect, 0, 0, 0, 0);
7118 wd->ges = elm_gesture_layer_add(obj);
7119 if (!wd->ges) ERR("elm_gesture_layer_add() failed");
7120 elm_gesture_layer_attach(wd->ges, wd->rect);
7121 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
7123 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
7125 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_END,
7127 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_ABORT,
7129 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_MOVE,
7131 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_END,
7133 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_ABORT,
7136 wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
7137 wd->id = ((int)getpid() << 16) | idnum;
7141 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
7143 evas_object_size_hint_min_set(obj, minw, minh);
7145 wd->sep_maps_markers = evas_object_rectangle_add(evas_object_evas_get(obj));
7146 evas_object_smart_member_add(wd->sep_maps_markers, wd->pan_smart);
7148 grid_create_all(obj);
7150 wd->paused = EINA_TRUE;
7151 elm_map_zoom_set(obj, 0);
7152 wd->paused = EINA_FALSE;
7155 // TODO: convert Elementary to subclassing of Evas_Smart_Class
7156 // TODO: and save some bytes, making descriptions per-class and not instance!
7157 evas_object_smart_callbacks_descriptions_set(obj, _signals);
7159 if (!ecore_file_download_protocol_available("http://"))
7161 ERR("Ecore must be built with curl support for the map widget!");
7172 Evas_Coord minw, minh;
7174 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
7175 ELM_SET_WIDTYPE(widtype, "map");
7176 elm_widget_type_set(obj, "map");
7177 elm_widget_sub_object_add(parent, obj);
7178 elm_widget_data_set(obj, wd);
7179 elm_widget_can_focus_set(obj, EINA_TRUE);
7180 elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
7181 elm_widget_del_hook_set(obj, _del_hook);
7182 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
7183 elm_widget_theme_hook_set(obj, _theme_hook);
7184 elm_widget_event_hook_set(obj, _event_hook);
7185 evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, wd);
7186 evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, wd);
7187 evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, wd);
7188 evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, wd);
7189 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
7191 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
7193 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL,
7194 _mouse_wheel_cb,wd);
7197 wd->scr = elm_smart_scroller_add(e);
7198 elm_widget_sub_object_add(obj, wd->scr);
7199 elm_smart_scroller_widget_set(wd->scr, obj);
7200 elm_smart_scroller_object_theme_set(obj, wd->scr, "map", "base", "default");
7201 elm_widget_resize_object_set(obj, wd->scr);
7202 elm_smart_scroller_wheel_disabled_set(wd->scr, EINA_TRUE);
7203 elm_smart_scroller_bounce_allow_set(wd->scr,
7204 _elm_config->thumbscroll_bounce_enable,
7205 _elm_config->thumbscroll_bounce_enable);
7206 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
7207 _changed_size_hints, wd);
7208 evas_object_smart_callback_add(wd->scr, "scroll", _scr, wd);
7209 evas_object_smart_callback_add(wd->scr, "drag", _scr, wd);
7210 evas_object_smart_callback_add(wd->scr, "animate,start", _scr_anim_start, wd);
7211 evas_object_smart_callback_add(wd->scr, "animate,stop", _scr_anim_stop, wd);
7215 evas_object_smart_clipped_smart_set(&parent_sc);
7217 sc.name = "elm_map_pan";
7218 sc.version = EVAS_SMART_CLASS_VERSION;
7220 sc.resize = _pan_resize;
7221 sc.move = _pan_move;
7222 sc.calculate = _pan_calculate;
7223 smart = evas_smart_class_new(&sc);
7228 wd->pan_smart = evas_object_smart_add(e, smart);
7229 pan = evas_object_smart_data_get(wd->pan_smart);
7232 elm_widget_sub_object_add(obj, wd->pan_smart);
7234 elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
7235 _pan_set, _pan_get, _pan_max_get,
7236 _pan_min_get, _pan_child_size_get);
7237 edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr),
7239 evas_object_size_hint_min_set(obj, minw, minh);
7241 wd->ges = elm_gesture_layer_add(obj);
7242 if (!wd->ges) ERR("elm_gesture_layer_add() failed");
7243 elm_gesture_layer_attach(wd->ges, obj);
7244 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
7245 _pinch_zoom_start_cb, wd);
7246 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
7247 _pinch_zoom_cb, wd);
7248 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_MOVE,
7249 _pinch_rotate_cb, wd);
7250 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_END,
7251 _pinch_rotate_end_cb, wd);
7252 elm_gesture_layer_cb_set(wd->ges, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_ABORT,
7253 _pinch_rotate_end_cb, wd);
7255 wd->sep_maps_markers = evas_object_rectangle_add(evas_object_evas_get(obj));
7256 elm_widget_sub_object_add(obj, wd->sep_maps_markers);
7257 evas_object_smart_member_add(wd->sep_maps_markers, wd->pan_smart);
7259 wd->map = evas_map_new(EVAS_MAP_POINT);
7261 _source_all_load(wd);
7262 wd->zoom_min = wd->src_tile->zoom_min;
7263 wd->zoom_max = wd->src_tile->zoom_max;
7264 // FIXME: Tile Provider is better to provide tile size!
7265 wd->tsize = DEFAULT_TILE_SIZE;
7269 wd->id = ((int)getpid() << 16) | idnum;
7271 _grid_all_create(wd);
7275 wd->mode = ELM_MAP_ZOOM_MODE_MANUAL;
7276 wd->markers_max_num = MARER_MAX_NUMBER;
7278 // TODO: convert Elementary to subclassing of Evas_Smart_Class
7279 // TODO: and save some bytes, making descriptions per-class and not instance!
7280 evas_object_smart_callbacks_descriptions_set(obj, _signals);
7282 if (!ecore_file_download_protocol_available("http://"))
7283 ERR("Ecore must be built with curl support for the map widget!");
7293 elm_map_zoom_set(Evas_Object *obj, int zoom)
7295 #ifdef HAVE_ELEMENTARY_ECORE_CON
7296 ELM_CHECK_WIDTYPE(obj, widtype);
7297 Widget_Data *wd = elm_widget_data_get(obj);
7298 EINA_SAFETY_ON_NULL_RETURN(wd);
7299 EINA_SAFETY_ON_NULL_RETURN(wd->src_tile);
7301 if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL) return;
7302 if (zoom < 0) zoom = 0;
7303 if (wd->zoom == zoom) return;
7304 if (zoom > wd->src_tile->zoom_max) zoom = wd->src_tile->zoom_max;
7305 if (zoom < wd->src_tile->zoom_min) zoom = wd->src_tile->zoom_min;
7307 Delayed_Data *data = ELM_NEW(Delayed_Data);
7308 data->func = _zoom_set;
7311 data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
7312 evas_object_smart_changed(data->wd->pan_smart);
7320 elm_map_zoom_get(const Evas_Object *obj)
7322 #ifdef HAVE_ELEMENTARY_ECORE_CON
7323 ELM_CHECK_WIDTYPE(obj, widtype) 0;
7324 Widget_Data *wd = elm_widget_data_get(obj);
7326 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, 0);
7335 elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode)
7337 #ifdef HAVE_ELEMENTARY_ECORE_CON
7338 ELM_CHECK_WIDTYPE(obj, widtype);
7339 Widget_Data *wd = elm_widget_data_get(obj);
7340 EINA_SAFETY_ON_NULL_RETURN(wd);
7342 if ((mode == ELM_MAP_ZOOM_MODE_MANUAL) && (wd->mode == !!mode)) return;
7344 Delayed_Data *data = ELM_NEW(Delayed_Data);
7346 data->func = _zoom_mode_set;
7348 data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
7349 evas_object_smart_changed(data->wd->pan_smart);
7356 EAPI Elm_Map_Zoom_Mode
7357 elm_map_zoom_mode_get(const Evas_Object *obj)
7359 #ifdef HAVE_ELEMENTARY_ECORE_CON
7360 ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ZOOM_MODE_MANUAL;
7361 Widget_Data *wd = elm_widget_data_get(obj);
7362 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, ELM_MAP_ZOOM_MODE_MANUAL);
7367 return ELM_MAP_ZOOM_MODE_MANUAL;
7372 elm_map_zoom_max_set(Evas_Object *obj, int zoom)
7374 #ifdef HAVE_ELEMENTARY_ECORE_CON
7375 ELM_CHECK_WIDTYPE(obj, widtype);
7376 Widget_Data *wd = elm_widget_data_get(obj);
7377 EINA_SAFETY_ON_NULL_RETURN(wd);
7378 EINA_SAFETY_ON_NULL_RETURN(wd->src_tile);
7380 if ((zoom > wd->src_tile->zoom_max) || (zoom < wd->src_tile->zoom_min))
7382 wd->zoom_max = zoom;
7390 elm_map_zoom_max_get(const Evas_Object *obj)
7392 #ifdef HAVE_ELEMENTARY_ECORE_CON
7393 ELM_CHECK_WIDTYPE(obj, widtype) 18;
7394 Widget_Data *wd = elm_widget_data_get(obj);
7395 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, -1);
7396 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src_tile, -1);
7398 return wd->zoom_max;
7406 elm_map_zoom_min_set(Evas_Object *obj, int zoom)
7408 #ifdef HAVE_ELEMENTARY_ECORE_CON
7409 ELM_CHECK_WIDTYPE(obj, widtype);
7410 Widget_Data *wd = elm_widget_data_get(obj);
7411 EINA_SAFETY_ON_NULL_RETURN(wd);
7412 EINA_SAFETY_ON_NULL_RETURN(wd->src_tile);
7414 if ((zoom > wd->src_tile->zoom_max) || (zoom < wd->src_tile->zoom_min))
7416 wd->zoom_min = zoom;
7424 elm_map_zoom_min_get(const Evas_Object *obj)
7426 #ifdef HAVE_ELEMENTARY_ECORE_CON
7427 ELM_CHECK_WIDTYPE(obj, widtype) 0;
7428 Widget_Data *wd = elm_widget_data_get(obj);
7429 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, -1);
7430 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src_tile, -1);
7432 return wd->zoom_min;
7441 elm_map_region_bring_in(Evas_Object *obj, double lon, double lat)
7443 #ifdef HAVE_ELEMENTARY_ECORE_CON
7444 ELM_CHECK_WIDTYPE(obj, widtype);
7445 Widget_Data *wd = elm_widget_data_get(obj);
7447 Delayed_Data *data = ELM_NEW(Delayed_Data);
7448 data->func = _region_bring_in;
7452 data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
7453 evas_object_smart_changed(data->wd->pan_smart);
7462 elm_map_region_show(Evas_Object *obj, double lon, double lat)
7464 #ifdef HAVE_ELEMENTARY_ECORE_CON
7465 ELM_CHECK_WIDTYPE(obj, widtype);
7466 Widget_Data *wd = elm_widget_data_get(obj);
7468 Delayed_Data *data = ELM_NEW(Delayed_Data);
7469 data->func = _region_show;
7473 data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
7474 evas_object_smart_changed(data->wd->pan_smart);
7483 elm_map_region_get(const Evas_Object *obj, double *lon, double *lat)
7485 #ifdef HAVE_ELEMENTARY_ECORE_CON
7486 ELM_CHECK_WIDTYPE(obj, widtype);
7487 Widget_Data *wd = elm_widget_data_get(obj);
7488 EINA_SAFETY_ON_NULL_RETURN(wd);
7491 Evas_Coord px, py, vw, vh;
7493 _pan_geometry_get(wd, &px, &py);
7494 _viewport_size_get(wd, &vw, &vh);
7495 _coord_to_region_convert(wd, vw/2 - px, vh/2 -py, wd->size.w, &tlon, &tlat);
7496 if (lon) *lon = tlon;
7497 if (lat) *lat = tlat;
7506 elm_map_paused_set(Evas_Object *obj, Eina_Bool paused)
7508 #ifdef HAVE_ELEMENTARY_ECORE_CON
7509 ELM_CHECK_WIDTYPE(obj, widtype);
7510 Widget_Data *wd = elm_widget_data_get(obj);
7511 EINA_SAFETY_ON_NULL_RETURN(wd);
7513 if (wd->paused == !!paused) return;
7514 wd->paused = !!paused;
7517 if (wd->zoom_animator)
7519 if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
7520 wd->zoom_animator = NULL;
7521 zoom_do(wd, wd->zoom);
7523 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
7524 "elm,state,busy,stop", "elm");
7528 if (wd->download_num >= 1)
7529 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
7530 "elm,state,busy,start", "elm");
7539 elm_map_paused_get(const Evas_Object *obj)
7541 #ifdef HAVE_ELEMENTARY_ECORE_CON
7542 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
7543 Widget_Data *wd = elm_widget_data_get(obj);
7544 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
7554 elm_map_rotate_set(Evas_Object *obj, double degree, Evas_Coord cx, Evas_Coord cy)
7556 #ifdef HAVE_ELEMENTARY_ECORE_CON
7557 ELM_CHECK_WIDTYPE(obj, widtype);
7558 Widget_Data *wd = elm_widget_data_get(obj);
7559 EINA_SAFETY_ON_NULL_RETURN(wd);
7561 wd->rotate.d = degree;
7565 evas_object_smart_changed(wd->pan_smart);
7575 elm_map_rotate_get(const Evas_Object *obj, double *degree, Evas_Coord *cx, Evas_Coord *cy)
7577 #ifdef HAVE_ELEMENTARY_ECORE_CON
7578 ELM_CHECK_WIDTYPE(obj, widtype);
7579 Widget_Data *wd = elm_widget_data_get(obj);
7580 EINA_SAFETY_ON_NULL_RETURN(wd);
7582 if (degree) *degree = wd->rotate.d;
7583 if (cx) *cx = wd->rotate.cx;
7584 if (cy) *cy = wd->rotate.cy;
7594 elm_map_wheel_disabled_set(Evas_Object *obj, Eina_Bool disabled)
7596 #ifdef HAVE_ELEMENTARY_ECORE_CON
7597 ELM_CHECK_WIDTYPE(obj, widtype);
7598 Widget_Data *wd = elm_widget_data_get(obj);
7599 EINA_SAFETY_ON_NULL_RETURN(wd);
7601 if ((!wd->wheel_disabled) && (disabled))
7602 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, obj);
7603 else if ((wd->wheel_disabled) && (!disabled))
7604 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, obj);
7605 wd->wheel_disabled = !!disabled;
7613 elm_map_wheel_disabled_get(const Evas_Object *obj)
7615 #ifdef HAVE_ELEMENTARY_ECORE_CON
7616 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
7617 Widget_Data *wd = elm_widget_data_get(obj);
7618 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
7620 return wd->wheel_disabled;
7628 elm_map_tile_load_status_get(const Evas_Object *obj, int *try_num, int *finish_num)
7630 #ifdef HAVE_ELEMENTARY_ECORE_CON
7631 ELM_CHECK_WIDTYPE(obj, widtype);
7632 Widget_Data *wd = elm_widget_data_get(obj);
7633 EINA_SAFETY_ON_NULL_RETURN(wd);
7635 if (try_num) *try_num = wd->try_num;
7636 if (finish_num) *finish_num = wd->finish_num;
7645 elm_map_canvas_to_region_convert(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, double *lon, double *lat)
7647 #ifdef HAVE_ELEMENTARY_ECORE_CON
7648 ELM_CHECK_WIDTYPE(obj, widtype);
7649 Widget_Data *wd = elm_widget_data_get(obj);
7650 EINA_SAFETY_ON_NULL_RETURN(wd);
7651 EINA_SAFETY_ON_NULL_RETURN(lon);
7652 EINA_SAFETY_ON_NULL_RETURN(lat);
7654 Evas_Coord px, py, vw, vh;
7655 _pan_geometry_get(wd, &px, &py);
7656 _viewport_size_get(wd, &vw, &vh);
7657 _coord_rotate(x - px, y - py, (vw / 2) - px, (vh / 2) - py, -wd->rotate.d,
7659 _coord_to_region_convert(wd, x, y, wd->size.w, lon, lat);
7670 elm_map_region_to_canvas_convert(const Evas_Object *obj, double lon, double lat, Evas_Coord *x, Evas_Coord *y)
7672 #ifdef HAVE_ELEMENTARY_ECORE_CON
7673 ELM_CHECK_WIDTYPE(obj, widtype);
7674 Widget_Data *wd = elm_widget_data_get(obj);
7675 EINA_SAFETY_ON_NULL_RETURN(wd);
7676 EINA_SAFETY_ON_NULL_RETURN(x);
7677 EINA_SAFETY_ON_NULL_RETURN(y);
7679 Evas_Coord px, py, vw, vh;
7680 _pan_geometry_get(wd, &px, &py);
7681 _viewport_size_get(wd, &vw, &vh);
7682 _region_to_coord_convert(wd, lon, lat, wd->size.w, x, y);
7683 _coord_rotate(*x, *y, (vw / 2) - px, (vh / 2) - py, wd->rotate.d,
7693 >>>>>>> remotes/origin/upstream
7699 elm_map_zoom_set(Evas_Object *obj, int zoom)
7701 elm_map_user_agent_set(Evas_Object *obj, const char *user_agent)
7702 >>>>>>> remotes/origin/upstream
7704 #ifdef HAVE_ELEMENTARY_ECORE_CON
7705 ELM_CHECK_WIDTYPE(obj, widtype);
7706 Widget_Data *wd = elm_widget_data_get(obj);
7709 Evas_Coord rx, ry, rw, rh;
7715 EINA_SAFETY_ON_NULL_RETURN(wd);
7716 EINA_SAFETY_ON_NULL_RETURN(wd->src);
7717 if (wd->zoom_animator) return;
7719 if (zoom < 0) zoom = 0;
7720 if (zoom > wd->src->zoom_max) zoom = wd->src->zoom_max;
7721 if (zoom < wd->src->zoom_min) zoom = wd->src->zoom_min;
7723 if ((wd->zoom - zoom) > 0) wd->zoom_method = ZOOM_METHOD_OUT;
7724 else if ((wd->zoom - zoom) < 0) wd->zoom_method = ZOOM_METHOD_IN;
7725 else wd->zoom_method = ZOOM_METHOD_NONE;
7728 wd->size.ow = wd->size.w;
7729 wd->size.oh = wd->size.h;
7730 elm_smart_scroller_child_pos_get(wd->scr, &rx, &ry);
7731 elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
7733 EINA_LIST_FOREACH(wd->route, l, r)
7737 EINA_LIST_FOREACH(r->path, l, p)
7739 evas_object_polygon_points_clear(p);
7744 EINA_LIST_FOREACH(wd->track, l, route)
7746 evas_object_hide(route);
7749 if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
7756 while (cumulw <= rw)
7765 while (cumulh <= rh)
7772 if (wd->mode == ELM_MAP_ZOOM_MODE_AUTO_FIT)
7774 if (p2w < p2h) z = p2w;
7777 else if (wd->mode == ELM_MAP_ZOOM_MODE_AUTO_FILL)
7779 if (p2w > p2h) z = p2w;
7785 wd->size.nw = pow(2.0, wd->zoom) * wd->tsize;
7786 wd->size.nh = pow(2.0, wd->zoom) * wd->tsize;
7789 if ((wd->size.w > 0) && (wd->size.h > 0))
7791 wd->size.spos.x = (double)(rx + (rw / 2)) / (double)wd->size.ow;
7792 wd->size.spos.y = (double)(ry + (rh / 2)) / (double)wd->size.oh;
7796 wd->size.spos.x = 0.5;
7797 wd->size.spos.y = 0.5;
7800 if (rw > wd->size.ow) wd->size.spos.x = 0.5;
7801 if (rh > wd->size.oh) wd->size.spos.y = 0.5;
7802 if (wd->size.spos.x > 1.0) wd->size.spos.x = 1.0;
7803 if (wd->size.spos.y > 1.0) wd->size.spos.y = 1.0;
7811 if (!wd->zoom_animator)
7813 wd->zoom_animator = ecore_animator_add(_zoom_anim, obj);
7815 if (wd->nosmooth == 1) _smooth_update(obj);
7816 evas_object_smart_callback_call(obj, SIG_ZOOM_START, NULL);
7820 if (wd->zoom_method != ZOOM_METHOD_NONE) evas_object_smart_callback_call(obj, SIG_ZOOM_CHANGE, NULL);
7828 elm_map_zoom_get(const Evas_Object *obj)
7830 #ifdef HAVE_ELEMENTARY_ECORE_CON
7831 ELM_CHECK_WIDTYPE(obj, widtype) 0;
7832 Widget_Data *wd = elm_widget_data_get(obj);
7840 EINA_SAFETY_ON_NULL_RETURN(wd);
7841 EINA_SAFETY_ON_NULL_RETURN(user_agent);
7843 eina_stringshare_replace(&wd->user_agent, user_agent);
7845 if (!wd->ua) wd->ua = eina_hash_string_small_new(NULL);
7846 eina_hash_set(wd->ua, "User-Agent", wd->user_agent);
7854 elm_map_user_agent_get(const Evas_Object *obj)
7856 #ifdef HAVE_ELEMENTARY_ECORE_CON
7857 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
7858 Widget_Data *wd = elm_widget_data_get(obj);
7859 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
7861 return wd->user_agent;
7865 >>>>>>> remotes/origin/upstream
7871 elm_map_zoom_mode_set(Evas_Object *obj, Elm_Map_Zoom_Mode mode)
7873 elm_map_source_set(Evas_Object *obj, Elm_Map_Source_Type type, const char *source_name)
7874 >>>>>>> remotes/origin/upstream
7876 #ifdef HAVE_ELEMENTARY_ECORE_CON
7877 ELM_CHECK_WIDTYPE(obj, widtype);
7878 Widget_Data *wd = elm_widget_data_get(obj);
7882 if (wd->mode == mode) return;
7885 if (wd->mode != ELM_MAP_ZOOM_MODE_MANUAL)
7889 elm_map_zoom_set(wd->obj, tz);
7897 EAPI Elm_Map_Zoom_Mode
7898 elm_map_zoom_mode_get(const Evas_Object *obj)
7900 #ifdef HAVE_ELEMENTARY_ECORE_CON
7901 ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ZOOM_MODE_MANUAL;
7902 Widget_Data *wd = elm_widget_data_get(obj);
7904 if (!wd) return ELM_MAP_ZOOM_MODE_MANUAL;
7908 return ELM_MAP_ZOOM_MODE_MANUAL;
7913 elm_map_geo_region_bring_in(Evas_Object *obj, double lon, double lat)
7915 #ifdef HAVE_ELEMENTARY_ECORE_CON
7916 ELM_CHECK_WIDTYPE(obj, widtype);
7917 Widget_Data *wd = elm_widget_data_get(obj);
7921 elm_map_utils_convert_geo_into_coord(obj, lon, lat, wd->size.w, &rx, &ry);
7922 elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
7927 if (wd->zoom_animator)
7930 if (!wd->nosmooth) _smooth_update(obj);
7931 ecore_animator_del(wd->zoom_animator);
7932 wd->zoom_animator = NULL;
7934 evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
7936 elm_smart_scroller_region_bring_in(wd->scr, rx, ry, rw, rh);
7938 wd->center_on.enabled = EINA_TRUE;
7939 wd->center_on.lon = lon;
7940 wd->center_on.lat = lat;
7949 elm_map_geo_region_show(Evas_Object *obj, double lon, double lat)
7951 #ifdef HAVE_ELEMENTARY_ECORE_CON
7952 ELM_CHECK_WIDTYPE(obj, widtype);
7953 Widget_Data *wd = elm_widget_data_get(obj);
7957 elm_map_utils_convert_geo_into_coord(obj, lon, lat, wd->size.w, &rx, &ry);
7958 elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
7963 if (wd->zoom_animator)
7966 ecore_animator_del(wd->zoom_animator);
7967 wd->zoom_animator = NULL;
7969 evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
7971 elm_smart_scroller_child_region_show(wd->scr, rx, ry, rw, rh);
7973 wd->center_on.enabled = EINA_TRUE;
7974 wd->center_on.lon = lon;
7975 wd->center_on.lat = lat;
7984 elm_map_geo_region_get(const Evas_Object *obj, double *lon, double *lat)
7986 #ifdef HAVE_ELEMENTARY_ECORE_CON
7987 ELM_CHECK_WIDTYPE(obj, widtype);
7988 Widget_Data *wd = elm_widget_data_get(obj);
7992 EINA_SAFETY_ON_NULL_RETURN(wd);
7994 _region_get(wd, NULL, NULL, &cx, &cy, NULL, NULL);
7995 rw = wd->size.w * wd->pinch.level;
7996 elm_map_utils_convert_coord_into_geo(obj, cx, cy, rw, &tlon, &tlat);
7997 if (lon) *lon = tlon;
7998 if (lat) *lat = tlat;
8004 EINA_SAFETY_ON_NULL_RETURN(wd);
8005 EINA_SAFETY_ON_NULL_RETURN(source_name);
8007 if (type == ELM_MAP_SOURCE_TYPE_TILE) _source_tile_set(wd, source_name);
8008 else if (type == ELM_MAP_SOURCE_TYPE_ROUTE)
8009 _source_route_set(wd, source_name);
8010 else if (type == ELM_MAP_SOURCE_TYPE_NAME) _source_name_set(wd, source_name);
8011 else ERR("Not supported map source type: %d", type);
8020 elm_map_source_get(const Evas_Object *obj, Elm_Map_Source_Type type)
8022 #ifdef HAVE_ELEMENTARY_ECORE_CON
8023 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
8024 Widget_Data *wd = elm_widget_data_get(obj);
8025 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
8026 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src_tile, NULL);
8028 if (type == ELM_MAP_SOURCE_TYPE_TILE) return wd->src_tile->name;
8029 else if (type == ELM_MAP_SOURCE_TYPE_ROUTE) return wd->src_route->name;
8030 else if (type == ELM_MAP_SOURCE_TYPE_NAME) return wd->src_name->name;
8031 else ERR("Not supported map source type: %d", type);
8040 elm_map_sources_get(const Evas_Object *obj, Elm_Map_Source_Type type)
8042 #ifdef HAVE_ELEMENTARY_ECORE_CON
8043 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
8044 Widget_Data *wd = elm_widget_data_get(obj);
8045 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
8047 if (type == ELM_MAP_SOURCE_TYPE_TILE) return wd->src_tile_names;
8048 else if (type == ELM_MAP_SOURCE_TYPE_ROUTE) return wd->src_route_names;
8049 else if (type == ELM_MAP_SOURCE_TYPE_NAME) return wd->src_tile_names;
8050 else ERR("Not supported map source type: %d", type);
8058 EAPI Elm_Map_Route *
8059 elm_map_route_add(Evas_Object *obj, Elm_Map_Route_Type type, Elm_Map_Route_Method method, double flon, double flat, double tlon, double tlat, Elm_Map_Route_Cb route_cb, void *data)
8061 #ifdef HAVE_ELEMENTARY_ECORE_CON
8062 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
8063 Widget_Data *wd = elm_widget_data_get(obj);
8064 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
8065 EINA_SAFETY_ON_NULL_RETURN_VAL(wd->src_route, NULL);
8069 char fname[PATH_MAX];
8071 if (!ecore_file_exists(CACHE_ROUTE_ROOT))
8072 ecore_file_mkpath(CACHE_ROUTE_ROOT);
8074 if (type == ELM_MAP_ROUTE_TYPE_MOTOCAR)
8075 type_name = strdup(ROUTE_TYPE_MOTORCAR);
8076 else if (type == ELM_MAP_ROUTE_TYPE_BICYCLE)
8077 type_name = strdup(ROUTE_TYPE_BICYCLE);
8078 else if (type == ELM_MAP_ROUTE_TYPE_FOOT)
8079 type_name = strdup(ROUTE_TYPE_FOOT);
8080 else type_name = NULL;
8082 url = wd->src_route->url_cb(obj, type_name, method, flon, flat, tlon, tlat);
8085 ERR("Route URL is NULL");
8086 if (type_name) free(type_name);
8089 if (type_name) free(type_name);
8091 Elm_Map_Route *route = ELM_NEW(Elm_Map_Route);
8093 snprintf(fname, sizeof(fname), CACHE_ROUTE_ROOT"/%d", rand());
8094 route->fname = strdup(fname);
8096 route->method = method;
8101 route->cb = route_cb;
8104 if (!ecore_file_download_full(url, route->fname, _route_cb, NULL, route,
8105 &(route->job), wd->ua) || !(route->job))
8107 ERR("Can't request Route from %s to %s", url, route->fname);
8112 INF("Route requested from %s to %s", url, route->fname);
8115 wd->routes = eina_list_append(wd->routes, route);
8116 evas_object_smart_callback_call(wd->obj, SIG_ROUTE_LOAD, route);
8117 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
8118 "elm,state,busy,start", "elm");
8136 elm_map_route_del(Elm_Map_Route *route)
8138 #ifdef HAVE_ELEMENTARY_ECORE_CON
8139 EINA_SAFETY_ON_NULL_RETURN(route);
8140 EINA_SAFETY_ON_NULL_RETURN(route->wd);
8141 ELM_CHECK_WIDTYPE(route->wd->obj, widtype);
8146 if (route->job) ecore_file_download_abort(route->job);
8148 EINA_LIST_FREE(route->waypoint, w)
8150 if (w->point) eina_stringshare_del(w->point);
8154 EINA_LIST_FREE(route->nodes, n)
8156 if (n->pos.address) eina_stringshare_del(n->pos.address);
8162 ecore_file_remove(route->fname);
8166 route->wd->routes = eina_list_remove(route->wd->routes, route);
8174 elm_map_route_distance_get(const Elm_Map_Route *route)
8176 #ifdef HAVE_ELEMENTARY_ECORE_CON
8177 EINA_SAFETY_ON_NULL_RETURN_VAL(route, 0.0);
8178 return route->info.distance;
8186 elm_map_route_node_get(const Elm_Map_Route *route)
8188 #ifdef HAVE_ELEMENTARY_ECORE_CON
8189 EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
8190 return route->info.nodes;
8198 elm_map_route_waypoint_get(const Elm_Map_Route *route)
8200 #ifdef HAVE_ELEMENTARY_ECORE_CON
8201 EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
8202 return route->info.waypoints;
8210 elm_map_name_add(const Evas_Object *obj, const char *address, double lon, double lat, Elm_Map_Name_Cb name_cb, void *data)
8212 #ifdef HAVE_ELEMENTARY_ECORE_CON
8213 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
8216 return _name_request(obj, ELM_MAP_NAME_METHOD_SEARCH, address, 0, 0,
8219 return _name_request(obj, ELM_MAP_NAME_METHOD_REVERSE, NULL, lon, lat,
8229 >>>>>>> remotes/origin/upstream
8235 elm_map_paused_set(Evas_Object *obj, Eina_Bool paused)
8237 #ifdef HAVE_ELEMENTARY_ECORE_CON
8238 ELM_CHECK_WIDTYPE(obj, widtype);
8239 Widget_Data *wd = elm_widget_data_get(obj);
8242 if (wd->paused == !!paused) return;
8243 wd->paused = !!paused;
8246 if (wd->zoom_animator)
8248 if (wd->zoom_animator) ecore_animator_del(wd->zoom_animator);
8249 wd->zoom_animator = NULL;
8251 evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
8253 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
8254 "elm,state,busy,stop", "elm");
8258 if (wd->download_num >= 1)
8259 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
8260 "elm,state,busy,start", "elm");
8269 elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused)
8271 #ifdef HAVE_ELEMENTARY_ECORE_CON
8272 ELM_CHECK_WIDTYPE(obj, widtype);
8273 Widget_Data *wd = elm_widget_data_get(obj);
8276 if (wd->paused_markers == !!paused) return;
8277 wd->paused_markers = paused;
8285 elm_map_paused_get(const Evas_Object *obj)
8287 #ifdef HAVE_ELEMENTARY_ECORE_CON
8288 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
8289 Widget_Data *wd = elm_widget_data_get(obj);
8291 if (!wd) return EINA_FALSE;
8300 elm_map_paused_markers_get(const Evas_Object *obj)
8302 #ifdef HAVE_ELEMENTARY_ECORE_CON
8303 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
8304 Widget_Data *wd = elm_widget_data_get(obj);
8306 if (!wd) return EINA_FALSE;
8307 return wd->paused_markers;
8312 elm_map_name_del(Elm_Map_Name *name)
8314 #ifdef HAVE_ELEMENTARY_ECORE_CON
8315 EINA_SAFETY_ON_NULL_RETURN(name);
8316 EINA_SAFETY_ON_NULL_RETURN(name->wd);
8317 ELM_CHECK_WIDTYPE(name->wd->obj, widtype);
8319 if (name->job) ecore_file_download_abort(name->job);
8320 if (name->address) free(name->address);
8323 ecore_file_remove(name->fname);
8327 name->wd->names = eina_list_remove(name->wd->names, name);
8335 elm_map_name_address_get(const Elm_Map_Name *name)
8337 #ifdef HAVE_ELEMENTARY_ECORE_CON
8338 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
8339 EINA_SAFETY_ON_NULL_RETURN_VAL(name->wd, NULL);
8340 ELM_CHECK_WIDTYPE(name->wd->obj, widtype) NULL;
8342 return name->address;
8350 elm_map_name_region_get(const Elm_Map_Name *name, double *lon, double *lat)
8352 #ifdef HAVE_ELEMENTARY_ECORE_CON
8353 EINA_SAFETY_ON_NULL_RETURN(name);
8354 EINA_SAFETY_ON_NULL_RETURN(name->wd);
8355 ELM_CHECK_WIDTYPE(name->wd->obj, widtype);
8357 if (lon) *lon = name->lon;
8358 if (lat) *lat = name->lat;
8366 EAPI Elm_Map_Overlay *
8367 elm_map_overlay_add(Evas_Object *obj, double lon, double lat)
8369 #ifdef HAVE_ELEMENTARY_ECORE_CON
8370 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
8371 Widget_Data *wd = elm_widget_data_get(obj);
8372 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
8374 Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay);
8376 overlay->type = ELM_MAP_OVERLAY_TYPE_DEFAULT;
8377 overlay->ovl = _overlay_default_new(wd, lon, lat, "radio");
8378 _overlay_default_cb_add(overlay->ovl, _overlay_clicked_cb, overlay);
8379 overlay->grp = _overlay_group_new(wd);
8380 wd->overlays = eina_list_append(wd->overlays, overlay);
8382 evas_object_smart_changed(wd->pan_smart);
8389 >>>>>>> remotes/origin/upstream
8395 elm_map_utils_downloading_status_get(const Evas_Object *obj, int *try_num, int *finish_num)
8397 #ifdef HAVE_ELEMENTARY_ECORE_CON
8398 ELM_CHECK_WIDTYPE(obj, widtype);
8399 Widget_Data *wd = elm_widget_data_get(obj);
8404 *try_num = wd->try_num;
8409 *finish_num = wd->finish_num;
8419 elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int size, double *lon, double *lat)
8421 #ifdef HAVE_ELEMENTARY_ECORE_CON
8422 ELM_CHECK_WIDTYPE(obj, widtype);
8423 Widget_Data *wd = elm_widget_data_get(obj);
8426 int zoom = floor(log(size / 256) / log(2));
8427 if ((wd->src) && (wd->src->coord_into_geo))
8429 if (wd->src->coord_into_geo(obj, zoom, x, y, size, lon, lat)) return;
8434 *lon = x / (double)size * 360.0 - 180;
8438 double n = ELM_PI - 2.0 * ELM_PI * y / size;
8439 *lat = 180.0 / ELM_PI * atan(0.5 * (exp(n) - exp(-n)));
8449 elm_map_overlay_del(Elm_Map_Overlay *overlay)
8451 #ifdef HAVE_ELEMENTARY_ECORE_CON
8452 EINA_SAFETY_ON_NULL_RETURN(overlay);
8453 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
8454 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
8456 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
8458 _overlay_default_cb_del(overlay->ovl, _overlay_clicked_cb);
8459 _overlay_default_free(overlay->ovl);
8461 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
8463 _overlay_bubble_cb_del(overlay->ovl);
8464 _overlay_bubble_free(overlay->ovl);
8466 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
8467 _overlay_class_free(overlay->ovl);
8469 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_ROUTE)
8470 _overlay_route_free(overlay->ovl);
8474 _overlay_group_cb_del(overlay->grp);
8475 _overlay_group_free(overlay->grp, overlay);
8478 overlay->wd->overlays = eina_list_remove(overlay->wd->overlays, overlay);
8479 evas_object_smart_changed(overlay->wd->pan_smart);
8487 EAPI Elm_Map_Overlay_Type
8488 elm_map_overlay_type_get(const Elm_Map_Overlay *overlay)
8490 #ifdef HAVE_ELEMENTARY_ECORE_CON
8491 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, ELM_MAP_OVERLAY_TYPE_NONE);
8492 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, ELM_MAP_OVERLAY_TYPE_NONE);
8493 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) ELM_MAP_OVERLAY_TYPE_NONE;
8495 return overlay->type;
8498 return OVERLAY_TYPE_NONE;
8499 >>>>>>> remotes/origin/upstream
8505 elm_map_utils_convert_geo_into_coord(const Evas_Object *obj, double lon, double lat, int size, int *x, int *y)
8507 #ifdef HAVE_ELEMENTARY_ECORE_CON
8508 ELM_CHECK_WIDTYPE(obj, widtype);
8509 Widget_Data *wd = elm_widget_data_get(obj);
8512 int zoom = floor(log(size / 256) / log(2));
8513 if ((wd->src) && (wd->src->geo_into_coord))
8515 if (wd->src->geo_into_coord(obj, zoom, lon, lat, size, x, y)) return;
8519 *x = floor((lon + 180.0) / 360.0 * size);
8521 *y = floor((1.0 - log( tan(lat * ELM_PI / 180.0) + 1.0 / cos(lat * ELM_PI / 180.0)) / ELM_PI) / 2.0 * size);
8533 elm_map_utils_convert_coord_into_name(const Evas_Object *obj, double lon, double lat)
8535 #ifdef HAVE_ELEMENTARY_ECORE_CON
8536 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
8537 return _utils_convert_name(obj, ELM_MAP_NAME_METHOD_REVERSE, NULL, lon, lat);
8543 elm_map_overlay_data_set(Elm_Map_Overlay *overlay, void *data)
8545 #ifdef HAVE_ELEMENTARY_ECORE_CON
8546 EINA_SAFETY_ON_NULL_RETURN(overlay);
8547 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
8548 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
8550 overlay->data = data;
8558 elm_map_overlay_data_get(const Elm_Map_Overlay *overlay)
8560 #ifdef HAVE_ELEMENTARY_ECORE_CON
8561 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL);
8562 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL);
8563 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL;
8565 return overlay->data;
8568 >>>>>>> remotes/origin/upstream
8575 elm_map_utils_convert_name_into_coord(const Evas_Object *obj, char *address)
8577 #ifdef HAVE_ELEMENTARY_ECORE_CON
8578 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
8579 if (!address) return NULL;
8580 return _utils_convert_name(obj, ELM_MAP_NAME_METHOD_SEARCH, address, 0.0, 0.0);
8588 EINA_DEPRECATED EAPI void
8589 elm_map_utils_rotate_coord(const Evas_Object *obj, const Evas_Coord x, const Evas_Coord y, const Evas_Coord cx, const Evas_Coord cy, const double degree, Evas_Coord *xx, Evas_Coord *yy)
8591 #ifdef HAVE_ELEMENTARY_ECORE_CON
8592 ELM_CHECK_WIDTYPE(obj, widtype);
8593 _coord_rotate(x, y, cx, cy, degree, xx, yy);
8604 elm_map_overlay_hide_set(Elm_Map_Overlay *overlay, Eina_Bool hide)
8606 #ifdef HAVE_ELEMENTARY_ECORE_CON
8607 EINA_SAFETY_ON_NULL_RETURN(overlay);
8608 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
8609 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
8611 if (overlay->hide == !!hide) return;
8612 overlay->hide = hide;
8614 evas_object_smart_changed(overlay->wd->pan_smart);
8622 elm_map_overlay_hide_get(const Elm_Map_Overlay *overlay)
8624 #ifdef HAVE_ELEMENTARY_ECORE_CON
8625 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, EINA_FALSE);
8626 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, EINA_FALSE);
8627 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) EINA_FALSE;
8629 return overlay->hide;
8633 >>>>>>> remotes/origin/upstream
8639 elm_map_canvas_to_geo_convert(const Evas_Object *obj, const Evas_Coord x, const Evas_Coord y, double *lon, double *lat)
8641 #ifdef HAVE_ELEMENTARY_ECORE_CON
8642 ELM_CHECK_WIDTYPE(obj, widtype);
8643 Widget_Data *wd = elm_widget_data_get(obj);
8644 EINA_SAFETY_ON_NULL_RETURN(lon);
8645 EINA_SAFETY_ON_NULL_RETURN(lat);
8646 EINA_SAFETY_ON_NULL_RETURN(wd);
8648 Evas_Coord xx, yy, w, h, mw, tx, ty, cx, cy;
8651 _region_get(wd, &xx, &yy, &cx, &cy, &w, &h);
8652 mw = wd->size.w * wd->pinch.level;
8664 elm_map_rotate_get(obj, &d, NULL, NULL);
8665 _coord_rotate(xx, yy, cx, cy, -d, &tx, &ty);
8666 elm_map_utils_convert_coord_into_geo(obj, tx, ty, mw, lon, lat);
8676 EAPI Elm_Map_Marker *
8677 elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, Elm_Map_Group_Class *clas_group, void *data)
8679 #ifdef HAVE_ELEMENTARY_ECORE_CON
8680 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
8681 Widget_Data *wd = elm_widget_data_get(obj);
8684 Marker_Group *group;
8692 if (!wd) return NULL;
8693 EINA_SAFETY_ON_NULL_RETURN_VAL(clas_group, NULL);
8694 EINA_SAFETY_ON_NULL_RETURN_VAL(clas, NULL);
8696 Elm_Map_Marker *marker = ELM_NEW(Elm_Map_Marker);
8699 marker->clas = clas;
8700 marker->clas_group = clas_group;
8701 marker->longitude = lon;
8702 marker->latitude = lat;
8703 marker->data = data;
8704 marker->x = calloc(wd->zoom_max + 1, sizeof(Evas_Coord));
8705 marker->y = calloc(wd->zoom_max + 1, sizeof(Evas_Coord));
8706 marker->groups = calloc(wd->zoom_max + 1, sizeof(Marker_Group*));
8708 tabi[1] = tabi[4] = tabi[6] = -1;
8709 tabi[2] = tabi[0] = tabi[7] = 0;
8710 tabi[3] = tabi[5] = tabi[8] = 1;
8712 tabj[1] = tabj[2] = tabj[3] = -1;
8713 tabj[4] = tabj[0] = tabj[5] = 0;
8714 tabj[6] = tabj[7] = tabj[8] = 1;
8716 if (!clas_group->priv.set)
8719 if (marker->clas_group && marker->clas_group->style)
8720 style = marker->clas_group->style;
8722 o = edje_object_add(evas_object_evas_get(obj));
8723 _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
8724 s = edje_object_data_get(o, "size_w");
8725 if (s) clas_group->priv.edje_w = atoi(s);
8726 else clas_group->priv.edje_w = 0;
8727 s = edje_object_data_get(o, "size_h");
8728 if (s) clas_group->priv.edje_h = atoi(s);
8729 else clas_group->priv.edje_h = 0;
8730 s = edje_object_data_get(o, "size_max_w");
8731 if (s) clas_group->priv.edje_max_w = atoi(s);
8732 else clas_group->priv.edje_max_w = 0;
8733 s = edje_object_data_get(o, "size_max_h");
8734 if (s) clas_group->priv.edje_max_h = atoi(s);
8735 else clas_group->priv.edje_max_h = 0;
8738 clas_group->priv.set = EINA_TRUE;
8741 if (!clas->priv.set)
8744 if (marker->clas && marker->clas->style)
8745 style = marker->clas->style;
8747 o = edje_object_add(evas_object_evas_get(obj));
8748 _elm_theme_object_set(obj, o, "map/marker", style, elm_widget_style_get(obj));
8749 s = edje_object_data_get(o, "size_w");
8750 if (s) clas->priv.edje_w = atoi(s);
8751 else clas->priv.edje_w = 0;
8752 s = edje_object_data_get(o, "size_h");
8753 if (s) clas->priv.edje_h = atoi(s);
8754 else clas->priv.edje_h = 0;
8757 clas->priv.set = EINA_TRUE;
8760 for (i = clas_group->zoom_displayed; i <= wd->zoom_max; i++)
8762 elm_map_utils_convert_geo_into_coord(obj, lon, lat, pow(2.0, i)*wd->tsize,
8763 &(marker->x[i]), &(marker->y[i]));
8765 //search in the matrixsparse the region where the marker will be
8766 mpi = marker->x[i] / wd->tsize;
8767 mpj = marker->y[i] / wd->tsize;
8769 if (!wd->markers[i])
8771 int size = pow(2.0, i);
8772 wd->markers[i] = eina_matrixsparse_new(size, size, NULL, NULL);
8776 if (i <= clas_group->zoom_grouped)
8778 for (j = 0, group = NULL; j < 9 && !group; j++)
8780 EINA_LIST_FOREACH(eina_matrixsparse_data_idx_get(wd->markers[i], mpj + tabj[j], mpi + tabi[j]),
8783 if (group->clas == marker->clas_group
8784 && ELM_RECTS_INTERSECT(marker->x[i]-clas->priv.edje_w/4,
8785 marker->y[i]-clas->priv.edje_h/4, clas->priv.edje_w, clas->priv.edje_h,
8786 group->x-group->w/4, group->y-group->h/4, group->w, group->h))
8788 group->markers = eina_list_append(group->markers, marker);
8789 group->update_nbelems = EINA_TRUE;
8790 group->update_resize = EINA_TRUE;
8792 group->sum_x += marker->x[i];
8793 group->sum_y += marker->y[i];
8794 group->x = group->sum_x / eina_list_count(group->markers);
8795 group->y = group->sum_y / eina_list_count(group->markers);
8797 group->w = group->clas->priv.edje_w + group->clas->priv.edje_w/8.
8798 * eina_list_count(group->markers);
8799 group->h = group->clas->priv.edje_h + group->clas->priv.edje_h/8.
8800 * eina_list_count(group->markers);
8801 if (group->w > group->clas->priv.edje_max_w) group->w = group->clas->priv.edje_max_w;
8802 if (group->h > group->clas->priv.edje_max_h) group->h = group->clas->priv.edje_max_h;
8804 if (group->obj && eina_list_count(group->markers) == 2)
8806 _group_object_free(group);
8807 _group_object_create(group);
8810 _group_bubble_content_update(group);
8819 group = calloc(1, sizeof(Marker_Group));
8821 group->sum_x = marker->x[i];
8822 group->sum_y = marker->y[i];
8823 group->x = marker->x[i];
8824 group->y = marker->y[i];
8825 group->w = clas_group->priv.edje_w;
8826 group->h = clas_group->priv.edje_h;
8827 group->clas = clas_group;
8829 group->markers = eina_list_append(group->markers, marker);
8830 group->update_nbelems = EINA_TRUE;
8831 group->update_resize = EINA_TRUE;
8833 eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
8837 l = eina_list_append(NULL, group);
8838 eina_matrixsparse_data_idx_set(wd->markers[i], mpj, mpi, l);
8839 eina_matrixsparse_cell_idx_get(wd->markers[i], mpj, mpi, &(group->cell));
8843 l = eina_matrixsparse_cell_data_get(group->cell);
8844 l = eina_list_append(l, group);
8845 eina_matrixsparse_cell_data_set(group->cell, l);
8848 marker->groups[i] = group;
8854 Evas_Coord ox, oy, ow, oh;
8855 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
8856 g = _get_current_grid(wd);
8857 marker_place(obj, g, wd->pan_x, wd->pan_y, ox, oy, ow, oh);
8870 elm_map_overlay_displayed_zoom_min_set(Elm_Map_Overlay *overlay, int zoom)
8872 #ifdef HAVE_ELEMENTARY_ECORE_CON
8873 EINA_SAFETY_ON_NULL_RETURN(overlay);
8874 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
8875 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
8877 overlay->zoom_min = zoom;
8878 evas_object_smart_changed(overlay->wd->pan_smart);
8886 elm_map_overlay_displayed_zoom_min_get(const Elm_Map_Overlay *overlay)
8888 #ifdef HAVE_ELEMENTARY_ECORE_CON
8889 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, 0);
8890 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, 0);
8891 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) 0;
8893 return overlay->zoom_min;
8901 elm_map_overlay_paused_set(Elm_Map_Overlay *overlay, Eina_Bool paused)
8903 #ifdef HAVE_ELEMENTARY_ECORE_CON
8904 EINA_SAFETY_ON_NULL_RETURN(overlay);
8905 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
8906 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
8908 if (overlay->paused == !!paused) return;
8909 overlay->paused = paused;
8911 evas_object_smart_changed(overlay->wd->pan_smart);
8919 elm_map_overlay_paused_get(const Elm_Map_Overlay *overlay)
8921 #ifdef HAVE_ELEMENTARY_ECORE_CON
8922 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, EINA_FALSE);
8923 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, EINA_FALSE);
8924 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) EINA_FALSE;
8926 return overlay->paused;
8934 elm_map_overlay_show(Elm_Map_Overlay *overlay)
8936 #ifdef HAVE_ELEMENTARY_ECORE_CON
8937 EINA_SAFETY_ON_NULL_RETURN(overlay);
8938 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
8939 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
8941 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
8943 Overlay_Default *ovl = overlay->ovl;
8944 elm_map_region_show(overlay->wd->obj, ovl->lon, ovl->lat);
8946 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
8948 Overlay_Bubble *ovl = overlay->ovl;
8949 elm_map_region_show(overlay->wd->obj, ovl->lon, ovl->lat);
8951 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
8953 Overlay_Class *ovl = overlay->ovl;
8954 double lon, lat, max_lo, min_lo, max_la, min_la;
8955 _region_max_min_get(ovl->members, &max_lo, &min_lo, &max_la, &min_la);
8956 lon = (max_lo + min_lo) / 2;
8957 lat = (max_la + min_la) / 2;
8958 elm_map_region_show(overlay->wd->obj, lon, lat);
8960 else ERR("Not supported overlay type: %d", overlay->type);
8962 evas_object_smart_changed(overlay->wd->pan_smart);
8969 elm_map_overlays_show(Eina_List *overlays)
8971 #ifdef HAVE_ELEMENTARY_ECORE_CON
8972 EINA_SAFETY_ON_NULL_RETURN(overlays);
8973 EINA_SAFETY_ON_FALSE_RETURN(eina_list_count(overlays));
8975 Elm_Map_Overlay *overlay;
8976 overlay = eina_list_data_get(overlays);
8978 Delayed_Data *data = ELM_NEW(Delayed_Data);
8979 data->func = _overlays_show;
8980 data->wd = overlay->wd;
8981 data->overlays = eina_list_clone(overlays);
8982 data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
8983 evas_object_smart_changed(data->wd->pan_smart);
8990 elm_map_overlay_region_set(Elm_Map_Overlay *overlay, double lon, double lat)
8992 #ifdef HAVE_ELEMENTARY_ECORE_CON
8993 EINA_SAFETY_ON_NULL_RETURN(overlay);
8994 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
8995 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
8997 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
8999 Overlay_Default *ovl = overlay->ovl;
9003 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
9005 Overlay_Bubble *ovl = overlay->ovl;
9009 else ERR("Not supported overlay type: %d", overlay->type);
9011 evas_object_smart_changed(overlay->wd->pan_smart);
9016 >>>>>>> remotes/origin/upstream
9022 elm_map_marker_remove(Elm_Map_Marker *marker)
9024 #ifdef HAVE_ELEMENTARY_ECORE_CON
9029 EINA_SAFETY_ON_NULL_RETURN(marker);
9032 for (i = marker->clas_group->zoom_displayed; i <= wd->zoom_max; i++)
9034 marker->groups[i]->markers = eina_list_remove(marker->groups[i]->markers, marker);
9035 if (!eina_list_count(marker->groups[i]->markers))
9037 groups = eina_matrixsparse_cell_data_get(marker->groups[i]->cell);
9038 groups = eina_list_remove(groups, marker->groups[i]);
9039 eina_matrixsparse_cell_data_set(marker->groups[i]->cell, groups);
9041 _group_object_free(marker->groups[i]);
9042 _group_bubble_free(marker->groups[i]);
9043 free(marker->groups[i]);
9047 marker->groups[i]->sum_x -= marker->x[i];
9048 marker->groups[i]->sum_y -= marker->y[i];
9050 marker->groups[i]->x = marker->groups[i]->sum_x / eina_list_count(marker->groups[i]->markers);
9051 marker->groups[i]->y = marker->groups[i]->sum_y / eina_list_count(marker->groups[i]->markers);
9053 marker->groups[i]->w = marker->groups[i]->clas->priv.edje_w
9054 + marker->groups[i]->clas->priv.edje_w/8. * eina_list_count(marker->groups[i]->markers);
9055 marker->groups[i]->h = marker->groups[i]->clas->priv.edje_h
9056 + marker->groups[i]->clas->priv.edje_h/8. * eina_list_count(marker->groups[i]->markers);
9057 if (marker->groups[i]->w > marker->groups[i]->clas->priv.edje_max_w)
9058 marker->groups[i]->w = marker->groups[i]->clas->priv.edje_max_w;
9059 if (marker->groups[i]->h > marker->groups[i]->clas->priv.edje_max_h)
9060 marker->groups[i]->h = marker->groups[i]->clas->priv.edje_max_h;
9062 if ((marker->groups[i]->obj) && (eina_list_count(marker->groups[i]->markers) == 1))
9064 _group_object_free(marker->groups[i]);
9065 _group_object_create(marker->groups[i]);
9070 if ((marker->content) && (marker->clas->func.del))
9071 marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
9072 else if (marker->content)
9073 evas_object_del(marker->content);
9075 if (marker->x) free(marker->x);
9076 if (marker->y) free(marker->y);
9077 if (marker->groups) free(marker->groups);
9084 Evas_Coord ox, oy, ow, oh;
9085 evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh);
9086 g = _get_current_grid(wd);
9087 marker_place(wd->obj, g, wd->pan_x, wd->pan_y, ox, oy, ow, oh);
9092 elm_map_overlay_region_get(const Elm_Map_Overlay *overlay, double *lon, double *lat)
9094 #ifdef HAVE_ELEMENTARY_ECORE_CON
9095 EINA_SAFETY_ON_NULL_RETURN(overlay);
9096 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
9097 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
9099 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
9101 const Overlay_Default *ovl = overlay->ovl;
9102 if (lon) *lon = ovl->lon;
9103 if (lat) *lat = ovl->lat;
9105 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_BUBBLE)
9107 const Overlay_Bubble *ovl = overlay->ovl;
9108 if (lon) *lon = ovl->lon;
9109 if (lat) *lat = ovl->lat;
9111 else ERR("Not supported overlay type: %d", overlay->type);
9116 >>>>>>> remotes/origin/upstream
9122 elm_map_marker_region_get(const Elm_Map_Marker *marker, double *lon, double *lat)
9124 #ifdef HAVE_ELEMENTARY_ECORE_CON
9125 EINA_SAFETY_ON_NULL_RETURN(marker);
9126 if (lon) *lon = marker->longitude;
9127 if (lat) *lat = marker->latitude;
9136 elm_map_marker_bring_in(Elm_Map_Marker *marker)
9138 #ifdef HAVE_ELEMENTARY_ECORE_CON
9139 EINA_SAFETY_ON_NULL_RETURN(marker);
9140 elm_map_geo_region_bring_in(marker->wd->obj, marker->longitude, marker->latitude);
9144 elm_map_overlay_icon_set(Elm_Map_Overlay *overlay, Evas_Object *icon)
9146 #ifdef HAVE_ELEMENTARY_ECORE_CON
9147 EINA_SAFETY_ON_NULL_RETURN(overlay);
9148 EINA_SAFETY_ON_NULL_RETURN(icon);
9149 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
9150 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
9152 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
9153 _overlay_default_update(overlay->wd, overlay->ovl, NULL, icon,
9155 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
9156 _overlay_class_update(overlay->wd, overlay->ovl, NULL, icon);
9157 else ERR("Not supported overlay type: %d", overlay->type);
9159 evas_object_smart_changed(overlay->wd->pan_smart);
9166 EAPI const Evas_Object *
9167 elm_map_overlay_icon_get(const Elm_Map_Overlay *overlay)
9169 #ifdef HAVE_ELEMENTARY_ECORE_CON
9170 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL);
9171 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL);
9172 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL;
9174 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
9176 const Overlay_Default *ovl = overlay->ovl;
9177 return elm_object_part_content_get(ovl->layout, "elm.icon");
9179 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
9181 const Overlay_Class *ovl = overlay->ovl;
9186 ERR("Not supported overlay type: %d", overlay->type);
9192 >>>>>>> remotes/origin/upstream
9198 elm_map_marker_show(Elm_Map_Marker *marker)
9200 #ifdef HAVE_ELEMENTARY_ECORE_CON
9201 EINA_SAFETY_ON_NULL_RETURN(marker);
9202 elm_map_geo_region_show(marker->wd->obj, marker->longitude, marker->latitude);
9206 elm_map_overlay_content_set(Elm_Map_Overlay *overlay, Evas_Object *obj)
9208 #ifdef HAVE_ELEMENTARY_ECORE_CON
9209 EINA_SAFETY_ON_NULL_RETURN(overlay);
9210 EINA_SAFETY_ON_NULL_RETURN(obj);
9211 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
9212 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
9214 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
9215 _overlay_default_update(overlay->wd, overlay->ovl, obj, NULL, NULL,
9217 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
9218 _overlay_class_update(overlay->wd, overlay->ovl, obj, NULL);
9219 else ERR("Not supported overlay type: %d", overlay->type);
9221 evas_object_smart_changed(overlay->wd->pan_smart);
9228 EAPI const Evas_Object *
9229 elm_map_overlay_content_get(const Elm_Map_Overlay *overlay)
9231 #ifdef HAVE_ELEMENTARY_ECORE_CON
9232 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay, NULL);
9233 EINA_SAFETY_ON_NULL_RETURN_VAL(overlay->wd, NULL);
9234 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype) NULL;
9236 if (overlay->type == ELM_MAP_OVERLAY_TYPE_DEFAULT)
9238 const Overlay_Default *ovl = overlay->ovl;
9239 return elm_object_part_content_get(ovl->layout, "elm.icon");
9241 else if (overlay->type == ELM_MAP_OVERLAY_TYPE_CLASS)
9243 const Overlay_Class *ovl = overlay->ovl;
9248 ERR("Not supported overlay type: %d", overlay->type);
9254 >>>>>>> remotes/origin/upstream
9260 elm_map_markers_list_show(Eina_List *markers)
9262 #ifdef HAVE_ELEMENTARY_ECORE_CON
9266 Elm_Map_Marker *marker, *m_max_lon = NULL, *m_max_lat = NULL, *m_min_lon = NULL, *m_min_lat = NULL;
9267 Evas_Coord rw, rh, xc, yc;
9270 EINA_SAFETY_ON_NULL_RETURN(markers);
9271 EINA_LIST_FOREACH(markers, l, marker)
9275 if ((!m_min_lon) || (marker->longitude < m_min_lon->longitude))
9278 if ((!m_max_lon) || (marker->longitude > m_max_lon->longitude))
9281 if ((!m_min_lat) || (marker->latitude > m_min_lat->latitude))
9284 if ((!m_max_lat) || (marker->latitude < m_max_lat->latitude))
9288 lon = (m_max_lon->longitude - m_min_lon->longitude) / 2. + m_min_lon->longitude;
9289 lat = (m_max_lat->latitude - m_min_lat->latitude) / 2. + m_min_lat->latitude;
9291 elm_smart_scroller_child_viewport_size_get(wd->scr, &rw, &rh);
9292 for (zoom = wd->src->zoom_max; zoom > wd->src->zoom_min; zoom--)
9294 Evas_Coord size = pow(2.0, zoom)*wd->tsize;
9295 elm_map_utils_convert_geo_into_coord(wd->obj, lon, lat, size, &xc, &yc);
9297 if ((m_min_lon->x[zoom] - wd->marker_max_w >= xc-rw/2)
9298 && (m_min_lat->y[zoom] - wd->marker_max_h >= yc-rh/2)
9299 && (m_max_lon->x[zoom] + wd->marker_max_w <= xc+rw/2)
9300 && (m_max_lat->y[zoom] + wd->marker_max_h <= yc+rh/2))
9304 elm_map_geo_region_show(wd->obj, lon, lat);
9305 elm_map_zoom_set(wd->obj, zoom);
9309 elm_map_overlay_color_set(Elm_Map_Overlay *overlay, int r, int g , int b, int a)
9311 #ifdef HAVE_ELEMENTARY_ECORE_CON
9312 EINA_SAFETY_ON_NULL_RETURN(overlay);
9313 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
9314 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
9316 if (overlay->type == ELM_MAP_OVERLAY_TYPE_ROUTE)
9318 Overlay_Route *route = overlay->ovl;
9324 else ERR("Not supported overlay type: %d", overlay->type);
9335 elm_map_overlay_color_get(const Elm_Map_Overlay *overlay, int *r, int *g , int *b, int *a)
9337 #ifdef HAVE_ELEMENTARY_ECORE_CON
9338 EINA_SAFETY_ON_NULL_RETURN(overlay);
9339 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
9340 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
9344 if (overlay->type == ELM_MAP_OVERLAY_TYPE_ROUTE)
9346 Overlay_Route *route = overlay->ovl;
9347 rr = route->color.r;
9348 gg = route->color.g;
9349 bb = route->color.b;
9350 aa = route->color.a;
9354 ERR("Not supported overlay type: %d", overlay->type);
9367 >>>>>>> remotes/origin/upstream
9373 elm_map_max_marker_per_group_set(Evas_Object *obj, int max)
9375 #ifdef HAVE_ELEMENTARY_ECORE_CON
9376 ELM_CHECK_WIDTYPE(obj, widtype);
9377 Widget_Data *wd = elm_widget_data_get(obj);
9380 wd->markers_max_num = max;
9388 elm_map_marker_object_get(const Elm_Map_Marker *marker)
9390 #ifdef HAVE_ELEMENTARY_ECORE_CON
9391 EINA_SAFETY_ON_NULL_RETURN_VAL(marker, NULL);
9392 return marker->content;
9396 elm_map_overlay_get_cb_set(Elm_Map_Overlay *overlay, Elm_Map_Overlay_Get_Cb get_cb, void *data)
9398 #ifdef HAVE_ELEMENTARY_ECORE_CON
9399 EINA_SAFETY_ON_NULL_RETURN(overlay);
9400 EINA_SAFETY_ON_NULL_RETURN(overlay->wd);
9401 ELM_CHECK_WIDTYPE(overlay->wd->obj, widtype);
9403 overlay->cb = get_cb;
9404 overlay->cb_data = data;
9412 EAPI Elm_Map_Overlay *
9413 elm_map_overlay_class_add(Evas_Object *obj)
9415 #ifdef HAVE_ELEMENTARY_ECORE_CON
9416 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
9417 Widget_Data *wd = elm_widget_data_get(obj);
9418 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
9420 Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay);
9422 overlay->type = ELM_MAP_OVERLAY_TYPE_CLASS;
9423 overlay->ovl = _overlay_class_new(wd, overlay);
9424 overlay->grp = NULL;
9425 wd->overlays = eina_list_append(wd->overlays, overlay);
9427 evas_object_smart_changed(wd->pan_smart);
9431 >>>>>>> remotes/origin/upstream
9438 elm_map_marker_update(Elm_Map_Marker *marker)
9440 #ifdef HAVE_ELEMENTARY_ECORE_CON
9441 EINA_SAFETY_ON_NULL_RETURN(marker);
9442 if (marker->content)
9444 if (marker->clas->func.del)
9445 marker->clas->func.del(marker->wd->obj, marker, marker->data, marker->content);
9447 evas_object_del(marker->content);
9448 marker->content = NULL;
9449 _group_bubble_content_update(marker->groups[marker->wd->zoom]);
9454 elm_map_overlay_class_append(Elm_Map_Overlay *group, Elm_Map_Overlay *overlay)
9456 #ifdef HAVE_ELEMENTARY_ECORE_CON
9457 EINA_SAFETY_ON_NULL_RETURN(group);
9458 EINA_SAFETY_ON_NULL_RETURN(overlay);
9459 EINA_SAFETY_ON_NULL_RETURN(group->wd);
9460 ELM_CHECK_WIDTYPE(group->wd->obj, widtype);
9461 EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS);
9463 if (overlay->type != ELM_MAP_OVERLAY_TYPE_DEFAULT)
9465 ERR("Currently group supports only default overlays");
9469 Overlay_Class *ovl = group->ovl;
9470 if (eina_list_data_find(ovl->members, overlay))
9472 ERR("Already added overlay into group");
9475 ovl->members = eina_list_append(ovl->members, overlay);
9476 overlay->grp->clas = group;
9478 evas_object_smart_changed(group->wd->pan_smart);
9482 >>>>>>> remotes/origin/upstream
9488 elm_map_bubbles_close(Evas_Object *obj)
9490 #ifdef HAVE_ELEMENTARY_ECORE_CON
9491 ELM_CHECK_WIDTYPE(obj, widtype);
9492 Widget_Data *wd = elm_widget_data_get(obj);
9493 Marker_Group *group;
9494 Eina_List *l, *l_next;
9497 EINA_LIST_FOREACH_SAFE(wd->opened_bubbles, l, l_next, group)
9498 _group_bubble_free(group);
9504 EAPI Elm_Map_Group_Class *
9505 elm_map_group_class_new(Evas_Object *obj)
9507 #ifdef HAVE_ELEMENTARY_ECORE_CON
9508 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
9509 Widget_Data *wd = elm_widget_data_get(obj);
9511 if (!wd) return NULL;
9512 Elm_Map_Group_Class *clas = calloc(1, sizeof(Elm_Map_Group_Class));
9513 clas->zoom_grouped = wd->zoom_max;
9514 wd->groups_clas = eina_list_append(wd->groups_clas, clas);
9523 elm_map_group_class_style_set(Elm_Map_Group_Class *clas, const char *style)
9525 #ifdef HAVE_ELEMENTARY_ECORE_CON
9526 EINA_SAFETY_ON_NULL_RETURN(clas);
9527 eina_stringshare_replace(&clas->style, style);
9535 elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, ElmMapGroupIconGetFunc icon_get)
9537 #ifdef HAVE_ELEMENTARY_ECORE_CON
9538 EINA_SAFETY_ON_NULL_RETURN(clas);
9539 clas->func.icon_get = icon_get;
9544 elm_map_overlay_class_remove(Elm_Map_Overlay *group, Elm_Map_Overlay *overlay)
9546 #ifdef HAVE_ELEMENTARY_ECORE_CON
9547 EINA_SAFETY_ON_NULL_RETURN(group);
9548 EINA_SAFETY_ON_NULL_RETURN(overlay);
9549 EINA_SAFETY_ON_NULL_RETURN(group->wd);
9550 ELM_CHECK_WIDTYPE(group->wd->obj, widtype);
9551 EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS);
9553 if (overlay->type != ELM_MAP_OVERLAY_TYPE_DEFAULT)
9555 ERR("Currently group supports only default overlays");
9558 Overlay_Class *ovl = group->ovl;
9559 ovl->members = eina_list_remove(ovl->members, overlay);
9560 overlay->grp->clas = NULL;
9561 _overlay_group_update(group->wd, overlay->grp, NULL);
9563 evas_object_smart_changed(group->wd->pan_smart);
9571 elm_map_overlay_class_zoom_max_set(Elm_Map_Overlay *group, int zoom)
9573 #ifdef HAVE_ELEMENTARY_ECORE_CON
9574 EINA_SAFETY_ON_NULL_RETURN(group);
9575 EINA_SAFETY_ON_NULL_RETURN(group->wd);
9576 ELM_CHECK_WIDTYPE(group->wd->obj, widtype);
9577 EINA_SAFETY_ON_FALSE_RETURN(group->type == ELM_MAP_OVERLAY_TYPE_CLASS);
9579 Overlay_Class *ovl = group->ovl;
9580 if (ovl->zoom_max == !!zoom) return;
9581 ovl->zoom_max = zoom;
9583 evas_object_smart_changed(group->wd->pan_smart);
9591 elm_map_overlay_class_zoom_max_get(const Elm_Map_Overlay *group)
9593 #ifdef HAVE_ELEMENTARY_ECORE_CON
9594 EINA_SAFETY_ON_NULL_RETURN_VAL(group, OVERLAY_CLASS_ZOOM_MAX);
9595 EINA_SAFETY_ON_NULL_RETURN_VAL(group->wd, OVERLAY_CLASS_ZOOM_MAX);
9596 ELM_CHECK_WIDTYPE(group->wd->obj, widtype) OVERLAY_CLASS_ZOOM_MAX;
9597 EINA_SAFETY_ON_FALSE_RETURN_VAL(group->type == ELM_MAP_OVERLAY_TYPE_CLASS, OVERLAY_CLASS_ZOOM_MAX);
9599 const Overlay_Class *ovl = group->ovl;
9600 return ovl->zoom_max;
9603 return OVERLAY_CLASS_ZOOM_MAX;
9607 EAPI Elm_Map_Overlay *
9608 elm_map_overlay_bubble_add(Evas_Object *obj)
9610 #ifdef HAVE_ELEMENTARY_ECORE_CON
9611 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
9612 Widget_Data *wd = elm_widget_data_get(obj);
9613 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
9615 Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay);
9617 overlay->type = ELM_MAP_OVERLAY_TYPE_BUBBLE;
9618 overlay->ovl = _overlay_bubble_new(wd);
9619 _overlay_bubble_cb_add(overlay->ovl, overlay);
9620 overlay->grp = _overlay_group_new(wd);
9621 wd->overlays = eina_list_append(wd->overlays, overlay);
9623 evas_object_smart_changed(wd->pan_smart);
9628 >>>>>>> remotes/origin/upstream
9634 elm_map_group_class_data_set(Elm_Map_Group_Class *clas, void *data)
9636 #ifdef HAVE_ELEMENTARY_ECORE_CON
9637 EINA_SAFETY_ON_NULL_RETURN(clas);
9643 elm_map_overlay_bubble_follow(Elm_Map_Overlay *bubble, Elm_Map_Overlay *parent)
9645 #ifdef HAVE_ELEMENTARY_ECORE_CON
9646 EINA_SAFETY_ON_NULL_RETURN(bubble);
9647 EINA_SAFETY_ON_NULL_RETURN(parent);
9648 ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype);
9649 EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE);
9651 Overlay_Bubble *ovl = bubble->ovl;
9652 Evas_Object *pobj = _overlay_obj_get(parent);
9657 evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_HIDE,
9658 _overlay_bubble_hide_cb, ovl);
9659 evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_SHOW,
9660 _overlay_bubble_chase_cb, ovl);
9661 evas_object_event_callback_del_full(ovl->pobj, EVAS_CALLBACK_MOVE,
9662 _overlay_bubble_chase_cb, ovl);
9666 evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_HIDE,
9667 _overlay_bubble_hide_cb, ovl);
9668 evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_SHOW,
9669 _overlay_bubble_chase_cb, ovl);
9670 evas_object_event_callback_add(ovl->pobj, EVAS_CALLBACK_MOVE,
9671 _overlay_bubble_chase_cb, ovl);
9673 _overlay_bubble_chase(ovl);
9674 evas_object_smart_changed(bubble->wd->pan_smart);
9678 >>>>>>> remotes/origin/upstream
9684 elm_map_group_class_zoom_displayed_set(Elm_Map_Group_Class *clas, int zoom)
9686 #ifdef HAVE_ELEMENTARY_ECORE_CON
9687 EINA_SAFETY_ON_NULL_RETURN(clas);
9688 clas->zoom_displayed = zoom;
9693 elm_map_overlay_bubble_content_append(Elm_Map_Overlay *bubble, Evas_Object *content)
9695 #ifdef HAVE_ELEMENTARY_ECORE_CON
9696 EINA_SAFETY_ON_NULL_RETURN(bubble);
9697 EINA_SAFETY_ON_NULL_RETURN(content);
9698 ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype);
9699 EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE);
9701 Overlay_Bubble *bb = bubble->ovl;
9702 elm_box_pack_end(bb->bx, content);
9704 evas_object_smart_changed(bubble->wd->pan_smart);
9708 >>>>>>> remotes/origin/upstream
9714 elm_map_group_class_zoom_grouped_set(Elm_Map_Group_Class *clas, int zoom)
9716 #ifdef HAVE_ELEMENTARY_ECORE_CON
9717 EINA_SAFETY_ON_NULL_RETURN(clas);
9718 clas->zoom_grouped = zoom;
9726 elm_map_group_class_hide_set(Evas_Object *obj, Elm_Map_Group_Class *clas, Eina_Bool hide)
9728 #ifdef HAVE_ELEMENTARY_ECORE_CON
9729 ELM_CHECK_WIDTYPE(obj, widtype);
9730 Widget_Data *wd = elm_widget_data_get(obj);
9733 EINA_SAFETY_ON_NULL_RETURN(clas);
9734 if (clas->hide == hide) return;
9739 Evas_Coord ox, oy, ow, oh;
9740 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
9741 g = _get_current_grid(wd);
9742 marker_place(obj, g, wd->pan_x, wd->pan_y, ox, oy, ow, oh);
9751 EAPI Elm_Map_Marker_Class *
9752 elm_map_marker_class_new(Evas_Object *obj)
9754 #ifdef HAVE_ELEMENTARY_ECORE_CON
9755 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
9756 Widget_Data *wd = elm_widget_data_get(obj);
9758 if (!wd) return NULL;
9759 Elm_Map_Marker_Class *clas = calloc(1, sizeof(Elm_Map_Marker_Class));
9760 wd->markers_clas = eina_list_append(wd->markers_clas, clas);
9765 elm_map_overlay_bubble_content_clear(Elm_Map_Overlay *bubble)
9767 #ifdef HAVE_ELEMENTARY_ECORE_CON
9768 EINA_SAFETY_ON_NULL_RETURN(bubble);
9769 ELM_CHECK_WIDTYPE(bubble->wd->obj, widtype);
9770 EINA_SAFETY_ON_FALSE_RETURN(bubble->type == ELM_MAP_OVERLAY_TYPE_BUBBLE);
9772 Overlay_Bubble *bb = bubble->ovl;
9773 elm_box_clear(bb->bx);
9775 evas_object_smart_changed(bubble->wd->pan_smart);
9781 EAPI Elm_Map_Overlay *
9782 elm_map_overlay_route_add(Evas_Object *obj, const Elm_Map_Route *route)
9784 #ifdef HAVE_ELEMENTARY_ECORE_CON
9785 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
9786 Widget_Data *wd = elm_widget_data_get(obj);
9787 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
9788 EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
9789 EINA_SAFETY_ON_NULL_RETURN_VAL(route->wd, NULL);
9790 EINA_SAFETY_ON_FALSE_RETURN_VAL(obj == route->wd->obj, NULL);
9792 Elm_Map_Overlay *overlay = ELM_NEW(Elm_Map_Overlay);
9794 overlay->type = ELM_MAP_OVERLAY_TYPE_ROUTE;
9795 overlay->ovl = _overlay_route_new(wd, route);
9796 overlay->grp = _overlay_group_new(wd);
9797 wd->overlays = eina_list_append(wd->overlays, overlay);
9799 evas_object_smart_changed(wd->pan_smart);
9810 elm_map_track_add(Evas_Object *obj, void *emap)
9812 #ifdef HAVE_ELEMENTARY_ECORE_CON
9813 EMap_Route *emapr = emap;
9814 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
9815 Widget_Data *wd = elm_widget_data_get(obj);
9816 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
9818 Evas_Object *route = elm_route_add(obj);
9819 elm_route_emap_set(route, emapr);
9820 wd->track = eina_list_append(wd->track, route);
9826 >>>>>>> remotes/origin/upstream
9833 elm_map_marker_class_style_set(Elm_Map_Marker_Class *clas, const char *style)
9835 #ifdef HAVE_ELEMENTARY_ECORE_CON
9836 EINA_SAFETY_ON_NULL_RETURN(clas);
9837 eina_stringshare_replace(&clas->style, style);
9845 elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerIconGetFunc icon_get)
9847 #ifdef HAVE_ELEMENTARY_ECORE_CON
9848 EINA_SAFETY_ON_NULL_RETURN(clas);
9849 clas->func.icon_get = icon_get;
9857 elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerGetFunc get)
9859 #ifdef HAVE_ELEMENTARY_ECORE_CON
9860 EINA_SAFETY_ON_NULL_RETURN(clas);
9861 clas->func.get = get;
9869 elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, ElmMapMarkerDelFunc del)
9871 #ifdef HAVE_ELEMENTARY_ECORE_CON
9872 EINA_SAFETY_ON_NULL_RETURN(clas);
9873 clas->func.del = del;
9881 elm_map_source_names_get(const Evas_Object *obj)
9883 #ifdef HAVE_ELEMENTARY_ECORE_CON
9884 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
9885 Widget_Data *wd = elm_widget_data_get(obj);
9887 if (!wd) return NULL;
9888 return wd->source_names;
9893 elm_map_track_remove(Evas_Object *obj, Evas_Object *route)
9895 #ifdef HAVE_ELEMENTARY_ECORE_CON
9896 ELM_CHECK_WIDTYPE(obj, widtype) ;
9897 Widget_Data *wd = elm_widget_data_get(obj);
9898 EINA_SAFETY_ON_NULL_RETURN(wd);
9900 wd->track = eina_list_remove(wd->track, route);
9901 evas_object_del(route);
9909 elm_map_track_add(Evas_Object *obj __UNUSED__, void *emap __UNUSED__)
9915 elm_map_track_remove(Evas_Object *obj __UNUSED__, Evas_Object *route __UNUSED__)
9920 /************************* Belows are deprecated APIs *************************/
9922 elm_map_source_zoom_max_set(Evas_Object *obj, int zoom)
9924 elm_map_zoom_max_set(obj, zoom);
9928 elm_map_source_zoom_max_get(const Evas_Object *obj)
9930 return elm_map_zoom_max_get(obj);
9934 elm_map_source_zoom_min_set(Evas_Object *obj, int zoom)
9936 elm_map_zoom_min_set(obj, zoom);
9940 elm_map_source_zoom_min_get(const Evas_Object *obj)
9942 return elm_map_zoom_min_get(obj);
9946 elm_map_utils_convert_coord_into_geo(const Evas_Object *obj, int x, int y, int size, double *lon, double *lat)
9948 #ifdef HAVE_ELEMENTARY_ECORE_CON
9949 ELM_CHECK_WIDTYPE(obj, widtype);
9950 Widget_Data *wd = elm_widget_data_get(obj);
9951 EINA_SAFETY_ON_NULL_RETURN(wd);
9953 _coord_to_region_convert(wd, x, y, size, lon, lat);
9965 elm_map_utils_convert_geo_into_coord(const Evas_Object *obj, double lon, double lat, int size, int *x, int *y)
9967 #ifdef HAVE_ELEMENTARY_ECORE_CON
9968 ELM_CHECK_WIDTYPE(obj, widtype);
9969 Widget_Data *wd = elm_widget_data_get(obj);
9970 EINA_SAFETY_ON_NULL_RETURN(wd);
9972 _region_to_coord_convert(wd, lon, lat, size, x, y);
9980 >>>>>>> remotes/origin/upstream
9986 elm_map_source_name_set(Evas_Object *obj, const char *source_name)
9988 #ifdef HAVE_ELEMENTARY_ECORE_CON
9989 ELM_CHECK_WIDTYPE(obj, widtype);
9990 Widget_Data *wd = elm_widget_data_get(obj);
9998 if (!strcmp(wd->src->name, source_name)) return;
9999 if (!wd->src->url_cb) return;
10002 grid_clear_all(obj);
10003 EINA_LIST_FOREACH(wd->map_sources_tab, l, s)
10005 if (!strcmp(s->name, source_name))
10016 if (wd->src->zoom_max < zoom)
10017 zoom = wd->src->zoom_max;
10018 if (wd->src->zoom_min > zoom)
10019 zoom = wd->src->zoom_min;
10021 grid_create_all(obj);
10022 elm_map_zoom_set(obj, zoom);
10025 (void) source_name;
10030 elm_map_source_name_get(const Evas_Object *obj)
10032 #ifdef HAVE_ELEMENTARY_ECORE_CON
10033 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
10034 Widget_Data *wd = elm_widget_data_get(obj);
10036 if ((!wd) || (!wd->src)) return NULL;
10037 return wd->src->name;
10045 elm_map_route_source_set(Evas_Object *obj, Elm_Map_Route_Sources source)
10047 #ifdef HAVE_ELEMENTARY_ECORE_CON
10048 ELM_CHECK_WIDTYPE(obj, widtype);
10049 Widget_Data *wd = elm_widget_data_get(obj);
10052 wd->route_source = source;
10059 EAPI Elm_Map_Route_Sources
10060 elm_map_route_source_get(const Evas_Object *obj)
10062 #ifdef HAVE_ELEMENTARY_ECORE_CON
10063 ELM_CHECK_WIDTYPE(obj, widtype) ELM_MAP_ROUTE_SOURCE_YOURS;
10064 Widget_Data *wd = elm_widget_data_get(obj);
10066 if (!wd) return ELM_MAP_ROUTE_SOURCE_YOURS;
10067 return wd->route_source;
10070 return ELM_MAP_ROUTE_SOURCE_YOURS;
10072 elm_map_utils_rotate_coord(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord cx, const Evas_Coord cy, double degree, Evas_Coord *xx, Evas_Coord *yy)
10074 #ifdef HAVE_ELEMENTARY_ECORE_CON
10075 ELM_CHECK_WIDTYPE(obj, widtype);
10076 _coord_rotate(x, y, cx, cy, degree, xx, yy);
10089 elm_map_utils_downloading_status_get(const Evas_Object *obj, int *try_num, int *finish_num)
10091 elm_map_tile_load_status_get(obj, try_num, finish_num);
10095 elm_map_geo_region_bring_in(Evas_Object *obj, double lon, double lat)
10097 elm_map_region_bring_in(obj, lon, lat);
10101 elm_map_geo_region_show(Evas_Object *obj, double lon, double lat)
10103 elm_map_region_show(obj, lon, lat);
10107 elm_map_geo_region_get(const Evas_Object *obj, double *lon, double *lat)
10109 elm_map_region_get(obj, lon, lat);
10112 EAPI Elm_Map_Name *
10113 elm_map_utils_convert_coord_into_name(const Evas_Object *obj, double lon, double lat)
10115 return elm_map_name_add(obj, NULL, lon, lat, NULL, NULL);
10118 EAPI Elm_Map_Name *
10119 elm_map_utils_convert_name_into_coord(const Evas_Object *obj, char *address)
10121 return elm_map_name_add(obj, address, 0, 0, NULL, NULL);
10125 elm_map_canvas_to_geo_convert(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, double *lon, double *lat)
10127 elm_map_canvas_to_region_convert(obj, x, y, lon, lat);
10130 EAPI Elm_Map_Marker *
10131 elm_map_marker_add(Evas_Object *obj, double lon, double lat, Elm_Map_Marker_Class *clas, Elm_Map_Group_Class *group_clas, void *data)
10133 #ifdef HAVE_ELEMENTARY_ECORE_CON
10134 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
10135 Widget_Data *wd = elm_widget_data_get(obj);
10137 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
10138 EINA_SAFETY_ON_NULL_RETURN_VAL(clas, NULL);
10140 Elm_Map_Marker *marker = ELM_NEW(Elm_Map_Marker);
10142 marker->clas = clas;
10143 marker->group_clas = group_clas;
10144 marker->longitude = lon;
10145 marker->latitude = lat;
10146 marker->data = data;
10149 _edj_marker_size_get(wd, &marker->w, &marker->h);
10151 marker->obj = elm_layout_add(wd->obj);
10152 evas_object_smart_member_add(marker->obj, wd->pan_smart);
10153 evas_object_stack_above(marker->obj, wd->sep_maps_markers);
10155 edje_object_signal_callback_add(elm_layout_edje_get(marker->obj),
10156 "open", "elm", _marker_bubble_open_cb,
10158 edje_object_signal_callback_add(elm_layout_edje_get(marker->obj),
10159 "bringin", "elm", _marker_bringin_cb,
10162 wd->markers = eina_list_append(wd->markers, marker);
10163 if (marker->group_clas) group_clas->markers = eina_list_append(group_clas->markers,
10165 evas_object_smart_changed(wd->pan_smart);
10175 >>>>>>> remotes/origin/upstream
10181 elm_map_source_zoom_max_set(Evas_Object *obj, int zoom)
10183 #ifdef HAVE_ELEMENTARY_ECORE_CON
10184 ELM_CHECK_WIDTYPE(obj, widtype);
10185 Widget_Data *wd = elm_widget_data_get(obj);
10187 if ((!wd) || (!wd->src)) return;
10188 if ((zoom > wd->zoom_max) || (zoom < wd->zoom_min)) return;
10189 wd->src->zoom_max = zoom;
10197 elm_map_source_zoom_max_get(const Evas_Object *obj)
10199 #ifdef HAVE_ELEMENTARY_ECORE_CON
10200 ELM_CHECK_WIDTYPE(obj, widtype) 18;
10201 Widget_Data *wd = elm_widget_data_get(obj);
10203 if ((!wd) || (!wd->src)) return 18;
10204 return wd->src->zoom_max;
10209 elm_map_marker_remove(Elm_Map_Marker *marker)
10211 _elm_map_marker_remove(marker);
10215 elm_map_marker_region_get(const Elm_Map_Marker *marker, double *lon, double *lat)
10217 #ifdef HAVE_ELEMENTARY_ECORE_CON
10218 EINA_SAFETY_ON_NULL_RETURN(marker);
10219 if (lon) *lon = marker->longitude;
10220 if (lat) *lat = marker->latitude;
10225 >>>>>>> remotes/origin/upstream
10231 elm_map_source_zoom_min_set(Evas_Object *obj, int zoom)
10233 #ifdef HAVE_ELEMENTARY_ECORE_CON
10234 ELM_CHECK_WIDTYPE(obj, widtype);
10235 Widget_Data *wd = elm_widget_data_get(obj);
10237 if ((!wd) || (!wd->src)) return;
10238 if ((zoom > wd->zoom_max) || (zoom < wd->zoom_min)) return;
10239 wd->src->zoom_min = zoom;
10247 elm_map_source_zoom_min_get(const Evas_Object *obj)
10249 #ifdef HAVE_ELEMENTARY_ECORE_CON
10250 ELM_CHECK_WIDTYPE(obj, widtype) 0;
10251 Widget_Data *wd = elm_widget_data_get(obj);
10253 if ((!wd) || (!wd->src)) return 0;
10254 return wd->src->zoom_min;
10259 elm_map_marker_bring_in(Elm_Map_Marker *marker)
10261 #ifdef HAVE_ELEMENTARY_ECORE_CON
10262 EINA_SAFETY_ON_NULL_RETURN(marker);
10263 elm_map_region_bring_in(marker->wd->obj, marker->longitude, marker->latitude);
10270 elm_map_marker_show(Elm_Map_Marker *marker)
10272 #ifdef HAVE_ELEMENTARY_ECORE_CON
10273 EINA_SAFETY_ON_NULL_RETURN(marker);
10274 elm_map_region_show(marker->wd->obj, marker->longitude, marker->latitude);
10277 >>>>>>> remotes/origin/upstream
10283 elm_map_user_agent_set(Evas_Object *obj, const char *user_agent)
10285 #ifdef HAVE_ELEMENTARY_ECORE_CON
10286 ELM_CHECK_WIDTYPE(obj, widtype);
10287 Widget_Data *wd = elm_widget_data_get(obj);
10290 if (!wd->user_agent) wd->user_agent = eina_stringshare_add(user_agent);
10291 else eina_stringshare_replace(&wd->user_agent, user_agent);
10293 if (!wd->ua) wd->ua = eina_hash_string_small_new(NULL);
10294 eina_hash_set(wd->ua, "User-Agent", wd->user_agent);
10302 elm_map_user_agent_get(const Evas_Object *obj)
10304 #ifdef HAVE_ELEMENTARY_ECORE_CON
10305 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
10306 Widget_Data *wd = elm_widget_data_get(obj);
10308 if (!wd) return NULL;
10309 return wd->user_agent;
10316 EAPI Elm_Map_Route *
10317 elm_map_route_add(Evas_Object *obj,
10318 Elm_Map_Route_Type type,
10319 Elm_Map_Route_Method method,
10325 #ifdef HAVE_ELEMENTARY_ECORE_CON
10326 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
10327 Widget_Data *wd = elm_widget_data_get(obj);
10328 char buf[PATH_MAX];
10330 char *type_name = NULL;
10333 if ((!wd) || (!wd->src)) return NULL;
10335 Elm_Map_Route *route = ELM_NEW(Elm_Map_Route);
10336 if (!route) return NULL;
10338 snprintf(buf, sizeof(buf), DEST_ROUTE_XML_FILE);
10346 route->con_url = ecore_con_url_new(NULL);
10347 route->ud.fname = strdup(buf);
10348 INF("xml file : %s", route->ud.fname);
10350 route->ud.fd = fdopen(fd, "w+");
10351 if ((!route->con_url) || (!route->ud.fd))
10353 ecore_con_url_free(route->con_url);
10359 route->color.r = 255;
10360 route->color.g = 0;
10361 route->color.b = 0;
10362 route->color.a = 255;
10363 route->handlers = eina_list_append
10364 (route->handlers, (void *)ecore_event_handler_add
10365 (ECORE_CON_EVENT_URL_COMPLETE, _route_complete_cb, route));
10367 route->inbound = EINA_FALSE;
10368 route->type = type;
10369 route->method = method;
10370 route->flon = flon;
10371 route->flat = flat;
10372 route->tlon = tlon;
10373 route->tlat = tlat;
10377 case ELM_MAP_ROUTE_TYPE_MOTOCAR:
10378 type_name = strdup(ROUTE_TYPE_MOTORCAR);
10380 case ELM_MAP_ROUTE_TYPE_BICYCLE:
10381 type_name = strdup(ROUTE_TYPE_BICYCLE);
10383 case ELM_MAP_ROUTE_TYPE_FOOT:
10384 type_name = strdup(ROUTE_TYPE_FOOT);
10390 source = wd->src->route_url_cb(obj, type_name, method, flon, flat, tlon, tlat);
10391 INF("route url = %s", source);
10393 wd->route = eina_list_append(wd->route, route);
10395 ecore_con_url_url_set(route->con_url, source);
10396 ecore_con_url_fd_set(route->con_url, fileno(route->ud.fd));
10397 ecore_con_url_data_set(route->con_url, route);
10398 ecore_con_url_get(route->con_url);
10399 if (type_name) free(type_name);
10400 if (source) free(source);
10402 edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr),
10403 "elm,state,busy,start", "elm");
10404 evas_object_smart_callback_call(wd->obj, SIG_ROUTE_LOAD, NULL);
10416 elm_map_markers_list_show(Eina_List *markers)
10418 #ifdef HAVE_ELEMENTARY_ECORE_CON
10419 EINA_SAFETY_ON_NULL_RETURN(markers);
10420 EINA_SAFETY_ON_FALSE_RETURN(eina_list_count(markers));
10422 Elm_Map_Marker *marker;
10423 marker = eina_list_data_get(markers);
10425 Delayed_Data *data = ELM_NEW(Delayed_Data);
10426 data->func = _marker_list_show;
10427 data->wd = marker->wd;
10428 data->markers = eina_list_clone(markers);
10429 data->wd->delayed_jobs = eina_list_append(data->wd->delayed_jobs, data);
10430 evas_object_smart_changed(data->wd->pan_smart);
10437 elm_map_paused_markers_set(Evas_Object *obj, Eina_Bool paused)
10439 #ifdef HAVE_ELEMENTARY_ECORE_CON
10440 ELM_CHECK_WIDTYPE(obj, widtype);
10441 Widget_Data *wd = elm_widget_data_get(obj);
10442 EINA_SAFETY_ON_NULL_RETURN(wd);
10444 if (wd->paused_markers == !!paused) return;
10445 wd->paused_markers = paused;
10453 elm_map_paused_markers_get(const Evas_Object *obj)
10455 #ifdef HAVE_ELEMENTARY_ECORE_CON
10456 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
10457 Widget_Data *wd = elm_widget_data_get(obj);
10458 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, EINA_FALSE);
10460 return wd->paused_markers;
10464 >>>>>>> remotes/origin/upstream
10470 elm_map_route_remove(Elm_Map_Route *route)
10472 #ifdef HAVE_ELEMENTARY_ECORE_CON
10473 EINA_SAFETY_ON_NULL_RETURN(route);
10478 Ecore_Event_Handler *h;
10480 EINA_LIST_FREE(route->path, p)
10482 evas_object_del(p);
10485 EINA_LIST_FREE(route->waypoint, w)
10487 if (w->point) eina_stringshare_del(w->point);
10491 EINA_LIST_FREE(route->nodes, n)
10493 if (n->pos.address) eina_stringshare_del(n->pos.address);
10497 EINA_LIST_FREE(route->handlers, h)
10499 ecore_event_handler_del(h);
10502 if (route->ud.fname)
10504 ecore_file_remove(route->ud.fname);
10505 free(route->ud.fname);
10506 route->ud.fname = NULL;
10514 elm_map_route_color_set(Elm_Map_Route *route, int r, int g , int b, int a)
10516 #ifdef HAVE_ELEMENTARY_ECORE_CON
10517 EINA_SAFETY_ON_NULL_RETURN(route);
10518 route->color.r = r;
10519 route->color.g = g;
10520 route->color.b = b;
10521 route->color.a = a;
10529 elm_map_max_marker_per_group_set(Evas_Object *obj, int max)
10531 #ifdef HAVE_ELEMENTARY_ECORE_CON
10532 ELM_CHECK_WIDTYPE(obj, widtype);
10533 Widget_Data *wd = elm_widget_data_get(obj);
10534 EINA_SAFETY_ON_NULL_RETURN(wd);
10536 wd->markers_max_num = max;
10544 elm_map_marker_object_get(const Elm_Map_Marker *marker)
10546 #ifdef HAVE_ELEMENTARY_ECORE_CON
10547 EINA_SAFETY_ON_NULL_RETURN_VAL(marker, NULL);
10548 return marker->content;
10552 >>>>>>> remotes/origin/upstream
10558 elm_map_route_color_get(const Elm_Map_Route *route, int *r, int *g , int *b, int *a)
10560 #ifdef HAVE_ELEMENTARY_ECORE_CON
10561 EINA_SAFETY_ON_NULL_RETURN(route);
10562 if (r) *r = route->color.r;
10563 if (g) *g = route->color.g;
10564 if (b) *b = route->color.b;
10565 if (a) *a = route->color.a;
10576 elm_map_route_distance_get(const Elm_Map_Route *route)
10578 #ifdef HAVE_ELEMENTARY_ECORE_CON
10579 EINA_SAFETY_ON_NULL_RETURN_VAL(route, 0.0);
10580 return route->info.distance;
10588 elm_map_route_node_get(const Elm_Map_Route *route)
10590 #ifdef HAVE_ELEMENTARY_ECORE_CON
10591 EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
10592 return route->info.nodes;
10600 elm_map_route_waypoint_get(const Elm_Map_Route *route)
10602 #ifdef HAVE_ELEMENTARY_ECORE_CON
10603 EINA_SAFETY_ON_NULL_RETURN_VAL(route, NULL);
10604 return route->info.waypoints;
10612 elm_map_name_address_get(const Elm_Map_Name *name)
10614 #ifdef HAVE_ELEMENTARY_ECORE_CON
10615 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
10616 return name->address;
10620 elm_map_marker_update(Elm_Map_Marker *marker)
10622 #ifdef HAVE_ELEMENTARY_ECORE_CON
10623 EINA_SAFETY_ON_NULL_RETURN(marker);
10624 Widget_Data *wd = marker->wd;
10625 EINA_SAFETY_ON_NULL_RETURN(wd);
10627 _marker_update(marker);
10634 elm_map_bubbles_close(Evas_Object *obj)
10636 #ifdef HAVE_ELEMENTARY_ECORE_CON
10637 ELM_CHECK_WIDTYPE(obj, widtype);
10638 Widget_Data *wd = elm_widget_data_get(obj);
10639 EINA_SAFETY_ON_NULL_RETURN(wd);
10642 Elm_Map_Marker *marker;
10643 EINA_LIST_FOREACH(wd->markers, l, marker)
10645 if (marker->bubble) _bubble_free(marker->bubble);
10646 marker->bubble = NULL;
10650 if (marker->group->bubble) _bubble_free(marker->group->bubble);
10651 marker->group->bubble = NULL;
10659 EAPI Elm_Map_Group_Class *
10660 elm_map_group_class_new(Evas_Object *obj)
10662 #ifdef HAVE_ELEMENTARY_ECORE_CON
10663 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
10664 Widget_Data *wd = elm_widget_data_get(obj);
10665 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
10667 Elm_Map_Group_Class *clas = ELM_NEW(Elm_Map_Group_Class);
10669 clas->zoom_displayed = 0;
10670 clas->zoom_grouped = 255;
10671 eina_stringshare_replace(&clas->style, "radio");
10673 wd->group_classes = eina_list_append(wd->group_classes, clas);
10678 >>>>>>> remotes/origin/upstream
10685 elm_map_name_region_get(const Elm_Map_Name *name, double *lon, double *lat)
10687 #ifdef HAVE_ELEMENTARY_ECORE_CON
10688 EINA_SAFETY_ON_NULL_RETURN(name);
10689 if (lon) *lon = name->lon;
10690 if (lat) *lat = name->lat;
10696 elm_map_group_class_style_set(Elm_Map_Group_Class *clas, const char *style)
10698 #ifdef HAVE_ELEMENTARY_ECORE_CON
10699 EINA_SAFETY_ON_NULL_RETURN(clas);
10700 eina_stringshare_replace(&clas->style, style);
10704 >>>>>>> remotes/origin/upstream
10710 elm_map_name_remove(Elm_Map_Name *name)
10712 #ifdef HAVE_ELEMENTARY_ECORE_CON
10713 EINA_SAFETY_ON_NULL_RETURN(name);
10716 free(name->address);
10717 name->address = NULL;
10721 ecore_event_handler_del(name->handler);
10722 name->handler = NULL;
10724 if (name->ud.fname)
10726 ecore_file_remove(name->ud.fname);
10727 free(name->ud.fname);
10728 name->ud.fname = NULL;
10733 elm_map_group_class_icon_cb_set(Elm_Map_Group_Class *clas, Elm_Map_Group_Icon_Get_Func icon_get)
10735 #ifdef HAVE_ELEMENTARY_ECORE_CON
10736 EINA_SAFETY_ON_NULL_RETURN(clas);
10737 clas->func.icon_get = icon_get;
10741 >>>>>>> remotes/origin/upstream
10747 elm_map_rotate_set(Evas_Object *obj, double degree, Evas_Coord cx, Evas_Coord cy)
10749 #ifdef HAVE_ELEMENTARY_ECORE_CON
10750 ELM_CHECK_WIDTYPE(obj, widtype);
10751 Widget_Data *wd = elm_widget_data_get(obj);
10754 wd->rotate.d = degree;
10755 wd->rotate.cx = cx;
10756 wd->rotate.cy = cy;
10757 wd->calc_job = ecore_job_add(_calc_job, wd);
10764 elm_map_group_class_data_set(Elm_Map_Group_Class *clas, void *data)
10766 #ifdef HAVE_ELEMENTARY_ECORE_CON
10767 EINA_SAFETY_ON_NULL_RETURN(clas);
10772 >>>>>>> remotes/origin/upstream
10778 elm_map_rotate_get(const Evas_Object *obj, double *degree, Evas_Coord *cx, Evas_Coord *cy)
10780 #ifdef HAVE_ELEMENTARY_ECORE_CON
10781 ELM_CHECK_WIDTYPE(obj, widtype);
10782 Widget_Data *wd = elm_widget_data_get(obj);
10785 if (degree) *degree = wd->rotate.d;
10786 if (cx) *cx = wd->rotate.cx;
10787 if (cy) *cy = wd->rotate.cy;
10794 elm_map_group_class_zoom_displayed_set(Elm_Map_Group_Class *clas, int zoom)
10796 #ifdef HAVE_ELEMENTARY_ECORE_CON
10797 EINA_SAFETY_ON_NULL_RETURN(clas);
10798 clas->zoom_displayed = zoom;
10802 >>>>>>> remotes/origin/upstream
10808 elm_map_wheel_disabled_set(Evas_Object *obj, Eina_Bool disabled)
10810 #ifdef HAVE_ELEMENTARY_ECORE_CON
10811 ELM_CHECK_WIDTYPE(obj, widtype);
10812 Widget_Data *wd = elm_widget_data_get(obj);
10815 if ((!wd->wheel_disabled) && (disabled))
10816 evas_object_event_callback_del_full(wd->rect, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, obj);
10817 else if ((wd->wheel_disabled) && (!disabled))
10818 evas_object_event_callback_add(wd->rect, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel_cb, obj);
10819 wd->wheel_disabled = !!disabled;
10827 elm_map_wheel_disabled_get(const Evas_Object *obj)
10829 #ifdef HAVE_ELEMENTARY_ECORE_CON
10830 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
10831 Widget_Data *wd = elm_widget_data_get(obj);
10833 if (!wd) return EINA_FALSE;
10834 return wd->wheel_disabled;
10843 elm_map_track_add(Evas_Object *obj, EMap_Route *emap)
10845 elm_map_group_class_zoom_grouped_set(Elm_Map_Group_Class *clas, int zoom)
10847 #ifdef HAVE_ELEMENTARY_ECORE_CON
10848 EINA_SAFETY_ON_NULL_RETURN(clas);
10849 clas->zoom_grouped = zoom;
10857 elm_map_group_class_hide_set(Evas_Object *obj, Elm_Map_Group_Class *clas, Eina_Bool hide)
10859 #ifdef HAVE_ELEMENTARY_ECORE_CON
10860 ELM_CHECK_WIDTYPE(obj, widtype);
10861 Widget_Data *wd = elm_widget_data_get(obj);
10862 EINA_SAFETY_ON_NULL_RETURN(wd);
10863 EINA_SAFETY_ON_NULL_RETURN(clas);
10866 evas_object_smart_changed(wd->pan_smart);
10874 EAPI Elm_Map_Marker_Class *
10875 elm_map_marker_class_new(Evas_Object *obj)
10876 >>>>>>> remotes/origin/upstream
10878 #ifdef HAVE_ELEMENTARY_ECORE_CON
10879 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
10880 Widget_Data *wd = elm_widget_data_get(obj);
10883 if (!wd) return EINA_FALSE;
10885 Evas_Object *route = elm_route_add(obj);
10886 elm_route_emap_set(route, emap);
10887 wd->track = eina_list_append(wd->track, route);
10899 elm_map_track_remove(Evas_Object *obj, Evas_Object *route)
10901 #ifdef HAVE_ELEMENTARY_ECORE_CON
10902 ELM_CHECK_WIDTYPE(obj, widtype) ;
10903 Widget_Data *wd = elm_widget_data_get(obj);
10907 wd->track = eina_list_remove(wd->track, route);
10908 evas_object_del(route);
10915 #ifdef HAVE_ELEMENTARY_ECORE_CON
10918 _mapnik_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
10920 char buf[PATH_MAX];
10921 // ((x+y+zoom)%3)+'a' is requesting map images from distributed tile servers (eg., a, b, c)
10922 snprintf(buf, sizeof(buf), "http://%c.tile.openstreetmap.org/%d/%d/%d.png", ((x+y+zoom)%3)+'a', zoom, x, y);
10923 return strdup(buf);
10927 _osmarender_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
10929 char buf[PATH_MAX];
10930 snprintf(buf, sizeof(buf), "http://%c.tah.openstreetmap.org/Tiles/tile/%d/%d/%d.png", ((x+y+zoom)%3)+'a', zoom, x, y);
10931 return strdup(buf);
10935 _cyclemap_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
10937 char buf[PATH_MAX];
10938 snprintf(buf, sizeof(buf), "http://%c.tile.opencyclemap.org/cycle/%d/%d/%d.png", ((x+y+zoom)%3)+'a', zoom, x, y);
10939 return strdup(buf);
10943 _mapquest_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
10945 char buf[PATH_MAX];
10946 snprintf(buf, sizeof(buf), "http://otile%d.mqcdn.com/tiles/1.0.0/osm/%d/%d/%d.png", ((x+y+zoom)%4)+1, zoom, x, y);
10947 return strdup(buf);
10951 _mapquest_aerial_url_cb(Evas_Object *obj __UNUSED__, int x, int y, int zoom)
10953 char buf[PATH_MAX];
10954 snprintf(buf, sizeof(buf), "http://oatile%d.mqcdn.com/naip/%d/%d/%d.png", ((x+y+zoom)%4)+1, zoom, x, y);
10955 return strdup(buf);
10958 static char *_yours_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
10960 char buf[PATH_MAX];
10961 snprintf(buf, sizeof(buf),
10962 "%s?flat=%lf&flon=%lf&tlat=%lf&tlon=%lf&v=%s&fast=%d&instructions=1",
10963 ROUTE_YOURS_URL, flat, flon, tlat, tlon, type_name, method);
10965 return strdup(buf);
10968 // TODO: fix monav api
10970 static char *_monav_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
10972 char buf[PATH_MAX];
10973 snprintf(buf, sizeof(buf),
10974 "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
10975 ROUTE_MONAV_URL, flat, flon, tlat, tlon, type_name, method);
10977 return strdup(buf);
10981 // TODO: fix ors api
10983 static char *_ors_url_cb(Evas_Object *obj __UNUSED__, char *type_name, int method, double flon, double flat, double tlon, double tlat)
10985 char buf[PATH_MAX];
10986 snprintf(buf, sizeof(buf),
10987 "%s?flat=%f&flon=%f&tlat=%f&tlon=%f&v=%s&fast=%d&instructions=1",
10988 ROUTE_ORS_URL, flat, flon, tlat, tlon, type_name, method);
10990 return strdup(buf);
10995 _nominatim_url_cb(Evas_Object *obj, int method, char *name, double lon, double lat)
10997 ELM_CHECK_WIDTYPE(obj, widtype) strdup("");
10998 Widget_Data *wd = elm_widget_data_get(obj);
11000 unsigned int ele, idx;
11001 char search_url[PATH_MAX];
11002 char buf[PATH_MAX];
11004 if (!wd) return strdup("");
11005 if (method == ELM_MAP_NAME_METHOD_SEARCH)
11007 search_url[0] = '\0';
11008 str = eina_str_split_full(name, " ", 0, &ele);
11009 for (idx = 0 ; idx < ele ; idx++)
11011 eina_strlcat(search_url, str[idx], sizeof(search_url));
11012 if (!(idx == (ele-1))) eina_strlcat(search_url, "+", sizeof(search_url));
11014 snprintf(buf, sizeof(buf), "%s/search?q=%s&format=xml&polygon=0&addressdetails=0", NAME_NOMINATIM_URL, search_url);
11022 else if (method == ELM_MAP_NAME_METHOD_REVERSE) snprintf(buf, sizeof(buf), "%s/reverse?format=xml&lat=%lf&lon=%lf&zoom=%d&addressdetails=0", NAME_NOMINATIM_URL, lat, lon, wd->zoom);
11023 else strcpy(buf, "");
11025 return strdup(buf);
11030 EINA_SAFETY_ON_NULL_RETURN_VAL(wd, NULL);
11032 Elm_Map_Marker_Class *clas = ELM_NEW(Elm_Map_Marker_Class);
11033 eina_stringshare_replace(&clas->style, "radio");
11035 wd->marker_classes = eina_list_append(wd->marker_classes, clas);
11044 elm_map_marker_class_style_set(Elm_Map_Marker_Class *clas, const char *style)
11046 #ifdef HAVE_ELEMENTARY_ECORE_CON
11047 EINA_SAFETY_ON_NULL_RETURN(clas);
11048 eina_stringshare_replace(&clas->style, style);
11056 elm_map_marker_class_icon_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Icon_Get_Func icon_get)
11058 #ifdef HAVE_ELEMENTARY_ECORE_CON
11059 EINA_SAFETY_ON_NULL_RETURN(clas);
11060 clas->func.icon_get = icon_get;
11068 elm_map_marker_class_get_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Get_Func get)
11070 #ifdef HAVE_ELEMENTARY_ECORE_CON
11071 EINA_SAFETY_ON_NULL_RETURN(clas);
11072 clas->func.get = get;
11080 elm_map_marker_class_del_cb_set(Elm_Map_Marker_Class *clas, Elm_Map_Marker_Del_Func del)
11082 #ifdef HAVE_ELEMENTARY_ECORE_CON
11083 EINA_SAFETY_ON_NULL_RETURN(clas);
11084 clas->func.del = del;
11092 elm_map_route_color_set(Elm_Map_Route *route __UNUSED__, int r __UNUSED__, int g __UNUSED__, int b __UNUSED__, int a __UNUSED__)
11098 elm_map_route_color_get(const Elm_Map_Route *route __UNUSED__, int *r __UNUSED__, int *g __UNUSED__, int *b __UNUSED__, int *a __UNUSED__)
11104 elm_map_route_remove(Elm_Map_Route *route)
11106 elm_map_route_del(route);
11110 elm_map_name_remove(Elm_Map_Name *name)
11112 elm_map_name_del(name);
11115 >>>>>>> remotes/origin/upstream