From d4a722571b875016e6752e91f134a6bbcaf08b7f Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 16 Jan 2023 11:59:41 +0100 Subject: [PATCH 1/5] Fix draggable markers --- .../main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt | 7 ++++++- .../kotlin/org/microg/gms/maps/mapbox/model/Marker.kt | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 1ca155ec4..deb3626ad 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -684,7 +684,12 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) override fun onAnnotationDrag(annotation: Symbol?) { try { - markers[annotation?.id]?.let { markerDragListener?.onMarkerDrag(it) } + annotation?.let { symbol -> + markers[symbol.id]?.let { marker -> + marker.setPositionWhileDragging(symbol.latLng.toGms()) + markerDragListener?.onMarkerDrag(marker) + } + } } catch (e: Exception) { Log.w(TAG, e) } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt index 06da36578..2aaf4da31 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt @@ -87,6 +87,14 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options map.symbolManager?.let { update(it) } } + /** + * New position is already reflected on map while if drag is in progress. Calling + * `symbolManager.update` would interrupt the drag. + */ + internal fun setPositionWhileDragging(position: LatLng) { + this.position = position + } + override fun getPosition(): LatLng = position override fun setTitle(title: String?) { -- GitLab From 5e74cdb2d06c37d445f470b08fd971662ff96af7 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 16 Jan 2023 18:41:21 +0100 Subject: [PATCH 2/5] Info window implementation --- .../gms/maps/internal/IGoogleMapDelegate.aidl | 6 +- .../internal/IOnInfoWindowCloseListener.aidl | 7 + .../IOnInfoWindowLongClickListener.aidl | 7 + .../org/microg/gms/maps/mapbox/GoogleMap.kt | 48 +++++- .../gms/maps/mapbox/model/BitmapDescriptor.kt | 2 +- .../gms/maps/mapbox/model/InfoWindow.kt | 152 ++++++++++++++++++ .../microg/gms/maps/mapbox/model/Marker.kt | 38 ++++- .../main/res/drawable/maps_default_bubble.xml | 33 ++++ .../res/layout/maps_default_bubble_layout.xml | 34 ++++ .../microg/gms/maps/vtm/GoogleMapImpl.java | 12 ++ 10 files changed, 323 insertions(+), 16 deletions(-) create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowCloseListener.aidl create mode 100644 play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowLongClickListener.aidl create mode 100644 play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt create mode 100644 play-services-maps-core-mapbox/src/main/res/drawable/maps_default_bubble.xml create mode 100644 play-services-maps-core-mapbox/src/main/res/layout/maps_default_bubble_layout.xml diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl index af44f1c50..fe592337f 100644 --- a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IGoogleMapDelegate.aidl @@ -18,6 +18,8 @@ import com.google.android.gms.maps.internal.IOnMapLongClickListener; import com.google.android.gms.maps.internal.IOnMarkerClickListener; import com.google.android.gms.maps.internal.IOnMarkerDragListener; import com.google.android.gms.maps.internal.IOnInfoWindowClickListener; +import com.google.android.gms.maps.internal.IOnInfoWindowCloseListener; +import com.google.android.gms.maps.internal.IOnInfoWindowLongClickListener; import com.google.android.gms.maps.internal.IInfoWindowAdapter; import com.google.android.gms.maps.internal.IOnMapLoadedCallback; import com.google.android.gms.maps.internal.IOnMyLocationChangeListener; @@ -120,9 +122,9 @@ interface IGoogleMapDelegate { void onExitAmbient() = 81; //void setOnGroundOverlayClickListener(IOnGroundOverlayClickListener listener) = 82; - //void setInfoWindowLongClickListener(IOnInfoWindowLongClickListener listener) = 83; + void setInfoWindowLongClickListener(IOnInfoWindowLongClickListener listener) = 83; //void setPolygonClickListener(IOnPolygonClickListener listener) = 84; - //void setInfoWindowCloseListener(IOnInfoWindowCloseListener listener) = 85; + void setInfoWindowCloseListener(IOnInfoWindowCloseListener listener) = 85; //void setPolylineClickListener(IOnPolylineClickListener listener) = 86; //void setCircleClickListener(IOnCircleClickListener listener) = 88; diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowCloseListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowCloseListener.aidl new file mode 100644 index 000000000..1ddae39c1 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowCloseListener.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.maps.internal; + +import com.google.android.gms.maps.model.internal.IMarkerDelegate; + +interface IOnInfoWindowCloseListener { + void onInfoWindowClose(IMarkerDelegate marker); +} diff --git a/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowLongClickListener.aidl b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowLongClickListener.aidl new file mode 100644 index 000000000..536e55e99 --- /dev/null +++ b/play-services-api/src/main/aidl/com/google/android/gms/maps/internal/IOnInfoWindowLongClickListener.aidl @@ -0,0 +1,7 @@ +package com.google.android.gms.maps.internal; + +import com.google.android.gms.maps.model.internal.IMarkerDelegate; + +interface IOnInfoWindowLongClickListener { + void onInfoWindowLongClick(IMarkerDelegate marker); +} diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index deb3626ad..076bdf641 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -52,6 +52,9 @@ import com.mapbox.mapboxsdk.plugins.annotation.Annotation import com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_ROUND import com.google.android.gms.dynamic.unwrap import com.mapbox.mapboxsdk.WellKnownTileServer +import org.microg.gms.maps.mapbox.model.DefaultInfoWindowAdapter +import org.microg.gms.maps.mapbox.model.InfoWindow +import org.microg.gms.maps.mapbox.model.getInfoWindowViewFor import org.microg.gms.maps.MapsConstants.* import org.microg.gms.maps.mapbox.model.* import org.microg.gms.maps.mapbox.utils.MapContext @@ -96,6 +99,12 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) private var mapLongClickListener: IOnMapLongClickListener? = null private var markerClickListener: IOnMarkerClickListener? = null private var markerDragListener: IOnMarkerDragListener? = null + private var infoWindowAdapter: IInfoWindowAdapter = DefaultInfoWindowAdapter(MapContext(context)) + internal var onInfoWindowClickListener: IOnInfoWindowClickListener? = null + internal var onInfoWindowLongClickListener: IOnInfoWindowLongClickListener? = null + internal var onInfoWindowCloseListener: IOnInfoWindowCloseListener? = null + + var currentInfoWindow: InfoWindow? = null var lineManager: LineManager? = null val pendingLines = mutableSetOf() @@ -456,13 +465,19 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } override fun setOnInfoWindowClickListener(listener: IOnInfoWindowClickListener?) { - Log.d(TAG, "unimplemented Method: setOnInfoWindowClickListener") + onInfoWindowClickListener = listener + } + override fun setInfoWindowLongClickListener(listener: IOnInfoWindowLongClickListener) { + onInfoWindowLongClickListener = listener } - override fun setInfoWindowAdapter(adapter: IInfoWindowAdapter?) { - Log.d(TAG, "unimplemented Method: setInfoWindowAdapter") + override fun setInfoWindowCloseListener(listener: IOnInfoWindowCloseListener) { + onInfoWindowCloseListener = listener + } + override fun setInfoWindowAdapter(adapter: IInfoWindowAdapter?) { + infoWindowAdapter = adapter ?: DefaultInfoWindowAdapter(MapContext(context)) } override fun getTestingHelper(): IObjectWrapper? { @@ -585,6 +600,7 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) map.addOnCameraMoveListener { try { cameraMoveListener?.onCameraMove() + currentInfoWindow?.update() } catch (e: Exception) { Log.w(TAG, e) } @@ -605,7 +621,11 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } map.addOnMapClickListener { latlng -> try { - mapClickListener?.let { if (!hasSymbolAt(latlng)) it.onMapClick(latlng.toGms()); } + if (!hasSymbolAt(latlng)) { + mapClickListener?.onMapClick(latlng.toGms()) + currentInfoWindow?.close() + currentInfoWindow = null + } } catch (e: Exception) { Log.w(TAG, e) } @@ -666,12 +686,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } symbolManager.iconAllowOverlap = true symbolManager.addClickListener { + val marker = markers[it.id] try { - markers[it.id]?.let { markerClickListener?.onMarkerClick(it) } == true + if (markers[it.id]?.let { markerClickListener?.onMarkerClick(it) } == true) { + return@addClickListener true + } } catch (e: Exception) { Log.w(TAG, e) - false + return@addClickListener false } + + marker?.let { showInfoWindow(it) } == true } symbolManager.addDragListener(object : OnSymbolDragListener { override fun onAnnotationDragStarted(annotation: Symbol?) { @@ -739,6 +764,17 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) } } + internal fun showInfoWindow(marker: MarkerImpl): Boolean { + infoWindowAdapter.getInfoWindowViewFor(marker, MapContext(context))?.let { infoView -> + currentInfoWindow?.close() + currentInfoWindow = InfoWindow(infoView, this, marker).also { infoWindow -> + mapView?.let { infoWindow.open(it) } + } + return true + } + return false + } + override fun useViewLifecycleWhenInFragment(): Boolean { Log.d(TAG, "unimplemented Method: useViewLifecycleWhenInFragment") return false diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt index e228387da..f0dc0f882 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/BitmapDescriptor.kt @@ -24,7 +24,7 @@ import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions import com.mapbox.mapboxsdk.style.layers.Property.ICON_ANCHOR_TOP_LEFT import com.mapbox.mapboxsdk.utils.ColorUtils -open class BitmapDescriptorImpl(private val id: String, private val size: FloatArray) { +open class BitmapDescriptorImpl(private val id: String, internal val size: FloatArray) { open fun applyTo(options: SymbolOptions, anchor: FloatArray, dpiFactor: Float): SymbolOptions { return options.withIconImage(id).withIconAnchor(ICON_ANCHOR_TOP_LEFT).withIconOffset(arrayOf(-anchor[0] * size[0] / dpiFactor, -anchor[1] * size[1] / dpiFactor)) } diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt new file mode 100644 index 000000000..c20eb7fbb --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt @@ -0,0 +1,152 @@ +package org.microg.gms.maps.mapbox.model + +import android.graphics.PointF +import android.view.LayoutInflater +import android.view.View +import android.view.View.VISIBLE +import android.view.ViewGroup +import android.view.ViewManager +import android.widget.FrameLayout +import android.widget.TextView +import com.google.android.gms.dynamic.ObjectWrapper +import com.google.android.gms.dynamic.unwrap +import com.google.android.gms.maps.internal.IInfoWindowAdapter +import com.google.android.gms.maps.model.internal.IMarkerDelegate +import com.mapbox.android.gestures.Utils +import com.mapbox.mapboxsdk.maps.MapView +import org.microg.gms.maps.mapbox.GoogleMapImpl +import org.microg.gms.maps.mapbox.R +import org.microg.gms.maps.mapbox.utils.MapContext +import org.microg.gms.maps.mapbox.utils.toMapbox +import kotlin.math.* + +/** + * `InfoWindow` is a tooltip shown when a [MarkerImpl] is tapped. Only + * one info window is displayed at a time. When the user clicks on a marker, the currently open info + * window will be closed and the new info window will be displayed. If the user clicks the same + * marker while its info window is currently open, the info window will be reopened. + * + * The info window is drawn oriented against the device's screen, centered above its associated + * marker, unless a different info window anchor is set. The default info window contains the title + * in bold and snippet text below the title. + * If neither is set, no default info window is shown. + * + * Based on Mapbox's / MapLibre's [com.mapbox.mapboxsdk.annotations.InfoWindow]. + * + */ + +fun IInfoWindowAdapter.getInfoWindowViewFor(marker: IMarkerDelegate, mapContext: MapContext): View? { + getInfoWindow(marker)?.unwrap()?.let { return it } + + getInfoContents(marker).unwrap()?.let { view -> + // Detach from previous BubbleLayout parent, if exists + view.parent?.let { (it as ViewManager).removeView(view) } + + return FrameLayout(view.context).apply { + background = mapContext.getDrawable(R.drawable.maps_default_bubble) + val fourDp = Utils.dpToPx(4f) + elevation = fourDp + setPadding(fourDp.toInt(), fourDp.toInt(), fourDp.toInt(), fourDp.toInt() * 3) + addView(view) + } + } + + // When a custom adapter is used, but both methods return null, the default adapter must be used + if (this !is DefaultInfoWindowAdapter) { + return DefaultInfoWindowAdapter(mapContext).getInfoWindowViewFor(marker, mapContext) + } + + return null +} + +class InfoWindow internal constructor( + private val view: View, private val map: GoogleMapImpl, internal val marker: MarkerImpl +) { + private var coordinates: PointF = PointF(0f, 0f) + var isVisible = false + + init { + view.setOnClickListener { + map.onInfoWindowClickListener?.onInfoWindowClick(marker) + } + view.setOnLongClickListener { + map.onInfoWindowLongClickListener?.onInfoWindowLongClick(marker) + true + } + } + + fun open(mapView: MapView) { + val lp: FrameLayout.LayoutParams = FrameLayout.LayoutParams( + FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT + ) + view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) + + close(true) // if it was already opened + mapView.addView(view, lp) + isVisible = true + + // Set correct position + update() + } + + /** + * Close this [InfoWindow] if it is visible, otherwise calling this will do nothing. + * + * @param silent `OnInfoWindowCloseListener` is only called if `silent` is not `false` + */ + fun close(silent: Boolean = false) { + if (isVisible) { + isVisible = false + (view.parent as ViewGroup?)?.removeView(view) + if (!silent) { + map.onInfoWindowCloseListener?.onInfoWindowClose(marker) + } + } + } + + /** + * Updates the position of the displayed view. + */ + fun update() { + map.map?.projection?.toScreenLocation(marker.position.toMapbox())?.let { + coordinates = it + } + + val iconDimensions = marker.getIconDimensions() + val width = iconDimensions?.get(0) ?: 0f + val height = iconDimensions?.get(1) ?: 0f + + view.x = + coordinates.x - view.measuredWidth / 2f + sin(Math.toRadians(marker.rotation.toDouble())).toFloat() * width * marker.getInfoWindowAnchor()[0] + view.y = coordinates.y - view.measuredHeight - max( + height * cos(Math.toRadians(marker.rotation.toDouble())).toFloat() * marker.getInfoWindowAnchor()[1], 0f + ) + } +} + +class DefaultInfoWindowAdapter(val context: MapContext) : IInfoWindowAdapter { + override fun asBinder() = null + + override fun getInfoWindow(marker: IMarkerDelegate?): ObjectWrapper { + return ObjectWrapper.wrap(if (marker != null && (marker.title != null || marker.snippet != null)) { + LayoutInflater.from(context).inflate(R.layout.maps_default_bubble_layout, null, false).apply { + marker.title?.let { + findViewById(R.id.title).apply { + text = it + visibility = VISIBLE + } + } + marker.snippet?.let { + findViewById(R.id.snippet).apply { + text = it + visibility = VISIBLE + } + } + } + } else { + null + }) + } + + override fun getInfoContents(marker: IMarkerDelegate?) = null +} \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt index 2aaf4da31..0d11c4c12 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/Marker.kt @@ -35,6 +35,7 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options private var visible: Boolean = options.isVisible private var rotation: Float = options.rotation private var anchor: FloatArray = floatArrayOf(options.anchorU, options.anchorV) + private var infoWindowAnchor: FloatArray? = null private var icon: BitmapDescriptorImpl? = options.icon?.remoteObject.unwrap() private var alpha: Float = options.alpha private var title: String? = options.title @@ -85,6 +86,7 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options this.position = position ?: return annotation?.latLng = position.toMapbox() map.symbolManager?.let { update(it) } + map.currentInfoWindow?.update() } /** @@ -93,18 +95,25 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options */ internal fun setPositionWhileDragging(position: LatLng) { this.position = position + map.currentInfoWindow?.update() } override fun getPosition(): LatLng = position override fun setTitle(title: String?) { this.title = title + map.currentInfoWindow?.let { + if (it.marker == this) it.close() + } } override fun getTitle(): String? = title override fun setSnippet(snippet: String?) { this.snippet = snippet + map.currentInfoWindow?.let { + if (it.marker == this) it.close() + } } override fun getSnippet(): String? = snippet @@ -118,18 +127,22 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options override fun isDraggable(): Boolean = draggable override fun showInfoWindow() { - Log.d(TAG, "unimplemented Method: showInfoWindow") - infoWindowShown = true + if (isInfoWindowShown) { + // Per docs, don't call `onWindowClose` if info window is re-opened programmatically + map.currentInfoWindow?.close(silent = true) + } + map.showInfoWindow(this) } override fun hideInfoWindow() { - Log.d(TAG, "unimplemented Method: hideInfoWindow") - infoWindowShown = false + if (isInfoWindowShown) { + map.currentInfoWindow?.close() + map.currentInfoWindow = null + } } override fun isInfoWindowShown(): Boolean { - Log.d(TAG, "unimplemented Method: isInfoWindowShow") - return infoWindowShown + return map.currentInfoWindow?.marker == this } override fun setVisible(visible: Boolean) { @@ -170,6 +183,9 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options anchor = floatArrayOf(x, y) annotation?.let { icon?.applyTo(it, anchor, map.dpiFactor) } map.symbolManager?.let { update(it) } + if (infoWindowAnchor == null) { + map.currentInfoWindow?.update() + } } override fun setFlat(flat: Boolean) { @@ -185,14 +201,18 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options this.rotation = rotation annotation?.iconRotate = rotation map.symbolManager?.let { update(it) } + map.currentInfoWindow?.update() } override fun getRotation(): Float = rotation override fun setInfoWindowAnchor(x: Float, y: Float) { - Log.d(TAG, "unimplemented Method: setInfoWindowAnchor") + infoWindowAnchor = floatArrayOf(x, y) + map.currentInfoWindow?.update() } + internal fun getInfoWindowAnchor() = infoWindowAnchor ?: floatArrayOf(0.5f, 1f) + override fun setAlpha(alpha: Float) { this.alpha = alpha annotation?.iconOpacity = if (visible) alpha else 0f @@ -222,6 +242,10 @@ class MarkerImpl(private val map: GoogleMapImpl, private val id: String, options Log.d(TAG, "onTransact [unknown]: $code, $data, $flags"); false } + fun getIconDimensions(): FloatArray? { + return icon?.size + } + companion object { private val TAG = "GmsMapMarker" } diff --git a/play-services-maps-core-mapbox/src/main/res/drawable/maps_default_bubble.xml b/play-services-maps-core-mapbox/src/main/res/drawable/maps_default_bubble.xml new file mode 100644 index 000000000..c172be81e --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/res/drawable/maps_default_bubble.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/play-services-maps-core-mapbox/src/main/res/layout/maps_default_bubble_layout.xml b/play-services-maps-core-mapbox/src/main/res/layout/maps_default_bubble_layout.xml new file mode 100644 index 000000000..6f175407c --- /dev/null +++ b/play-services-maps-core-mapbox/src/main/res/layout/maps_default_bubble_layout.xml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file diff --git a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java index 87a512091..301c7ed2e 100644 --- a/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java +++ b/play-services-maps-core-vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java @@ -45,6 +45,8 @@ import com.google.android.gms.maps.internal.IOnCameraMoveCanceledListener; import com.google.android.gms.maps.internal.IOnCameraMoveListener; import com.google.android.gms.maps.internal.IOnCameraMoveStartedListener; import com.google.android.gms.maps.internal.IOnInfoWindowClickListener; +import com.google.android.gms.maps.internal.IOnInfoWindowCloseListener; +import com.google.android.gms.maps.internal.IOnInfoWindowLongClickListener; import com.google.android.gms.maps.internal.IOnMapClickListener; import com.google.android.gms.maps.internal.IOnMapLoadedCallback; import com.google.android.gms.maps.internal.IOnMapLongClickListener; @@ -661,6 +663,16 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub } + @Override + public void setInfoWindowLongClickListener(IOnInfoWindowLongClickListener listener) throws RemoteException { + Log.d(TAG, "unimplemented Method: setInfoWindowLongClickListener"); + } + + @Override + public void setInfoWindowCloseListener(IOnInfoWindowCloseListener listener) throws RemoteException { + Log.d(TAG, "unimplemented Method: setInfoWindowCloseListener"); + } + @Override public void onStart() throws RemoteException { Log.d(TAG, "unimplemented Method: onStart"); -- GitLab From 05fd044674a906a4901a8e420dec2777f2da9bac Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Mon, 16 Jan 2023 18:44:08 +0100 Subject: [PATCH 3/5] Close info window `onDestroy` --- .../src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index 076bdf641..be5b69509 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -796,6 +796,8 @@ class GoogleMapImpl(private val context: Context, var options: GoogleMapOptions) symbolManager?.onDestroy() symbolManager = null + currentInfoWindow?.close() + pendingMarkers.clear() markers.clear() -- GitLab From d671ea6b2577cd0b5d1d275ac6da06ecad5139f4 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Wed, 18 Jan 2023 18:47:54 +0100 Subject: [PATCH 4/5] Apply review --- .../gms/maps/mapbox/model/InfoWindow.kt | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt index c20eb7fbb..ffbbc618d 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt @@ -76,13 +76,13 @@ class InfoWindow internal constructor( } fun open(mapView: MapView) { - val lp: FrameLayout.LayoutParams = FrameLayout.LayoutParams( + val layoutParams: FrameLayout.LayoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT ) view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) close(true) // if it was already opened - mapView.addView(view, lp) + mapView.addView(view, layoutParams) isVisible = true // Set correct position @@ -128,24 +128,28 @@ class DefaultInfoWindowAdapter(val context: MapContext) : IInfoWindowAdapter { override fun asBinder() = null override fun getInfoWindow(marker: IMarkerDelegate?): ObjectWrapper { - return ObjectWrapper.wrap(if (marker != null && (marker.title != null || marker.snippet != null)) { + + if (marker == null) return ObjectWrapper.wrap(null) + + val showDefaultMarker = (marker.title != null) || (marker.snippet != null) + + return if (!showDefaultMarker) ObjectWrapper.wrap(null) + else ObjectWrapper.wrap( LayoutInflater.from(context).inflate(R.layout.maps_default_bubble_layout, null, false).apply { + marker.title?.let { - findViewById(R.id.title).apply { - text = it - visibility = VISIBLE - } + val titleTextView = findViewById(R.id.title) + titleTextView.text = it + titleTextView.visibility = VISIBLE } + marker.snippet?.let { - findViewById(R.id.snippet).apply { - text = it - visibility = VISIBLE - } + val snippetTextView = findViewById(R.id.snippet) + snippetTextView.text = it + snippetTextView.visibility = VISIBLE } } - } else { - null - }) + ) } override fun getInfoContents(marker: IMarkerDelegate?) = null -- GitLab From 2e3a01fc0f9fba78852316eab311b2133aa45c73 Mon Sep 17 00:00:00 2001 From: Fynn Godau Date: Thu, 19 Jan 2023 09:47:22 +0100 Subject: [PATCH 5/5] Apply review 2 --- .../main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt index ffbbc618d..c5f00abbd 100644 --- a/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt +++ b/play-services-maps-core-mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/model/InfoWindow.kt @@ -36,7 +36,7 @@ import kotlin.math.* */ fun IInfoWindowAdapter.getInfoWindowViewFor(marker: IMarkerDelegate, mapContext: MapContext): View? { - getInfoWindow(marker)?.unwrap()?.let { return it } + getInfoWindow(marker).unwrap()?.let { return it } getInfoContents(marker).unwrap()?.let { view -> // Detach from previous BubbleLayout parent, if exists -- GitLab