1 // ==========================================================================
  2 // Project:   The M-Project - Mobile HTML5 Application Framework
  3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
  4 //            (c) 2011 panacoda GmbH. All rights reserved.
  5 // Creator:   Dominik
  6 // Date:      27.01.2011
  7 // License:   Dual licensed under the MIT or GPL Version 2 licenses.
  8 //            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
  9 //            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
 10 // ==========================================================================
 11 
 12 /**
 13  * A constant value for the map's marker animation type: none
 14  *
 15  * @type String
 16  */
 17 M.MAP_MARKER_ANIMATION_NONE = 'NONE';
 18 
 19 /**
 20  * A constant value for the map's marker animation type: drop
 21  *
 22  * @type String
 23  */
 24 M.MAP_MARKER_ANIMATION_DROP = 'DROP';
 25 
 26 /**
 27  * A constant value for the map's marker animation type: bounce
 28  *
 29  * @type String
 30  */
 31 M.MAP_MARKER_ANIMATION_BOUNCE = 'BOUNCE';
 32 
 33 /**
 34  * @class
 35  *
 36  * M.MapMarkerView is the prototype of a map marker view. It defines a set
 37  * of methods for adding, removing and managing the markers of a M.MapView.
 38  *
 39  * The M.MapMarkerView is based on google maps markers.
 40  *
 41  * @extends M.View
 42  */
 43 M.MapMarkerView = M.View.extend(
 44 /** @scope M.MapMarkerView.prototype */ {
 45 
 46     /**
 47      * The type of this object.
 48      *
 49      * @type String
 50      */
 51     type: 'M.MapMarkerView',
 52 
 53     /**
 54      * This property is used to save a reference to the actual google map marker.
 55      * It is set automatically when the map marker is firstly initialized.
 56      *
 57      * @type Object
 58      */
 59     marker: null,
 60 
 61     /**
 62      * This property can be used to store additional information about a marker.
 63      * Since this property is an object, you can store pretty much anything in
 64      * this property.
 65      *
 66      * This can be useful especially if you are using the click event for map
 67      * markers. So you can store any information with a marker and retrieve
 68      * this information on the click event.
 69      *
 70      * @type Object
 71      */
 72     data: null,
 73 
 74     /**
 75      * This property contains a reference to the marker's map view.
 76      *
 77      * @type M.MapView
 78      */
 79     map: null,
 80 
 81     /**
 82      * This property specifies the title of a map marker view. It can be used in
 83      * an annotation.
 84      *
 85      * @type String
 86      */
 87     title: null,
 88 
 89     /**
 90      * This property specifies the message of a map marker view respectively for
 91      * its annotation.
 92      *
 93      * @type String
 94      */
 95     message: null,
 96 
 97     /**
 98      * This property can be used to specify whether or not to show the annotation,
 99      * if title and / or message are defined, automatically on click event.
100      *
101      * @type Boolean
102      */
103     showAnnotationOnClick: NO,
104 
105     /**
106      * This property contains a reference to a google maps info window that is
107      * connected to this map marker. By calling either the showAnnotation() or
108      * the hideAnnotation() method, this info window can be toggled.
109      *
110      * Additionally the info window will be automatically set to visible if the
111      * showAnnotationOnClick property is set to YES.
112      *
113      * @type Object
114      */
115     annotation: null,
116 
117     /**
118      * This property specifies whether the marker is draggable or not. If set
119      * to NO, a user won't be able to move the marker. For further information
120      * see the google maps API specification:
121      *
122      *   http://code.google.com/intl/en-US/apis/maps/documentation/javascript/reference.html#MarkerOptions
123      *
124      * @type Boolean
125      */
126     isDraggable: NO,
127 
128     /**
129      * This property specifies the location for this map marker view, as an M.Location
130      * object. Its latitude and longitude properties are directly mapped to the position
131      * property of a google maps marker. For further information see the google maps API
132      * specification:
133      *
134      *   http://code.google.com/intl/en-US/apis/maps/documentation/javascript/reference.html#MarkerOptions
135      *
136      * @type M.Location
137      */
138     location: M.Location.extend({
139         latitude: 48.813338,
140         longitude: 9.178463
141     }),
142 
143     /**
144      * This property can be used to specify the animation type for this map marker
145      * view. If this property is set, the markerAnimationType property of the parent
146      * map view is ignored. The following three values are possible:
147      *
148      *   M.MAP_MARKER_ANIMATION_NONE --> no animation
149      *   M.MAP_MARKER_ANIMATION_DROP --> the marker drops onto the map
150      *   M.MAP_MARKER_ANIMATION_BOUNCE --> the marker constantly bounces
151      *
152      * @type String
153      */
154     markerAnimationType: null,
155 
156     /**
157      * This property specifies the recommended events for this type of view.
158      *
159      * @type Array
160      */
161     recommendedEvents: ['click', 'tap'],
162 
163     /**
164      * This method initializes an M.MapMarkerView. It connects a map marker directly with
165      * the parent map view and returns the created M.MapMarkerView object.
166      *
167      * Note: By calling this method, the map marker won't be displayed on the map. It only gets
168      * initialized and can no be displayed by using the map view's addMarker() method or via
169      * content binding.
170      *
171      * @param {Object} options The options for the map marker view.
172      */
173     init: function(options) {
174         var marker = this.extend(options);
175 
176         if(marker.annotation || marker.message) {
177             var content = marker.title ? '<h1 class="ui-annotation-header">' + marker.title + '</h1>' : '';
178             content += marker.message ? '<p class="ui-annotation-message">' + marker.message + '</p>' : '';
179             
180             marker.annotation = new google.maps.InfoWindow({
181                 content: content,
182                 maxWidth: 100
183             });
184         }
185 
186         return marker;
187     },
188 
189     /**
190      * This method is responsible for registering events for view elements and its child views. It
191      * basically passes the view's event-property to M.EventDispatcher to bind the appropriate
192      * events.
193      *
194      * It extend M.View's registerEvents method with some special stuff for list item views and
195      * their internal events.
196      */
197     registerEvents: function() {
198         this.internalEvents = {
199             tap: {
200                 target: this,
201                 action: 'showAnnotation'
202             }
203         }
204 
205         var that = this;
206         google.maps.event.addListener(this.marker, 'click', function() {
207             M.EventDispatcher.callHandler(that.internalEvents.tap, event, YES);
208         });
209     },
210 
211     /**
212      * This method can be used to remove a map marker from a map view.
213      */
214     remove: function() {
215         this.map.removeMarker(this);
216     },
217 
218     /**
219      * This method can be used to show a map markers annotation.
220      */
221     showAnnotation: function(id, event, nextEvent) {
222         if(this.annotation) {
223             this.annotation.open(this.map.map, this.marker);
224         }
225 
226         /* delegate event to external handler, if specified */
227         if(this.events || this.map.events) {
228             var events = this.events ? this.events : this.map.events;
229             for(var e in events) {
230                 if(e === (event.type === 'click' ? 'tap' : event.type)) {
231                     M.EventDispatcher.callHandler(events[e], event, NO, [this]);
232                 }
233             }
234         }
235     }
236 
237 });