From e6ca2ffc47947ec487ccd4fb5c38036a9fafcfb8 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Thu, 29 Feb 2024 18:25:39 -0300 Subject: [PATCH 1/3] feat: add support for adding custom control buttons Close #115 --- .../addons/googlemaps/ControlPosition.java | 98 +++++++++++++++++++ .../addons/googlemaps/CustomControl.java | 73 ++++++++++++++ .../vaadin/addons/googlemaps/GoogleMap.java | 21 +++- .../addons/googlemaps/GoogleMapMarker.java | 2 +- .../addons/googlemaps/GoogleMapPoint.java | 2 +- .../addons/googlemaps/GoogleMapPoly.java | 2 +- 6 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/flowingcode/vaadin/addons/googlemaps/ControlPosition.java create mode 100644 src/main/java/com/flowingcode/vaadin/addons/googlemaps/CustomControl.java diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/ControlPosition.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/ControlPosition.java new file mode 100644 index 0000000..7b26145 --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/ControlPosition.java @@ -0,0 +1,98 @@ +/*- + * #%L + * Google Maps Addon + * %% + * Copyright (C) 2020 - 2024 Flowing Code + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +package com.flowingcode.vaadin.addons.googlemaps; + +/** + * Enum representing supported control positions for map control buttons. + */ +public enum ControlPosition { + + /** + * Indicates that the control should be placed along the top center of the map. + */ + TOP_CENTER, + + /** + * Indicates that the control should be placed along the top left of the map, with any + * sub-elements of the control "flowing" towards the top center. + */ + TOP_LEFT, + + /** + * Indicates that the control should be placed along the top right of the map, with any + * sub-elements of the control "flowing" towards the top center. + */ + TOP_RIGHT, + + /** + * Indicates that the control should be placed along the top left of the map, but below any + * TOP_LEFT elements. + */ + LEFT_TOP, + + /** + * Indicates that the control should be placed along the top right of the map, but below any + * TOP_RIGHT elements. + */ + RIGHT_TOP, + + /** + * Indicates that the control should be placed along the left side of the map, centered between + * the TOP_LEFT and BOTTOM_LEFT positions + */ + LEFT_CENTER, + + /** + * Indicates that the control should be placed along the right side of the map, centered between + * the TOP_RIGHT and BOTTOM_RIGHT positions. + */ + RIGHT_CENTER, + + /** + * Indicates that the control should be placed along the bottom left of the map, but above any + * BOTTOM_LEFT elements. + */ + LEFT_BOTTOM, + + /** + * Indicates that the control should be placed along the bottom right of the map, but above any + * BOTTOM_RIGHT elements. + */ + RIGHT_BOTTOM, + + /** + * Indicates that the control should be placed along the bottom center of the map. + */ + BOTTOM_CENTER, + + /** + * Indicates that the control should be placed along the bottom left of the map, with any + * sub-elements of the control "flowing" towards the bottom center. + */ + BOTTOM_LEFT, + + /** + * Indicates that the control should be placed along the bottom right of the map, with any + * sub-elements of the control "flowing" towards the bottom center. + */ + BOTTOM_RIGHT; + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/CustomControl.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/CustomControl.java new file mode 100644 index 0000000..717d6a7 --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/CustomControl.java @@ -0,0 +1,73 @@ +/*- + * #%L + * Google Maps Addon + * %% + * Copyright (C) 2020 - 2024 Flowing Code + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +package com.flowingcode.vaadin.addons.googlemaps; + +import com.vaadin.flow.component.button.Button; +import elemental.json.Json; +import elemental.json.JsonObject; +import java.io.Serializable; +import java.util.Optional; + +/** + * Represents a custom control that can be added to the map. + * + * A button to represent the custom control and the {@link ControlPosition position} where the + * button should be displayed within the map should be specified. + * + */ +public class CustomControl implements Serializable { + + private static final long serialVersionUID = -1821466465711569857L; + + private Button controlButton; + + private ControlPosition controlPosition; + + public CustomControl(Button controlButton, ControlPosition controlPosition) { + this.controlButton = controlButton; + this.controlPosition = controlPosition; + } + + public Button getControlButton() { + return controlButton; + } + + public void setControlButton(Button controlButton) { + this.controlButton = controlButton; + } + + public ControlPosition getControlPosition() { + return controlPosition; + } + + public void setControlPosition(ControlPosition controlPosition) { + this.controlPosition = controlPosition; + } + + protected JsonObject getJson(int id) { + JsonObject js = Json.createObject(); + js.put("id", id); + Optional.ofNullable(controlPosition) + .ifPresent(value -> js.put("position", controlPosition.name())); + return js; + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java index 391f838..2b317a3 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java @@ -35,6 +35,8 @@ import com.vaadin.flow.dom.DebouncePhase; import com.vaadin.flow.dom.DomListenerRegistration; import com.vaadin.flow.shared.Registration; +import elemental.json.Json; +import elemental.json.JsonArray; import elemental.json.JsonObject; import elemental.json.JsonValue; import java.util.List; @@ -44,7 +46,7 @@ @SuppressWarnings("serial") @Tag("google-map") @JsModule("@flowingcode/google-map/google-map.js") -@NpmPackage(value = "@flowingcode/google-map", version = "3.6.1") +@NpmPackage(value = "@flowingcode/google-map", version = "3.7.1") @NpmPackage(value = "@googlemaps/markerclusterer", version = "2.0.8") @JsModule("./googlemaps/geolocation.js") public class GoogleMap extends Component implements HasSize { @@ -625,5 +627,20 @@ public LatLonBounds getBounds() { return bounds; } } - + + /** + * Adds custom control buttons to the map. + * + * @param customControls list of custom controls to add to the map + */ + public void addCustomControls(CustomControl... customControls) { + JsonArray jsonArray = Json.createArray(); + for (int i = 0; i < customControls.length; i++) { + CustomControl customControl = customControls[i]; + jsonArray.set(i, customControl.getJson(i)); + customControl.getControlButton().getElement().setAttribute("slot", "customControlSlot_" + i); + this.getElement().appendChild(customControl.getControlButton().getElement()); + } + this.getElement().setPropertyJson("customControls", jsonArray); + } } diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapMarker.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapMarker.java index b8cc6bb..8d859c2 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapMarker.java +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapMarker.java @@ -39,7 +39,7 @@ @SuppressWarnings("serial") @Tag("google-map-marker") @JsModule("@flowingcode/google-map/google-map-marker.js") -@NpmPackage(value = "@flowingcode/google-map", version = "3.6.1") +@NpmPackage(value = "@flowingcode/google-map", version = "3.7.1") @NpmPackage(value = "@googlemaps/markerclusterer", version = "2.0.8") public class GoogleMapMarker extends Component { diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoint.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoint.java index e93a744..7e4994b 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoint.java +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoint.java @@ -28,7 +28,7 @@ @SuppressWarnings("serial") @Tag("google-map-point") @JsModule("@flowingcode/google-map/google-map-point.js") -@NpmPackage(value = "@flowingcode/google-map", version = "3.6.1") +@NpmPackage(value = "@flowingcode/google-map", version = "3.7.1") @NpmPackage(value = "@googlemaps/markerclusterer", version = "2.0.8") public class GoogleMapPoint extends Component { diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoly.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoly.java index 92582d6..dfd6137 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoly.java +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMapPoly.java @@ -39,7 +39,7 @@ @Tag("google-map-poly") @JsModule("@flowingcode/google-map/google-map-poly.js") @JsModule("@flowingcode/google-map/google-map-point.js") -@NpmPackage(value = "@flowingcode/google-map", version = "3.6.1") +@NpmPackage(value = "@flowingcode/google-map", version = "3.7.1") @NpmPackage(value = "@googlemaps/markerclusterer", version = "2.0.8") public abstract class GoogleMapPoly extends Component { From 17e6b67582c170c976dfb44d4081ef7268f96848 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Thu, 29 Feb 2024 18:27:47 -0300 Subject: [PATCH 2/3] refactor(demo): make GeolocationDemo to use custom control button Close #114 --- .../addons/googlemaps/GeolocationDemo.java | 35 ++++++++++--------- .../google-maps/geolocation-demo-styles.css | 31 ++++++++++++++++ 2 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 src/test/resources/META-INF/resources/frontend/styles/google-maps/geolocation-demo-styles.css diff --git a/src/test/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationDemo.java b/src/test/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationDemo.java index 89ef83f..a9fd1dc 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationDemo.java @@ -23,15 +23,19 @@ import com.flowingcode.vaadin.addons.demo.DemoSource; import com.flowingcode.vaadin.addons.googlemaps.GoogleMap.MapType; import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.dependency.CssImport; +import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.notification.Notification; -import com.vaadin.flow.component.orderedlayout.FlexLayout; -import com.vaadin.flow.component.orderedlayout.FlexLayout.FlexWrap; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; @PageTitle("Geolocation Demo") @DemoSource +@DemoSource( + value = "/src/test/resources/META-INF/resources/frontend/styles/google-maps/geolocation-demo-styles.css", + caption = "geolocation-demo-styles.css") @Route(value = "googlemaps/geolocation", layout = GooglemapsDemoView.class) +@CssImport("./styles/google-maps/geolocation-demo-styles.css") @SuppressWarnings("serial") public class GeolocationDemo extends AbstractGoogleMapsDemo { @@ -40,22 +44,21 @@ protected void createGoogleMapsDemo(String apiKey) { GoogleMap gmaps = new GoogleMap(apiKey, null, null); gmaps.setMapType(MapType.ROADMAP); gmaps.setSizeFull(); + add(gmaps); - FlexLayout layout = new FlexLayout(); - layout.setFlexWrap(FlexWrap.WRAP); - layout.add(new Button("Go to current location", e -> gmaps.goToCurrentLocation())); - add(gmaps, layout); + // create custom control button to pan to current location + Button currentLocationButton = new Button("Go to current location", + VaadinIcon.CROSSHAIRS.create(), e -> gmaps.goToCurrentLocation()); + currentLocationButton.setClassName("geolocation-button"); + CustomControl geolocationControl = + new CustomControl(currentLocationButton, ControlPosition.TOP_CENTER); + gmaps.addCustomControls(geolocationControl); - gmaps.addCurrentLocationEventListener( - e -> - gmaps.addMarker( - new GoogleMapMarker("You are here!", gmaps.getCenter(), false, Markers.GREEN))); + gmaps.addCurrentLocationEventListener(e -> gmaps + .addMarker(new GoogleMapMarker("You are here!", gmaps.getCenter(), false, Markers.GREEN))); - gmaps.addGeolocationErrorEventListener( - e -> - Notification.show( - e.isBrowserHasGeolocationSupport() - ? "The geolocation service failed on retrieving your location." - : "Your browser doesn't support geolocation.")); + gmaps.addGeolocationErrorEventListener(e -> Notification.show(e.isBrowserHasGeolocationSupport() + ? "The geolocation service failed on retrieving your location." + : "Your browser doesn't support geolocation.")); } } diff --git a/src/test/resources/META-INF/resources/frontend/styles/google-maps/geolocation-demo-styles.css b/src/test/resources/META-INF/resources/frontend/styles/google-maps/geolocation-demo-styles.css new file mode 100644 index 0000000..0d1ebd6 --- /dev/null +++ b/src/test/resources/META-INF/resources/frontend/styles/google-maps/geolocation-demo-styles.css @@ -0,0 +1,31 @@ +/*- + * #%L + * Google Maps Addon + * %% + * Copyright (C) 2020 - 2024 Flowing Code + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +.geolocation-button { + background: white; + margin: 10px; + height: 40px; + color: black; + cursor: pointer; + font-family: Arial; + font-size: 18px; + border-radius: 0; + box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px; +} \ No newline at end of file From 3de09b964cc613496ec5911884efa91ed27e8f53 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Thu, 29 Feb 2024 18:29:11 -0300 Subject: [PATCH 3/3] build: update version to 1.12.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c75b4d1..fac4dba 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.flowingcode.vaadin.addons google-maps - 1.11.1-SNAPSHOT + 1.12.0-SNAPSHOT Google Maps Addon Integration of google-map for Vaadin platform