@rnmapbox/maps 10.3.2-rc.1 → 10.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt +2 -0
- package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerView.kt +0 -2
- package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotation.kt +6 -2
- package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationCoordinator.kt +10 -2
- package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManagerView.kt +143 -0
- package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotationManagerViewManager.kt +105 -0
- package/android/src/main/java/com/rnmapbox/rnmbx/components/mapview/RNMBXMapView.kt +33 -7
- package/ios/RNMBX/RNMBXMapView.swift +69 -7
- package/ios/RNMBX/RNMBXPointAnnotation.swift +11 -5
- package/ios/RNMBX/RNMBXPointAnnotationManagerComponentView.h +15 -0
- package/ios/RNMBX/RNMBXPointAnnotationManagerComponentView.mm +98 -0
- package/ios/RNMBX/RNMBXPointAnnotationManagerComponentView.swift +130 -0
- package/ios/RNMBX/rnmapbox_maps-Swift.pre.h +1 -1
- package/lib/module/Mapbox.native.js +1 -0
- package/lib/module/Mapbox.native.js.map +1 -1
- package/lib/module/components/PointAnnotationManager.js +37 -0
- package/lib/module/components/PointAnnotationManager.js.map +1 -0
- package/lib/module/components/StyleImport.js +9 -1
- package/lib/module/components/StyleImport.js.map +1 -1
- package/lib/module/specs/RNMBXPointAnnotationManagerNativeComponent.ts +28 -0
- package/lib/typescript/scripts/autogenHelpers/DocJSONBuilder.d.mts.map +1 -1
- package/lib/typescript/src/Mapbox.native.d.ts +2 -0
- package/lib/typescript/src/Mapbox.native.d.ts.map +1 -1
- package/lib/typescript/src/components/PointAnnotationManager.d.ts +59 -0
- package/lib/typescript/src/components/PointAnnotationManager.d.ts.map +1 -0
- package/lib/typescript/src/components/StyleImport.d.ts +63 -3
- package/lib/typescript/src/components/StyleImport.d.ts.map +1 -1
- package/lib/typescript/src/specs/RNMBXPointAnnotationManagerNativeComponent.d.ts +20 -0
- package/lib/typescript/src/specs/RNMBXPointAnnotationManagerNativeComponent.d.ts.map +1 -0
- package/package.json +6 -2
- package/rnmapbox-maps.podspec +12 -3
- package/src/Mapbox.native.ts +2 -0
- package/src/components/PointAnnotationManager.tsx +97 -0
- package/src/components/StyleImport.tsx +71 -4
- package/src/specs/RNMBXPointAnnotationManagerNativeComponent.ts +28 -0
|
@@ -11,6 +11,7 @@ import com.rnmapbox.rnmbx.components.annotation.RNMBXCalloutManager
|
|
|
11
11
|
import com.rnmapbox.rnmbx.components.annotation.RNMBXMarkerViewContentManager
|
|
12
12
|
import com.rnmapbox.rnmbx.components.annotation.RNMBXMarkerViewManager
|
|
13
13
|
import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationManager
|
|
14
|
+
import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationManagerViewManager
|
|
14
15
|
import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationModule
|
|
15
16
|
import com.rnmapbox.rnmbx.components.camera.RNMBXCameraManager
|
|
16
17
|
import com.rnmapbox.rnmbx.components.camera.RNMBXCameraModule
|
|
@@ -135,6 +136,7 @@ class RNMBXPackage : TurboReactPackage() {
|
|
|
135
136
|
managers.add(RNMBXMarkerViewManager(reactApplicationContext))
|
|
136
137
|
managers.add(RNMBXMarkerViewContentManager(reactApplicationContext))
|
|
137
138
|
managers.add(RNMBXPointAnnotationManager(reactApplicationContext, getViewTagResolver(reactApplicationContext, "RNMBXPointAnnotationManager")))
|
|
139
|
+
managers.add(RNMBXPointAnnotationManagerViewManager(reactApplicationContext))
|
|
138
140
|
managers.add(RNMBXCalloutManager())
|
|
139
141
|
managers.add(RNMBXNativeUserLocationManager())
|
|
140
142
|
managers.add(RNMBXCustomLocationProviderManager())
|
|
@@ -129,8 +129,6 @@ class RNMBXMarkerView(context: Context?, private val mManager: RNMBXMarkerViewMa
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
if (view.width == 0 || view.height == 0) {
|
|
132
|
-
// Fixes https://github.com/rnmapbox/maps/issues/4206
|
|
133
|
-
// Wait for the next layout via onLayoutChange
|
|
134
132
|
return
|
|
135
133
|
}
|
|
136
134
|
|
package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXPointAnnotation.kt
CHANGED
|
@@ -27,6 +27,9 @@ import com.rnmapbox.rnmbx.v11compat.annotation.*;
|
|
|
27
27
|
class RNMBXPointAnnotation(private val mContext: Context, private val mManager: RNMBXPointAnnotationManager) : AbstractMapFeature(mContext), View.OnLayoutChangeListener {
|
|
28
28
|
|
|
29
29
|
var pointAnnotations: RNMBXPointAnnotationCoordinator? = null
|
|
30
|
+
|
|
31
|
+
var parentCoordinator: RNMBXPointAnnotationCoordinator? = null
|
|
32
|
+
|
|
30
33
|
var annotation: PointAnnotation? = null
|
|
31
34
|
private set
|
|
32
35
|
private var mMap: MapboxMap? = null
|
|
@@ -97,7 +100,7 @@ class RNMBXPointAnnotation(private val mContext: Context, private val mManager:
|
|
|
97
100
|
override fun addToMap(mapView: RNMBXMapView) {
|
|
98
101
|
super.addToMap(mapView)
|
|
99
102
|
mMap = mapView.getMapboxMap()
|
|
100
|
-
pointAnnotations = mapView.pointAnnotations
|
|
103
|
+
pointAnnotations = parentCoordinator ?: mapView.pointAnnotations
|
|
101
104
|
makeMarker()
|
|
102
105
|
if (mChildView != null) {
|
|
103
106
|
if (!mChildView!!.isAttachedToWindow) {
|
|
@@ -117,7 +120,8 @@ class RNMBXPointAnnotation(private val mContext: Context, private val mManager:
|
|
|
117
120
|
override fun removeFromMap(mapView: RNMBXMapView, reason: RemovalReason): Boolean {
|
|
118
121
|
val map = mMapView ?: mapView
|
|
119
122
|
|
|
120
|
-
|
|
123
|
+
val coordinator = pointAnnotations ?: map.pointAnnotations
|
|
124
|
+
annotation?.let { coordinator.delete(it) }
|
|
121
125
|
|
|
122
126
|
mChildView?.let { map.offscreenAnnotationViewContainer?.removeView(it) }
|
|
123
127
|
calloutView?.let { map.offscreenAnnotationViewContainer?.removeView(it)}
|
|
@@ -13,7 +13,7 @@ import com.mapbox.maps.plugin.annotation.generated.createPointAnnotationManager
|
|
|
13
13
|
import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotation
|
|
14
14
|
import com.rnmapbox.rnmbx.utils.Logger
|
|
15
15
|
|
|
16
|
-
class RNMBXPointAnnotationCoordinator(val mapView: MapView) {
|
|
16
|
+
class RNMBXPointAnnotationCoordinator(val mapView: MapView, layerId: String? = "RNMBX-mapview-annotations") {
|
|
17
17
|
val manager: PointAnnotationManager;
|
|
18
18
|
var annotationClicked = false
|
|
19
19
|
var annotationDragged = false
|
|
@@ -24,7 +24,11 @@ class RNMBXPointAnnotationCoordinator(val mapView: MapView) {
|
|
|
24
24
|
val callouts: MutableMap<String, RNMBXPointAnnotation> = hashMapOf()
|
|
25
25
|
|
|
26
26
|
init {
|
|
27
|
-
manager =
|
|
27
|
+
manager = if (layerId != null) {
|
|
28
|
+
mapView.annotations.createPointAnnotationManager(AnnotationConfig(layerId = layerId))
|
|
29
|
+
} else {
|
|
30
|
+
mapView.annotations.createPointAnnotationManager()
|
|
31
|
+
}
|
|
28
32
|
manager.addClickListener(OnPointAnnotationClickListener { pointAnnotation ->
|
|
29
33
|
onAnnotationClick(pointAnnotation)
|
|
30
34
|
false
|
|
@@ -161,6 +165,10 @@ class RNMBXPointAnnotationCoordinator(val mapView: MapView) {
|
|
|
161
165
|
annotations[annotation.iD!!] = annotation
|
|
162
166
|
}
|
|
163
167
|
|
|
168
|
+
fun destroy() {
|
|
169
|
+
mapView.annotations.removeAnnotationManager(manager)
|
|
170
|
+
}
|
|
171
|
+
|
|
164
172
|
companion object {
|
|
165
173
|
const val LOG_TAG = "RNMBXPointAnnotationCoordinator";
|
|
166
174
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
package com.rnmapbox.rnmbx.components.annotation
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.view.View
|
|
5
|
+
import com.rnmapbox.rnmbx.components.AbstractMapFeature
|
|
6
|
+
import com.rnmapbox.rnmbx.components.RemovalReason
|
|
7
|
+
import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView
|
|
8
|
+
import com.rnmapbox.rnmbx.utils.Logger
|
|
9
|
+
|
|
10
|
+
class RNMBXPointAnnotationManagerView(context: Context) : AbstractMapFeature(context) {
|
|
11
|
+
var reactId: String? = null
|
|
12
|
+
var isDefault: Boolean = false
|
|
13
|
+
|
|
14
|
+
var slot: String? = null
|
|
15
|
+
set(value) { field = value; applyProps() }
|
|
16
|
+
var iconAllowOverlap: Boolean? = null
|
|
17
|
+
set(value) { field = value; applyProps() }
|
|
18
|
+
var iconIgnorePlacement: Boolean? = null
|
|
19
|
+
set(value) { field = value; applyProps() }
|
|
20
|
+
var iconOptional: Boolean? = null
|
|
21
|
+
set(value) { field = value; applyProps() }
|
|
22
|
+
var textAllowOverlap: Boolean? = null
|
|
23
|
+
set(value) { field = value; applyProps() }
|
|
24
|
+
var textIgnorePlacement: Boolean? = null
|
|
25
|
+
set(value) { field = value; applyProps() }
|
|
26
|
+
var textOptional: Boolean? = null
|
|
27
|
+
set(value) { field = value; applyProps() }
|
|
28
|
+
|
|
29
|
+
private val annotations = mutableListOf<RNMBXPointAnnotation>()
|
|
30
|
+
private var coordinator: RNMBXPointAnnotationCoordinator? = null
|
|
31
|
+
|
|
32
|
+
fun addAnnotation(childView: View, childPosition: Int) {
|
|
33
|
+
if (childView !is RNMBXPointAnnotation) {
|
|
34
|
+
Logger.w(LOG_TAG, "PointAnnotationManager: only PointAnnotation children are supported")
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
annotations.add(childPosition, childView)
|
|
38
|
+
val mapView = mMapView
|
|
39
|
+
if (mapView != null) {
|
|
40
|
+
ensureCoordinator(mapView)
|
|
41
|
+
attachAnnotation(childView, mapView)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fun removeAnnotationAt(childPosition: Int) {
|
|
46
|
+
val childView = annotations.removeAt(childPosition)
|
|
47
|
+
val mapView = mMapView
|
|
48
|
+
if (mapView != null) {
|
|
49
|
+
coordinator?.remove(childView)
|
|
50
|
+
childView.removeFromMap(mapView, RemovalReason.VIEW_REMOVAL)
|
|
51
|
+
}
|
|
52
|
+
childView.parentCoordinator = null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override fun getChildAt(childPosition: Int): View {
|
|
56
|
+
return annotations[childPosition]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
override fun getChildCount(): Int {
|
|
60
|
+
return annotations.size
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private fun attachAnnotation(annotation: RNMBXPointAnnotation, mapView: RNMBXMapView) {
|
|
64
|
+
val coordinator = coordinator ?: return
|
|
65
|
+
annotation.parentCoordinator = coordinator
|
|
66
|
+
coordinator.add(annotation)
|
|
67
|
+
annotation.addToMap(mapView)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private fun ensureCoordinator(mapView: RNMBXMapView) {
|
|
71
|
+
if (coordinator != null) return
|
|
72
|
+
coordinator = if (isDefault) {
|
|
73
|
+
val existing = mapView.defaultPointAnnotationManagerView
|
|
74
|
+
if (existing != null && existing !== this) {
|
|
75
|
+
Logger.w(LOG_TAG, "PointAnnotationManager: multiple default managers declared, ignoring extra default")
|
|
76
|
+
} else {
|
|
77
|
+
mapView.defaultPointAnnotationManagerView = this
|
|
78
|
+
}
|
|
79
|
+
mapView.pointAnnotations
|
|
80
|
+
} else {
|
|
81
|
+
val c = RNMBXPointAnnotationCoordinator(mapView.mapView, reactId)
|
|
82
|
+
mapView.registerPointAnnotationCoordinator(c)
|
|
83
|
+
c
|
|
84
|
+
}
|
|
85
|
+
applyProps()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override fun addToMap(mapView: RNMBXMapView) {
|
|
89
|
+
super.addToMap(mapView)
|
|
90
|
+
ensureCoordinator(mapView)
|
|
91
|
+
for (annotation in annotations) {
|
|
92
|
+
attachAnnotation(annotation, mapView)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
override fun removeFromMap(mapView: RNMBXMapView, reason: RemovalReason): Boolean {
|
|
97
|
+
for (annotation in annotations) {
|
|
98
|
+
coordinator?.remove(annotation)
|
|
99
|
+
annotation.removeFromMap(mapView, reason)
|
|
100
|
+
annotation.parentCoordinator = null
|
|
101
|
+
}
|
|
102
|
+
coordinator?.let { c ->
|
|
103
|
+
if (isDefault) {
|
|
104
|
+
// The default coordinator is shared with bare annotations; leave it in
|
|
105
|
+
// place, just clear the configuration this view applied.
|
|
106
|
+
c.manager.slot = null
|
|
107
|
+
c.manager.iconAllowOverlap = null
|
|
108
|
+
c.manager.iconIgnorePlacement = null
|
|
109
|
+
c.manager.iconOptional = null
|
|
110
|
+
c.manager.textAllowOverlap = null
|
|
111
|
+
c.manager.textIgnorePlacement = null
|
|
112
|
+
c.manager.textOptional = null
|
|
113
|
+
} else {
|
|
114
|
+
mapView.unregisterPointAnnotationCoordinator(c)
|
|
115
|
+
c.destroy()
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (mapView.defaultPointAnnotationManagerView === this) {
|
|
119
|
+
mapView.defaultPointAnnotationManagerView = null
|
|
120
|
+
}
|
|
121
|
+
coordinator = null
|
|
122
|
+
return super.removeFromMap(mapView, reason)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private fun applyProps() {
|
|
126
|
+
val manager = coordinator?.manager ?: return
|
|
127
|
+
manager.slot = slot
|
|
128
|
+
// Only write when the prop is set. The annotation plugin defaults
|
|
129
|
+
// iconAllowOverlap/iconIgnorePlacement to true so annotations always show;
|
|
130
|
+
// writing null here would clobber that back to the style default (false) and
|
|
131
|
+
// cull colliding pins.
|
|
132
|
+
iconAllowOverlap?.let { manager.iconAllowOverlap = it }
|
|
133
|
+
iconIgnorePlacement?.let { manager.iconIgnorePlacement = it }
|
|
134
|
+
iconOptional?.let { manager.iconOptional = it }
|
|
135
|
+
textAllowOverlap?.let { manager.textAllowOverlap = it }
|
|
136
|
+
textIgnorePlacement?.let { manager.textIgnorePlacement = it }
|
|
137
|
+
textOptional?.let { manager.textOptional = it }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
companion object {
|
|
141
|
+
const val LOG_TAG = "RNMBXPointAnnotationManagerView"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
package com.rnmapbox.rnmbx.components.annotation
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import com.facebook.react.bridge.Dynamic
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.bridge.ReadableType
|
|
7
|
+
import com.facebook.react.common.MapBuilder
|
|
8
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
9
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
10
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
11
|
+
import com.facebook.react.viewmanagers.RNMBXPointAnnotationManagerManagerDelegate
|
|
12
|
+
import com.facebook.react.viewmanagers.RNMBXPointAnnotationManagerManagerInterface
|
|
13
|
+
import com.rnmapbox.rnmbx.components.AbstractEventEmitter
|
|
14
|
+
|
|
15
|
+
class RNMBXPointAnnotationManagerViewManager(context: ReactApplicationContext) :
|
|
16
|
+
AbstractEventEmitter<RNMBXPointAnnotationManagerView>(context),
|
|
17
|
+
RNMBXPointAnnotationManagerManagerInterface<RNMBXPointAnnotationManagerView> {
|
|
18
|
+
private val mDelegate: ViewManagerDelegate<RNMBXPointAnnotationManagerView> =
|
|
19
|
+
RNMBXPointAnnotationManagerManagerDelegate(this)
|
|
20
|
+
|
|
21
|
+
override fun getDelegate(): ViewManagerDelegate<RNMBXPointAnnotationManagerView> {
|
|
22
|
+
return mDelegate
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
override fun customEvents(): Map<String, String>? {
|
|
26
|
+
return MapBuilder.builder<String, String>().build()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override fun getName(): String {
|
|
30
|
+
return REACT_CLASS
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override fun createViewInstance(context: ThemedReactContext): RNMBXPointAnnotationManagerView {
|
|
34
|
+
return RNMBXPointAnnotationManagerView(context)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override fun addView(parent: RNMBXPointAnnotationManagerView, childView: View, childPosition: Int) {
|
|
38
|
+
parent.addAnnotation(childView, childPosition)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
override fun removeViewAt(parent: RNMBXPointAnnotationManagerView, childPosition: Int) {
|
|
42
|
+
parent.removeAnnotationAt(childPosition)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun getChildAt(parent: RNMBXPointAnnotationManagerView, childPosition: Int): View {
|
|
46
|
+
return parent.getChildAt(childPosition)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
override fun getChildCount(parent: RNMBXPointAnnotationManagerView): Int {
|
|
50
|
+
return parent.getChildCount()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private fun optBoolean(value: Dynamic): Boolean? {
|
|
54
|
+
return if (value.isNull || value.type != ReadableType.Boolean) null else value.asBoolean()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
companion object {
|
|
58
|
+
const val REACT_CLASS = "RNMBXPointAnnotationManager"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@ReactProp(name = "id")
|
|
62
|
+
override fun setId(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
63
|
+
view.reactId = if (value.isNull) null else value.asString()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@ReactProp(name = "isDefault")
|
|
67
|
+
override fun setIsDefault(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
68
|
+
view.isDefault = !value.isNull && value.asBoolean()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@ReactProp(name = "slot")
|
|
72
|
+
override fun setSlot(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
73
|
+
view.slot = if (value.isNull) null else value.asString()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@ReactProp(name = "iconAllowOverlap")
|
|
77
|
+
override fun setIconAllowOverlap(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
78
|
+
view.iconAllowOverlap = optBoolean(value)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@ReactProp(name = "iconIgnorePlacement")
|
|
82
|
+
override fun setIconIgnorePlacement(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
83
|
+
view.iconIgnorePlacement = optBoolean(value)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@ReactProp(name = "iconOptional")
|
|
87
|
+
override fun setIconOptional(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
88
|
+
view.iconOptional = optBoolean(value)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@ReactProp(name = "textAllowOverlap")
|
|
92
|
+
override fun setTextAllowOverlap(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
93
|
+
view.textAllowOverlap = optBoolean(value)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@ReactProp(name = "textIgnorePlacement")
|
|
97
|
+
override fun setTextIgnorePlacement(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
98
|
+
view.textIgnorePlacement = optBoolean(value)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@ReactProp(name = "textOptional")
|
|
102
|
+
override fun setTextOptional(view: RNMBXPointAnnotationManagerView, value: Dynamic) {
|
|
103
|
+
view.textOptional = optBoolean(value)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -61,6 +61,7 @@ import com.rnmapbox.rnmbx.utils.extensions.toReadableArray
|
|
|
61
61
|
import java.util.*
|
|
62
62
|
|
|
63
63
|
import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationCoordinator
|
|
64
|
+
import com.rnmapbox.rnmbx.components.annotation.RNMBXPointAnnotationManagerView
|
|
64
65
|
import com.rnmapbox.rnmbx.components.images.ImageManager
|
|
65
66
|
import com.rnmapbox.rnmbx.utils.extensions.toStringKeyPairs
|
|
66
67
|
|
|
@@ -135,16 +136,35 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie
|
|
|
135
136
|
|
|
136
137
|
private val mSources: MutableMap<String, RNMBXSource<*>>
|
|
137
138
|
private val mImages: MutableList<RNMBXImages>
|
|
138
|
-
|
|
139
|
+
val pointAnnotationCoordinators = mutableListOf<RNMBXPointAnnotationCoordinator>()
|
|
140
|
+
private var pointAnnotationGesturesInited = false
|
|
141
|
+
|
|
142
|
+
var defaultPointAnnotationManagerView: RNMBXPointAnnotationManagerView? = null
|
|
143
|
+
|
|
144
|
+
private fun ensurePointAnnotationGestures() {
|
|
145
|
+
if (pointAnnotationGesturesInited) return
|
|
139
146
|
val gesturesPlugin: GesturesPlugin = mapView.gestures
|
|
140
147
|
gesturesPlugin.removeOnMapClickListener(this)
|
|
141
148
|
gesturesPlugin.removeOnMapLongClickListener(this)
|
|
142
|
-
|
|
143
|
-
val result = RNMBXPointAnnotationCoordinator(mapView)
|
|
144
|
-
|
|
145
149
|
gesturesPlugin.addOnMapClickListener(this)
|
|
146
150
|
gesturesPlugin.addOnMapLongClickListener(this)
|
|
151
|
+
pointAnnotationGesturesInited = true
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
fun registerPointAnnotationCoordinator(coordinator: RNMBXPointAnnotationCoordinator) {
|
|
155
|
+
ensurePointAnnotationGestures()
|
|
156
|
+
if (!pointAnnotationCoordinators.contains(coordinator)) {
|
|
157
|
+
pointAnnotationCoordinators.add(coordinator)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
fun unregisterPointAnnotationCoordinator(coordinator: RNMBXPointAnnotationCoordinator) {
|
|
162
|
+
pointAnnotationCoordinators.remove(coordinator)
|
|
163
|
+
}
|
|
147
164
|
|
|
165
|
+
public val pointAnnotations: RNMBXPointAnnotationCoordinator by lazy {
|
|
166
|
+
val result = RNMBXPointAnnotationCoordinator(mapView)
|
|
167
|
+
registerPointAnnotationCoordinator(result)
|
|
148
168
|
result
|
|
149
169
|
}
|
|
150
170
|
private var mProjection: ProjectionName = ProjectionName.MERCATOR
|
|
@@ -690,11 +710,17 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie
|
|
|
690
710
|
|
|
691
711
|
override fun onMapClick(point: Point): Boolean {
|
|
692
712
|
val _this = this
|
|
693
|
-
if (
|
|
713
|
+
if (pointAnnotationCoordinators.any { it.getAndClearAnnotationClicked() }) {
|
|
694
714
|
return true
|
|
695
715
|
}
|
|
696
716
|
if (deselectAnnotationOnTap) {
|
|
697
|
-
|
|
717
|
+
var deselected = false
|
|
718
|
+
for (coordinator in pointAnnotationCoordinators) {
|
|
719
|
+
if (coordinator.deselectSelectedAnnotation()) {
|
|
720
|
+
deselected = true
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
if (deselected) {
|
|
698
724
|
return true
|
|
699
725
|
}
|
|
700
726
|
}
|
|
@@ -728,7 +754,7 @@ open class RNMBXMapView(private val mContext: Context, var mManager: RNMBXMapVie
|
|
|
728
754
|
|
|
729
755
|
override fun onMapLongClick(point: Point): Boolean {
|
|
730
756
|
val _this = this
|
|
731
|
-
if (
|
|
757
|
+
if (pointAnnotationCoordinators.any { it.getAndClearAnnotationDragged() }) {
|
|
732
758
|
return true
|
|
733
759
|
}
|
|
734
760
|
val screenPointPx = mMap?.pixelForCoordinate(point)
|
|
@@ -229,12 +229,31 @@ open class RNMBXMapView: UIView, RCTInvalidating {
|
|
|
229
229
|
|
|
230
230
|
var cancelables = Set<AnyCancelable>()
|
|
231
231
|
|
|
232
|
+
var pointAnnotationManagers: [RNMBXPointAnnotationManager] = []
|
|
233
|
+
|
|
234
|
+
weak var defaultPointAnnotationManagerView: RNMBXPointAnnotationManagerView? = nil
|
|
235
|
+
|
|
232
236
|
lazy var pointAnnotationManager : RNMBXPointAnnotationManager = {
|
|
233
|
-
let result = RNMBXPointAnnotationManager(annotations: mapView.annotations, mapView: mapView)
|
|
237
|
+
let result = RNMBXPointAnnotationManager(annotations: mapView.annotations, mapView: mapView, id: "RNMBX-mapview-point-annotations")
|
|
234
238
|
self._removeMapboxLongPressGestureRecognizer()
|
|
239
|
+
self.registerPointAnnotationManager(result)
|
|
235
240
|
return result
|
|
236
241
|
}()
|
|
237
242
|
|
|
243
|
+
func registerPointAnnotationManager(_ manager: RNMBXPointAnnotationManager) {
|
|
244
|
+
if !pointAnnotationManagers.contains(where: { $0 === manager }) {
|
|
245
|
+
pointAnnotationManagers.append(manager)
|
|
246
|
+
}
|
|
247
|
+
// We handle taps ourselves; detach Mapbox's built-in tap target for this manager.
|
|
248
|
+
if let mapView = _mapView {
|
|
249
|
+
mapView.gestures.singleTapGestureRecognizer.removeTarget(manager.manager, action: nil)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
func unregisterPointAnnotationManager(_ manager: RNMBXPointAnnotationManager) {
|
|
254
|
+
pointAnnotationManagers.removeAll { $0 === manager }
|
|
255
|
+
}
|
|
256
|
+
|
|
238
257
|
lazy var calloutAnnotationManager : MapboxMaps.PointAnnotationManager = {
|
|
239
258
|
let manager = mapView.annotations.makePointAnnotationManager(id: "RNMBX-mapview-callouts")
|
|
240
259
|
manager.iconAllowOverlap = true
|
|
@@ -1284,7 +1303,10 @@ extension RNMBXMapView {
|
|
|
1284
1303
|
func applyOnPress() {
|
|
1285
1304
|
let singleTapGestureRecognizer = self.mapView.gestures.singleTapGestureRecognizer
|
|
1286
1305
|
|
|
1287
|
-
|
|
1306
|
+
// Detach Mapbox's built-in tap target for every manager; we handle taps ourselves.
|
|
1307
|
+
for manager in pointAnnotationManagers {
|
|
1308
|
+
singleTapGestureRecognizer.removeTarget(manager.manager, action: nil)
|
|
1309
|
+
}
|
|
1288
1310
|
singleTapGestureRecognizer.addTarget(self, action: #selector(doHandleTap(_:)))
|
|
1289
1311
|
|
|
1290
1312
|
self.tapDelegate = IgnoreRNMBXMakerViewGestureDelegate(originalDelegate: singleTapGestureRecognizer.delegate)
|
|
@@ -1386,13 +1408,34 @@ extension RNMBXMapView: GestureManagerDelegate {
|
|
|
1386
1408
|
return event
|
|
1387
1409
|
}
|
|
1388
1410
|
|
|
1411
|
+
private func handleTapAcrossPointAnnotationManagers(_ sender: UITapGestureRecognizer, index: Int, noneFound: @escaping () -> Void) {
|
|
1412
|
+
if index >= pointAnnotationManagers.count {
|
|
1413
|
+
noneFound()
|
|
1414
|
+
return
|
|
1415
|
+
}
|
|
1416
|
+
pointAnnotationManagers[index].handleTap(sender) { _ in
|
|
1417
|
+
self.handleTapAcrossPointAnnotationManagers(sender, index: index + 1, noneFound: noneFound)
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
@discardableResult
|
|
1422
|
+
func deselectCurrentlySelectedPointAnnotation(deselectAnnotationOnTap: Bool) -> Bool {
|
|
1423
|
+
var any = false
|
|
1424
|
+
for manager in pointAnnotationManagers {
|
|
1425
|
+
if manager.deselectCurrentlySelected(deselectAnnotationOnTap: deselectAnnotationOnTap) {
|
|
1426
|
+
any = true
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
return any
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1389
1432
|
@objc
|
|
1390
1433
|
func doHandleTap(_ sender: UITapGestureRecognizer) {
|
|
1391
1434
|
let tapPoint = sender.location(in: self)
|
|
1392
|
-
|
|
1435
|
+
handleTapAcrossPointAnnotationManagers(sender, index: 0) {
|
|
1393
1436
|
DispatchQueue.main.async {
|
|
1394
1437
|
if (self.deselectAnnotationOnTap) {
|
|
1395
|
-
if (self.
|
|
1438
|
+
if (self.deselectCurrentlySelectedPointAnnotation(deselectAnnotationOnTap: true)) {
|
|
1396
1439
|
return
|
|
1397
1440
|
}
|
|
1398
1441
|
}
|
|
@@ -1435,10 +1478,23 @@ extension RNMBXMapView: GestureManagerDelegate {
|
|
|
1435
1478
|
}
|
|
1436
1479
|
}
|
|
1437
1480
|
|
|
1481
|
+
private func handleLongPressAcrossPointAnnotationManagers(_ sender: UILongPressGestureRecognizer, index: Int, noneFound: @escaping () -> Void) {
|
|
1482
|
+
if index >= pointAnnotationManagers.count {
|
|
1483
|
+
noneFound()
|
|
1484
|
+
return
|
|
1485
|
+
}
|
|
1486
|
+
pointAnnotationManagers[index].handleLongPress(sender) { _ in
|
|
1487
|
+
self.handleLongPressAcrossPointAnnotationManagers(sender, index: index + 1, noneFound: noneFound)
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1438
1491
|
@objc
|
|
1439
1492
|
func doHandleLongPress(_ sender: UILongPressGestureRecognizer) {
|
|
1440
1493
|
let position = sender.location(in: self)
|
|
1441
|
-
|
|
1494
|
+
handleLongPressAcrossPointAnnotationManagers(sender, index: 0) {
|
|
1495
|
+
// Source-based drag handling only starts on `.began`; annotation drag
|
|
1496
|
+
// continuation (.changed/.ended) is consumed by the owning manager above.
|
|
1497
|
+
guard sender.state == .began else { return }
|
|
1442
1498
|
DispatchQueue.main.async {
|
|
1443
1499
|
let draggableSources = self.draggableSources()
|
|
1444
1500
|
self.doHandleTapInSources(sources: draggableSources, tapPoint: position, hits: [:], touchedSources: []) { (hits, draggedSources) in
|
|
@@ -2026,8 +2082,12 @@ class RNMBXPointAnnotationManager : AnnotationInteractionDelegate {
|
|
|
2026
2082
|
var manager : MapboxMaps.PointAnnotationManager
|
|
2027
2083
|
weak var mapView : MapView? = nil
|
|
2028
2084
|
|
|
2029
|
-
init(annotations: AnnotationOrchestrator, mapView: MapView) {
|
|
2030
|
-
|
|
2085
|
+
init(annotations: AnnotationOrchestrator, mapView: MapView, id: String? = nil) {
|
|
2086
|
+
if let id = id {
|
|
2087
|
+
manager = annotations.makePointAnnotationManager(id: id)
|
|
2088
|
+
} else {
|
|
2089
|
+
manager = annotations.makePointAnnotationManager()
|
|
2090
|
+
}
|
|
2031
2091
|
manager.delegate = self
|
|
2032
2092
|
self.mapView = mapView
|
|
2033
2093
|
}
|
|
@@ -2119,6 +2179,7 @@ class RNMBXPointAnnotationManager : AnnotationInteractionDelegate {
|
|
|
2119
2179
|
|
|
2120
2180
|
case .changed:
|
|
2121
2181
|
guard var annotation = self.draggedAnnotation else {
|
|
2182
|
+
noAnnotationFound(sender)
|
|
2122
2183
|
return
|
|
2123
2184
|
}
|
|
2124
2185
|
|
|
@@ -2130,6 +2191,7 @@ class RNMBXPointAnnotationManager : AnnotationInteractionDelegate {
|
|
|
2130
2191
|
}
|
|
2131
2192
|
case .cancelled, .ended:
|
|
2132
2193
|
guard let annotation = self.draggedAnnotation else {
|
|
2194
|
+
noAnnotationFound(sender)
|
|
2133
2195
|
return
|
|
2134
2196
|
}
|
|
2135
2197
|
// Optionally notify some other delegate to tell them the drag finished.
|
|
@@ -12,6 +12,12 @@ final class WeakRef<T: AnyObject> {
|
|
|
12
12
|
public class RNMBXPointAnnotation : RNMBXInteractiveElement {
|
|
13
13
|
weak var manager: RNMBXPointAnnotationManager? = nil
|
|
14
14
|
|
|
15
|
+
weak var ownerManager: RNMBXPointAnnotationManager? = nil
|
|
16
|
+
|
|
17
|
+
var resolvedManager: RNMBXPointAnnotationManager? {
|
|
18
|
+
return ownerManager ?? map?.pointAnnotationManager
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
static let key = "RNMBXPointAnnotation"
|
|
16
22
|
static var gid = 0;
|
|
17
23
|
|
|
@@ -293,28 +299,28 @@ public class RNMBXPointAnnotation : RNMBXInteractiveElement {
|
|
|
293
299
|
|
|
294
300
|
extension RNMBXPointAnnotation {
|
|
295
301
|
func removeIfAdded() {
|
|
296
|
-
if added, let pointAnnotationManager =
|
|
302
|
+
if added, let pointAnnotationManager = resolvedManager {
|
|
297
303
|
pointAnnotationManager.remove(annotation)
|
|
298
304
|
added = false
|
|
299
305
|
}
|
|
300
306
|
}
|
|
301
|
-
|
|
307
|
+
|
|
302
308
|
@discardableResult
|
|
303
309
|
func addIfPossible() -> Bool {
|
|
304
310
|
if !added
|
|
305
311
|
&& annotation.point.coordinates.isValid()
|
|
306
312
|
&& (logged("PointAnnotation: missing id attribute") { return id }) != nil,
|
|
307
|
-
let pointAnnotationManager =
|
|
313
|
+
let pointAnnotationManager = resolvedManager {
|
|
308
314
|
pointAnnotationManager.add(annotation, self)
|
|
309
315
|
added = true
|
|
310
316
|
return true
|
|
311
317
|
}
|
|
312
318
|
return false
|
|
313
319
|
}
|
|
314
|
-
|
|
320
|
+
|
|
315
321
|
func update(callback: (_ annotation: inout PointAnnotation) -> Void) {
|
|
316
322
|
callback(&annotation)
|
|
317
|
-
if let pointAnnotationManager =
|
|
323
|
+
if let pointAnnotationManager = resolvedManager {
|
|
318
324
|
if added {
|
|
319
325
|
pointAnnotationManager.update(annotation)
|
|
320
326
|
} else if !added {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#ifdef __cplusplus
|
|
2
|
+
|
|
3
|
+
#import <UIKit/UIKit.h>
|
|
4
|
+
|
|
5
|
+
#import <React/RCTUIManager.h>
|
|
6
|
+
#import <React/RCTViewComponentView.h>
|
|
7
|
+
|
|
8
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
9
|
+
|
|
10
|
+
@interface RNMBXPointAnnotationManagerComponentView : RCTViewComponentView
|
|
11
|
+
|
|
12
|
+
@end
|
|
13
|
+
|
|
14
|
+
NS_ASSUME_NONNULL_END
|
|
15
|
+
#endif // __cplusplus
|