1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <Elementary.h>
25 #include "maps_view.h"
26 #include "maps_view_plugin.h"
27 #include "maps_util.h"
29 #include "empty_module.h"
31 #include "command_queue.h"
32 #include "poly_shape_hit_test.h"
33 #include "gesture_processor.h"
34 #include "inertial_camera.h"
35 #include "inertial_gesture.h"
36 #include "gesture_detector_statemachine.h"
37 #include "maps_view_event_data.h"
38 #include "maps_condition.h"
41 * The structure of callbacks info, Maps View is invoking during events
43 typedef struct _maps_view_callback_info_s {
44 maps_view_on_event_cb callback;
46 } maps_view_callback_info_s;
49 * The structure of map view idle listener callbacks info
51 typedef struct _maps_view_idle_listener_info_s {
52 void (*callback)(void *user_data);
54 } maps_view_idle_listener_info_s;
57 * The structure of Maps View internal data
59 typedef struct _maps_view_s {
60 /* Map Coordinates and Area */
62 maps_coordinates_h center;
64 /* Run-time scale values */
66 double rotation_angle; /* in graduses */
69 /* Camera inertial transition data */
70 view::inertial_camera *inertial_camera;
71 view::inertial_gesture *inertial_gesture;
72 maps_view_idle_listener_info_s idle_listener;
74 /* We'd better to store that values in order to easily limit zoom level
75 * and factor in the run time without accessing the plugin frequently */
79 /* The handle of Maps Service, used by Map View */
82 /* List of Visual Objects on the View */
83 maps_item_list_h view_objects;
92 maps_view_action_e gesture_actions[MAPS_VIEW_GESTURE_LONG_PRESS + 1];
93 bool gesture_available[MAPS_VIEW_GESTURE_LONG_PRESS + 1];
95 /* Continuous gesture info */
96 view::finger_event_stream *finger_stream;
98 /* Map View callbacks */
99 maps_view_callback_info_s event_callbacks[MAPS_VIEW_EVENT_READY + 1];
102 /* Evas Queue support */
104 Ecore_Animator *animator;
105 volatile bool ready_to_draw;
107 /* Map View Preferences */
108 maps_view_type_e type;
110 bool buildings_enabled;
111 bool traffic_enabled;
112 bool public_transit_enabled;
113 bool scalebar_enabled;
115 /* To check hit_test */
119 void *maps_plugin_view_handle;
123 /* ---------------------------------------------------------------------------*/
126 const gsize _MAPS_VIEW_LANGUAGE_MAX_LENGTH = MAPS_BASE_TYPE_MAX_LEN;
129 /* ---------------------------------------------------------------------------*/
131 extern plugin::plugin_s *__extract_plugin(maps_service_h maps);
132 extern int _maps_view_event_data_set_type(const maps_view_event_data_h event, maps_view_event_type_e event_type);
133 extern int _maps_view_event_data_set_gesture_type(const maps_view_event_data_h event, maps_view_gesture_e gesture_type);
134 extern int _maps_view_event_data_set_action_type(const maps_view_event_data_h event, maps_view_action_e action_type);
135 extern int _maps_view_event_data_set_center(const maps_view_event_data_h event, const maps_coordinates_h center);
136 extern int _maps_view_event_data_set_delta(const maps_view_event_data_h event, int delta_x, int delta_y);
137 extern int _maps_view_event_data_set_position(const maps_view_event_data_h event, int x, int y);
138 extern int _maps_view_event_data_set_fingers(const maps_view_event_data_h event, int fingers);
139 extern int _maps_view_event_data_set_zoom_factor(const maps_view_event_data_h event, double zoom_factor);
140 extern int _maps_view_event_data_set_rotation_angle(const maps_view_event_data_h event, double rotation_angle);
141 extern int _maps_view_event_data_set_object(const maps_view_event_data_h event, const maps_view_object_h object);
142 extern int _maps_view_event_data_create(maps_view_event_data_h *event);
143 extern int _maps_view_object_set_view(const maps_view_object_h object, const maps_view_h view);
144 maps_view_event_data_h _maps_view_create_event_data(maps_view_event_type_e type);
145 void _maps_view_invoke_event_callback(const maps_view_h view, const maps_view_event_data_h event_data);
146 int _maps_view_set_inertia_enabled(const maps_view_h view, bool enabled);
147 extern bool _maps_view_object_overlay_cb(int index, int total, maps_view_object_h object, void *user_data);
148 extern int _maps_view_object_overlay_operation(maps_view_h view, maps_view_object_h object, maps_view_object_operation_e operation);
149 static int __maps_view_set_center(maps_view_h view, maps_coordinates_h coordinates, bool internal);
150 int _maps_view_move_center(maps_view_h view, const int delta_x, const int delta_y);
151 int _maps_view_get_plugin_center(const maps_view_h view, maps_coordinates_h *center);
152 int _maps_coordinates_copy(maps_coordinates_h orig, maps_coordinates_h dest);
154 /* ---------------------------------------------------------------------------*/
157 /* TODO: Apply this approach for other cases, particularly, in maps_service.h*/
158 const plugin::interface_s *__get_plugin_interface(maps_view_h view)
160 const plugin::plugin_s *p =
161 __extract_plugin(((maps_view_s *)view)->maps);
162 return (p) ? (&p->interface) : plugin::get_empty_interface_ptr();
166 /* ---------------------------------------------------------------------------*/
169 static void __maps_view_on_event_empty_cb(maps_view_event_type_e type,
170 maps_view_event_data_h event_data, void *user_data)
176 session::command_queue *__maps_view_select_q()
179 * This is a draw-enforcing mode, when the rendering and drawing
180 * of the map is happening as fast as it possible.
181 * This mode is good when the Map View is a single active widget
183 * In this mode we are relying on the ecore main loop and the
184 * assumption, that loop steps will apear continuously, not
186 * https://docs.enlightenment.org/efl/1.15.0/Ecore_Main_Loop_Page.html
188 return session::command_queue_sync::interface();
191 * This is an analogy of previous mode, but with thread safety
194 /*return session::command_queue_async::interface();*/
197 * This is a thread-friendly mode, when all heavy computations
198 * are performed in the "idle" mode.
199 * This mode is good for apps, which has other active widgets in
200 * addition to Map View.
201 * This approach allows compression of repeating commands as well
203 /* return session::command_queue_view::interface(); */
206 bool _maps_view_is_gesture_available(maps_view_h view, maps_view_gesture_e gesture)
210 maps_view_s *v = (maps_view_s *)view;
211 return v->gesture_available[gesture];
214 maps_view_action_e _maps_view_get_gesture_action(maps_view_h view, maps_view_gesture_e gesture)
217 return MAPS_VIEW_ACTION_NONE;
218 maps_view_s *v = (maps_view_s *)view;
219 return v->gesture_actions[gesture];
222 void *_maps_view_get_maps_service_ptr(maps_view_h view)
226 maps_view_s *v = (maps_view_s *)view;
230 int _maps_view_on_overlay_update_all(maps_view_h view)
233 return MAPS_ERROR_INVALID_PARAMETER;
235 maps_view_s *v = (maps_view_s *)view;
236 if (!v->view_objects)
237 return MAPS_ERROR_NOT_FOUND;
238 return maps_item_list_foreach(v->view_objects, NULL, _maps_view_object_overlay_cb, v->clipper);
242 int _maps_view_on_object_operation(maps_view_h view, maps_view_object_h object, maps_view_object_operation_e operation)
245 return MAPS_ERROR_INVALID_PARAMETER;
247 maps_view_object_type_e type;
248 maps_view_object_get_type(object, &type);
249 if (type == MAPS_VIEW_OBJECT_OVERLAY) {
250 return _maps_view_object_overlay_operation(view, object, operation);
252 if(!__get_plugin_interface(view)->maps_plugin_on_object)
253 return MAPS_ERROR_INVALID_PARAMETER;
255 return __get_plugin_interface(view)->maps_plugin_on_object(view, object, operation);
260 static void __on_canvas_tap(void *data, Evas *e, Evas_Object *obj, void *event_info)
262 MAPS_LOGI("__on_canvas_tap");
263 if (!event_info || !data)
266 /* Extract the view ptr */
267 maps_view_s *v = (maps_view_s *)data;
268 if (!v->finger_stream)
271 /* Detect & Process the gesture */
272 v->finger_stream->tap((Evas_Event_Mouse_Down *)event_info);
275 static void __on_canvas_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
277 MAPS_LOGI("__on_canvas_up");
278 if (!event_info || !data)
281 /* Extract the view ptr */
282 maps_view_s *v = (maps_view_s *)data;
283 if (!v->finger_stream)
286 /* Detect & Process the gesture */
287 v->finger_stream->up((Evas_Event_Mouse_Up *)event_info);
290 static void __on_canvas_line(void *data, Evas *e, Evas_Object *obj, void *event_info)
292 MAPS_LOGI("__on_canvas_line");
293 if (!event_info || !data)
296 /* Extract view ptr */
297 maps_view_s *v = (maps_view_s *)data;
298 if (!v->finger_stream)
301 /* Detect & Process the gesture */
302 v->finger_stream->move((Evas_Event_Mouse_Move *)event_info);
305 static void __on_canvas_multi_tap(void *data, Evas *e, Evas_Object *obj, void *event_info)
307 MAPS_LOGI("__on_canvas_multi_tap");
308 if (!event_info || !data)
311 /* Extract view ptr */
312 maps_view_s *v = (maps_view_s *)data;
313 if (!v->finger_stream)
316 /* Detect & Process the gesture */
317 v->finger_stream->multi_tap((Evas_Event_Multi_Down *)event_info);
320 static void __on_canvas_multi_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
322 MAPS_LOGI("__on_canvas_multi_up");
323 if (!event_info || !data)
326 /* Extract view ptr */
327 maps_view_s *v = (maps_view_s *)data;
328 if (!v->finger_stream)
331 /* Detect & Process the gesture */
332 v->finger_stream->multi_up((Evas_Event_Multi_Up *)event_info);
335 static void __on_canvas_multi_line(void *data, Evas *e, Evas_Object *obj, void *event_info)
337 MAPS_LOGI("__on_canvas_multi_line");
338 if (!event_info || !data)
341 /* Extract view ptr */
342 maps_view_s *v = (maps_view_s *)data;
343 if (!v->finger_stream)
346 /* Detect & Process the gesture */
347 v->finger_stream->multi_move((Evas_Event_Multi_Move *)event_info);
351 static int __maps_plugin_render_map(const maps_view_h view,
352 const maps_coordinates_h coordinates, const double zoom_factor, const double rotation_angle)
354 if (!view || !coordinates)
355 return MAPS_ERROR_INVALID_PARAMETER;
357 return __get_plugin_interface(view)->maps_plugin_render_map(view,
358 coordinates, zoom_factor, rotation_angle);
362 void _maps_view_set_idle_listener(const maps_view_h view,
363 void (*callback)(void *user_data), void *user_data)
367 maps_view_s *v = (maps_view_s *)view;
368 v->idle_listener.callback = callback;
369 v->idle_listener.user_data = user_data;
372 void _maps_view_halt_inertial_camera(maps_view_h view)
374 maps_view_s *v = (maps_view_s *)view;
375 if (v && v->inertial_camera && v->inertial_camera->is_transiting()) {
376 v->inertial_camera->set_transiting(false);
381 static Eina_Bool __maps_view_on_idle_cb(void *data)
384 return ECORE_CALLBACK_RENEW;
386 maps_view_s *v = (maps_view_s *)data;
388 bool is_transiting = false;
389 bool is_continue = false;
391 view::inertial_gesture *ig = v->inertial_gesture;
392 if (ig && ig->is_transiting()) {
393 is_transiting |= true;
394 is_continue |= ig->next_transition_step();
398 view::inertial_camera *ic = v->inertial_camera;
399 if (ic && ic->is_transiting()) {
400 is_transiting |= true;
401 is_continue |= ic->next_transition_step();
402 __maps_plugin_render_map(v,
403 ic->get_cur_center(),
404 ic->get_cur_zoom_factor(),
405 ic->get_cur_rotation_angle());
406 _maps_coordinates_copy(ic->get_cur_center(), v->center);
408 _maps_view_on_overlay_update_all(v);
412 if (is_transiting && !is_continue) {
413 maps_view_event_data_h ed = _maps_view_create_event_data(MAPS_VIEW_EVENT_READY);
415 _maps_view_invoke_event_callback(v, ed);
416 maps_view_event_data_destroy(ed);
420 return ECORE_CALLBACK_RENEW; // same as EINA_TRUE
423 static Eina_Bool __maps_view_animator_cb(void *data)
425 return ECORE_CALLBACK_RENEW;
429 void __maps_view_ready(const maps_view_h view)
433 maps_view_s *v = (maps_view_s*)view;
436 _maps_view_set_inertia_enabled(view, true);
438 /* Invoke user registered event callback */
439 maps_view_event_data_h ed = _maps_view_create_event_data(MAPS_VIEW_EVENT_READY);
441 _maps_view_invoke_event_callback(view, ed);
442 maps_view_event_data_destroy(ed);
447 /* ----------------------CREATE AND DESTROY-----------------------------------*/
450 static void __maps_view_parent_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
452 maps_view_s *v = (maps_view_s*)data;
454 int x, y, w, h, ox, oy, ow, oh;
456 /* get geometries of evas object to check how much are changed */
457 evas_object_geometry_get(v->parent, &x, &y, &w, &h);
458 evas_object_geometry_get(v->panel, &ox, &oy, &ow, &oh);
460 /* compensate difference of center to keep the map image not to move for eyes after ready */
462 _maps_view_move_center(v, (x - ox) / 2, (y - oy) / 2);
464 /* set center with stored value */
465 _maps_view_get_plugin_center(v, &v->center);
466 maps_view_set_screen_location(v, x, y, w, h);
469 static void __maps_view_panel_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
471 maps_view_s *v = (maps_view_s*)data;
473 int x, y, w, h, ox, oy, ow, oh;
475 /* get geometries of evas object to check how much are changed */
476 evas_object_geometry_get(v->panel, &x, &y, &w, &h);
477 evas_object_geometry_get(v->clipper, &ox, &oy, &ow, &oh);
479 /* compensate difference of center to keep the map image not to move for eyes after ready */
481 _maps_view_move_center(v, (x - ox) / 2, (y - oy) / 2);
483 /* set center with stored value */
484 _maps_view_get_plugin_center(v, &v->center);
485 maps_view_set_screen_location(v, x, y, w, h);
489 static void __maps_view_create_panel(maps_view_h view, Evas_Object *obj)
494 maps_view_s *v = (maps_view_s*)view;
496 /* Initialize the panel */
497 if (!strncmp(evas_object_type_get(obj), "image", strlen("image"))) {
498 /* if obj is Evas_Image object */
499 MAPS_LOGD("The panel is a Evas_Image");
502 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_RESIZE, __maps_view_panel_resize_cb, v);
504 /* if obj is the other kind of (smart) objects */
506 v->panel = evas_object_image_add(evas_object_evas_get(v->parent));
507 evas_object_smart_member_add(v->panel, v->parent);
508 evas_object_event_callback_add(v->parent, EVAS_CALLBACK_RESIZE, __maps_view_parent_resize_cb, v);
510 if (evas_object_visible_get(v->parent))
511 evas_object_show(v->panel);
513 evas_object_hide(v->panel);
515 /* Equal size of a panel object and a parent object */
517 evas_object_geometry_get(v->parent, &x, &y, &w, &h);
518 evas_object_move(v->panel, x, y);
519 evas_object_resize(v->panel, w, h);
520 evas_object_image_fill_set(v->panel, 0, 0, w, h);
522 evas_object_image_filled_set(v->panel, EINA_FALSE);
525 /* Create the panel and link it to the instance of Maps Service */
526 EXPORT_API int maps_view_create(maps_service_h maps, Evas_Object *obj, maps_view_h *view)
528 if (!maps_condition_check_maps_feature())
529 return MAPS_ERROR_NOT_SUPPORTED;
531 return MAPS_ERROR_INVALID_PARAMETER;
532 if (!maps_condition_check_service_supported(maps, MAPS_SERVICE_VIEW))
533 return MAPS_ERROR_NOT_SUPPORTED;
535 return MAPS_ERROR_INVALID_PARAMETER;
536 if (!maps_condition_check_privilege())
537 return MAPS_ERROR_PERMISSION_DENIED;
539 maps_view_s *v = g_slice_new0(maps_view_s);
542 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
543 return MAPS_ERROR_OUT_OF_MEMORY;
547 /* Initialize the list with visual objects */
548 maps_item_list_create(&v->view_objects);
550 /* Initialize the panel */
551 __maps_view_create_panel(v, obj);
553 v->maps_plugin_view_handle = NULL;
555 /* Set up event callbacks by default */
556 const int event_callback_cnt =
557 sizeof(v->event_callbacks) / sizeof(v->event_callbacks[0]);
558 for(int i = 0; i < event_callback_cnt; i ++) {
559 v->event_callbacks[i].callback = __maps_view_on_event_empty_cb;
560 v->event_callbacks[i].user_data = NULL;
563 /* Assign gestures to actions */
564 v->gesture_actions[MAPS_VIEW_GESTURE_SCROLL] = MAPS_VIEW_ACTION_NONE;
565 v->gesture_actions[MAPS_VIEW_GESTURE_ZOOM] = MAPS_VIEW_ACTION_ZOOM;
566 v->gesture_actions[MAPS_VIEW_GESTURE_TAP] = MAPS_VIEW_ACTION_NONE;
567 v->gesture_actions[MAPS_VIEW_GESTURE_DOUBLE_TAP] = MAPS_VIEW_ACTION_ZOOM_IN;
568 v->gesture_actions[MAPS_VIEW_GESTURE_2_FINGER_TAP] = MAPS_VIEW_ACTION_ZOOM_OUT;
569 v->gesture_actions[MAPS_VIEW_GESTURE_ROTATE] = MAPS_VIEW_ACTION_ROTATE;
570 v->gesture_actions[MAPS_VIEW_GESTURE_LONG_PRESS] = MAPS_VIEW_ACTION_NONE;
571 v->gesture_actions[MAPS_VIEW_GESTURE_NONE] = MAPS_VIEW_ACTION_NONE;
573 /* Set up gesture availability */
574 v->gesture_available[MAPS_VIEW_GESTURE_SCROLL] = true;
575 v->gesture_available[MAPS_VIEW_GESTURE_ZOOM] = true;
576 v->gesture_available[MAPS_VIEW_GESTURE_TAP] = true;
577 v->gesture_available[MAPS_VIEW_GESTURE_DOUBLE_TAP] = true;
578 v->gesture_available[MAPS_VIEW_GESTURE_2_FINGER_TAP] = true;
579 v->gesture_available[MAPS_VIEW_GESTURE_ROTATE] = true;
580 v->gesture_available[MAPS_VIEW_GESTURE_LONG_PRESS] = true;
581 v->gesture_available[MAPS_VIEW_GESTURE_NONE] = false;
583 /* Gesture Processing */
584 v->finger_stream = new view::finger_event_stream(v);
585 if (!v->finger_stream) {
587 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
588 return MAPS_ERROR_OUT_OF_MEMORY;
591 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_DOWN, __on_canvas_tap, v);
592 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_UP, __on_canvas_up, v);
593 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_MOVE, __on_canvas_line, v);
595 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_DOWN, __on_canvas_multi_tap, v);
596 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_UP, __on_canvas_multi_up, v);
597 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_MOVE, __on_canvas_multi_line, v);
599 /* Set up canvas and Ecore */
600 v->canvas = evas_object_evas_get(v->panel);
601 /*v->ee = ecore_evas_ecore_evas_get(v->canvas);*/
603 v->clipper = evas_object_rectangle_add(v->canvas);
605 /* Link with Maps Service */
608 /* Set up canvas and Ecore */
609 v->language = g_strdup("en-US");
611 /* Add an idle handler */
612 v->idler = ecore_idler_add(__maps_view_on_idle_cb, v);
614 /* Set up the animation frame rate */
615 /*ecore_animator_frametime_set(0.1);*/
617 /* Create the animator and assign the drawing task */
618 v->animator = ecore_animator_add(__maps_view_animator_cb, v);
620 /* Set up the output pointer to the Maps View */
621 *view = (maps_view_h) v;
623 if (__get_plugin_interface(v)) {
624 /* Notify the Plugin, that the view is created */
625 if (__get_plugin_interface(v)->maps_plugin_create_map_view)
626 __get_plugin_interface(v)->maps_plugin_create_map_view(*view, __maps_view_ready);
628 MAPS_LOGE("ERROR!! maps_plugin_create_map_view function pointer is null");
630 /* Set up zoom and rotation */
631 if (__get_plugin_interface(v)->maps_plugin_get_min_zoom_level)
632 __get_plugin_interface(v)->maps_plugin_get_min_zoom_level(v, &v->min_zoom_level);
634 MAPS_LOGE("ERROR!! maps_plugin_get_min_zoom_level function pointer is null");
636 if (__get_plugin_interface(v)->maps_plugin_get_max_zoom_level)
637 __get_plugin_interface(v)->maps_plugin_get_max_zoom_level(v, &v->max_zoom_level);
639 MAPS_LOGE("ERROR!! maps_plugin_get_max_zoom_level function pointer is null");
642 if (v->min_zoom_level <= 0)
643 v->min_zoom_level = 2;
644 if (v->max_zoom_level <= 0)
645 v->max_zoom_level = 2;
647 v->zoom_level = v->min_zoom_level;
648 v->zoom_factor = double(v->zoom_level);
649 v->rotation_angle = 0.;
651 maps_coordinates_create(.0, .0, &v->center);
653 v->type = MAPS_VIEW_TYPE_NORMAL;
654 v->buildings_enabled = false;
655 v->traffic_enabled = false;
656 v->public_transit_enabled = false;
658 /* To check hit_test */
659 maps_get_screen_dpi(&v->screen_dpi);
660 v->min_hit_area = MAX(20, v->screen_dpi / 5);
662 /* Update map view */
663 __maps_view_set_center(v, v->center, TRUE);
665 return MAPS_ERROR_NONE;
668 /* Destroy the panel and unlink it from the instance of Maps Service */
669 EXPORT_API int maps_view_destroy(maps_view_h view)
671 if (!maps_condition_check_maps_feature())
672 return MAPS_ERROR_NOT_SUPPORTED;
674 return MAPS_ERROR_INVALID_PARAMETER;
675 if (!maps_condition_check_privilege())
676 return MAPS_ERROR_PERMISSION_DENIED;
678 maps_view_s *v = (maps_view_s *) view;
680 /* Unregister gesture processing */
681 if (v->finger_stream)
682 delete v->finger_stream;
683 v->finger_stream = NULL;
685 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_DOWN, __on_canvas_tap);
686 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_UP, __on_canvas_up);
687 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_MOVE, __on_canvas_line);
689 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_DOWN, __on_canvas_multi_tap);
690 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_UP, __on_canvas_multi_up);
691 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_MOVE, __on_canvas_multi_line);
694 /* Unregister idle handler */
696 ecore_idler_del(v->idler);
698 view::inertial_camera *inertial_camera = v->inertial_camera;
699 v->inertial_camera = NULL;
700 v->idle_listener.callback = NULL;
702 /* Delete the animator */
704 ecore_animator_del(v->animator);
706 /* Notify the Plugin, that the view is to be destroyed */
707 if (__get_plugin_interface(view)) {
708 if (__get_plugin_interface(view)->maps_plugin_destroy_map_view)
709 __get_plugin_interface(view)->maps_plugin_destroy_map_view(view);
711 MAPS_LOGE("ERROR!! maps_plugin_destroy_map_view function pointer is null");
714 /* Destroy a visual panel */
716 evas_object_del(v->panel);
719 evas_object_del(v->clipper);
722 maps_coordinates_destroy(v->center);
725 maps_area_destroy(v->area);
727 /* Destroy the list with visual objects */
728 maps_item_list_remove_all(v->view_objects, maps_view_object_destroy);
729 maps_item_list_destroy(v->view_objects);
734 g_slice_free(maps_view_s, v);
737 delete inertial_camera;
739 return MAPS_ERROR_NONE;
743 int _maps_view_set_center_directly(const maps_view_h view,
744 const maps_coordinates_h coordinates)
746 if (!view || !coordinates)
747 return MAPS_ERROR_INVALID_PARAMETER;
749 maps_view_s *v = (maps_view_s *) view;
750 if (v->center != coordinates) {
752 maps_coordinates_destroy(v->center);
753 maps_coordinates_clone(coordinates, &v->center);
755 return MAPS_ERROR_NONE;
758 int _maps_view_get_plugin_center(const maps_view_h view,
759 maps_coordinates_h *center)
761 if (!view || !center)
762 return MAPS_ERROR_INVALID_PARAMETER;
764 return __get_plugin_interface(view)->maps_plugin_get_center(view, center);
768 /*----------------------MAP ZOOM, ROTATE, SET CENTER--------------------------*/
770 /* Show the map with a given position centered using current zoom level and
773 static int __maps_view_set_center(maps_view_h view, maps_coordinates_h coordinates, bool internal)
775 if (!view || !coordinates)
776 return MAPS_ERROR_INVALID_PARAMETER;
777 double zoom_factor = 1.;
778 int error = maps_view_get_zoom_factor(view, &zoom_factor);
779 if (error != MAPS_ERROR_NONE)
782 double rotation_angle = 0.;
783 error = maps_view_get_orientation(view, &rotation_angle);
784 if (error != MAPS_ERROR_NONE)
787 maps_view_s *v = (maps_view_s *) view;
789 /* Set up the target for camera inertial movement */
790 if(v->inertial_camera && !internal)
791 v->inertial_camera->set_targets(coordinates,
795 /* Rund rendering in the plugin */
796 error = __maps_plugin_render_map(view,
801 if (v->center != coordinates) {
802 maps_coordinates_destroy(v->center);
803 maps_coordinates_clone(coordinates, &v->center);
806 _maps_view_on_overlay_update_all(view);
809 /* Invoke user registered event callback */
810 maps_view_event_data_h ed =
811 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
813 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_SCROLL);
814 _maps_view_event_data_set_center(ed, v->center);
815 _maps_view_invoke_event_callback(v, ed);
816 maps_view_event_data_destroy(ed);
823 EXPORT_API int maps_view_set_center(maps_view_h view, maps_coordinates_h coordinates)
825 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
826 return MAPS_ERROR_NOT_SUPPORTED;
827 if (!view || !coordinates)
828 return MAPS_ERROR_INVALID_PARAMETER;
829 if (!maps_condition_check_privilege())
830 return MAPS_ERROR_PERMISSION_DENIED;
832 return __maps_view_set_center(view, coordinates, FALSE);
836 int _maps_view_move_center(maps_view_h view, const int delta_x, const int delta_y)
839 return MAPS_ERROR_INVALID_PARAMETER;
841 int error = __get_plugin_interface(view)->maps_plugin_move_center(view, delta_x, delta_y);
843 /* update position of overlay objects */
844 _maps_view_on_overlay_update_all(view);
846 /* Invoke user registered event callback */
847 maps_view_event_data_h ed =
848 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
850 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_SCROLL);
851 _maps_view_event_data_set_delta(ed, delta_x, delta_y);
852 _maps_view_invoke_event_callback(view, ed);
853 maps_view_event_data_destroy(ed);
860 EXPORT_API int maps_view_set_scalebar_enabled(const maps_view_h view, bool enable)
862 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
863 return MAPS_ERROR_NOT_SUPPORTED;
865 return MAPS_ERROR_INVALID_PARAMETER;
866 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_SCALEBAR))
867 return MAPS_ERROR_NOT_SUPPORTED;
868 if (!maps_condition_check_privilege())
869 return MAPS_ERROR_PERMISSION_DENIED;
871 return __get_plugin_interface(view)->maps_plugin_set_scalebar(view, enable);
874 EXPORT_API int maps_view_get_scalebar_enabled(const maps_view_h view, bool *enabled)
876 if (!maps_condition_check_maps_feature())
877 return MAPS_ERROR_NOT_SUPPORTED;
879 return MAPS_ERROR_INVALID_PARAMETER;
880 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_SCALEBAR))
881 return MAPS_ERROR_NOT_SUPPORTED;
883 return MAPS_ERROR_INVALID_PARAMETER;
885 return __get_plugin_interface(view)->maps_plugin_get_scalebar(view, enabled);
888 EXPORT_API int maps_view_get_center(const maps_view_h view, maps_coordinates_h *coordinates)
890 if (!maps_condition_check_maps_feature())
891 return MAPS_ERROR_NOT_SUPPORTED;
892 if (!view || !coordinates)
893 return MAPS_ERROR_INVALID_PARAMETER;
894 maps_view_s *v = (maps_view_s *) view;
895 return maps_coordinates_clone(v->center, coordinates);
898 EXPORT_API int maps_view_set_zoom_level(maps_view_h view, int level)
900 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
901 return MAPS_ERROR_NOT_SUPPORTED;
903 return MAPS_ERROR_INVALID_PARAMETER;
904 if (!maps_condition_check_privilege())
905 return MAPS_ERROR_PERMISSION_DENIED;
907 maps_view_s *v = (maps_view_s *) view;
908 int new_level = level;
909 if (new_level < v->min_zoom_level) new_level = v->min_zoom_level;
910 if (new_level > v->max_zoom_level) new_level = v->max_zoom_level;
912 /* Add inertia to the zoom process */
913 if (v->inertial_camera)
914 v->inertial_camera->set_zoom_target(double(new_level)); //LCOV_EXCL_LINE
916 v->zoom_level = new_level;
917 v->zoom_factor = double(new_level); /* Update the integer zoom level too */
919 const int error = maps_view_set_center(view, v->center);
921 /* Invoke user registered event callback */
922 maps_view_event_data_h ed =
923 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
925 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ZOOM);
926 _maps_view_event_data_set_zoom_factor(ed, v->zoom_factor);
927 _maps_view_invoke_event_callback(v, ed);
928 maps_view_event_data_destroy(ed);
934 EXPORT_API int maps_view_get_zoom_level(const maps_view_h view, int *level)
936 if (!maps_condition_check_maps_feature())
937 return MAPS_ERROR_NOT_SUPPORTED;
939 return MAPS_ERROR_INVALID_PARAMETER;
940 maps_view_s *v = (maps_view_s *) view;
941 *level = v->zoom_level;
942 return MAPS_ERROR_NONE;
945 EXPORT_API int maps_view_set_min_zoom_level(maps_view_h view, int level)
947 if (!maps_condition_check_maps_feature())
948 return MAPS_ERROR_NOT_SUPPORTED;
950 return MAPS_ERROR_INVALID_PARAMETER;
951 if (!maps_condition_check_privilege())
952 return MAPS_ERROR_PERMISSION_DENIED;
954 maps_view_s *v = (maps_view_s *) view;
955 int min_zoom_level = -1;
956 __get_plugin_interface(v)->maps_plugin_get_min_zoom_level(view, &min_zoom_level);
957 if (min_zoom_level < 0)
958 return MAPS_ERROR_INVALID_OPERATION;
959 if ((level < min_zoom_level) || (level > v->max_zoom_level))
960 return MAPS_ERROR_INVALID_PARAMETER;
961 v->min_zoom_level = level;
962 if (v->min_zoom_level > v->zoom_level)
963 maps_view_set_zoom_level(view, v->min_zoom_level);
964 return MAPS_ERROR_NONE;
967 EXPORT_API int maps_view_get_min_zoom_level(const maps_view_h view, int *min_zoom_level)
969 if (!maps_condition_check_maps_feature())
970 return MAPS_ERROR_NOT_SUPPORTED;
971 if (!view || !min_zoom_level)
972 return MAPS_ERROR_INVALID_PARAMETER;
973 maps_view_s *v = (maps_view_s *) view;
974 *min_zoom_level = v->min_zoom_level;
975 return MAPS_ERROR_NONE;
978 EXPORT_API int maps_view_set_max_zoom_level(maps_view_h view, int level)
980 if (!maps_condition_check_maps_feature())
981 return MAPS_ERROR_NOT_SUPPORTED;
983 return MAPS_ERROR_INVALID_PARAMETER;
984 if (!maps_condition_check_privilege())
985 return MAPS_ERROR_PERMISSION_DENIED;
987 maps_view_s *v = (maps_view_s *) view;
988 int max_zoom_level = -1;
989 __get_plugin_interface(v)->maps_plugin_get_max_zoom_level(view, &max_zoom_level);
990 if (max_zoom_level < 0)
991 return MAPS_ERROR_INVALID_OPERATION;
992 if ((level < v->min_zoom_level) || (level > max_zoom_level))
993 return MAPS_ERROR_INVALID_PARAMETER;
994 v->max_zoom_level = level;
995 if (v->max_zoom_level < v->zoom_level)
996 maps_view_set_zoom_level(view, v->max_zoom_level);
997 return MAPS_ERROR_NONE;
1000 EXPORT_API int maps_view_get_max_zoom_level(const maps_view_h view, int *max_zoom_level)
1002 if (!maps_condition_check_maps_feature())
1003 return MAPS_ERROR_NOT_SUPPORTED;
1004 if (!view || !max_zoom_level)
1005 return MAPS_ERROR_INVALID_PARAMETER;
1006 maps_view_s *v = (maps_view_s *) view;
1007 *max_zoom_level = v->max_zoom_level;
1008 return MAPS_ERROR_NONE;
1011 int _maps_view_set_zoom_rotate(maps_view_h view,
1012 const bool zoom_changed,
1013 const double factor,
1014 const bool rotation_changed,
1018 return MAPS_ERROR_INVALID_PARAMETER;
1020 maps_view_s *v = (maps_view_s *) view;
1022 /* 1. Apply new zoom and orientation values */
1024 double new_factor = factor;
1025 if (new_factor < v->min_zoom_level) new_factor = v->min_zoom_level;
1026 if (new_factor > v->max_zoom_level) new_factor = v->max_zoom_level;
1028 /* Add inertia to the zoom process */
1029 if (v->inertial_camera)
1030 v->inertial_camera->set_zoom_target(new_factor);
1032 /* Update Map View zoom factor */
1033 v->zoom_factor = new_factor;
1035 /* Update the integer zoom level too */
1036 v->zoom_level = int(new_factor);
1039 if (rotation_changed) {
1040 /* Add inertia to the rotation process */
1041 if (v->inertial_camera)
1042 v->inertial_camera->set_rotation_target(angle); //LCOV_EXCL_LINE
1044 /* Update Map View rotation angle */
1045 v->rotation_angle = angle;
1048 /* 2. Send update center command to the plugin */
1049 const int error = maps_view_set_center(view, v->center);
1051 /* Notify the user about changes */
1053 /* Invoke user registered event callback */
1054 maps_view_event_data_h ed =
1055 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
1058 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ZOOM);
1059 _maps_view_event_data_set_zoom_factor(ed, v->zoom_factor);
1060 _maps_view_invoke_event_callback(v, ed);
1061 maps_view_event_data_destroy(ed);
1066 if (rotation_changed) {
1067 /* Invoke user registered event callback */
1068 maps_view_event_data_h ed =
1069 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
1071 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ROTATE);
1072 _maps_view_event_data_set_rotation_angle(ed, v->rotation_angle);
1073 _maps_view_invoke_event_callback(v, ed);
1074 maps_view_event_data_destroy(ed);
1081 EXPORT_API int maps_view_set_zoom_factor(const maps_view_h view,
1082 const double factor)
1084 if (!maps_condition_check_maps_feature())
1085 return MAPS_ERROR_NOT_SUPPORTED;
1087 return MAPS_ERROR_INVALID_PARAMETER;
1089 maps_view_s *v = (maps_view_s *) view;
1090 double new_factor = factor;
1091 if (new_factor < v->min_zoom_level) new_factor = v->min_zoom_level;
1092 if (new_factor > v->max_zoom_level) new_factor = v->max_zoom_level;
1094 return _maps_view_set_zoom_rotate(view, true, new_factor, false, .0);
1097 EXPORT_API int maps_view_get_zoom_factor(const maps_view_h view, double *factor)
1099 if (!maps_condition_check_maps_feature())
1100 return MAPS_ERROR_NOT_SUPPORTED;
1101 if (!view || !factor)
1102 return MAPS_ERROR_INVALID_PARAMETER;
1103 maps_view_s *v = (maps_view_s *) view;
1104 *factor = v->zoom_factor;
1105 return MAPS_ERROR_NONE;
1108 EXPORT_API int maps_view_set_orientation(maps_view_h view, double angle)
1110 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1111 return MAPS_ERROR_NOT_SUPPORTED;
1113 return MAPS_ERROR_INVALID_PARAMETER;
1114 if (!maps_condition_check_privilege())
1115 return MAPS_ERROR_PERMISSION_DENIED;
1117 /* Add inertia to the rotation process */
1118 maps_view_s *v = (maps_view_s *)view;
1119 if (v->inertial_camera)
1120 v->inertial_camera->set_rotation_target(angle); //LCOV_EXCL_LINE
1122 return _maps_view_set_zoom_rotate(view, false, .0, true, angle);
1125 EXPORT_API int maps_view_get_orientation(const maps_view_h view, double *angle)
1127 if (!maps_condition_check_maps_feature())
1128 return MAPS_ERROR_NOT_SUPPORTED;
1129 if (!view || !angle)
1130 return MAPS_ERROR_INVALID_PARAMETER;
1131 maps_view_s *v = (maps_view_s *) view;
1132 *angle = v->rotation_angle;
1133 return MAPS_ERROR_NONE;
1137 /*----------------------SCREEN <--> GEOGRAPHY---------------------------------*/
1140 /* Converting screen coordinates to geographical */
1141 EXPORT_API int maps_view_screen_to_geolocation(maps_view_h view,
1142 int x, int y, maps_coordinates_h *coordinates)
1144 if (!maps_condition_check_maps_feature())
1145 return MAPS_ERROR_NOT_SUPPORTED;
1146 if (!view || !coordinates)
1147 return MAPS_ERROR_INVALID_PARAMETER;
1148 if (!maps_condition_check_privilege())
1149 return MAPS_ERROR_PERMISSION_DENIED;
1153 maps_view_get_screen_location(view, &posx, &posy, NULL, NULL);
1154 return __get_plugin_interface(view)->
1155 maps_plugin_screen_to_geography(view, x - posx, y - posy, coordinates);
1158 EXPORT_API int maps_view_geolocation_to_screen(const maps_view_h view,
1159 const maps_coordinates_h coordinates, int *x, int *y)
1161 if (!maps_condition_check_maps_feature())
1162 return MAPS_ERROR_NOT_SUPPORTED;
1163 if (!view || !coordinates || !x || !y)
1164 return MAPS_ERROR_INVALID_PARAMETER;
1165 if (!maps_condition_check_privilege())
1166 return MAPS_ERROR_PERMISSION_DENIED;
1170 maps_view_get_screen_location(view, &posx, &posy, NULL, NULL);
1171 const int error = __get_plugin_interface(view)->
1172 maps_plugin_geography_to_screen(view, coordinates, x, y);
1179 /* --------------------MAPS VIEW PREFERENCES----------------------------------*/
1182 EXPORT_API int maps_view_set_type(maps_view_h view, maps_view_type_e type)
1184 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1185 return MAPS_ERROR_NOT_SUPPORTED;
1187 return MAPS_ERROR_INVALID_PARAMETER;
1188 if ((type < MAPS_VIEW_TYPE_NORMAL) || (type > MAPS_VIEW_TYPE_HYBRID))
1189 return MAPS_ERROR_INVALID_PARAMETER;
1190 if (!maps_condition_check_privilege())
1191 return MAPS_ERROR_PERMISSION_DENIED;
1193 maps_view_s *v = (maps_view_s *) view;
1195 return maps_view_set_center(view, v->center);
1198 EXPORT_API int maps_view_get_type(const maps_view_h view, maps_view_type_e *type)
1200 if (!maps_condition_check_maps_feature())
1201 return MAPS_ERROR_NOT_SUPPORTED;
1203 return MAPS_ERROR_INVALID_PARAMETER;
1204 maps_view_s *v = (maps_view_s *) view;
1206 return MAPS_ERROR_NONE;
1209 EXPORT_API int maps_view_set_buildings_enabled(maps_view_h view, bool enabled)
1211 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1212 return MAPS_ERROR_NOT_SUPPORTED;
1214 return MAPS_ERROR_INVALID_PARAMETER;
1215 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_BUILDING))
1216 return MAPS_ERROR_NOT_SUPPORTED;
1217 if (!maps_condition_check_privilege())
1218 return MAPS_ERROR_PERMISSION_DENIED;
1220 maps_view_s *v = (maps_view_s *) view;
1221 v->buildings_enabled = enabled;
1222 return maps_view_set_center(view, v->center);
1225 EXPORT_API int maps_view_get_buildings_enabled(const maps_view_h view, bool *enabled)
1227 if (!maps_condition_check_maps_feature())
1228 return MAPS_ERROR_NOT_SUPPORTED;
1230 return MAPS_ERROR_INVALID_PARAMETER;
1231 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_BUILDING))
1232 return MAPS_ERROR_NOT_SUPPORTED;
1234 return MAPS_ERROR_INVALID_PARAMETER;
1235 maps_view_s *v = (maps_view_s *) view;
1236 *enabled = v->buildings_enabled;
1237 return MAPS_ERROR_NONE;
1240 EXPORT_API int maps_view_set_traffic_enabled(maps_view_h view, bool enabled)
1242 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1243 return MAPS_ERROR_NOT_SUPPORTED;
1245 return MAPS_ERROR_INVALID_PARAMETER;
1246 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_TRAFFIC))
1247 return MAPS_ERROR_NOT_SUPPORTED;
1248 if (!maps_condition_check_privilege())
1249 return MAPS_ERROR_PERMISSION_DENIED;
1251 maps_view_s *v = (maps_view_s *) view;
1252 v->traffic_enabled = enabled;
1253 return maps_view_set_center(view, v->center);
1256 EXPORT_API int maps_view_get_traffic_enabled(const maps_view_h view, bool *enabled)
1258 if (!maps_condition_check_maps_feature())
1259 return MAPS_ERROR_NOT_SUPPORTED;
1261 return MAPS_ERROR_INVALID_PARAMETER;
1262 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_TRAFFIC))
1263 return MAPS_ERROR_NOT_SUPPORTED;
1265 return MAPS_ERROR_INVALID_PARAMETER;
1266 maps_view_s *v = (maps_view_s *) view;
1267 *enabled = v->traffic_enabled;
1268 return MAPS_ERROR_NONE;
1271 EXPORT_API int maps_view_set_public_transit_enabled(maps_view_h view, bool enabled)
1273 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1274 return MAPS_ERROR_NOT_SUPPORTED;
1276 return MAPS_ERROR_INVALID_PARAMETER;
1277 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_PUBLIC_TRANSIT))
1278 return MAPS_ERROR_NOT_SUPPORTED;
1279 if (!maps_condition_check_privilege())
1280 return MAPS_ERROR_PERMISSION_DENIED;
1282 maps_view_s *v = (maps_view_s *) view;
1283 v->public_transit_enabled = enabled;
1284 return maps_view_set_center(view, v->center);
1287 EXPORT_API int maps_view_get_public_transit_enabled(const maps_view_h view, bool *enabled)
1289 if (!maps_condition_check_maps_feature())
1290 return MAPS_ERROR_NOT_SUPPORTED;
1292 return MAPS_ERROR_INVALID_PARAMETER;
1293 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_PUBLIC_TRANSIT))
1294 return MAPS_ERROR_NOT_SUPPORTED;
1296 return MAPS_ERROR_INVALID_PARAMETER;
1297 maps_view_s *v = (maps_view_s *) view;
1298 *enabled = v->public_transit_enabled;
1299 return MAPS_ERROR_NONE;
1302 int _maps_view_set_inertia_enabled(maps_view_h view, bool enabled)
1305 return MAPS_ERROR_INVALID_PARAMETER;
1306 maps_view_s *v = (maps_view_s *) view;
1309 if (!v->inertial_gesture) {
1310 v->inertial_gesture = new view::inertial_gesture(view);
1311 if (!v->inertial_gesture) {
1313 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
1314 return MAPS_ERROR_OUT_OF_MEMORY;
1319 if (!v->inertial_camera) {
1320 v->inertial_camera = new view::inertial_camera(view);
1321 if (!v->inertial_camera) {
1323 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
1324 return MAPS_ERROR_OUT_OF_MEMORY;
1329 v->finger_stream->set_gesture_detector(v->inertial_gesture);
1331 v->finger_stream->set_gesture_detector(new view::gesture_detector_statemachine(view));
1333 if (v->inertial_gesture) {
1334 /* Unset Inertial Camera */
1335 if (v->inertial_gesture->is_transiting()) {
1336 v->inertial_gesture->set_transiting(false);
1339 view::inertial_gesture *inertial_gesture = v->inertial_gesture;
1340 v->inertial_gesture = NULL;
1341 delete inertial_gesture;
1344 if (v->inertial_camera) {
1345 /* Unset Inertial Camera */
1346 if (v->inertial_camera->is_transiting()) {
1347 v->inertial_camera->set_transiting(false);
1350 view::inertial_camera *inertial_camera = v->inertial_camera;
1351 v->inertial_camera = NULL;
1352 delete inertial_camera;
1355 return MAPS_ERROR_NONE;
1359 EXPORT_API int maps_view_get_inertia_enabled(maps_view_h view, bool *enabled)
1361 if (!maps_condition_check_maps_feature())
1362 return MAPS_ERROR_NOT_SUPPORTED;
1363 if (!view || !enabled)
1364 return MAPS_ERROR_INVALID_PARAMETER;
1366 maps_view_s *v = (maps_view_s *) view;
1367 *enabled = v->inertial_camera != NULL;
1368 return MAPS_ERROR_NONE;
1372 EXPORT_API int maps_view_set_language(maps_view_h view, const char *language)
1374 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1375 return MAPS_ERROR_NOT_SUPPORTED;
1376 if (!view || !language)
1377 return MAPS_ERROR_INVALID_PARAMETER;
1378 if (!maps_condition_check_privilege())
1379 return MAPS_ERROR_PERMISSION_DENIED;
1381 maps_view_s *v = (maps_view_s *) view;
1382 int error = maps_set_string(language, _MAPS_VIEW_LANGUAGE_MAX_LENGTH, &v->language);
1383 if (error == MAPS_ERROR_NONE)
1384 error = maps_view_set_center(view, v->center);
1388 EXPORT_API int maps_view_get_language(const maps_view_h view, char **language)
1390 if (!maps_condition_check_maps_feature())
1391 return MAPS_ERROR_NOT_SUPPORTED;
1392 if (!view || !language)
1393 return MAPS_ERROR_INVALID_PARAMETER;
1394 return maps_get_string(((maps_view_s *) view)->language,
1395 _MAPS_VIEW_LANGUAGE_MAX_LENGTH, language);
1399 /* --------------------MAPS PANEL MANIPULATIONS-------------------------------*/
1401 EXPORT_API int maps_view_get_viewport(const maps_view_h view, Evas_Object **viewport)
1403 if (!maps_condition_check_maps_feature())
1404 return MAPS_ERROR_NOT_SUPPORTED;
1405 if (!view || !viewport)
1406 return MAPS_ERROR_INVALID_PARAMETER;
1407 maps_view_s *v = (maps_view_s *) view;
1408 *viewport = v->panel;
1409 return MAPS_ERROR_NONE;
1412 int _maps_view_get_parent(const maps_view_h view, Evas_Object **parent)
1414 if (!view || !parent)
1415 return MAPS_ERROR_INVALID_PARAMETER;
1416 maps_view_s *v = (maps_view_s *) view;
1417 *parent = v->parent;
1418 return MAPS_ERROR_NONE;
1421 int _maps_view_get_clipper(const maps_view_h view, Evas_Object **clipper)
1423 if (!view || !clipper)
1424 return MAPS_ERROR_INVALID_PARAMETER;
1425 maps_view_s *v = (maps_view_s *) view;
1426 *clipper = v->clipper;
1427 return MAPS_ERROR_NONE;
1430 EXPORT_API int maps_view_set_screen_location(maps_view_h view, int x, int y, int width, int height)
1432 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1433 return MAPS_ERROR_NOT_SUPPORTED;
1435 return MAPS_ERROR_INVALID_PARAMETER;
1436 if (!maps_condition_check_privilege())
1437 return MAPS_ERROR_PERMISSION_DENIED;
1439 int error = maps_view_move(view, x, y);
1440 if (error == MAPS_ERROR_NONE)
1441 error = maps_view_resize(view, width, height);
1445 EXPORT_API int maps_view_get_screen_location(const maps_view_h view, int *x, int *y, int *width, int *height)
1447 if (!maps_condition_check_maps_feature())
1448 return MAPS_ERROR_NOT_SUPPORTED;
1449 if (!view || (!x && !y && !width && !height))
1450 return MAPS_ERROR_INVALID_PARAMETER;
1451 maps_view_s *v = (maps_view_s *) view;
1452 evas_object_geometry_get(v->panel, x, y, width, height);
1453 return MAPS_ERROR_NONE;
1456 EXPORT_API int maps_view_move(maps_view_h view, int x, int y)
1458 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1459 return MAPS_ERROR_NOT_SUPPORTED;
1461 return MAPS_ERROR_INVALID_PARAMETER;
1463 maps_view_s *v = (maps_view_s *) view;
1464 evas_object_move(v->panel, x, y);
1465 evas_object_move(v->clipper, x, y);
1466 return MAPS_ERROR_NONE;
1469 EXPORT_API int maps_view_resize(maps_view_h view, int width, int height)
1471 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1472 return MAPS_ERROR_NOT_SUPPORTED;
1473 if (!view || (width <= 0) || (height <= 0))
1474 return MAPS_ERROR_INVALID_PARAMETER;
1475 if (!maps_condition_check_privilege())
1476 return MAPS_ERROR_PERMISSION_DENIED;
1478 maps_view_s *v = (maps_view_s *) view;
1479 evas_object_resize(v->panel, width, height);
1480 evas_object_resize(v->clipper, width, height);
1481 evas_object_image_fill_set(v->panel, 0, 0, width, height);
1482 return __maps_view_set_center(view, v->center, TRUE);
1485 EXPORT_API int maps_view_set_visibility(maps_view_h view, bool visible)
1487 if (!maps_condition_check_maps_feature())
1488 return MAPS_ERROR_NOT_SUPPORTED;
1490 return MAPS_ERROR_INVALID_PARAMETER;
1492 maps_view_s *v = (maps_view_s *) view;
1494 evas_object_show(v->panel);
1496 evas_object_hide(v->panel);
1497 return MAPS_ERROR_NONE;
1500 EXPORT_API int maps_view_get_visibility(const maps_view_h view, bool *visible)
1502 if (!maps_condition_check_maps_feature())
1503 return MAPS_ERROR_NOT_SUPPORTED;
1504 if (!view || !visible)
1505 return MAPS_ERROR_INVALID_PARAMETER;
1507 maps_view_s *v = (maps_view_s *) view;
1508 *visible = evas_object_visible_get(v->panel) == EINA_TRUE;
1509 return MAPS_ERROR_NONE;
1513 int _maps_view_redraw(const maps_view_h view)
1516 return MAPS_ERROR_INVALID_PARAMETER;
1518 maps_view_s *v = (maps_view_s *) view;
1520 /* Signal to the animator, that we are ready to draw */
1521 v->ready_to_draw = true;
1523 return MAPS_ERROR_NONE;
1527 /* ---------------------USER CONTROL------------------------------------------*/
1530 EXPORT_API int maps_view_set_event_cb(maps_view_h view, maps_view_event_type_e type,
1531 maps_view_on_event_cb callback, void *user_data)
1533 if (!maps_condition_check_maps_feature())
1534 return MAPS_ERROR_NOT_SUPPORTED;
1535 if (!view || !callback)
1536 return MAPS_ERROR_INVALID_PARAMETER;
1537 if ((type < MAPS_VIEW_EVENT_GESTURE) || (type > MAPS_VIEW_EVENT_READY))
1538 return MAPS_ERROR_INVALID_PARAMETER;
1540 maps_view_s *v = (maps_view_s *) view;
1541 v->event_callbacks[type].callback = callback;
1542 v->event_callbacks[type].user_data = user_data;
1544 return MAPS_ERROR_NONE;
1547 EXPORT_API int maps_view_unset_event_cb(maps_view_h view, maps_view_event_type_e type)
1549 if (!maps_condition_check_maps_feature())
1550 return MAPS_ERROR_NOT_SUPPORTED;
1552 return MAPS_ERROR_INVALID_PARAMETER;
1553 if ((type < MAPS_VIEW_EVENT_GESTURE) || (type > MAPS_VIEW_EVENT_READY))
1554 return MAPS_ERROR_INVALID_PARAMETER;
1556 maps_view_s *v = (maps_view_s *) view;
1557 v->event_callbacks[type].callback = __maps_view_on_event_empty_cb;
1558 v->event_callbacks[type].user_data = NULL;
1560 return MAPS_ERROR_NONE;
1563 EXPORT_API int maps_view_set_gesture_enabled(maps_view_h view, maps_view_gesture_e gesture, bool enabled)
1565 if (!maps_condition_check_maps_feature())
1566 return MAPS_ERROR_NOT_SUPPORTED;
1568 return MAPS_ERROR_INVALID_PARAMETER;
1569 if ((gesture < MAPS_VIEW_GESTURE_NONE) || (gesture > MAPS_VIEW_GESTURE_LONG_PRESS))
1570 return MAPS_ERROR_INVALID_PARAMETER;
1571 maps_view_s *v = (maps_view_s *) view;
1572 v->gesture_available[gesture] = enabled;
1573 return MAPS_ERROR_NONE;
1576 EXPORT_API int maps_view_get_gesture_enabled(const maps_view_h view, maps_view_gesture_e gesture, bool *enabled)
1578 if (!maps_condition_check_maps_feature())
1579 return MAPS_ERROR_NOT_SUPPORTED;
1580 if (!view || !enabled)
1581 return MAPS_ERROR_INVALID_PARAMETER;
1582 if ((gesture < MAPS_VIEW_GESTURE_NONE) || (gesture > MAPS_VIEW_GESTURE_LONG_PRESS))
1583 return MAPS_ERROR_INVALID_PARAMETER;
1584 maps_view_s *v = (maps_view_s *) view;
1585 *enabled = v->gesture_available[gesture];
1586 return MAPS_ERROR_NONE;
1590 /* ---------------------VISUAL OBJECTS ON THE MAP-----------------------------*/
1592 EXPORT_API int maps_view_add_object(maps_view_h view, maps_view_object_h object)
1594 if (!maps_condition_check_maps_feature())
1595 return MAPS_ERROR_NOT_SUPPORTED;
1596 if (!view || !object)
1597 return MAPS_ERROR_INVALID_PARAMETER;
1598 if (!maps_condition_check_privilege())
1599 return MAPS_ERROR_PERMISSION_DENIED;
1601 int error = MAPS_ERROR_NONE;
1603 /* Add Visual Object to the list of View Visual Objects */
1604 maps_view_s *v = (maps_view_s *)view;
1605 error = maps_item_list_append(v->view_objects, object, NULL);
1606 if (error != MAPS_ERROR_NONE)
1609 /* Link the object with the View */
1610 error = _maps_view_object_set_view(object, view);
1611 if (error != MAPS_ERROR_NONE)
1614 /* Notify the plugin about added object */
1615 error = _maps_view_on_object_operation(view, object, MAPS_VIEW_OBJECT_ADD);
1616 if (error != MAPS_ERROR_NONE)
1619 /* Redraw the view */
1620 error = _maps_view_redraw(v);
1621 if (error != MAPS_ERROR_NONE)
1624 return MAPS_ERROR_NONE;
1627 return error; //LCOV_EXCL_LINE
1630 EXPORT_API int maps_view_remove_object(maps_view_h view, maps_view_object_h object)
1632 if (!maps_condition_check_maps_feature())
1633 return MAPS_ERROR_NOT_SUPPORTED;
1634 if (!view || !object)
1635 return MAPS_ERROR_INVALID_PARAMETER;
1636 if (!maps_condition_check_privilege())
1637 return MAPS_ERROR_PERMISSION_DENIED;
1639 int error = MAPS_ERROR_NONE;
1641 /* Remove Visual Object from the list of View Visual Objects */
1642 maps_view_s *v = (maps_view_s *)view;
1643 error = maps_item_list_remove(v->view_objects, object, maps_view_object_destroy);
1644 if (error != MAPS_ERROR_NONE)
1647 /* Redraw the view */
1648 error = _maps_view_redraw(v);
1649 if (error != MAPS_ERROR_NONE)
1650 return error; //LCOV_EXCL_LINE
1652 return MAPS_ERROR_NONE;
1658 EXPORT_API int maps_view_remove_all_objects(maps_view_h view)
1660 if (!maps_condition_check_maps_feature())
1661 return MAPS_ERROR_NOT_SUPPORTED;
1663 return MAPS_ERROR_INVALID_PARAMETER;
1664 if (!maps_condition_check_privilege())
1665 return MAPS_ERROR_PERMISSION_DENIED;
1667 int error = MAPS_ERROR_NONE;
1669 maps_view_s *v = (maps_view_s *)view;
1670 error = maps_item_list_remove_all(v->view_objects, maps_view_object_destroy);
1671 if (error != MAPS_ERROR_NONE)
1674 /* Redraw the view */
1675 error = _maps_view_redraw(v);
1676 if (error != MAPS_ERROR_NONE)
1677 return error; //LCOV_EXCL_LINE
1679 return MAPS_ERROR_NONE;
1685 EXPORT_API int maps_view_foreach_object(maps_view_h view, maps_view_object_cb callback, void *user_data)
1687 if (!maps_condition_check_maps_feature())
1688 return MAPS_ERROR_NOT_SUPPORTED;
1689 if (!view || !callback)
1690 return MAPS_ERROR_INVALID_PARAMETER;
1691 maps_view_s *v = (maps_view_s *)view;
1692 if (!v->view_objects)
1693 return MAPS_ERROR_NOT_FOUND;
1694 return maps_item_list_foreach(v->view_objects, NULL, callback, user_data);
1698 /* ----------------------SEND MAP VIEW CALLBACK TO THE USER-------------------*/
1700 /* TODO: Consider refactoring of send Map View Callbacks to the User */
1702 maps_view_event_data_h _maps_view_create_event_data(maps_view_event_type_e type)
1704 maps_view_event_data_h event_data = NULL;
1705 const int error = _maps_view_event_data_create(&event_data);
1706 if (error != MAPS_ERROR_NONE) {
1708 maps_view_event_data_destroy(event_data);
1714 _maps_view_event_data_set_type(event_data, type);
1718 void _maps_view_invoke_event_callback(maps_view_h view, maps_view_event_data_h event_data)
1720 if (!view || !event_data)
1721 return; //LCOV_EXCL_LINE
1723 maps_view_s *v = (maps_view_s *)view;
1725 maps_view_event_type_e type = MAPS_VIEW_EVENT_GESTURE;
1726 maps_view_event_data_get_type(event_data, &type);
1729 int maps_view_event_data_get_gesture_type(const maps_view_event_data_h event, maps_view_gesture_e *gesture_type);
1730 int maps_view_event_data_get_action_type(const maps_view_event_data_h event, maps_view_action_e *action_type);
1731 int maps_view_event_data_get_object(const maps_view_event_data_h event, maps_view_object_h *object);
1732 int maps_view_object_get_type(maps_view_object_h object, maps_view_object_type_e *type);
1735 if (type == MAPS_VIEW_EVENT_GESTURE) {
1736 maps_view_event_data_get_gesture_type(event_data, (maps_view_gesture_e*)&subtype);
1737 } else if (type == MAPS_VIEW_EVENT_ACTION) {
1738 maps_view_event_data_get_action_type(event_data, (maps_view_action_e*)&subtype);
1739 } else if (type == MAPS_VIEW_EVENT_OBJECT) {
1740 maps_view_object_h object;
1741 maps_view_event_data_get_object(event_data, &object);
1742 maps_view_object_get_type(object, (maps_view_object_type_e*)&subtype);
1744 if (type == MAPS_VIEW_EVENT_READY)
1745 MAPS_LOGD("[invoked event] type=%d, subtype=%d", type, subtype);
1748 v->event_callbacks[type].callback(type, event_data, v->event_callbacks[type].user_data);
1751 /* ----------------------HIT TEST---------------------------------------------*/
1752 /* TODO: consider refactoring of Hit Test features and separation as
1753 * dedicated classes */
1755 typedef struct _maps_view_hit_test_data_s {
1759 maps_view_object_h object;
1760 } maps_view_hit_test_data_s;
1763 typedef struct _maps_view_collect_poly_object_point_s {
1765 view::poly_shape_hit_test *pd;
1766 } maps_view_collect_poly_object_point_s;
1769 static bool __maps_view_object_poly_collect_points_cb(int index, maps_coordinates_h point, void *user_data)
1771 if (!point || !user_data)
1774 maps_view_collect_poly_object_point_s *cpop =
1775 (maps_view_collect_poly_object_point_s *)user_data;
1779 if (maps_view_geolocation_to_screen(cpop->v, point, &x, &y) == MAPS_ERROR_NONE)
1780 cpop->pd->add_point(float(x), float(y));
1785 static bool __maps_view_hit_test_cb(int index, int total, maps_view_object_h object, void *user_data)
1787 if (!object || !user_data)
1790 /* If it is an unvisible object, skip this hit-testing. */
1791 bool visible = false;
1792 maps_view_object_get_visible(object, &visible);
1793 if (!visible) return true;
1795 maps_view_hit_test_data_s *htd = (maps_view_hit_test_data_s *)user_data;
1797 maps_view_object_type_e type;
1798 maps_view_object_get_type(object, &type);
1800 case MAPS_VIEW_OBJECT_POLYLINE: {
1801 view::poly_shape_hit_test pd;
1802 maps_view_collect_poly_object_point_s cpop = {htd->v, &pd};
1803 int error = maps_view_object_polyline_foreach_point(object,
1804 __maps_view_object_poly_collect_points_cb, &cpop);
1805 if (error != MAPS_ERROR_NONE)
1809 maps_view_object_polyline_get_width(object, &width);
1810 if (pd.hit_test(float(htd->x), float(htd->y), false, width))
1811 htd->object = object;
1816 case MAPS_VIEW_OBJECT_POLYGON: {
1817 view::poly_shape_hit_test pd;
1818 maps_view_collect_poly_object_point_s cpop = {htd->v, &pd};
1819 int error = maps_view_object_polygon_foreach_point(object,
1820 __maps_view_object_poly_collect_points_cb, &cpop);
1821 if (error != MAPS_ERROR_NONE)
1824 if (pd.hit_test(float(htd->x), float(htd->y), true))
1825 htd->object = object;
1829 case MAPS_VIEW_OBJECT_MARKER: {
1830 maps_coordinates_h c = NULL;
1831 maps_view_object_marker_get_coordinates(object, &c);
1835 maps_view_geolocation_to_screen(htd->v, c, &x, &y);
1836 maps_coordinates_destroy(c);
1840 maps_view_object_marker_get_size(object, &w, &h);
1842 /* In case of PIN marker type, rearrange the hit-area. */
1843 maps_view_marker_type_e marker_type;
1844 maps_view_object_marker_get_type(object, &marker_type);
1845 if (marker_type == MAPS_VIEW_MARKER_PIN)
1848 /* Add some margin of the hit-area. */
1849 w = MAX(w, htd->v->min_hit_area);
1850 h = MAX(h, htd->v->min_hit_area);
1852 /* Gets a half range to check hit-area */
1853 int hw = (int)(w / 2. + .5);
1854 int hh = (int)(h / 2. + .5);
1856 /* Check hit-area */
1857 if ((x > (htd->x - hw)) && (x < (htd->x + hw))
1858 && (y > (htd->y - hh)) && (y < (htd->y + hh))) {
1859 htd->object = object;
1874 maps_view_object_h _maps_view_object_hit_test(maps_view_h view, int x, int y, maps_view_gesture_e gesture)
1879 maps_view_s *v = (maps_view_s *)view;
1881 /* Check if we are going to inform anyone about object events */
1882 if (v->event_callbacks[MAPS_VIEW_EVENT_OBJECT].callback
1883 == __maps_view_on_event_empty_cb)
1886 /* 1. Iterate through the list of object and test the hit */
1887 maps_view_hit_test_data_s htd = {v, x, y, NULL};
1888 int error = maps_view_foreach_object(view, __maps_view_hit_test_cb, &htd);
1889 if ((error != MAPS_ERROR_NONE) || !htd.object)
1892 /*g_print("Hit Test: FOUND OBJECT: %p\n", htd.object);*/
1894 /* Invoke user registered event callback */
1895 maps_view_event_data_h ed =
1896 _maps_view_create_event_data(MAPS_VIEW_EVENT_OBJECT);
1898 _maps_view_event_data_set_object(ed, htd.object);
1899 _maps_view_event_data_set_gesture_type(ed, gesture);
1900 _maps_view_invoke_event_callback(view, ed);
1901 maps_view_event_data_destroy(ed);
1904 /* 2. Extract test result */
1909 EXPORT_API int maps_view_get_maps_plugin_view_handle(maps_view_h view, void **maps_plugin_view_handle)
1911 if (!maps_condition_check_maps_feature())
1912 return MAPS_ERROR_NOT_SUPPORTED;
1913 if (!view || !maps_plugin_view_handle)
1914 return MAPS_ERROR_INVALID_PARAMETER;
1916 maps_view_s *v = (maps_view_s *)view;
1917 *maps_plugin_view_handle = v->maps_plugin_view_handle;
1918 return MAPS_ERROR_NONE;
1921 EXPORT_API int maps_view_set_maps_plugin_view_handle(maps_view_h view, void *maps_plugin_view_handle)
1923 if (!maps_condition_check_maps_feature())
1924 return MAPS_ERROR_NOT_SUPPORTED;
1926 return MAPS_ERROR_INVALID_PARAMETER;
1928 maps_view_s *v = (maps_view_s *)view;
1929 v->maps_plugin_view_handle = maps_plugin_view_handle;
1930 return MAPS_ERROR_NONE;
1933 EXPORT_API int maps_view_get_scale_factor(maps_view_h view, double *scale_factor)
1935 if (!maps_condition_check_maps_feature())
1936 return MAPS_ERROR_NOT_SUPPORTED;
1937 if (!view || !scale_factor)
1938 return MAPS_ERROR_INVALID_PARAMETER;
1940 const plugin::interface_s *plugin = __get_plugin_interface(view);
1942 return MAPS_ERROR_INVALID_PARAMETER;
1943 if (!plugin->maps_plugin_get_view_scale_factor)
1944 return MAPS_ERROR_NOT_SUPPORTED;
1945 return plugin->maps_plugin_get_view_scale_factor(view, scale_factor);
1948 EXPORT_API int maps_view_set_scale_factor(maps_view_h view, double scale_factor)
1950 if (!maps_condition_check_maps_feature())
1951 return MAPS_ERROR_NOT_SUPPORTED;
1953 return MAPS_ERROR_INVALID_PARAMETER;
1954 if (scale_factor < 0.1 || scale_factor > 10.0)
1955 return MAPS_ERROR_INVALID_PARAMETER;
1957 const plugin::interface_s *plugin = __get_plugin_interface(view);
1959 return MAPS_ERROR_INVALID_PARAMETER;
1960 if (!plugin->maps_plugin_set_view_scale_factor)
1961 return MAPS_ERROR_NOT_SUPPORTED;
1963 return plugin->maps_plugin_set_view_scale_factor(view, scale_factor);