Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce feature drag and pointer events handling #162

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

// if imports can't resolve: https://stackoverflow.com/a/65903576/9439899

import CameraChangeReason
import LngLat
import MapCamera
import MapLibreFlutterApi
import MapLibreHostApi
import MapOptions
import android.content.Context

Check failure on line 5 in android/src/main/kotlin/com/github/josxha/maplibre/MapLibreMapController.kt

View workflow job for this annotation

GitHub Actions / [Kotlin] Code quality

[ktlint] reported by reviewdog 🐶 Imports must be ordered in lexicographic order without any empty lines in-between with "java", "javax", "kotlin" and aliases in the end Raw Output: android/src/main/kotlin/com/github/josxha/maplibre/MapLibreMapController.kt:5:1: error: Imports must be ordered in lexicographic order without any empty lines in-between with "java", "javax", "kotlin" and aliases in the end (standard:import-ordering)
import android.graphics.BitmapFactory
import android.graphics.PointF
import android.view.MotionEvent
import android.view.View
import android.widget.FrameLayout
import androidx.lifecycle.DefaultLifecycleObserver
import com.google.gson.Gson
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.platform.PlatformView
import java.io.IOException
import java.net.URL
import org.maplibre.android.MapLibre
import org.maplibre.android.camera.CameraPosition
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.gestures.AndroidGesturesManager
import org.maplibre.android.gestures.MoveGestureDetector
import org.maplibre.android.maps.MapLibreMap
import org.maplibre.android.maps.MapLibreMap.OnCameraMoveStartedListener.REASON_API_ANIMATION
import org.maplibre.android.maps.MapLibreMap.OnCameraMoveStartedListener.REASON_API_GESTURE
Expand All @@ -40,8 +40,13 @@
import org.maplibre.android.style.layers.PropertyValue
import org.maplibre.android.style.layers.RasterLayer
import org.maplibre.android.style.layers.SymbolLayer
import java.io.IOException
import java.net.URL
import CameraChangeReason
import LngLat
import LongPressEventType
import MapCamera
import MapLibreFlutterApi
import MapLibreHostApi
import MapOptions

class MapLibreMapController(
private val viewId: Int,
Expand All @@ -58,6 +63,9 @@
private val flutterApi: MapLibreFlutterApi
private lateinit var mapOptions: MapOptions
private var style: Style? = null
private var gesturesManager: AndroidGesturesManager? = null
private lateinit var defaultGesturesManager: AndroidGesturesManager
private var dragGesturesEnabled: Boolean = false

init {
val channelSuffix = viewId.toString()
Expand Down Expand Up @@ -104,6 +112,7 @@
lifecycleProvider.getLifecycle()?.addObserver(this)
mapView.getMapAsync(this)
mapViewContainer.addView(mapView)
toggleLongPressMove(mapOptions.gestures.drag)
}
}

Expand All @@ -112,12 +121,20 @@
override fun onMapReady(mapLibreMap: MapLibreMap) {
this.mapLibreMap = mapLibreMap
MapLibreRegistry.addMap(viewId, mapLibreMap)

gesturesManager = this.mapLibreMap.getGesturesManager()
defaultGesturesManager = gesturesManager!!

this.mapLibreMap.addOnMapClickListener { latLng ->
flutterApi.onClick(LngLat(latLng.longitude, latLng.latitude)) { }
flutterApi.onClick(LngLat(latLng.longitude, latLng.latitude)) {}
true
}
this.mapLibreMap.addOnMapLongClickListener { latLng ->
flutterApi.onLongClick(LngLat(latLng.longitude, latLng.latitude)) { }
flutterApi.onLongClick(LngLat(latLng.longitude, latLng.latitude)) {}
if (dragGesturesEnabled) {
gesturesManager?.setMoveGestureListener(LongPressMoveGestureListener())
mapLibreMap.uiSettings.setAllGesturesEnabled(false)
}
true
}
this.mapLibreMap.addOnCameraMoveListener {
Expand All @@ -127,8 +144,8 @@
val camera = MapCamera(center, position.zoom, position.tilt, position.bearing)
flutterApi.onMoveCamera(camera) {}
}
this.mapLibreMap.addOnCameraIdleListener { flutterApi.onCameraIdle { } }
this.mapView.addOnDidBecomeIdleListener { flutterApi.onIdle { } }
this.mapLibreMap.addOnCameraIdleListener { flutterApi.onCameraIdle {} }
this.mapView.addOnDidBecomeIdleListener { flutterApi.onIdle {} }
this.mapLibreMap.addOnCameraMoveStartedListener { reason ->
val changeReason =
when (reason) {
Expand All @@ -137,14 +154,14 @@
REASON_DEVELOPER_ANIMATION -> CameraChangeReason.DEVELOPER_ANIMATION
else -> null
}
if (changeReason != null) flutterApi.onStartMoveCamera(changeReason) { }
if (changeReason != null) flutterApi.onStartMoveCamera(changeReason) {}
}
val style = Style.Builder().fromUri(mapOptions.style)
mapLibreMap.setStyle(style) { loadedStyle ->
this.style = loadedStyle
flutterApi.onStyleLoaded { }
flutterApi.onStyleLoaded {}
}
flutterApi.onMapReady { }
flutterApi.onMapReady {}
}

