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)
175 session::command_queue *__maps_view_select_q()
178 * This is a draw-enforcing mode, when the rendering and drawing
179 * of the map is happening as fast as it possible.
180 * This mode is good when the Map View is a single active widget
182 * In this mode we are relying on the ecore main loop and the
183 * assumption, that loop steps will apear continuously, not
185 * https://docs.enlightenment.org/efl/1.15.0/Ecore_Main_Loop_Page.html
187 return session::command_queue_sync::interface();
190 * This is an analogy of previous mode, but with thread safety
193 /*return session::command_queue_async::interface();*/
196 * This is a thread-friendly mode, when all heavy computations
197 * are performed in the "idle" mode.
198 * This mode is good for apps, which has other active widgets in
199 * addition to Map View.
200 * This approach allows compression of repeating commands as well
202 /* return session::command_queue_view::interface(); */
205 bool _maps_view_is_gesture_available(maps_view_h view, maps_view_gesture_e gesture)
209 maps_view_s *v = (maps_view_s *)view;
210 return v->gesture_available[gesture];
213 maps_view_action_e _maps_view_get_gesture_action(maps_view_h view, maps_view_gesture_e gesture)
216 return MAPS_VIEW_ACTION_NONE;
217 maps_view_s *v = (maps_view_s *)view;
218 return v->gesture_actions[gesture];
221 void *_maps_view_get_maps_service_ptr(maps_view_h view)
225 maps_view_s *v = (maps_view_s *)view;
229 int _maps_view_on_overlay_update_all(maps_view_h view)
232 return MAPS_ERROR_INVALID_PARAMETER;
234 maps_view_s *v = (maps_view_s *)view;
235 if (!v->view_objects)
236 return MAPS_ERROR_NOT_FOUND;
237 return maps_item_list_foreach(v->view_objects, NULL, _maps_view_object_overlay_cb, v->clipper);
240 int _maps_view_on_object_operation(maps_view_h view, maps_view_object_h object, maps_view_object_operation_e operation)
243 return MAPS_ERROR_INVALID_PARAMETER;
245 maps_view_object_type_e type;
246 maps_view_object_get_type(object, &type);
247 if (type == MAPS_VIEW_OBJECT_OVERLAY) {
248 return _maps_view_object_overlay_operation(view, object, operation);
250 if(!__get_plugin_interface(view)->maps_plugin_on_object)
251 return MAPS_ERROR_INVALID_PARAMETER;
253 return __get_plugin_interface(view)->maps_plugin_on_object(view, object, operation);
257 static void __on_canvas_tap(void *data, Evas *e, Evas_Object *obj, void *event_info)
259 MAPS_LOGI("__on_canvas_tap");
260 if (!event_info || !data)
263 /* Extract the view ptr */
264 maps_view_s *v = (maps_view_s *)data;
265 if (!v->finger_stream)
268 /* Detect & Process the gesture */
269 v->finger_stream->tap((Evas_Event_Mouse_Down *)event_info);
272 static void __on_canvas_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
274 MAPS_LOGI("__on_canvas_up");
275 if (!event_info || !data)
278 /* Extract the view ptr */
279 maps_view_s *v = (maps_view_s *)data;
280 if (!v->finger_stream)
283 /* Detect & Process the gesture */
284 v->finger_stream->up((Evas_Event_Mouse_Up *)event_info);
287 static void __on_canvas_line(void *data, Evas *e, Evas_Object *obj, void *event_info)
289 MAPS_LOGI("__on_canvas_line");
290 if (!event_info || !data)
293 /* Extract view ptr */
294 maps_view_s *v = (maps_view_s *)data;
295 if (!v->finger_stream)
298 /* Detect & Process the gesture */
299 v->finger_stream->move((Evas_Event_Mouse_Move *)event_info);
302 static void __on_canvas_multi_tap(void *data, Evas *e, Evas_Object *obj, void *event_info)
304 MAPS_LOGI("__on_canvas_multi_tap");
305 if (!event_info || !data)
308 /* Extract view ptr */
309 maps_view_s *v = (maps_view_s *)data;
310 if (!v->finger_stream)
313 /* Detect & Process the gesture */
314 v->finger_stream->multi_tap((Evas_Event_Multi_Down *)event_info);
317 static void __on_canvas_multi_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
319 MAPS_LOGI("__on_canvas_multi_up");
320 if (!event_info || !data)
323 /* Extract view ptr */
324 maps_view_s *v = (maps_view_s *)data;
325 if (!v->finger_stream)
328 /* Detect & Process the gesture */
329 v->finger_stream->multi_up((Evas_Event_Multi_Up *)event_info);
332 static void __on_canvas_multi_line(void *data, Evas *e, Evas_Object *obj, void *event_info)
334 MAPS_LOGI("__on_canvas_multi_line");
335 if (!event_info || !data)
338 /* Extract view ptr */
339 maps_view_s *v = (maps_view_s *)data;
340 if (!v->finger_stream)
343 /* Detect & Process the gesture */
344 v->finger_stream->multi_move((Evas_Event_Multi_Move *)event_info);
347 static int __maps_plugin_render_map(const maps_view_h view,
348 const maps_coordinates_h coordinates, const double zoom_factor, const double rotation_angle)
350 if (!view || !coordinates)
351 return MAPS_ERROR_INVALID_PARAMETER;
353 return __get_plugin_interface(view)->maps_plugin_render_map(view,
354 coordinates, zoom_factor, rotation_angle);
357 void _maps_view_set_idle_listener(const maps_view_h view,
358 void (*callback)(void *user_data), void *user_data)
362 maps_view_s *v = (maps_view_s *)view;
363 v->idle_listener.callback = callback;
364 v->idle_listener.user_data = user_data;
367 void _maps_view_halt_inertial_camera(maps_view_h view)
369 maps_view_s *v = (maps_view_s *)view;
370 if (v && v->inertial_camera && v->inertial_camera->is_transiting()) {
371 v->inertial_camera->set_transiting(false);
376 static Eina_Bool __maps_view_on_idle_cb(void *data)
379 return ECORE_CALLBACK_RENEW;
381 maps_view_s *v = (maps_view_s *)data;
383 bool is_transiting = false;
384 bool is_continue = false;
386 view::inertial_gesture *ig = v->inertial_gesture;
387 if (ig && ig->is_transiting()) {
388 is_transiting |= true;
389 is_continue |= ig->next_transition_step();
393 view::inertial_camera *ic = v->inertial_camera;
394 if (ic && ic->is_transiting()) {
395 is_transiting |= true;
396 is_continue |= ic->next_transition_step();
397 __maps_plugin_render_map(v,
398 ic->get_cur_center(),
399 ic->get_cur_zoom_factor(),
400 ic->get_cur_rotation_angle());
401 _maps_coordinates_copy(ic->get_cur_center(), v->center);
403 _maps_view_on_overlay_update_all(v);
407 if (is_transiting && !is_continue) {
408 maps_view_event_data_h ed = _maps_view_create_event_data(MAPS_VIEW_EVENT_READY);
410 _maps_view_invoke_event_callback(v, ed);
411 maps_view_event_data_destroy(ed);
415 return ECORE_CALLBACK_RENEW; // same as EINA_TRUE
418 static Eina_Bool __maps_view_animator_cb(void *data)
420 return ECORE_CALLBACK_RENEW;
423 void __maps_view_ready(const maps_view_h view)
427 maps_view_s *v = (maps_view_s*)view;
430 _maps_view_set_inertia_enabled(view, true);
432 /* Invoke user registered event callback */
433 maps_view_event_data_h ed = _maps_view_create_event_data(MAPS_VIEW_EVENT_READY);
435 _maps_view_invoke_event_callback(view, ed);
436 maps_view_event_data_destroy(ed);
441 /* ----------------------CREATE AND DESTROY-----------------------------------*/
443 static void __maps_view_parent_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
445 maps_view_s *v = (maps_view_s*)data;
447 int x, y, w, h, ox, oy, ow, oh;
449 /* get geometries of evas object to check how much are changed */
450 evas_object_geometry_get(v->parent, &x, &y, &w, &h);
451 evas_object_geometry_get(v->panel, &ox, &oy, &ow, &oh);
453 /* compensate difference of center to keep the map image not to move for eyes after ready */
455 _maps_view_move_center(v, (x - ox) / 2, (y - oy) / 2);
457 /* set center with stored value */
458 _maps_view_get_plugin_center(v, &v->center);
459 maps_view_set_screen_location(v, x, y, w, h);
462 static void __maps_view_panel_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
464 maps_view_s *v = (maps_view_s*)data;
466 int x, y, w, h, ox, oy, ow, oh;
468 /* get geometries of evas object to check how much are changed */
469 evas_object_geometry_get(v->panel, &x, &y, &w, &h);
470 evas_object_geometry_get(v->clipper, &ox, &oy, &ow, &oh);
472 /* compensate difference of center to keep the map image not to move for eyes after ready */
474 _maps_view_move_center(v, (x - ox) / 2, (y - oy) / 2);
476 /* set center with stored value */
477 _maps_view_get_plugin_center(v, &v->center);
478 maps_view_set_screen_location(v, x, y, w, h);
481 static void __maps_view_create_panel(maps_view_h view, Evas_Object *obj)
486 maps_view_s *v = (maps_view_s*)view;
488 /* Initialize the panel */
489 if (!strncmp(evas_object_type_get(obj), "image", strlen("image"))) {
490 /* if obj is Evas_Image object */
491 MAPS_LOGD("The panel is a Evas_Image");
494 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_RESIZE, __maps_view_panel_resize_cb, v);
496 /* if obj is the other kind of (smart) objects */
498 v->panel = evas_object_image_add(evas_object_evas_get(v->parent));
499 evas_object_smart_member_add(v->panel, v->parent);
500 evas_object_event_callback_add(v->parent, EVAS_CALLBACK_RESIZE, __maps_view_parent_resize_cb, v);
502 if (evas_object_visible_get(v->parent))
503 evas_object_show(v->panel);
505 evas_object_hide(v->panel);
507 /* Equal size of a panel object and a parent object */
509 evas_object_geometry_get(v->parent, &x, &y, &w, &h);
510 evas_object_move(v->panel, x, y);
511 evas_object_resize(v->panel, w, h);
512 evas_object_image_fill_set(v->panel, 0, 0, w, h);
514 evas_object_image_filled_set(v->panel, EINA_FALSE);
517 /* Create the panel and link it to the instance of Maps Service */
518 EXPORT_API int maps_view_create(maps_service_h maps, Evas_Object *obj, maps_view_h *view)
520 if (!maps_condition_check_maps_feature())
521 return MAPS_ERROR_NOT_SUPPORTED;
523 return MAPS_ERROR_INVALID_PARAMETER;
524 if (!maps_condition_check_service_supported(maps, MAPS_SERVICE_VIEW))
525 return MAPS_ERROR_NOT_SUPPORTED;
527 return MAPS_ERROR_INVALID_PARAMETER;
528 if (!maps_condition_check_privilege())
529 return MAPS_ERROR_PERMISSION_DENIED;
531 maps_view_s *v = g_slice_new0(maps_view_s);
533 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
534 return MAPS_ERROR_OUT_OF_MEMORY;
537 /* Initialize the list with visual objects */
538 maps_item_list_create(&v->view_objects);
540 /* Initialize the panel */
541 __maps_view_create_panel(v, obj);
543 v->maps_plugin_view_handle = NULL;
545 /* Set up event callbacks by default */
546 const int event_callback_cnt =
547 sizeof(v->event_callbacks) / sizeof(v->event_callbacks[0]);
548 for(int i = 0; i < event_callback_cnt; i ++) {
549 v->event_callbacks[i].callback = __maps_view_on_event_empty_cb;
550 v->event_callbacks[i].user_data = NULL;
553 /* Assign gestures to actions */
554 v->gesture_actions[MAPS_VIEW_GESTURE_SCROLL] = MAPS_VIEW_ACTION_NONE;
555 v->gesture_actions[MAPS_VIEW_GESTURE_ZOOM] = MAPS_VIEW_ACTION_ZOOM;
556 v->gesture_actions[MAPS_VIEW_GESTURE_TAP] = MAPS_VIEW_ACTION_NONE;
557 v->gesture_actions[MAPS_VIEW_GESTURE_DOUBLE_TAP] = MAPS_VIEW_ACTION_ZOOM_IN;
558 v->gesture_actions[MAPS_VIEW_GESTURE_2_FINGER_TAP] = MAPS_VIEW_ACTION_ZOOM_OUT;
559 v->gesture_actions[MAPS_VIEW_GESTURE_ROTATE] = MAPS_VIEW_ACTION_ROTATE;
560 v->gesture_actions[MAPS_VIEW_GESTURE_LONG_PRESS] = MAPS_VIEW_ACTION_NONE;
561 v->gesture_actions[MAPS_VIEW_GESTURE_NONE] = MAPS_VIEW_ACTION_NONE;
563 /* Set up gesture availability */
564 v->gesture_available[MAPS_VIEW_GESTURE_SCROLL] = true;
565 v->gesture_available[MAPS_VIEW_GESTURE_ZOOM] = true;
566 v->gesture_available[MAPS_VIEW_GESTURE_TAP] = true;
567 v->gesture_available[MAPS_VIEW_GESTURE_DOUBLE_TAP] = true;
568 v->gesture_available[MAPS_VIEW_GESTURE_2_FINGER_TAP] = true;
569 v->gesture_available[MAPS_VIEW_GESTURE_ROTATE] = true;
570 v->gesture_available[MAPS_VIEW_GESTURE_LONG_PRESS] = true;
571 v->gesture_available[MAPS_VIEW_GESTURE_NONE] = false;
573 /* Gesture Processing */
574 v->finger_stream = new view::finger_event_stream(v);
575 if (!v->finger_stream) {
576 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
577 return MAPS_ERROR_OUT_OF_MEMORY;
579 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_DOWN, __on_canvas_tap, v);
580 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_UP, __on_canvas_up, v);
581 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MOUSE_MOVE, __on_canvas_line, v);
583 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_DOWN, __on_canvas_multi_tap, v);
584 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_UP, __on_canvas_multi_up, v);
585 evas_object_event_callback_add(v->panel, EVAS_CALLBACK_MULTI_MOVE, __on_canvas_multi_line, v);
587 /* Set up canvas and Ecore */
588 v->canvas = evas_object_evas_get(v->panel);
589 /*v->ee = ecore_evas_ecore_evas_get(v->canvas);*/
591 v->clipper = evas_object_rectangle_add(v->canvas);
593 /* Link with Maps Service */
596 /* Set up canvas and Ecore */
597 v->language = g_strdup("en-US");
599 /* Add an idle handler */
600 v->idler = ecore_idler_add(__maps_view_on_idle_cb, v);
602 /* Set up the animation frame rate */
603 /*ecore_animator_frametime_set(0.1);*/
605 /* Create the animator and assign the drawing task */
606 v->animator = ecore_animator_add(__maps_view_animator_cb, v);
608 /* Set up the output pointer to the Maps View */
609 *view = (maps_view_h) v;
611 if (__get_plugin_interface(v)) {
612 /* Notify the Plugin, that the view is created */
613 if (__get_plugin_interface(v)->maps_plugin_create_map_view)
614 __get_plugin_interface(v)->maps_plugin_create_map_view(*view, __maps_view_ready);
616 MAPS_LOGE("ERROR!! maps_plugin_create_map_view function pointer is null");
618 /* Set up zoom and rotation */
619 if (__get_plugin_interface(v)->maps_plugin_get_min_zoom_level)
620 __get_plugin_interface(v)->maps_plugin_get_min_zoom_level(v, &v->min_zoom_level);
622 MAPS_LOGE("ERROR!! maps_plugin_get_min_zoom_level function pointer is null");
624 if (__get_plugin_interface(v)->maps_plugin_get_max_zoom_level)
625 __get_plugin_interface(v)->maps_plugin_get_max_zoom_level(v, &v->max_zoom_level);
627 MAPS_LOGE("ERROR!! maps_plugin_get_max_zoom_level function pointer is null");
630 if (v->min_zoom_level <= 0)
631 v->min_zoom_level = 2;
632 if (v->max_zoom_level <= 0)
633 v->max_zoom_level = 2;
635 v->zoom_level = v->min_zoom_level;
636 v->zoom_factor = double(v->zoom_level);
637 v->rotation_angle = 0.;
639 maps_coordinates_create(.0, .0, &v->center);
641 v->type = MAPS_VIEW_TYPE_NORMAL;
642 v->buildings_enabled = false;
643 v->traffic_enabled = false;
644 v->public_transit_enabled = false;
646 /* To check hit_test */
647 maps_get_screen_dpi(&v->screen_dpi);
648 v->min_hit_area = MAX(20, v->screen_dpi / 5);
650 /* Update map view */
651 __maps_view_set_center(v, v->center, TRUE);
653 return MAPS_ERROR_NONE;
656 /* Destroy the panel and unlink it from the instance of Maps Service */
657 EXPORT_API int maps_view_destroy(maps_view_h view)
659 if (!maps_condition_check_maps_feature())
660 return MAPS_ERROR_NOT_SUPPORTED;
662 return MAPS_ERROR_INVALID_PARAMETER;
663 if (!maps_condition_check_privilege())
664 return MAPS_ERROR_PERMISSION_DENIED;
666 maps_view_s *v = (maps_view_s *) view;
668 /* Unregister gesture processing */
669 if (v->finger_stream)
670 delete v->finger_stream;
671 v->finger_stream = NULL;
673 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_DOWN, __on_canvas_tap);
674 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_UP, __on_canvas_up);
675 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MOUSE_MOVE, __on_canvas_line);
677 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_DOWN, __on_canvas_multi_tap);
678 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_UP, __on_canvas_multi_up);
679 evas_object_event_callback_del(v->panel, EVAS_CALLBACK_MULTI_MOVE, __on_canvas_multi_line);
682 /* Unregister idle handler */
684 ecore_idler_del(v->idler);
686 view::inertial_camera *inertial_camera = v->inertial_camera;
687 v->inertial_camera = NULL;
688 v->idle_listener.callback = NULL;
690 /* Delete the animator */
692 ecore_animator_del(v->animator);
694 /* Notify the Plugin, that the view is to be destroyed */
695 if (__get_plugin_interface(view)) {
696 if (__get_plugin_interface(view)->maps_plugin_destroy_map_view)
697 __get_plugin_interface(view)->maps_plugin_destroy_map_view(view);
699 MAPS_LOGE("ERROR!! maps_plugin_destroy_map_view function pointer is null");
702 /* Destroy a visual panel */
704 evas_object_del(v->panel);
707 evas_object_del(v->clipper);
710 maps_coordinates_destroy(v->center);
713 maps_area_destroy(v->area);
715 /* Destroy the list with visual objects */
716 maps_item_list_remove_all(v->view_objects, maps_view_object_destroy);
717 maps_item_list_destroy(v->view_objects);
722 g_slice_free(maps_view_s, v);
725 delete inertial_camera;
727 return MAPS_ERROR_NONE;
731 int _maps_view_set_center_directly(const maps_view_h view,
732 const maps_coordinates_h coordinates)
734 if (!view || !coordinates)
735 return MAPS_ERROR_INVALID_PARAMETER;
737 maps_view_s *v = (maps_view_s *) view;
738 if (v->center != coordinates) {
740 maps_coordinates_destroy(v->center);
741 maps_coordinates_clone(coordinates, &v->center);
743 return MAPS_ERROR_NONE;
746 int _maps_view_get_plugin_center(const maps_view_h view,
747 maps_coordinates_h *center)
749 if (!view || !center)
750 return MAPS_ERROR_INVALID_PARAMETER;
752 return __get_plugin_interface(view)->maps_plugin_get_center(view, center);
755 /*----------------------MAP ZOOM, ROTATE, SET CENTER--------------------------*/
757 /* Show the map with a given position centered using current zoom level and
760 static int __maps_view_set_center(maps_view_h view, maps_coordinates_h coordinates, bool internal)
762 if (!view || !coordinates)
763 return MAPS_ERROR_INVALID_PARAMETER;
764 double zoom_factor = 1.;
765 int error = maps_view_get_zoom_factor(view, &zoom_factor);
766 if (error != MAPS_ERROR_NONE)
769 double rotation_angle = 0.;
770 error = maps_view_get_orientation(view, &rotation_angle);
771 if (error != MAPS_ERROR_NONE)
774 maps_view_s *v = (maps_view_s *) view;
776 /* Set up the target for camera inertial movement */
777 if(v->inertial_camera && !internal)
778 v->inertial_camera->set_targets(coordinates,
782 /* Rund rendering in the plugin */
783 error = __maps_plugin_render_map(view,
788 if (v->center != coordinates) {
789 maps_coordinates_destroy(v->center);
790 maps_coordinates_clone(coordinates, &v->center);
793 _maps_view_on_overlay_update_all(view);
796 /* Invoke user registered event callback */
797 maps_view_event_data_h ed =
798 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
800 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_SCROLL);
801 _maps_view_event_data_set_center(ed, v->center);
802 _maps_view_invoke_event_callback(v, ed);
803 maps_view_event_data_destroy(ed);
810 EXPORT_API int maps_view_set_center(maps_view_h view, maps_coordinates_h coordinates)
812 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
813 return MAPS_ERROR_NOT_SUPPORTED;
814 if (!view || !coordinates)
815 return MAPS_ERROR_INVALID_PARAMETER;
816 if (!maps_condition_check_privilege())
817 return MAPS_ERROR_PERMISSION_DENIED;
819 return __maps_view_set_center(view, coordinates, FALSE);
822 int _maps_view_move_center(maps_view_h view, const int delta_x, const int delta_y)
825 return MAPS_ERROR_INVALID_PARAMETER;
827 int error = __get_plugin_interface(view)->maps_plugin_move_center(view, delta_x, delta_y);
829 /* update position of overlay objects */
830 _maps_view_on_overlay_update_all(view);
832 /* Invoke user registered event callback */
833 maps_view_event_data_h ed =
834 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
836 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_SCROLL);
837 _maps_view_event_data_set_delta(ed, delta_x, delta_y);
838 _maps_view_invoke_event_callback(view, ed);
839 maps_view_event_data_destroy(ed);
845 EXPORT_API int maps_view_set_scalebar_enabled(const maps_view_h view, bool enable)
847 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
848 return MAPS_ERROR_NOT_SUPPORTED;
850 return MAPS_ERROR_INVALID_PARAMETER;
851 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_SCALEBAR))
852 return MAPS_ERROR_NOT_SUPPORTED;
853 if (!maps_condition_check_privilege())
854 return MAPS_ERROR_PERMISSION_DENIED;
856 return __get_plugin_interface(view)->maps_plugin_set_scalebar(view, enable);
859 EXPORT_API int maps_view_get_scalebar_enabled(const maps_view_h view, bool *enabled)
861 if (!maps_condition_check_maps_feature())
862 return MAPS_ERROR_NOT_SUPPORTED;
864 return MAPS_ERROR_INVALID_PARAMETER;
865 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_SCALEBAR))
866 return MAPS_ERROR_NOT_SUPPORTED;
868 return MAPS_ERROR_INVALID_PARAMETER;
870 return __get_plugin_interface(view)->maps_plugin_get_scalebar(view, enabled);
873 EXPORT_API int maps_view_get_center(const maps_view_h view, maps_coordinates_h *coordinates)
875 if (!maps_condition_check_maps_feature())
876 return MAPS_ERROR_NOT_SUPPORTED;
877 if (!view || !coordinates)
878 return MAPS_ERROR_INVALID_PARAMETER;
879 maps_view_s *v = (maps_view_s *) view;
880 return maps_coordinates_clone(v->center, coordinates);
883 EXPORT_API int maps_view_set_zoom_level(maps_view_h view, int level)
885 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
886 return MAPS_ERROR_NOT_SUPPORTED;
888 return MAPS_ERROR_INVALID_PARAMETER;
889 if (!maps_condition_check_privilege())
890 return MAPS_ERROR_PERMISSION_DENIED;
892 maps_view_s *v = (maps_view_s *) view;
893 int new_level = level;
894 if (new_level < v->min_zoom_level) new_level = v->min_zoom_level;
895 if (new_level > v->max_zoom_level) new_level = v->max_zoom_level;
897 /* Add inertia to the zoom process */
898 if (v->inertial_camera)
899 v->inertial_camera->set_zoom_target(double(new_level));
901 v->zoom_level = new_level;
902 v->zoom_factor = double(new_level); /* Update the integer zoom level too */
904 const int error = maps_view_set_center(view, v->center);
906 /* Invoke user registered event callback */
907 maps_view_event_data_h ed =
908 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
910 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ZOOM);
911 _maps_view_event_data_set_zoom_factor(ed, v->zoom_factor);
912 _maps_view_invoke_event_callback(v, ed);
913 maps_view_event_data_destroy(ed);
919 EXPORT_API int maps_view_get_zoom_level(const maps_view_h view, int *level)
921 if (!maps_condition_check_maps_feature())
922 return MAPS_ERROR_NOT_SUPPORTED;
924 return MAPS_ERROR_INVALID_PARAMETER;
925 maps_view_s *v = (maps_view_s *) view;
926 *level = v->zoom_level;
927 return MAPS_ERROR_NONE;
930 EXPORT_API int maps_view_set_min_zoom_level(maps_view_h view, int level)
932 if (!maps_condition_check_maps_feature())
933 return MAPS_ERROR_NOT_SUPPORTED;
935 return MAPS_ERROR_INVALID_PARAMETER;
936 if (!maps_condition_check_privilege())
937 return MAPS_ERROR_PERMISSION_DENIED;
939 maps_view_s *v = (maps_view_s *) view;
940 int min_zoom_level = -1;
941 __get_plugin_interface(v)->maps_plugin_get_min_zoom_level(view, &min_zoom_level);
942 if (min_zoom_level < 0)
943 return MAPS_ERROR_INVALID_OPERATION;
944 if ((level < min_zoom_level) || (level > v->max_zoom_level))
945 return MAPS_ERROR_INVALID_PARAMETER;
946 v->min_zoom_level = level;
947 if (v->min_zoom_level > v->zoom_level)
948 maps_view_set_zoom_level(view, v->min_zoom_level);
949 return MAPS_ERROR_NONE;
952 EXPORT_API int maps_view_get_min_zoom_level(const maps_view_h view, int *min_zoom_level)
954 if (!maps_condition_check_maps_feature())
955 return MAPS_ERROR_NOT_SUPPORTED;
956 if (!view || !min_zoom_level)
957 return MAPS_ERROR_INVALID_PARAMETER;
958 maps_view_s *v = (maps_view_s *) view;
959 *min_zoom_level = v->min_zoom_level;
960 return MAPS_ERROR_NONE;
963 EXPORT_API int maps_view_set_max_zoom_level(maps_view_h view, int level)
965 if (!maps_condition_check_maps_feature())
966 return MAPS_ERROR_NOT_SUPPORTED;
968 return MAPS_ERROR_INVALID_PARAMETER;
969 if (!maps_condition_check_privilege())
970 return MAPS_ERROR_PERMISSION_DENIED;
972 maps_view_s *v = (maps_view_s *) view;
973 int max_zoom_level = -1;
974 __get_plugin_interface(v)->maps_plugin_get_max_zoom_level(view, &max_zoom_level);
975 if (max_zoom_level < 0)
976 return MAPS_ERROR_INVALID_OPERATION;
977 if ((level < v->min_zoom_level) || (level > max_zoom_level))
978 return MAPS_ERROR_INVALID_PARAMETER;
979 v->max_zoom_level = level;
980 if (v->max_zoom_level < v->zoom_level)
981 maps_view_set_zoom_level(view, v->max_zoom_level);
982 return MAPS_ERROR_NONE;
985 EXPORT_API int maps_view_get_max_zoom_level(const maps_view_h view, int *max_zoom_level)
987 if (!maps_condition_check_maps_feature())
988 return MAPS_ERROR_NOT_SUPPORTED;
989 if (!view || !max_zoom_level)
990 return MAPS_ERROR_INVALID_PARAMETER;
991 maps_view_s *v = (maps_view_s *) view;
992 *max_zoom_level = v->max_zoom_level;
993 return MAPS_ERROR_NONE;
996 int _maps_view_set_zoom_rotate(maps_view_h view,
997 const bool zoom_changed,
999 const bool rotation_changed,
1003 return MAPS_ERROR_INVALID_PARAMETER;
1005 maps_view_s *v = (maps_view_s *) view;
1007 /* 1. Apply new zoom and orientation values */
1009 double new_factor = factor;
1010 if (new_factor < v->min_zoom_level) new_factor = v->min_zoom_level;
1011 if (new_factor > v->max_zoom_level) new_factor = v->max_zoom_level;
1013 /* Add inertia to the zoom process */
1014 if (v->inertial_camera)
1015 v->inertial_camera->set_zoom_target(new_factor);
1017 /* Update Map View zoom factor */
1018 v->zoom_factor = new_factor;
1020 /* Update the integer zoom level too */
1021 v->zoom_level = int(new_factor);
1024 if (rotation_changed) {
1025 /* Add inertia to the rotation process */
1026 if (v->inertial_camera)
1027 v->inertial_camera->set_rotation_target(angle);
1029 /* Update Map View rotation angle */
1030 v->rotation_angle = angle;
1033 /* 2. Send update center command to the plugin */
1034 const int error = maps_view_set_center(view, v->center);
1036 /* Notify the user about changes */
1038 /* Invoke user registered event callback */
1039 maps_view_event_data_h ed =
1040 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
1042 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ZOOM);
1043 _maps_view_event_data_set_zoom_factor(ed, v->zoom_factor);
1044 _maps_view_invoke_event_callback(v, ed);
1045 maps_view_event_data_destroy(ed);
1049 if (rotation_changed) {
1050 /* Invoke user registered event callback */
1051 maps_view_event_data_h ed =
1052 _maps_view_create_event_data(MAPS_VIEW_EVENT_ACTION);
1054 _maps_view_event_data_set_action_type(ed, MAPS_VIEW_ACTION_ROTATE);
1055 _maps_view_event_data_set_rotation_angle(ed, v->rotation_angle);
1056 _maps_view_invoke_event_callback(v, ed);
1057 maps_view_event_data_destroy(ed);
1064 EXPORT_API int maps_view_set_zoom_factor(const maps_view_h view,
1065 const double factor)
1067 if (!maps_condition_check_maps_feature())
1068 return MAPS_ERROR_NOT_SUPPORTED;
1070 return MAPS_ERROR_INVALID_PARAMETER;
1072 maps_view_s *v = (maps_view_s *) view;
1073 double new_factor = factor;
1074 if (new_factor < v->min_zoom_level) new_factor = v->min_zoom_level;
1075 if (new_factor > v->max_zoom_level) new_factor = v->max_zoom_level;
1077 return _maps_view_set_zoom_rotate(view, true, new_factor, false, .0);
1080 EXPORT_API int maps_view_get_zoom_factor(const maps_view_h view, double *factor)
1082 if (!maps_condition_check_maps_feature())
1083 return MAPS_ERROR_NOT_SUPPORTED;
1084 if (!view || !factor)
1085 return MAPS_ERROR_INVALID_PARAMETER;
1086 maps_view_s *v = (maps_view_s *) view;
1087 *factor = v->zoom_factor;
1088 return MAPS_ERROR_NONE;
1091 EXPORT_API int maps_view_set_orientation(maps_view_h view, double angle)
1093 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1094 return MAPS_ERROR_NOT_SUPPORTED;
1096 return MAPS_ERROR_INVALID_PARAMETER;
1097 if (!maps_condition_check_privilege())
1098 return MAPS_ERROR_PERMISSION_DENIED;
1100 /* Add inertia to the rotation process */
1101 maps_view_s *v = (maps_view_s *)view;
1102 if (v->inertial_camera)
1103 v->inertial_camera->set_rotation_target(angle);
1105 return _maps_view_set_zoom_rotate(view, false, .0, true, angle);
1108 EXPORT_API int maps_view_get_orientation(const maps_view_h view, double *angle)
1110 if (!maps_condition_check_maps_feature())
1111 return MAPS_ERROR_NOT_SUPPORTED;
1112 if (!view || !angle)
1113 return MAPS_ERROR_INVALID_PARAMETER;
1114 maps_view_s *v = (maps_view_s *) view;
1115 *angle = v->rotation_angle;
1116 return MAPS_ERROR_NONE;
1120 /*----------------------SCREEN <--> GEOGRAPHY---------------------------------*/
1123 /* Converting screen coordinates to geographical */
1124 EXPORT_API int maps_view_screen_to_geolocation(maps_view_h view,
1125 int x, int y, maps_coordinates_h *coordinates)
1127 if (!maps_condition_check_maps_feature())
1128 return MAPS_ERROR_NOT_SUPPORTED;
1129 if (!view || !coordinates)
1130 return MAPS_ERROR_INVALID_PARAMETER;
1131 if (!maps_condition_check_privilege())
1132 return MAPS_ERROR_PERMISSION_DENIED;
1136 maps_view_get_screen_location(view, &posx, &posy, NULL, NULL);
1137 return __get_plugin_interface(view)->
1138 maps_plugin_screen_to_geography(view, x - posx, y - posy, coordinates);
1141 EXPORT_API int maps_view_geolocation_to_screen(const maps_view_h view,
1142 const maps_coordinates_h coordinates, int *x, int *y)
1144 if (!maps_condition_check_maps_feature())
1145 return MAPS_ERROR_NOT_SUPPORTED;
1146 if (!view || !coordinates || !x || !y)
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 const int error = __get_plugin_interface(view)->
1155 maps_plugin_geography_to_screen(view, coordinates, x, y);
1162 /* --------------------MAPS VIEW PREFERENCES----------------------------------*/
1165 EXPORT_API int maps_view_set_type(maps_view_h view, maps_view_type_e type)
1167 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1168 return MAPS_ERROR_NOT_SUPPORTED;
1170 return MAPS_ERROR_INVALID_PARAMETER;
1171 if ((type < MAPS_VIEW_TYPE_NORMAL) || (type > MAPS_VIEW_TYPE_HYBRID))
1172 return MAPS_ERROR_INVALID_PARAMETER;
1173 if (!maps_condition_check_privilege())
1174 return MAPS_ERROR_PERMISSION_DENIED;
1176 maps_view_s *v = (maps_view_s *) view;
1178 return maps_view_set_center(view, v->center);
1181 EXPORT_API int maps_view_get_type(const maps_view_h view, maps_view_type_e *type)
1183 if (!maps_condition_check_maps_feature())
1184 return MAPS_ERROR_NOT_SUPPORTED;
1186 return MAPS_ERROR_INVALID_PARAMETER;
1187 maps_view_s *v = (maps_view_s *) view;
1189 return MAPS_ERROR_NONE;
1192 EXPORT_API int maps_view_set_buildings_enabled(maps_view_h view, bool enabled)
1194 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1195 return MAPS_ERROR_NOT_SUPPORTED;
1197 return MAPS_ERROR_INVALID_PARAMETER;
1198 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_BUILDING))
1199 return MAPS_ERROR_NOT_SUPPORTED;
1200 if (!maps_condition_check_privilege())
1201 return MAPS_ERROR_PERMISSION_DENIED;
1203 maps_view_s *v = (maps_view_s *) view;
1204 v->buildings_enabled = enabled;
1205 return maps_view_set_center(view, v->center);
1208 EXPORT_API int maps_view_get_buildings_enabled(const maps_view_h view, bool *enabled)
1210 if (!maps_condition_check_maps_feature())
1211 return MAPS_ERROR_NOT_SUPPORTED;
1213 return MAPS_ERROR_INVALID_PARAMETER;
1214 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_BUILDING))
1215 return MAPS_ERROR_NOT_SUPPORTED;
1217 return MAPS_ERROR_INVALID_PARAMETER;
1218 maps_view_s *v = (maps_view_s *) view;
1219 *enabled = v->buildings_enabled;
1220 return MAPS_ERROR_NONE;
1223 EXPORT_API int maps_view_set_traffic_enabled(maps_view_h view, bool enabled)
1225 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1226 return MAPS_ERROR_NOT_SUPPORTED;
1228 return MAPS_ERROR_INVALID_PARAMETER;
1229 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_TRAFFIC))
1230 return MAPS_ERROR_NOT_SUPPORTED;
1231 if (!maps_condition_check_privilege())
1232 return MAPS_ERROR_PERMISSION_DENIED;
1234 maps_view_s *v = (maps_view_s *) view;
1235 v->traffic_enabled = enabled;
1236 return maps_view_set_center(view, v->center);
1239 EXPORT_API int maps_view_get_traffic_enabled(const maps_view_h view, bool *enabled)
1241 if (!maps_condition_check_maps_feature())
1242 return MAPS_ERROR_NOT_SUPPORTED;
1244 return MAPS_ERROR_INVALID_PARAMETER;
1245 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_TRAFFIC))
1246 return MAPS_ERROR_NOT_SUPPORTED;
1248 return MAPS_ERROR_INVALID_PARAMETER;
1249 maps_view_s *v = (maps_view_s *) view;
1250 *enabled = v->traffic_enabled;
1251 return MAPS_ERROR_NONE;
1254 EXPORT_API int maps_view_set_public_transit_enabled(maps_view_h view, bool enabled)
1256 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1257 return MAPS_ERROR_NOT_SUPPORTED;
1259 return MAPS_ERROR_INVALID_PARAMETER;
1260 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_PUBLIC_TRANSIT))
1261 return MAPS_ERROR_NOT_SUPPORTED;
1262 if (!maps_condition_check_privilege())
1263 return MAPS_ERROR_PERMISSION_DENIED;
1265 maps_view_s *v = (maps_view_s *) view;
1266 v->public_transit_enabled = enabled;
1267 return maps_view_set_center(view, v->center);
1270 EXPORT_API int maps_view_get_public_transit_enabled(const maps_view_h view, bool *enabled)
1272 if (!maps_condition_check_maps_feature())
1273 return MAPS_ERROR_NOT_SUPPORTED;
1275 return MAPS_ERROR_INVALID_PARAMETER;
1276 if (!maps_condition_check_view_data_supported(view, MAPS_VIEW_PUBLIC_TRANSIT))
1277 return MAPS_ERROR_NOT_SUPPORTED;
1279 return MAPS_ERROR_INVALID_PARAMETER;
1280 maps_view_s *v = (maps_view_s *) view;
1281 *enabled = v->public_transit_enabled;
1282 return MAPS_ERROR_NONE;
1285 int _maps_view_set_inertia_enabled(maps_view_h view, bool enabled)
1288 return MAPS_ERROR_INVALID_PARAMETER;
1289 maps_view_s *v = (maps_view_s *) view;
1292 if (!v->inertial_gesture) {
1293 v->inertial_gesture = new view::inertial_gesture(view);
1294 if (!v->inertial_gesture) {
1295 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
1296 return MAPS_ERROR_OUT_OF_MEMORY;
1300 if (!v->inertial_camera) {
1301 v->inertial_camera = new view::inertial_camera(view);
1302 if (!v->inertial_camera) {
1303 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
1304 return MAPS_ERROR_OUT_OF_MEMORY;
1308 v->finger_stream->set_gesture_detector(v->inertial_gesture);
1310 v->finger_stream->set_gesture_detector(new view::gesture_detector_statemachine(view));
1312 if (v->inertial_gesture) {
1313 /* Unset Inertial Camera */
1314 if (v->inertial_gesture->is_transiting()) {
1315 v->inertial_gesture->set_transiting(false);
1318 view::inertial_gesture *inertial_gesture = v->inertial_gesture;
1319 v->inertial_gesture = NULL;
1320 delete inertial_gesture;
1323 if (v->inertial_camera) {
1324 /* Unset Inertial Camera */
1325 if (v->inertial_camera->is_transiting()) {
1326 v->inertial_camera->set_transiting(false);
1329 view::inertial_camera *inertial_camera = v->inertial_camera;
1330 v->inertial_camera = NULL;
1331 delete inertial_camera;
1334 return MAPS_ERROR_NONE;
1337 EXPORT_API int maps_view_get_inertia_enabled(maps_view_h view, bool *enabled)
1339 if (!maps_condition_check_maps_feature())
1340 return MAPS_ERROR_NOT_SUPPORTED;
1341 if (!view || !enabled)
1342 return MAPS_ERROR_INVALID_PARAMETER;
1344 maps_view_s *v = (maps_view_s *) view;
1345 *enabled = v->inertial_camera != NULL;
1346 return MAPS_ERROR_NONE;
1349 EXPORT_API int maps_view_set_language(maps_view_h view, const char *language)
1351 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1352 return MAPS_ERROR_NOT_SUPPORTED;
1353 if (!view || !language)
1354 return MAPS_ERROR_INVALID_PARAMETER;
1355 if (!maps_condition_check_privilege())
1356 return MAPS_ERROR_PERMISSION_DENIED;
1358 maps_view_s *v = (maps_view_s *) view;
1359 int error = maps_set_string(language, _MAPS_VIEW_LANGUAGE_MAX_LENGTH, &v->language);
1360 if (error == MAPS_ERROR_NONE)
1361 error = maps_view_set_center(view, v->center);
1365 EXPORT_API int maps_view_get_language(const maps_view_h view, char **language)
1367 if (!maps_condition_check_maps_feature())
1368 return MAPS_ERROR_NOT_SUPPORTED;
1369 if (!view || !language)
1370 return MAPS_ERROR_INVALID_PARAMETER;
1371 return maps_get_string(((maps_view_s *) view)->language,
1372 _MAPS_VIEW_LANGUAGE_MAX_LENGTH, language);
1376 /* --------------------MAPS PANEL MANIPULATIONS-------------------------------*/
1378 EXPORT_API int maps_view_get_viewport(const maps_view_h view, Evas_Object **viewport)
1380 if (!maps_condition_check_maps_feature())
1381 return MAPS_ERROR_NOT_SUPPORTED;
1382 if (!view || !viewport)
1383 return MAPS_ERROR_INVALID_PARAMETER;
1384 maps_view_s *v = (maps_view_s *) view;
1385 *viewport = v->panel;
1386 return MAPS_ERROR_NONE;
1389 int _maps_view_get_parent(const maps_view_h view, Evas_Object **parent)
1391 if (!view || !parent)
1392 return MAPS_ERROR_INVALID_PARAMETER;
1393 maps_view_s *v = (maps_view_s *) view;
1394 *parent = v->parent;
1395 return MAPS_ERROR_NONE;
1398 int _maps_view_get_clipper(const maps_view_h view, Evas_Object **clipper)
1400 if (!view || !clipper)
1401 return MAPS_ERROR_INVALID_PARAMETER;
1402 maps_view_s *v = (maps_view_s *) view;
1403 *clipper = v->clipper;
1404 return MAPS_ERROR_NONE;
1407 EXPORT_API int maps_view_set_screen_location(maps_view_h view, int x, int y, int width, int height)
1409 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1410 return MAPS_ERROR_NOT_SUPPORTED;
1412 return MAPS_ERROR_INVALID_PARAMETER;
1413 if (!maps_condition_check_privilege())
1414 return MAPS_ERROR_PERMISSION_DENIED;
1416 int error = maps_view_move(view, x, y);
1417 if (error == MAPS_ERROR_NONE)
1418 error = maps_view_resize(view, width, height);
1422 EXPORT_API int maps_view_get_screen_location(const maps_view_h view, int *x, int *y, int *width, int *height)
1424 if (!maps_condition_check_maps_feature())
1425 return MAPS_ERROR_NOT_SUPPORTED;
1426 if (!view || (!x && !y && !width && !height))
1427 return MAPS_ERROR_INVALID_PARAMETER;
1428 maps_view_s *v = (maps_view_s *) view;
1429 evas_object_geometry_get(v->panel, x, y, width, height);
1430 return MAPS_ERROR_NONE;
1433 EXPORT_API int maps_view_move(maps_view_h view, int x, int y)
1435 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1436 return MAPS_ERROR_NOT_SUPPORTED;
1438 return MAPS_ERROR_INVALID_PARAMETER;
1440 maps_view_s *v = (maps_view_s *) view;
1441 evas_object_move(v->panel, x, y);
1442 evas_object_move(v->clipper, x, y);
1443 return MAPS_ERROR_NONE;
1446 EXPORT_API int maps_view_resize(maps_view_h view, int width, int height)
1448 if (!maps_condition_check_maps_feature() || !maps_condition_check_internet_feature())
1449 return MAPS_ERROR_NOT_SUPPORTED;
1450 if (!view || (width <= 0) || (height <= 0))
1451 return MAPS_ERROR_INVALID_PARAMETER;
1452 if (!maps_condition_check_privilege())
1453 return MAPS_ERROR_PERMISSION_DENIED;
1455 maps_view_s *v = (maps_view_s *) view;
1456 evas_object_resize(v->panel, width, height);
1457 evas_object_resize(v->clipper, width, height);
1458 evas_object_image_fill_set(v->panel, 0, 0, width, height);
1459 return __maps_view_set_center(view, v->center, TRUE);
1462 EXPORT_API int maps_view_set_visibility(maps_view_h view, bool visible)
1464 if (!maps_condition_check_maps_feature())
1465 return MAPS_ERROR_NOT_SUPPORTED;
1467 return MAPS_ERROR_INVALID_PARAMETER;
1469 maps_view_s *v = (maps_view_s *) view;
1471 evas_object_show(v->panel);
1473 evas_object_hide(v->panel);
1474 return MAPS_ERROR_NONE;
1477 EXPORT_API int maps_view_get_visibility(const maps_view_h view, bool *visible)
1479 if (!maps_condition_check_maps_feature())
1480 return MAPS_ERROR_NOT_SUPPORTED;
1481 if (!view || !visible)
1482 return MAPS_ERROR_INVALID_PARAMETER;
1484 maps_view_s *v = (maps_view_s *) view;
1485 *visible = evas_object_visible_get(v->panel) == EINA_TRUE;
1486 return MAPS_ERROR_NONE;
1489 int _maps_view_redraw(const maps_view_h view)
1492 return MAPS_ERROR_INVALID_PARAMETER;
1494 maps_view_s *v = (maps_view_s *) view;
1496 /* Signal to the animator, that we are ready to draw */
1497 v->ready_to_draw = true;
1499 return MAPS_ERROR_NONE;
1502 /* ---------------------USER CONTROL------------------------------------------*/
1505 EXPORT_API int maps_view_set_event_cb(maps_view_h view, maps_view_event_type_e type,
1506 maps_view_on_event_cb callback, void *user_data)
1508 if (!maps_condition_check_maps_feature())
1509 return MAPS_ERROR_NOT_SUPPORTED;
1510 if (!view || !callback)
1511 return MAPS_ERROR_INVALID_PARAMETER;
1512 if ((type < MAPS_VIEW_EVENT_GESTURE) || (type > MAPS_VIEW_EVENT_READY))
1513 return MAPS_ERROR_INVALID_PARAMETER;
1515 maps_view_s *v = (maps_view_s *) view;
1516 v->event_callbacks[type].callback = callback;
1517 v->event_callbacks[type].user_data = user_data;
1519 return MAPS_ERROR_NONE;
1522 EXPORT_API int maps_view_unset_event_cb(maps_view_h view, maps_view_event_type_e type)
1524 if (!maps_condition_check_maps_feature())
1525 return MAPS_ERROR_NOT_SUPPORTED;
1527 return MAPS_ERROR_INVALID_PARAMETER;
1528 if ((type < MAPS_VIEW_EVENT_GESTURE) || (type > MAPS_VIEW_EVENT_READY))
1529 return MAPS_ERROR_INVALID_PARAMETER;
1531 maps_view_s *v = (maps_view_s *) view;
1532 v->event_callbacks[type].callback = __maps_view_on_event_empty_cb;
1533 v->event_callbacks[type].user_data = NULL;
1535 return MAPS_ERROR_NONE;
1538 EXPORT_API int maps_view_set_gesture_enabled(maps_view_h view, maps_view_gesture_e gesture, bool enabled)
1540 if (!maps_condition_check_maps_feature())
1541 return MAPS_ERROR_NOT_SUPPORTED;
1543 return MAPS_ERROR_INVALID_PARAMETER;
1544 if ((gesture < MAPS_VIEW_GESTURE_NONE) || (gesture > MAPS_VIEW_GESTURE_LONG_PRESS))
1545 return MAPS_ERROR_INVALID_PARAMETER;
1546 maps_view_s *v = (maps_view_s *) view;
1547 v->gesture_available[gesture] = enabled;
1548 return MAPS_ERROR_NONE;
1551 EXPORT_API int maps_view_get_gesture_enabled(const maps_view_h view, maps_view_gesture_e gesture, bool *enabled)
1553 if (!maps_condition_check_maps_feature())
1554 return MAPS_ERROR_NOT_SUPPORTED;
1555 if (!view || !enabled)
1556 return MAPS_ERROR_INVALID_PARAMETER;
1557 if ((gesture < MAPS_VIEW_GESTURE_NONE) || (gesture > MAPS_VIEW_GESTURE_LONG_PRESS))
1558 return MAPS_ERROR_INVALID_PARAMETER;
1559 maps_view_s *v = (maps_view_s *) view;
1560 *enabled = v->gesture_available[gesture];
1561 return MAPS_ERROR_NONE;
1565 /* ---------------------VISUAL OBJECTS ON THE MAP-----------------------------*/
1567 EXPORT_API int maps_view_add_object(maps_view_h view, maps_view_object_h object)
1569 if (!maps_condition_check_maps_feature())
1570 return MAPS_ERROR_NOT_SUPPORTED;
1571 if (!view || !object)
1572 return MAPS_ERROR_INVALID_PARAMETER;
1573 if (!maps_condition_check_privilege())
1574 return MAPS_ERROR_PERMISSION_DENIED;
1576 int error = MAPS_ERROR_NONE;
1578 /* Add Visual Object to the list of View Visual Objects */
1579 maps_view_s *v = (maps_view_s *)view;
1580 error = maps_item_list_append(v->view_objects, object, NULL);
1581 if (error != MAPS_ERROR_NONE)
1584 /* Link the object with the View */
1585 error = _maps_view_object_set_view(object, view);
1586 if (error != MAPS_ERROR_NONE)
1589 /* Notify the plugin about added object */
1590 error = _maps_view_on_object_operation(view, object, MAPS_VIEW_OBJECT_ADD);
1591 if (error != MAPS_ERROR_NONE)
1594 /* Redraw the view */
1595 error = _maps_view_redraw(v);
1596 if (error != MAPS_ERROR_NONE)
1599 return MAPS_ERROR_NONE;
1605 EXPORT_API int maps_view_remove_object(maps_view_h view, maps_view_object_h object)
1607 if (!maps_condition_check_maps_feature())
1608 return MAPS_ERROR_NOT_SUPPORTED;
1609 if (!view || !object)
1610 return MAPS_ERROR_INVALID_PARAMETER;
1611 if (!maps_condition_check_privilege())
1612 return MAPS_ERROR_PERMISSION_DENIED;
1614 int error = MAPS_ERROR_NONE;
1616 /* Remove Visual Object from the list of View Visual Objects */
1617 maps_view_s *v = (maps_view_s *)view;
1618 error = maps_item_list_remove(v->view_objects, object, maps_view_object_destroy);
1619 if (error != MAPS_ERROR_NONE)
1622 /* Redraw the view */
1623 error = _maps_view_redraw(v);
1624 if (error != MAPS_ERROR_NONE)
1627 return MAPS_ERROR_NONE;
1633 EXPORT_API int maps_view_remove_all_objects(maps_view_h view)
1635 if (!maps_condition_check_maps_feature())
1636 return MAPS_ERROR_NOT_SUPPORTED;
1638 return MAPS_ERROR_INVALID_PARAMETER;
1639 if (!maps_condition_check_privilege())
1640 return MAPS_ERROR_PERMISSION_DENIED;
1642 int error = MAPS_ERROR_NONE;
1644 maps_view_s *v = (maps_view_s *)view;
1645 error = maps_item_list_remove_all(v->view_objects, maps_view_object_destroy);
1646 if (error != MAPS_ERROR_NONE)
1649 /* Redraw the view */
1650 error = _maps_view_redraw(v);
1651 if (error != MAPS_ERROR_NONE)
1654 return MAPS_ERROR_NONE;
1660 EXPORT_API int maps_view_foreach_object(maps_view_h view, maps_view_object_cb callback, void *user_data)
1662 if (!maps_condition_check_maps_feature())
1663 return MAPS_ERROR_NOT_SUPPORTED;
1664 if (!view || !callback)
1665 return MAPS_ERROR_INVALID_PARAMETER;
1666 maps_view_s *v = (maps_view_s *)view;
1667 if (!v->view_objects)
1668 return MAPS_ERROR_NOT_FOUND;
1669 return maps_item_list_foreach(v->view_objects, NULL, callback, user_data);
1673 /* ----------------------SEND MAP VIEW CALLBACK TO THE USER-------------------*/
1675 /* TODO: Consider refactoring of send Map View Callbacks to the User */
1677 maps_view_event_data_h _maps_view_create_event_data(maps_view_event_type_e type)
1679 maps_view_event_data_h event_data = NULL;
1680 const int error = _maps_view_event_data_create(&event_data);
1681 if (error != MAPS_ERROR_NONE) {
1682 maps_view_event_data_destroy(event_data);
1687 _maps_view_event_data_set_type(event_data, type);
1691 void _maps_view_invoke_event_callback(maps_view_h view, maps_view_event_data_h event_data)
1693 if (!view || !event_data)
1696 maps_view_s *v = (maps_view_s *)view;
1698 maps_view_event_type_e type = MAPS_VIEW_EVENT_GESTURE;
1699 maps_view_event_data_get_type(event_data, &type);
1702 int maps_view_event_data_get_gesture_type(const maps_view_event_data_h event, maps_view_gesture_e *gesture_type);
1703 int maps_view_event_data_get_action_type(const maps_view_event_data_h event, maps_view_action_e *action_type);
1704 int maps_view_event_data_get_object(const maps_view_event_data_h event, maps_view_object_h *object);
1705 int maps_view_object_get_type(maps_view_object_h object, maps_view_object_type_e *type);
1708 if (type == MAPS_VIEW_EVENT_GESTURE) {
1709 maps_view_event_data_get_gesture_type(event_data, (maps_view_gesture_e*)&subtype);
1710 } else if (type == MAPS_VIEW_EVENT_ACTION) {
1711 maps_view_event_data_get_action_type(event_data, (maps_view_action_e*)&subtype);
1712 } else if (type == MAPS_VIEW_EVENT_OBJECT) {
1713 maps_view_object_h object;
1714 maps_view_event_data_get_object(event_data, &object);
1715 maps_view_object_get_type(object, (maps_view_object_type_e*)&subtype);
1717 if (type == MAPS_VIEW_EVENT_READY)
1718 MAPS_LOGD("[invoked event] type=%d, subtype=%d", type, subtype);
1721 v->event_callbacks[type].callback(type, event_data, v->event_callbacks[type].user_data);
1724 /* ----------------------HIT TEST---------------------------------------------*/
1725 /* TODO: consider refactoring of Hit Test features and separation as
1726 * dedicated classes */
1728 typedef struct _maps_view_hit_test_data_s {
1732 maps_view_object_h object;
1733 } maps_view_hit_test_data_s;
1736 typedef struct _maps_view_collect_poly_object_point_s {
1738 view::poly_shape_hit_test *pd;
1739 } maps_view_collect_poly_object_point_s;
1742 static bool __maps_view_object_poly_collect_points_cb(int index, maps_coordinates_h point, void *user_data)
1744 if (!point || !user_data)
1747 maps_view_collect_poly_object_point_s *cpop =
1748 (maps_view_collect_poly_object_point_s *)user_data;
1752 if (maps_view_geolocation_to_screen(cpop->v, point, &x, &y) == MAPS_ERROR_NONE)
1753 cpop->pd->add_point(float(x), float(y));
1758 static bool __maps_view_hit_test_cb(int index, int total, maps_view_object_h object, void *user_data)
1760 if (!object || !user_data)
1763 /* If it is an unvisible object, skip this hit-testing. */
1764 bool visible = false;
1765 maps_view_object_get_visible(object, &visible);
1766 if (!visible) return true;
1768 maps_view_hit_test_data_s *htd = (maps_view_hit_test_data_s *)user_data;
1770 maps_view_object_type_e type;
1771 maps_view_object_get_type(object, &type);
1773 case MAPS_VIEW_OBJECT_POLYLINE: {
1774 view::poly_shape_hit_test pd;
1775 maps_view_collect_poly_object_point_s cpop = {htd->v, &pd};
1776 int error = maps_view_object_polyline_foreach_point(object,
1777 __maps_view_object_poly_collect_points_cb, &cpop);
1778 if (error != MAPS_ERROR_NONE)
1782 maps_view_object_polyline_get_width(object, &width);
1783 if (pd.hit_test(float(htd->x), float(htd->y), false, width))
1784 htd->object = object;
1789 case MAPS_VIEW_OBJECT_POLYGON: {
1790 view::poly_shape_hit_test pd;
1791 maps_view_collect_poly_object_point_s cpop = {htd->v, &pd};
1792 int error = maps_view_object_polygon_foreach_point(object,
1793 __maps_view_object_poly_collect_points_cb, &cpop);
1794 if (error != MAPS_ERROR_NONE)
1797 if (pd.hit_test(float(htd->x), float(htd->y), true))
1798 htd->object = object;
1802 case MAPS_VIEW_OBJECT_MARKER: {
1803 maps_coordinates_h c = NULL;
1804 maps_view_object_marker_get_coordinates(object, &c);
1808 maps_view_geolocation_to_screen(htd->v, c, &x, &y);
1809 maps_coordinates_destroy(c);
1813 maps_view_object_marker_get_size(object, &w, &h);
1815 /* In case of PIN marker type, rearrange the hit-area. */
1816 maps_view_marker_type_e marker_type;
1817 maps_view_object_marker_get_type(object, &marker_type);
1818 if (marker_type == MAPS_VIEW_MARKER_PIN)
1821 /* Add some margin of the hit-area. */
1822 w = MAX(w, htd->v->min_hit_area);
1823 h = MAX(h, htd->v->min_hit_area);
1825 /* Gets a half range to check hit-area */
1826 int hw = (int)(w / 2. + .5);
1827 int hh = (int)(h / 2. + .5);
1829 /* Check hit-area */
1830 if ((x > (htd->x - hw)) && (x < (htd->x + hw))
1831 && (y > (htd->y - hh)) && (y < (htd->y + hh))) {
1832 htd->object = object;
1847 maps_view_object_h _maps_view_object_hit_test(maps_view_h view, int x, int y, maps_view_gesture_e gesture)
1852 maps_view_s *v = (maps_view_s *)view;
1854 /* Check if we are going to inform anyone about object events */
1855 if (v->event_callbacks[MAPS_VIEW_EVENT_OBJECT].callback
1856 == __maps_view_on_event_empty_cb)
1859 /* 1. Iterate through the list of object and test the hit */
1860 maps_view_hit_test_data_s htd = {v, x, y, NULL};
1861 int error = maps_view_foreach_object(view, __maps_view_hit_test_cb, &htd);
1862 if ((error != MAPS_ERROR_NONE) || !htd.object)
1865 /*g_print("Hit Test: FOUND OBJECT: %p\n", htd.object);*/
1867 /* Invoke user registered event callback */
1868 maps_view_event_data_h ed =
1869 _maps_view_create_event_data(MAPS_VIEW_EVENT_OBJECT);
1871 _maps_view_event_data_set_object(ed, htd.object);
1872 _maps_view_event_data_set_gesture_type(ed, gesture);
1873 _maps_view_invoke_event_callback(view, ed);
1874 maps_view_event_data_destroy(ed);
1877 /* 2. Extract test result */
1881 EXPORT_API int maps_view_get_maps_plugin_view_handle(maps_view_h view, void **maps_plugin_view_handle)
1883 if (!maps_condition_check_maps_feature())
1884 return MAPS_ERROR_NOT_SUPPORTED;
1885 if (!view || !maps_plugin_view_handle)
1886 return MAPS_ERROR_INVALID_PARAMETER;
1888 maps_view_s *v = (maps_view_s *)view;
1889 *maps_plugin_view_handle = v->maps_plugin_view_handle;
1890 return MAPS_ERROR_NONE;
1893 EXPORT_API int maps_view_set_maps_plugin_view_handle(maps_view_h view, void *maps_plugin_view_handle)
1895 if (!maps_condition_check_maps_feature())
1896 return MAPS_ERROR_NOT_SUPPORTED;
1898 return MAPS_ERROR_INVALID_PARAMETER;
1900 maps_view_s *v = (maps_view_s *)view;
1901 v->maps_plugin_view_handle = maps_plugin_view_handle;
1902 return MAPS_ERROR_NONE;
1905 EXPORT_API int maps_view_get_scale_factor(maps_view_h view, double *scale_factor)
1907 if (!maps_condition_check_maps_feature())
1908 return MAPS_ERROR_NOT_SUPPORTED;
1909 if (!view || !scale_factor)
1910 return MAPS_ERROR_INVALID_PARAMETER;
1912 const plugin::interface_s *plugin = __get_plugin_interface(view);
1914 return MAPS_ERROR_INVALID_PARAMETER;
1915 if (!plugin->maps_plugin_get_view_scale_factor)
1916 return MAPS_ERROR_NOT_SUPPORTED;
1917 return plugin->maps_plugin_get_view_scale_factor(view, scale_factor);
1920 EXPORT_API int maps_view_set_scale_factor(maps_view_h view, double scale_factor)
1922 if (!maps_condition_check_maps_feature())
1923 return MAPS_ERROR_NOT_SUPPORTED;
1925 return MAPS_ERROR_INVALID_PARAMETER;
1926 if (scale_factor < 0.1 || scale_factor > 10.0)
1927 return MAPS_ERROR_INVALID_PARAMETER;
1929 const plugin::interface_s *plugin = __get_plugin_interface(view);
1931 return MAPS_ERROR_INVALID_PARAMETER;
1932 if (!plugin->maps_plugin_set_view_scale_factor)
1933 return MAPS_ERROR_NOT_SUPPORTED;
1935 return plugin->maps_plugin_set_view_scale_factor(view, scale_factor);