001    package com.google.gwt.maps.client.events;
002    
003    import com.google.gwt.ajaxloader.client.ArrayHelper;
004    import com.google.gwt.ajaxloader.client.Properties;
005    import com.google.gwt.core.client.GWT;
006    import com.google.gwt.core.client.JavaScriptObject;
007    import com.google.gwt.core.client.JsArray;
008    import com.google.gwt.event.dom.client.ClickHandler;
009    import com.google.gwt.event.shared.HandlerRegistration;
010    import com.google.gwt.maps.client.MapWidget;
011    import com.google.gwt.maps.client.events.mapchange.MapChangeEventFormatter;
012    
013    public class MapHandlerRegistration {
014    
015            /**
016             * event handler
017             * 
018             * @param jso
019             * @param eventType
020             * @param handler
021             * @param formatter
022             */
023            public static <E extends MapEvent> HandlerRegistration addHandler(
024                            JavaScriptObject jso, MapEventType eventType,
025                            MapHandler<E> handler, MapEventFormatter<E> formatter) {
026                    final JavaScriptObject listener = addHandlerImpl(jso,
027                                    eventType.value(), handler, formatter);
028                    HandlerRegistration registration = new HandlerRegistration() {
029                            @Override
030                            public void removeHandler() {
031                                    removeHandlerImpl(listener);
032                            }
033                    };
034                    return registration;
035            }
036    
037            /**
038             * event handler for the mvc object
039             * 
040             * @param jso
041             * @param eventType
042             * @param handler
043             * @param formatter
044             */
045            public static <E extends MapEvent> HandlerRegistration addHandlerMvc(
046                            JavaScriptObject jso, MapEventType eventType,
047                            MapHandler<E> handler, MapEventFormatter<E> formatter) {
048                    final JavaScriptObject listener = addHandlerImplMvc(jso,
049                                    eventType.value(), handler, formatter);
050                    HandlerRegistration registration = new HandlerRegistration() {
051                            @Override
052                            public void removeHandler() {
053                                    removeHandlerImpl(listener);
054                            }
055                    };
056                    return registration;
057            }
058    
059            /**
060             * event handler for the drawing overlay objects
061             * 
062             * @param jso
063             * @param eventType
064             * @param handler
065             * @param formatter
066             */
067            public static <E extends MapEvent> HandlerRegistration addHandlerDrawing(
068                            JavaScriptObject jso, MapEventType eventType,
069                            MapHandler<E> handler, MapEventFormatter<E> formatter) {
070    
071                    final JavaScriptObject listener = addHandlerImplDrawing(jso,
072                                    eventType.value(), handler, formatter);
073                    HandlerRegistration registration = new HandlerRegistration() {
074                            @Override
075                            public void removeHandler() {
076                                    removeHandlerImpl(listener);
077                            }
078                    };
079                    return registration;
080            }
081    
082            /**
083             * process the callback and send it to the handler
084             * 
085             * @param jso
086             * @param eventName
087             * @param handler
088             * @param formatter
089             */
090            private static native <E extends MapEvent> JavaScriptObject addHandlerImpl(
091                            JavaScriptObject jso, String eventName, MapHandler<E> handler,
092                            MapEventFormatter<E> formatter) /*-{
093                    var callback = function(event) {
094                            @com.google.gwt.maps.client.events.MapHandlerRegistration::onCallback(Lcom/google/gwt/maps/client/events/MapHandler;Lcom/google/gwt/ajaxloader/client/Properties;Lcom/google/gwt/maps/client/events/MapEventFormatter;)(handler, event, formatter);
095                    };
096                    return $wnd.google.maps.event.addListener(jso, eventName, callback)
097            }-*/;
098    
099            /**
100             * process the callback and send it to the handler
101             * 
102             * @param jso
103             * @param eventName
104             * @param handler
105             * @param formatter
106             */
107            private static native <E extends MapEvent> JavaScriptObject addHandlerImplMvc(
108                            JavaScriptObject jso, String eventName, MapHandler<E> handler,
109                            MapEventFormatter<E> formatter) /*-{
110                    var callback = function(event) {
111                            var eventCon = {
112                                    index : event
113                            };
114                            @com.google.gwt.maps.client.events.MapHandlerRegistration::onCallback(Lcom/google/gwt/maps/client/events/MapHandler;Lcom/google/gwt/ajaxloader/client/Properties;Lcom/google/gwt/maps/client/events/MapEventFormatter;)(handler, eventCon, formatter);
115                    };
116                    return $wnd.google.maps.event.addListener(jso, eventName, callback)
117            }-*/;
118    
119            /**
120             * drawing sends events partly with different signature or arguments.
121             * 
122             * @param jso
123             * @param eventName
124             * @param handler
125             * @param formatter
126             */
127            private static native <E extends MapEvent> JavaScriptObject addHandlerImplDrawing(
128                            JavaScriptObject jso, String eventName, MapHandler<E> handler,
129                            MapEventFormatter<E> formatter) /*-{
130                    var callback = function(event) {
131                            var eventCon = {
132                                    overlay : event
133                            };
134                            @com.google.gwt.maps.client.events.MapHandlerRegistration::onCallback(Lcom/google/gwt/maps/client/events/MapHandler;Lcom/google/gwt/ajaxloader/client/Properties;Lcom/google/gwt/maps/client/events/MapEventFormatter;)(handler, eventCon, formatter);
135                    };
136                    return $wnd.google.maps.event.addListener(jso, eventName, callback)
137            }-*/;
138    
139            /**
140             * HandlerRegistration call when finished
141             * 
142             * @param listener
143             */
144            private static native void removeHandlerImpl(JavaScriptObject listener) /*-{
145                    $wnd.google.maps.MapsEventListener.addListener(listener);
146            }-*/;
147    
148            /**
149             * process generic handler callback
150             * 
151             * @param handler
152             * @param properties
153             * @param formatter
154             */
155            protected static <E extends MapEvent> void onCallback(
156                            final MapHandler<E> handler, final Properties properties,
157                            final MapEventFormatter<E> formatter) {
158                    try {
159                            formatEvent(handler, properties, formatter);
160                    } catch (Throwable x) {
161                            GWT.getUncaughtExceptionHandler().onUncaughtException(x);
162                    }
163            }
164    
165            /**
166             * create a map event
167             * 
168             * @param handler
169             * @param properties
170             * @param formatter
171             */
172            private static <E extends MapEvent> void formatEvent(MapHandler<E> handler,
173                            Properties properties, MapEventFormatter<E> formatter) {
174                    E event = formatter.createEvent(properties);
175                    handler.onEvent(event);
176            }
177    
178            /**
179             * Triggers the given event. All arguments after eventName are passed as
180             * arguments to the listeners. <br>
181             * <b>Note:</b> Use Marker in objects to click on.
182             * 
183             * @param w
184             * @param eventType
185             * @param objects
186             */
187            public static void trigger(MapWidget w, MapEventType eventType,
188                            JavaScriptObject... objects) {
189                    JsArray<JavaScriptObject> a = ArrayHelper.toJsArray(objects);
190                    triggerImpl(w, eventType.value(), a);
191            }
192    
193            private static native void triggerImpl(MapWidget w, String eventName,
194                            JsArray<JavaScriptObject> args) /*-{
195                    var jso = w.@com.google.gwt.maps.client.MapWidget::getJso()();
196                    $wnd.google.maps.event.trigger(jso, eventName, args);
197            }-*/;
198    
199            /**
200             * Triggers the given event. All arguments after eventName are passed as
201             * arguments to the listeners. <br>
202             * <b>Note:</b> Use Marker in objects to click on.
203             * 
204             * @param w
205             * @param eventType
206             */
207            public static void trigger(MapWidget w, MapEventType eventType) {
208                    triggerImpl(w, eventType.value());
209            }
210    
211            private static native void triggerImpl(MapWidget w, String eventName) /*-{
212                    var jso = w.@com.google.gwt.maps.client.MapWidget::getJso()();
213                    $wnd.google.maps.event.trigger(jso, eventName);
214            }-*/;
215    
216            /**
217             * experimental for the moment. I'm not satisfied as of yet with this
218             * strategy.
219             * 
220             * Cross browser event handler registration. This listener is removed by
221             * calling removeListener(handle) for the handle that is returned by this
222             * function.
223             * 
224             * @param jso
225             * @param type
226             * @param handler
227             * @param capture
228             */
229            public static <E> void addDomListener(JavaScriptObject jso,
230                            com.google.gwt.event.dom.client.DomEvent.Type<ClickHandler> type,
231                            MapHandler<E> handler, boolean capture) {
232                    addDomListener(jso, type.getName(), handler, capture);
233            }
234    
235            private static native <E> void addDomListener(JavaScriptObject object,
236                            String eventName, MapHandler<?> handler, boolean capture) /*-{
237                    var callback = function(event) {
238                            @com.google.gwt.maps.client.events.MapHandlerRegistration::addDomListenerImpl(Lcom/google/gwt/ajaxloader/client/Properties;Lcom/google/gwt/maps/client/events/MapHandler;)(event, handler)
239                    };
240                    $wnd.google.maps.event.addDomListener(object, eventName, callback,
241                                    capture);
242            }-*/;
243    
244            private static void addDomListenerImpl(Properties properties,
245                            MapHandler<MapEvent> handler) {
246                    MapChangeEventFormatter formatter = new MapChangeEventFormatter();
247                    handler.onEvent(formatter.createEvent(properties));
248            }
249    
250    }