2014.01.04 * Fixed a bug that caused missing tiles near the edge of a map. * Utils.getHostname(String) now returns null for relative URLs. Previously it would return GWT.getHostPageBaseURL(). * Fixed a bug which caused the map not to work under IE if tile image URLs were relative rather than absolute. * Disabled a special "safe" image loading mechanism for IE 8 and later. This mechanism was a workaround for image loading issues in earlier versions of IE, but made the images load somewhat slower. * Projection.fromLatLngToPixel(LatLng, int) now returns a PointView instead of a Point. Implementations can just change the return type. Users of the interface may either change the type of the receiving variable, create a new Point from the PointView, or set an existing Point to the values of the PointView via Point.set(PointView). * Fixed a bug where the coordinates for touch events were taken relative to the target element, instead of current target element. This, for example, would break pinching the map if you added a big overlay and pinched over it, as the coordinates for pinching were calculated relative to the overlay instead of the map. 2013.01.25 * WebKit-based browsers on Android 4.2+ are now officially supported! Tested on a Galaxy Nexus (Android 4.2.1) and a Nexus 7 (Android 4.2.1). * It is now easy to fully utilize the display capabilities of devices whose screens have a higher pixel density than they report (such as retina iPhone/iPad, or the Galaxy Nexus). Simply use Map.getVersionScaledToDisplay() on your Map object to obtain a version that scales the tiles down by window.devicePixelRatio. See the tutorial for more information on this. * Fixed ImageButton to properly respond to touch events in any browser that supports them, rather than only MobileSafari. * Added a new class, ImageTileLayer, which simplifies even more implementing an image-based tile layer. All you have to specify is the tile size and a pattern for tile URLs. See the tutorial and class documentation for details. * Added a MapWidget.applyMagnification(animate, roundingDirection) method which allows controlling the direction of the rounding of magnification towards the closest supported zoom. PinchMagnifyAction now uses this method to make sure that a zoom-in pinch (stretch) action always ends up a larger zoom than the temporary magnification, and a zoom-out pinch action ends up at a smaller zoom (within the range of supported zooms, of course). * All of the subpackages of com.maryanovsky.gwtutils.client.iphone.ui have been moved under com.maryanovsky.gwtutils.client.ui, and the package itself has been removed. For example, com.maryanovsky.gwtutils.client.iphone.ui.touch.gestures has been renamed to com.maryanovsky.gwtutils.client.ui.touch.gestures. * The com.maryanovsky.map.client.actions.desktop package has been renamed to com.maryanovsky.map.client.actions.mouse. Accordingly, the DesktopStandardActions class in it has been renamed to StandardMouseActions. * The com.maryanovsky.map.client.actions.iphone package has been renamed to com.maryanovsky.map.client.actions.touch. Accordingly, the IPhoneStandardActions class has been renamed to StandardMultiTouchActions. * Added a GWT compile-time property named interactionMode that determines whether StandardMouseActions or StandardMultiTouchActions replaces StandardActions. Its default value is determined from the browser's user.agent, but if you are writing specifically a desktop or specifically a mobile app, set it to either "mouse" or "touch" in your projects .gwt.xml file. 2012.04.04 * LargeZoomObject was not working correctly if you started dragging the mark and then moved the mouse outside the widget (it wasn't setting and release mouse event capture properly). * TileLayer now returns a Tile instance instead of a tile image URL. This allows implementing tiles that aren't just a single image. To replicate the old functionality, use the (now public) ImageTile class in the tiles subpackage. * Since Google has been actively making it hard to support their maps, I have no choice to conclude that they don't want their maps to be used from libraries other than their own. Removed support for Google Maps. * Updated code to compile cleanly under GWT 2.4, which is now required. 2011.04.04 * MapWidget's addOverlay and removeOverlay methods that took a Collection now take a Collection arguments. * Mobile AppleWebKit is now properly depected in all instances. Previously, it would not get properly detected when launching from the iPhone home screen. * Removed the touch event related classes from GwtUtils as they are now available as part of GWT 2.2. As a consequence, SashaMaps now requires GWT 2.2 or later. * Removed TouchEventsCanceller, as you can now use EventCancellingPanel to cancel touch events, instead. * The WidgetOverlay.makeXDraggable methods were renamed to explicitly specify whether the overlay is draggable by mouse or by touch. The new method names have a "ByMouse" or "ByTouch" suffix. * The iOS demo now works properly in both portrait and landscape modes, and when switching between the two. This was done by adding "user-scalable=no" to the viewport meta tag in HTML (see updated documentation in the tutorial). * The iPad is now fully supported! Previously the map worked, but would glitch and flicker when dragged/pinched due to a bug in Safari. * Fixed the inertial drag action for touch devices. It was not calculating the speed and angle correctly. 2010.04.16 * LatLng now has a fromUrlValue(String) method which is the inverse of LatLng.toUrlValue(). * Callback.callBack(T) has been renamed to Callback.callback(T) (lowercase 'b'). * Added TouchEventsCanceller, a new TouchListener which invokes cancelBubble(true) and preventDefault() on all events it receives. This is useful to completely prevent the default responses to touch gestures on the iPhone. * Fixed DragRecognizer to properly cancel dragging when a 2nd finger touches the screen. * Fixed PinchRecognizer to be more lenient when detecting pinching. It now allows the first finger to move before the 2nd finger touches the screen. * The MapWidget is no longer itself keyboard-focusable. * com.maryanovsky.gwtutils.ui.EventCancellingPanel, a new class, has been added to GwtUtils to facilitate convenient cancelling of event bubbling and the prevention of default action. To cancel touch events, use com.maryanovsky.gwtutils.client.iphone.ui.event.touch.TouchCanceller. * GwtUtils and SashaMaps have been updated to use the new GWT 1.6 EventHandler system. The following has changed: - ImageButton.onClick() has been removed. Instead of overriding it, simply add a click handler. - ImageButton.addClickListener() and ImageButton.removeClickListener() have been removed. Use ImageButton.addClickHandler() instead. - Form.setDefaultFocusedWidget now takes a Focusable as argument. - UiUtils.trackResizes has been renamed to addSizeChangeHandler. UiUtils.stopTrackingResizes has been removed. Instead, you simply use the HandlerRegistration returned by addSizeChangeHandler. * Added support for the new ClientBundle: - ImageButton now has constructors which take ImageResource arguments. - LargeZoomWidget.Images is now a ClientBundle. - BubbleWidget.Images is now a ClientBundle. - ScaleWidget.Images is now a ClientBundle. * The com.maryanovsky.gwtutils.client.iphone package has been completely reworked to use the new event handling system. * All of the classes and packages in com.maryanovsky.gwtutils.client.iphone have been moved into the iphone.ui subpackage, to make room for future iphone-related, but not UI-related classes/packages. * UserEventManager and the corresponding Actions are gone. Instead, a mechanism similar to iPhone gesture recognitions has been implemented. See the com.maryanovsky.gwtutils.client.ui.mouse.gestures package for more information. * IPhoneStandardActions and DesktopStandardActions methods now return the gesture recognizers for the gestures they add a action for. The method names have been renamed accordingly. * All the map actions are now implemented in their own top-level classes under the actions.desktop and actions.iphone subpackages of the com.maryanovsky.map.client package. IPhoneStandardActions and DesktopStandardActions have been moved to their respective package. * Added ButtonTapRecognizer and corresponding classes in the iphone.ui.touch.gestures.buttontap subpackage. This recognizes a tap on a button, which is different from a regular one (for example, it allows the finger to move before lifting). * All the gesture recognizers (for both mouse and touch events) now take a Condition argument which allows creating recognizers for a subset of the gestures normally recognized. For example, a TapRecognizer may be customized to only recognize double-taps. 2009.09.24 * Added MapWidget.setLoadTilesDuringTemporaryChanges(boolean), a new method which allows disabling the loading of new tiles during temporary changes to the map's location (such as while the user is in the middle of panning the map). This speeds up things on slower devices, such as an iPhone. Note that the default value of this setting is false when running on Mobile Safari. * Added new methods to control the magnification of the map in MapWidget: setMagnification, getMagnification and applyMagnification. * Added a new method: MapWidget.getUserEventWidget(). * TileLayerWidget.isMagnificationSupported() and MapWidget.isAnimatedZoomSupported() are now deprecated and always return true. * MapWidget.startAnimation() now takes a MapAnimation as argument instead of a regular Animation. The new MapWidget.MapAnimation class is a subclass of Animation that adds methods for getting notified before temporary offset or magnification are set on the map widget. If you've previously used custom animations with MapWidget, simply subclass MapWidget.MapAnimation instead of Animation to correct compilation errors. * UiUtils.setVisible(Widget, boolean) was renamed to setVisibility. * Added a new method, UiUtils.getVisibility(Widget). * Added a new method, MapWidget.getOverlays(). * MapWidget now works (properly) on the iPhone! * WidgetOverlay now works properly on the iPhone, including dragging. * ImageButton now works properly on the iPhone. * Removed ImageButton.handleBrowserEvent(Event). You may still listen to click events in a subclass by overriding the new ImageButton.onClick() method. * The abstract map action classes (MapClickAction, MapDragAction, MapMoveAction and MapWheelAction) classes that were previously member types of MapWidget have been made into top-level classes and moved to the new actions subpackage. * The map action implementations (MapWidget.DRAG_MAP_ACTION, MapWidget.PAN_ACTION etc.) have been moved to the new DesktopStandardActions class in the new actions subpackage. * AreaSelectionAction has been moved to the new actions subpackage. 2009.07.24 * The com.maryanovsky.gwtutils.client package has been refactored into several subpackages: event, geom, net, text and ui. * Added Properties, a new class, to GwtUtils. A Properties object holds a set of property names mapped to values, which can be retrieved and parsed as several types (integer, double etc.). * Added a parseProperties(propertiesText, boolean trim) method to ParseUtils, which optionally trims the property names and values. * Added a getUrlParams(Map params) method to Utils, which adds the URL parameters of the current page to the specified map. * Added Application, a new class, to GwtUtils. The Application class implements EntryPoint and handles much of the work required to start an application (such as retrieving the settings). * Added Factory, a new interface, to GwtUtils. * Added LatLngBounds, a new class, to SashaMaps. Also, added two new related methods to MapWidget: getBounds() which returns the LatLngBounds of the current display and show(LatLngBounds bounds, boolean animate) which displays the specified bounds with optional animation. * Fixed a bug in WidgetOverlay which caused overlays that were removed and then re-added not to be positioned properly (they were losing their "position:absolute" CSS attribute when removed). * Added a new method: WidgetOverlay.updateWidgetSize(SizeView), which should be invoked when the size of the widget changes, so that WidgetOverlay can update its position accordingly. * Added BubbleWidget, a new map widget/overlay to SashaMaps. BubbleWidget is a comics-style "talk" bubble which can display arbitrary content. The class can be found in the com.maryanovsky.map.client.widgets.bubble package. * Utils.getUrlParams(Map) is now implemented using Window.Location.getParameterMap() instead of native code directly. Additionally, it now returns the map, after adding the parameters to it. * Added a new method, Utils.getUrlParams(), which returns the map of URL parameters. * Added key modifier masks to UserEventManager and a getModifiers(Event) method which returns an OR of the modifiers pressed for the event. * All the action setter methods in UserEventManager now allow specifying which keyboard modifiers must be pressed for the action to be invoked. The old action setter methods which take no argument will now register the action to be called only when no keyboard modifiers are pressed (note that previously it would invoke it regardless of which modifiers are pressed, so this change could break the behaviour of some apps). * Added two new convenience methods to UiUtils: setAbsoluteBounds(Widget, RectangleView) and setBounds(Widget, RectangleView). * Added AreaSelectionAction, a new map action which allows the user to select the area he wants to zoom-in on by dragging a selection rectangle. * Animated zoom is now supported under all browsers and platforms. Note, however, that on some browser/OS combinations the animation is not as smooth as on others, so you may want to disable animated zoom on those. In particular, Firefox under Windows seems to suffer from this problem. * Fixed a bug in UserEventManager which sometimes caused mouse wheel up/down events to go unreported. * Added 3 new interfaces to com.maryanovsky.gwtutils.client.text: Encoder, Decoder and Transcoder. Transcoder also contains implementations for some common data types. * Added 3 new methods to BrowserUtils: getHostname(), getPathname() and setDocumentLocation(String). * Added a new interface to com.maryanovsky.gwtutils.client.event: HasChange. * Added a new class to com.maryanovsky.gwtutils.client.ui: PlainHyperlink. * ParseUtils.parseProperties now allows continuing the logical line on a new physical line by ending it with a backslash. * Fixed a bug which sometimes caused magnified tiles (during animated zoom) to be placed wrongly, breaking the lovely effect. * Added new methods to BrowserUtils to detect some common operating systems: isWindows(), isMacOS() and isLinux(). 2009.05.21 * GwtUtils and SashaMaps have been updated to use the new language features available in Java 1.5, the support for which was added in GWT 1.5. This includes use of type-parameterization, foreach loops, better use of Collections etc. This change affects users of SashaMaps in ways listed below. * GWT 1.5.3 is now required to compile SashaMaps. * Alignment is now an enum. It no longer has a public constructor, but instead a getInstance(HorizontalAlignmentConstant, VerticalAlignmentConstant) method. * Callback is now parameterized with the type of the object passed to the callback method. * Pair is now type-parameterized, in the obvious manner. * ReadyListener and DelegatingReadyListenerCollection are now parameterized with the type of the source object. * GroupReadyListener is now parameterized with both the type of the items in the interest set and the type of the source object. * GroupReadyListener's constructor no longer allows a null value for the source parameter. This is because the type of the source parameter must be known at compile time. Previously, a null value meant that the newly created GroupReadyListener itself was used as the source. * ResultCallback is now parameterized with the type of the result object. * XmlResponseHandler is now parameterized with the type of the result object. * An XmlResponseHandler with a null parser must either be parameterized with com.google.gwt.xml.client.Document or override the parseResponse(Document) method. * The XmlResponseHandler constructor that does not take a parser as an argument has been removed as it can only be used if the result object is of type Document. * The setGridRow, addWidget and addDialogButtons methods in UiUtils now take Lists of widgets and vertical and horizontal alignments. Previously they took arrays. * Wherever the documentation of a method asked to treat the returned collection as unmodifiable (and in many places where it forgot to do so, but obviously intended to), the returned collection is now actually unmodifiable. * MenuItemSeparator has been removed from GwtUtils, as GWT 1.5 has this functionality built-in. * Updated the GoogleMaps implementation to use the new tile protocol (Google stopped supporting the old one). 2008.11.07 * Moved support for Google Maps into its own package - com.maryanovsky.map.client.google. The com.maryanovsky.map.client.impl package is no longer with us. * Using Google Maps now requires a Google Maps API key. * Added a ParseUtils class into GwtUtils. The class has some useful parsing utilities, mainly for processing XML documents. * Many classes, which were not meant to be subclassed, are now declared final. * LatLng now allows -180 as a legal longitude value. * LatLng.equals(Object) and LatLng.hashCode() now compare LatLng objects for geographical identity. That is, two LatLng objects are considered equal if they represent the same location on the globe. For example, (latitude=20, longitude=-180) and (latitude=20, longitude=180) are equal. * Added a new interface, DoublePointView, and an implementation, DoublePoint, to GwtUtils. Additionally, LatLng now implements DoublePointView. * Fixed a bug in TileLayerWidget where tile width and tile height were mixed up, which would have caused problems for tile layers where they are different. * The location passed to TileLayer.getTileUrl(x,y,zoom) is now the middle of the tile instead of the top-left. This is done to avoid tile-boundary issues and make it easier on TileLayer implementations to return the right tile. Existing correct TileLayer implementations should not be affected. * Added support for Web Map Service maps - see the com.maryanovsky.map.client.opengis.wms package. * Refactored the way projections are implemented - see the new com.maryanovsky.map.client.projections package and the AbstractProjection class. * Replaced WidgetOverlay's 4 getters and setters of horizontal and vertical alignment with setAlignment(Alignment) and getAlignment(). * Improved the performance of adding many WidgetOverlays and the handling of the map when many have been added. * The styling of the rectangle in the overview map widget marking the bounds of the main map widget is no longer hard-coded. It now sits in the overview.css file and can be overridden. 2008.07.28 * OverviewMapWidget.Synchronization has a new method: MapLocationModel createOverviewLocationModel(MapWidget mainWidget). This method is responsible for creating the MapLocationModel of the overview map widget. Assigning this responsibility to a separate method allows the overview MapLocationModel to be different from the model of the main map widget. Previously, the overview map widget used a copy of main map widget's model, which, for example, restricted it to the same range of zooms. The default implementation of the new method in OverviewMapWidget.StandardSynchronization now behaves as OverviewMapWidget used to (i.e. creates a copy of the main map widget's model). * Moved OverviewMapWidget into com.maryanovsky.map.client.widgets.overview. Future map related widgets will also be placed under the widgets subpackage. * Implemented a GoogleMaps-like LargeZoomWidget. * Implemented a GoogleMaps-like ScaleWidget. * Added a new method to the Projection interface - getWrapSize(int zoom), which returns the size of the entire map in pixels at a given zoom. This allows MapWidget to correctly wrap locations when the entire map (earth) is displayed more than once. * The length of pan and zoom animations in MapWidget is now customizeable. * Changed the default length of pan and zoom animations in MapWidget from 500ms to 300ms. * Fixed a bug in PilePanel (a GwtUtils class) causing PopupPanels to appear behind any overlays and widgets on the map. * To improve performance, WidgetOverlay now hides (via setVisible(false)) its widget if the widget's bounds do not intersect with the bounds of the overlay panel. * Many changes and new features in the GwtUtils library. * Other bugfixes I implemented but didn't write down their descriptions. * The release file now includes the tutorial and the javadoc for both Sasha Maps and GwtUtils. * The released source is now obfuscated. You may receive the full unobfuscated source by obtaining a commercial license.