package edu.ucdavis.cstars.client; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Position; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.user.client.ui.SimplePanel; import edu.ucdavis.cstars.client.event.MapPanEndHandler; import edu.ucdavis.cstars.client.event.MapPanStartHandler; import edu.ucdavis.cstars.client.event.MapZoomEndHandler; import edu.ucdavis.cstars.client.geometry.Extent; import edu.ucdavis.cstars.client.geometry.Point; /** * The base class for the out-of-the-box InfoWindow. To create a custom info window, extend this class and adhere to the following requirements: * - Provide implementation for the listed methods * - Expose listed properties * - Fire listed events * * It is necessary to provide a base implementation so that the custom info window provides a minimum level of functionality and works as expected. * Custom info windows can define additional properties, methods and events to enhance the info window and provide a richer user experience. * * GWT NOTES: * - currently ignoring dijit startup/destory... use gwt not dijit ;) * - The root element is a SimplePanel (div) called 'panel'. In the extended class you need to define your title widget and content window, as well * as attach them the panel in the init() method. Call getPanel() to access this root panel. * * @author Justin Merz */ public abstract class InfoWindowBase { protected SimplePanel panel = new SimplePanel(); private Point currentPoint = null; private JavaScriptObject jso = null; protected MapWidget map = null; /** * Call this method in the constructor of your inheriting child class. */ public void load() { if( !assertLoaded() ) return; panel.getElement().getStyle().setPosition(Position.ABSOLUTE); panel.getElement().getStyle().setZIndex(500); init(); initJso(); } public abstract void init(); /** * Access to root panel of new info window. Use this your init() method. * * @return SimplePanel */ protected SimplePanel getPanel() { return panel; } protected Element getPanelElement() { return panel.getElement(); } protected native InfoWindowBase initJso() /*-{ var w = new $wnd.esri.InfoWindowBase(); var ref = this; this.@edu.ucdavis.cstars.client.InfoWindowBase::jso = w; w["domNode"] = this.@edu.ucdavis.cstars.client.InfoWindowBase::getPanelElement()(); w["isShowing"] = false; w["resize"] = function(width, height) { ref.@edu.ucdavis.cstars.client.InfoWindowBase::resize(II)(width, height); } // save original function w["__esri_setMap"] = w.setMap; // set new setMap function w["setMap"] = function(map) { w.__esri_setMap(map); ref.@edu.ucdavis.cstars.client.InfoWindowBase::_setMap(Ledu/ucdavis/cstars/client/MapWidget;)(map.__gwt_MapWidget); } w["unsetMap"] = function(map) { ref.@edu.ucdavis.cstars.client.InfoWindowBase::hide()(); } w["setTitle"] = function(title) { if( typeof title == "string" ) { ref.@edu.ucdavis.cstars.client.InfoWindowBase::setTitle(Ljava/lang/String;)(title); } //w.place(title, ref.@edu.ucdavis.cstars.client.InfoWindowBase::getTitleWidgetElement()()); } w["setContent"] = function(content) { if( typeof content == "string" ) { ref.@edu.ucdavis.cstars.client.InfoWindowBase::setContent(Ljava/lang/String;)(content); } //w.place(content, ref.@edu.ucdavis.cstars.client.InfoWindowBase::getContentWidgetElement()()); } w["show"] = function(location) { ref.@edu.ucdavis.cstars.client.InfoWindowBase::show(Ledu/ucdavis/cstars/client/geometry/Point;)(location); w.isShowing = true; w.onShow(); } w["hide"] = function() { ref.@edu.ucdavis.cstars.client.InfoWindowBase::hide()(); w.isShowing = false; } w["destroy"] = function() { ref.@edu.ucdavis.cstars.client.InfoWindowBase::hide()(); } }-*/; public abstract void setContent(String content); public abstract void setTitle(String title); /** * Check that the esri.InfoWindowBase has been loaded * * @return boolean */ public static native boolean assertLoaded() /*-{ if( $wnd.esri.InfoWindowBase ) return true; $wnd.alert("The ESRI_INFOWINDOWBASE package has not been loaded"); return false; }-*/; public JavaScriptObject getInfoWindowBaseObject() { return jso; } /** * The reference to a DOM node where the info window is constructed. * * @return Element */ public final Element getDomNode() { return panel.getElement(); }; /** * Indicates if the info window is visible. When true the window is visible. * Sub-classes should define this property. * * @return boolean */ public native boolean isShowing() /*-{ return this.@edu.ucdavis.cstars.client.InfoWindowBase::jso.isShowing; }-*/; /** * Hide the info window. Fire the onHide event at the end of your implementation of this method to hide the info window. */ public final void hide() { panel.setVisible(false); _hide(); onHide(); } private native void _hide() /*-{ this.@edu.ucdavis.cstars.client.InfoWindowBase::jso.isShowing = false; }-*/; /** * Resize the info window to the specified width and height (in pixels). * * @param width - width of window. * @param height - height of window. */ public final void resize(int width, int height) { panel.setSize(width+"px", height+"px"); } /** *This method is called by the map when the object is set as its info window. * * @param map - MapWidget */ public void setMap(MapWidget map) {} private void _setMap(MapWidget map) { this.map = map; map.addInfoWindow(panel); map.addPanStartHandler(new MapPanStartHandler(){ @Override public void onMapPanStart(Extent extent, Point delta) { if( isShowing() ) panel.setVisible(false); } }); map.addPanEndHandler(new MapPanEndHandler(){ @Override public void onMapPanEnd(Extent extent, Point delta) { if( isShowing() ) { panel.setVisible(true); update(); } } }); map.addZoomEndHandler(new MapZoomEndHandler(){ @Override public void onZoomEnd(Extent extent, float zoomFactor, Point anchor, int level) { if( isShowing() ) { update(); } } }); setMap(map); } /** * Display the info window at the specified location. * * @param location - location window will be shown at */ public void show(Point loc) { currentPoint = loc; update(); onShow(); } public void update() { if( currentPoint != null ) { Point loc = map.toScreen(currentPoint); panel.getElement().getStyle().setLeft(loc.getX()+10, Unit.PX); panel.getElement().getStyle().setTop(loc.getY()+10, Unit.PX); panel.setVisible(true); } } public Point getCurrentPoint() { return currentPoint; } /** * Fires after the info window is hidden. */ public abstract void onHide(); /** * Fires after the info window becomes visible. */ public abstract void onShow(); }