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 can be used to specify a custom marker icon. Simply pass a valid
158      * path to an image and it will be shown instead of google's default marker.
159      *
160      * @type String
161      */
162     icon: null,
163 
164     /**
165      * This property specifies the recommended events for this type of view.
166      *
167      * @type Array
168      */
169     recommendedEvents: ['click', 'tap'],
170 
171     /**
172      * This method initializes an M.MapMarkerView. It connects a map marker directly with
173      * the parent map view and returns the created M.MapMarkerView object.
174      *
175      * Note: By calling this method, the map marker won't be displayed on the map. It only gets
176      * initialized and can no be displayed by using the map view's addMarker() method or via
177      * content binding.
178      *
179      * @param {Object} options The options for the map marker view.
180      */
181     init: function(options) {
182         var marker = this.extend(options);
183 
184         if(marker.annotation || marker.message) {
185             var content = marker.title ? '<h1 class="ui-annotation-header">' + marker.title + '</h1>' : '';
186             content += marker.message ? '<p class="ui-annotation-message">' + marker.message + '</p>' : '';
187             
188             marker.annotation = new google.maps.InfoWindow({
189                 content: content,
190                 maxWidth: 100
191             });
192         }
193 
194         return marker;
195     },
196 
197     /**
198      * This method is responsible for registering events for view elements and its child views. It
199      * basically passes the view's event-property to M.EventDispatcher to bind the appropriate
200      * events.
201      *
202      * It extend M.View's registerEvents method with some special stuff for list item views and
203      * their internal events.
204      */
205     registerEvents: function() {
206         this.internalEvents = {
207             tap: {
208                 target: this,
209                 action: 'showAnnotation'
210             }
211         }
212 
213         var that = this;
214         google.maps.event.addListener(this.marker, 'click', function() {
215             M.EventDispatcher.callHandler(that.internalEvents.tap, event, YES);
216         });
217     },
218 
219     /**
220      * This method can be used to remove a map marker from a map view.
221      */
222     remove: function() {
223         this.map.removeMarker(this);
224     },
225 
226     /**
227      * This method can be used to show a map markers annotation.
228      */
229     showAnnotation: function(id, event, nextEvent) {
230         if(this.annotation) {
231             this.annotation.open(this.map.map, this.marker);
232         }
233 
234         /* delegate event to external handler, if specified */
235         if(this.events || this.map.events) {
236             var events = this.events ? this.events : this.map.events;
237             for(var e in events) {
238                 if(e === (event.type === 'click' ? 'tap' : event.type)) {
239                     M.EventDispatcher.callHandler(events[e], event, NO, [this]);
240                 }
241             }
242         }
243     }
244 
245 });