override fun dispose() {
Expand All @@ -156,7 +173,7 @@
private fun parsePaintProperties(entries: Map<String, Any>): Array<PropertyValue<*>> =
entries
.map { entry ->
// println("${entry.key}; ${entry.value::class.java.typeName}; ${entry.value}")
// println("${entry.key}; ${entry.value::class.java.typeName}; ${entry.value}")
when (entry.value) {
is ArrayList<*> -> {
val value = entry.value as ArrayList<*>
Expand All @@ -183,7 +200,7 @@
private fun parseLayoutProperties(entries: Map<String, Any>): Array<PropertyValue<*>> =
entries
.map { entry ->
// println("${entry.key}; ${entry.value::class.java.typeName}; ${entry.value}")
// println("${entry.key}; ${entry.value::class.java.typeName}; ${entry.value}")
when (entry.value) {
is ArrayList<*> -> {
val value = entry.value as ArrayList<*>
Expand Down Expand Up @@ -341,7 +358,7 @@
callback: (Result<Unit>) -> Unit,
) {
val layer = RasterLayer(id, sourceId)
// layer.setProperties(*parseProperties(paint), *parseProperties(layout))
// layer.setProperties(*parseProperties(paint), *parseProperties(layout))
if (belowLayerId == null) {
mapLibreMap.style?.addLayer(layer)
} else {
Expand Down Expand Up @@ -389,4 +406,54 @@
mapLibreMap.style?.addImage(id, bitmap)
callback(Result.success(Unit))
}

override fun toggleLongPressMove(enabled: Boolean) {
dragGesturesEnabled = enabled
}

inner class LongPressMoveGestureListener : MoveGestureDetector.OnMoveGestureListener {
override fun onMoveBegin(detector: MoveGestureDetector): Boolean {
val pointLatLng = motionEventToLngLat(detector.currentEvent)
flutterApi.onLongPressMove(LongPressEventType.BEGIN, pointLatLng) {}
return true
}

override fun onMove(
detector: MoveGestureDetector,
distanceX: Float,
distanceY: Float,
): Boolean {
val pointLatLng = motionEventToLngLat(detector.currentEvent)
if (detector.pointersCount > 1) {
stopDragging(pointLatLng)
return true
}

flutterApi.onLongPressMove(LongPressEventType.MOVE, pointLatLng) {}
return true
}

override fun onMoveEnd(
detector: MoveGestureDetector,
velocityX: Float,
velocityY: Float,
) {
val pointLatLng = motionEventToLngLat(detector.currentEvent)
stopDragging(pointLatLng)
}

private fun stopDragging(point: LngLat) {
flutterApi.onLongPressMove(LongPressEventType.END, point) {}

// Reset the move gesture listener to the default one.
mapLibreMap.setGesturesManager(defaultGesturesManager, true, true)
mapLibreMap.uiSettings.setAllGesturesEnabled(true)
}

private fun motionEventToLngLat(event: MotionEvent): LngLat {
val point = PointF(event.x, event.y)
val latLng = mapLibreMap.projection.fromScreenLocation(point)
return LngLat(latLng.longitude, latLng.latitude)
}
}
}
Loading
Loading